MemPrint and MemInput
#1
So, if there's a few absolute things that I've learned about what folks say about QB64 from over the years, two of the most prevalent have to be:
1) MEM IS HARD!! IT'S NOT FOR BEGINNERS!!
2) Opening files for INPUT and OUTPUT is the most basic of BASIC.  *EVERYONE* knows how to do this -- if not, then they'll learn it by the second lesson on learning QB64...

Now, I'm not saying I agree with point 1 -- I truly don't think that mem is all that hard to learn and use, which is why I've made videos and written a bazillion words on how to help folks understand it.   BUT, even after all that, the general consensus is "Mem is hard and not for beginners!"

But...  What if I told you guys that I was working on a way to bring those two concepts together?? That I was making a means so that one could use _MEM just as easily as they can use LINE INPUT and PRINT??

Don't believe it??

Then let me present.... Dum Dum De Dummmm:

Code: (Select All)
 Type Mem_File_Type
    inUse As Integer
    EOF_Marker As _Offset
    Current_Pos As _Offset
    Content As _MEM
End Type

Dim Shared MemFile(1 To 100) As Mem_File_Type
'BI HEADER INFO BEFORE THIS




handle = MemFileOpen
MemPrint handle, "Hello World", 1
MemPrint handle, "My name is Steve", 1
MemSeek handle, 0


Do Until MemEOF(handle)
    MemLineInput handle, temp$
    Print temp$
Loop





'BM FOOTER INFO AFTER THIS
Function MemFileOpen
    'Error codes for MemFileOpen
    '1: No mem files available.  (All 100 are in use!  Free some to use more!)
    For i = 1 To 100
        If MemFile(i).inUse = 0 Then Exit For
    Next
    If i > 100 Then MemFileOpen = 0 'can't open any more memfiles!
    MemFileOpen = i
    MemFile(i).inUse = -1 'TRUE
    MemFile(i).EOF_Marker = 0 'nothing is written in the file to begin with
    MemFile(i).Current_Pos = 0 'and we're at the start of our nothing in the file
    MemFile(i).Content = _MemNew(1000000) '1mb memfile by default
    $Checking:Off
    _MemFill MemFile(i).Content, MemFile(i).Content.OFFSET, MemFile(i).Content.SIZE, 0 As _UNSIGNED _BYTE
    'make certain to blank the file when opening it for the first time so we don't have unwanted characters in it.
    $Checking:On
End Function

Function MemEOF (memfile)
    If MemFile(memfile).inUse = 0 Then Error 53: Exit Function 'File Not Found Error message
    If MemFile(memfile).Current_Pos >= MemFile(memfile).EOF_Marker Then MemEOF = -1
End Function


Sub MemSeek (memfile, position As _Offset)
    If MemFile(memfile).inUse = 0 Then Error 53: Exit Sub 'File Not Found Error message
    If position < 0 Then Error 5: Exit Sub 'Invalid Function Call
    If position > MemFile(memfile).EOF_Marker Then Error 5: Exit Sub 'Invalid Function Call
    MemFile(memfile).Current_Pos = position
End Sub

Sub MemLineInput (memfile, what$)
    'only valid line endings here are CHR$(10), chr$(13), and chr$(13) + chr$(10)

    If MemFile(memfile).inUse = 0 Then Error 53: Exit Sub 'File Not Found Error message

    Dim As _Offset CP, EP, Size, L
    Dim tempM As _MEM
    tempM = MemFile(memfile).Content 'it's just much shorter to type!

    CP = MemFile(memfile).Current_Pos
    EP = MemFile(memfile).EOF_Marker
    If CP >= EP Then Error 62: Exit Sub 'INPUT PAST END OF FILE error
    Size = tempM.SIZE
    Do
        a$ = _MemGet(tempM, tempM.OFFSET + CP, String * 1)
        Select Case a$
            Case Chr$(13)
                a1$ = _MemGet(tempM, tempM.OFFSET + CP + 1, String * 1)
                If al$ = Chr$(10) Then CP = CP + 1 'move the Current Pointer past the 2nd character in a windows CRLF ending
                finished = -1
            Case Chr$(10)
                finished = -1
            Case Else
                temp$ = temp$ + a$
        End Select
        CP = CP + 1
        If CP >= EP Then finished = -1
    Loop Until finished
    MemFile(memfile).Current_Pos = CP
    what$ = temp$
End Sub



Sub MemPrint (memfile, what$, EOL_Type As Integer)
    'memfile is the memfile handle to print to
    'what$ is what we want to print
    'EOL_Type is the type of line ending we want after this print statement
    '1: This is a CHR$(10) line ending                  (Linux style line ending)
    '2: This is a CHR$(13) line ending                  (Old Mac style line ending)
    '3: This is a CHR$(13) + CHR$(10) line ending      (Old Windows style line ending)
    '4: This is a COMMA line ending.  Use this if writing continous CSV fields.
    '      (Think PRINT #1, stuff$, <-- see the comma there at the end of the print statement??)


    If MemFile(memfile).inUse = 0 Then Error 53: Exit Sub 'File Not Found Error message

    Dim CRLF As String
    Dim As _Offset CP, EP, Size, L

    Select Case EOL_Type
        Case 1: CRLF = Chr$(10)
        Case 2: CRLF = Chr$(13)
        Case 3: CRLF = Chr$(13) + Chr$(10)
        Case 4: CRLF = ","
    End Select
    CP = MemFile(memfile).Current_Pos
    EP = MemFile(memfile).EOF_Marker
    Size = MemFile(memfile).Content.SIZE
    L = Len(what$) + Len(CRLF)
    If CP + L > Size Then 'we're writing beyond the bounds of our reserved memory!
        Dim tempM As _MEM
        recheck:
        If Size <= 100000000 Then 'resize our memblock (to the limit) to save our data
            tempM = _MemNew(Size * 10)
            _MemCopy MemFile(memfile).Content, MemFile(memfile).Content.OFFSET, Size To tempM, tempM.OFFSET
            _MemFree MemFile(memfile).Content
            MemFile(memfile).Content = tempM
            Size = Size * 10
            GoTo recheck 'just to make certain that our reserved memory is now large enough to hold our data
        Else
            Error 61 'DISK FULL ERROR MESSAGE
            Exit Sub 'I'm coding a hard size limit of 1GB for each memfile opened!
            '        Anything larger than that, and I'm tossing a Disk Full Error
        End If
    End If
    _MemPut MemFile(memfile).Content, MemFile(memfile).Content.OFFSET + CP, what$ + CRLF
    MemFile(memfile).Current_Pos = CP + L
    If CP + L > EP Then MemFile(memfile).EOF_Marker = CP + L
End Sub



Here's the main code of relevance for the end user -- see how it'd compare to a normal file being opened in QB64:

Code: (Select All)
handle = MemFileOpen
MemPrint handle, "Hello World", 1
MemPrint handle, "My name is Steve", 1
MemSeek handle, 0


Do Until MemEOF(handle)
    MemLineInput handle, temp$
    Print temp$
Loop


The very first line here is a wee bit odd, but think of it as:   handle = FREEFILE    It basically gives you a free handle and readies a block of memory for you to make use of.

PRINT #1, "Hello World"
PRINT #1, "My name is Steve"

Hopefully you can see where the next lines would match up to a simple file PRINT statement?  That , 1 at the end there is basically the way of telling the program what file ending we want, or if we want to toss a comma at the end of this data, for CSVs.   (Think of it as being PRINT #1, "Hello World",  <-- do we put that comma there at the end, or not??)  ,1 says we're going with a normal CHR$(10) file ending at the end of the data.

The MemSeek is basically the same as the SEEK statement, with the exception that we start at position 0 rather than position 1.  (I may adjust this later, if folks feel its necessary.)

DO UNTIL EOF(1)
    LINE INPUT #1, temp$
    PRINT temp$
LOOP

And the next few lines should definitely be noticeably comparable to the file LINE INPUT method.  Right?



It's all in mem...  but it's simple PRINT and LINE INPUT style commands...

Is your mind blown yet??



Yet to do:

There needs to be a CLOSE statement to close the files and free the memory for good.
I also want to add 2 quick commands :  MemFileSave -- to save the mem block to disk.   MemFileLoad -- to load the file back into memory.

And what's the purpose to such a system??  Besides trying to make use of the speed of using mem?

To reduce disk reads and writes as much as possible and save wear and usage of SSDs.  Load the whole file at once.  Save the whole file at once.  Otherwise, just read and write to a mem block exactly as you normally would a file!  No need to track offsets.  No _memget or _memput....   Just simple PRINT and INPUT file access like folks are used to doing already.


Any and all comments and feedback is appreciated.  Post questions and suggestions galore!  Honestly, I'd say this is already 90% finished.  If anyone has any specific user requests, get them in *now*, before I wrap this up in the next day or so, and move on to something else.  Wink
Reply


Messages In This Thread
MemPrint and MemInput - by SMcNeill - 08-22-2022, 12:59 AM
RE: MemPrint and MemInput - by OldMoses - 08-22-2022, 01:56 AM
RE: MemPrint and MemInput - by SMcNeill - 08-22-2022, 02:04 AM
RE: MemPrint and MemInput - by SMcNeill - 08-22-2022, 10:01 AM
RE: MemPrint and MemInput - by justsomeguy - 08-22-2022, 11:09 AM
RE: MemPrint and MemInput - by SMcNeill - 08-22-2022, 11:14 AM
RE: MemPrint and MemInput - by SMcNeill - 08-22-2022, 03:03 PM
RE: MemPrint and MemInput - by justsomeguy - 08-22-2022, 08:59 PM



Users browsing this thread: 1 Guest(s)