EuroAssembler Index Manual Download Source Macros


Sitemap Links Forum Tests Projects

linf64.htm
Class
FILE64
Encoding
FileStatusEnc
Macros
FileAppend
FileAssign
FileClose
FileCreate
FileDelete
FileEach
FileEnclose
FileEnclose$
FileEncloseLn
FileExists?
FileFlush
FileGetSize
FileLoad
FileMapCreate
FileMapOpen
FileMkDir
FileMove
FileNameParse
FileOpen
FileRead
FileReset
FileStore
FileStreamAppend
FileStreamCreate
FileStreamOpen
FileStreamRead
FileStreamReadByte
FileStreamReadLn
FileStreamWrite
FileStreamWriteByte
FileStreamWrite$
FileStreamWriteDword
FileStreamWriteLn
FileStreamWriteRT
FileStreamWriteWord
FileWrite
FileWrite$
FileWriteLn
FileWriteRT

This library contains wrapper macros which encapsulate LinABI calls for most typical file operations in 64bit Linux . See also equivalent homonymous macroinstructions in linf32.htm, winf32.htm, winf64.htm.

File Access methodOpenData transferClose
read file at once - FileLoad FileClose
write file at once - FileStore-
standard readFileOpen FileReadFileClose
standard writeFileCreate FileWrite, FileWriteLn, FileWrite$FileClose
standard write at the end of fileFileAppend FileWrite, FileWriteLn, FileWrite$FileClose
memory mapped readFileMapOpen- FileClose
memory mapped writeFileMapCreate -FileClose
buffered readFileStreamOpen FileStreamReadByte, FileStreamRead, FileStreamReadLn FileClose
buffered writeFileStreamCreate FileStreamWriteByte, FileStreamWriteWord, FileStreamWriteDword, FileStreamWrite, FileStreamWriteLn, FileStreamWrite$FileClose
buffered write at end of fileFileStreamAppend FileStreamWriteByte, FileStreamWriteWord, FileStreamWriteDword, FileStreamWrite, FileStreamWriteLn, FileStreamWrite$FileClose
append to file - FileEnclose, FileEncloseLn, FileEnclose$-
special functionsFileReset FileAssign, FileExists?, FileNameParse, FileMove, FileMkDir, FileEach FileDelete

Macros return the results in registers, usually RAX. Other registers do not change. CF is set when error occurs, ZF is set at the end of file, DF must be always reset. Other flags are undefined.

Association of the FILE64 object with the name of file is provided separately, using the macro FileAssign. File must be assigned before opening.

Macro names suffixed with ~Ln write LineFeed character after the data. Macro names suffixed with ~$ expect NULL-terminated input data.

Acces methods at once, stream, memory-map allocate dynamic virtual memory. It will be freed in FileClose.

Access methodVirtual memory
reservedcomitted
At once loadfilesizefilesize
At once storenonenone
Standardnonenone
MemoryMappedfilesizepagesize
Streamedbuffersizebuffersize

File access method at once loads entire file content into comitted memory, so it is suitable for small files only. The loaded/stored file doesn't need explicit opening nor closing.

This access method is equivalent to PHP functions file_get_contents, file_put_contents.

Access method enclose opens the file at its end for writing, appends the data and closes file in one operation.

Standard read/write methods only encapsulate ABI functions read/write and they can process files of any size. Example:


[.bss] InpFile DS FILE64 OutFile DS FILE64 Record: DB 512 * BYTE [.text] FileAssign InpFile, ="Input.dat" FileAssign OutFile, ="Output.dat" FileOpen InpFile JC .InpErr: FileCreate OutFile JC .OutErr: .Next: FileRead InpFile, Record, SIZE# Record JC .InpErr: JZ .EOF: CALL ModifyRecord FileWrite OutFile, Record, SIZE# Record JC .OutErr: JMP .Next: .InpErr: StdOutput ="Error reading ",InpFile.Name JMP .EOF: .OutErr: StdOutput ="Error writing ",OutFile.Name .EOF: FileClose OutFile, InpFile TerminateProgram

Memory mapped file access reserves memory for the entire file contents virtually loaded to memory.

Streamed (buffered) file access method allocates its own memory buffer to accelerate reading/writing of small pieces of data. This method is also suitable for processing text files line by line. Example:

FileAssign InpFile, ="Input.txt" FileAssign OutFile, ="Output.txt" FileStreamOpen InpFile JC .Error: FileStreamCreate OutFile JC .Error: .Next:FileStreamReadLn InpFile JC .Error: JZ .EOF: MOV ECX,EAX ; RAX=Line size, RSI=pointer to the line in buffer. LEA RDI,[WorkLine] REP MOVSB CALL ModifyWorkLine FileStreamWrite OutFile, WorkLine, RAX JC .Error: JMP .Next: .EOF: FileClose OutFile, InpFile

Common limitations: This library cannot be used if special requirements are required, such as overlapped file access, other than normal file attributes, nonstandard share disposition, files bigger than 2 GB, filename longer than 260 characters.

Runtime procedures defined in this library use macros LinABI, Dispatch, status32.htm.


linf64 HEAD
 INCLUDEHEAD1 lins.htm, linsfile.htm, linabi.htm, cpuext.htm, status32.htm
FILE64
structure keeps information about the file status. Variable with FILE structure should be defined for each file used in program, either statically (in .data segment) or cleared when defined on stack or .bss. Pointer to a FILE64 structured variable is passed as the first parameter to all macros in this library.
FILE64    STRUC
 .Ptr       DQ  Q ; Pointer to the current data content in memory-mapped|buffered data.
 .Top       DQ  Q ; Pointer to the end of the memory-mapped|buffered data.
 .BufPtr    DQ  Q ; Address of the start of memory-map|allocated buffer.
 .BufSize   DQ  Q ; Size of memory map|buffer.
 .Pos       DQ  Q ; Zero based offset of the current file position: lseek(.Handle,.Pos,SEEK_SET).
 .Size      DQ  Q ; File size in bytes.
 .Handle    DQ  Q ; File descriptor.
 .MapHandle DQ  Q ; Pointer to the start of mapped memory, identical with .BufPtr.
 .Status    DD  D ; File status flags, see FileStatusEnc.
 .NameOffs  DD  D ; Offset of the filename without path inside the .Name. Zero if no path in .Name.
 .ExtOffs   DD  D ; Offset of the file extension inside the .Name.
 .Name      D NAME_MAX * B ; Zero terminated file name.
 ENDSTRUC FILE64
FileStatusEnc
Definition of flags which describe FILE64.Status.
fi64StFound      EQU 0x00000010 ; File was once succesfully opened.
fi64StAppend     EQU 0x00100000 ; Created file should move its pointer to the end.
fi64StStdIO      EQU 0x00200000 ; FILE64.Handle is standard input|output.
fi64StAllocated  EQU 0x00400000 ; FILE64.BufPtr is pointer to the allocated memory.
fi64StUnicode    EQU 0x00800000 ; FILE64.Name is in WIDE characters (not used in Linux).
fi64StMapCreated EQU 0x01000000 ; FILE64.MapHandle is valid for writing.
fi64StMapOpened  EQU 0x02000000 ; FILE64.MapHandle is valid for reading.
fi64StMapped     EQU 0x04000000 ; FILE64.Ptr is pointer to the mapped memory.
fi64StCreated    EQU 0x10000000 ; FILE64.Handle is valid for writing.
fi64StOpened     EQU 0x20000000 ; FILE64.Handle is valid for reading.
FileNameParse FileNamePtr, Size= -1, Unicode=%^UNICODE
FileNameParse will analyze string with complete FileName, which may contain path, name, extension. It returns pointers to the name without path and to the file extension.
Name starts behind the last slash /, backslash \ or colon:. If no such characters exists, the whole input string is name.
File extension starts at the last point . in the name. If there is no point in name, the extension is empty.
Input
FileNamePtr is pointer to a string of characters.
Size=-1 is the size of input string in bytes. By default it is unlimited and the string must be zero terminated in this case.
Unicode=%^UNICODE is ignored.
Output
RAX is pointer to the start of name without path.
RCX is pointer to the start of extension.
RDX points behind the last FileName character.
Path starts at %FileNamePtr, size=RAX - OFFSET#FileNamePtr
Name starts at RAX, size=RCX - RAX
Extension starts at RCX, size=RDX - RCX
Error
-
Examples
%FileNamePtr │ │ │ │ "/var/lib/nam.part1.txt" "\plain" "./.profile" "name" │ │ │ │ │ │ │ │ │ RAX │ │ RAX │ RAX │ RAX │ RCX │ RCX RCX │ RCX RDX RDX RDX RDX
FileNameParse %MACRO FileNamePtr,Size=-1, Unicode=%^UNICODE
    PUSHQ %Size,%FileNamePtr
    CALL FileNameParse@RT::
FileNameParse@RT:: PROC1
    PUSH RBX,RSI
     SUB EBX,EBX       ; Prepare returned value of RAX.
     SUB ECX,ECX       ; Prepare returned value of RCX.
     MOV RSI,[RSP+3*8] ; %FileNamePtr.
     MOV RDX,[RSP+4*8] ; %Size.
     TEST RDX
     JS .NextChar:
     ADD RDX,RSI       ; End of input string or -1.
 .NextChar:
     CMP RSI,RDX
     JNB .End:
     LODSB
     Dispatch AL,47,46,0,58,92 ; slash, dot, null, colon, backslash.
     ; Ordinary character.
     LEA RAX,[RSI-1]
     TEST RBX
     JNZ .NextChar:
     MOV RBX,RAX
     JMP .NextChar:
.46: ; dot .
     LEA RCX,[RSI-1]
     JMP .NextChar:
.47: ; colon, slash, backslash
.58:
.92: MOV RBX,RSI
     JMP .NextChar:
.0:  DEC RSI ; Byte NULL.
.End:MOV RDX,RSI
     TEST RCX
     JNZ .E1:
     MOV RCX,RSI
.E1: TEST RBX
     JNZ .E2:
     MOV RBX,RSI
.E2: MOV RAX,RBX
    POP RSI,RBX
    RET 2*8
   ENDPROC1 FileNameParse@RT::
 %ENDMACRO FileNameParse
FileAssign theFile, Name$1, Name$2,,,Size=-1, Unicode=%^UNICODE
Macro FileAssign associates file name with the FILE64 data object. Name of the file is copied to theFile.Name member.
The file must be assigned with file name before it is created or opened. FileAssign can concatenate the filename from several input strings, e.g. path, name, extension.
Input
theFile is pointer to a FILE64 structured memory variable.
Name$* is pointer to a zero terminated string with the file name or its part. It needs not be zero terminated when Size= is expicitly specified. Filename will be concatenated when more than one string is provided.
Device name may be assigned instead of a disk file.
Size= applies to all input strings. Size is unlimited by default and the strings must be zero terminated in this case.
Unicode=%^UNICODE is ignored in Linux
Output
Members of theFile .Name, .NameOffs, .ExtOffs, of theFile are set.
Error
CF=1 if the concatenated name length exceeds SIZE# FILE64.Name, i.e. NAME_MAX=260 bytes.
Depends on
FileNameParse
Examples
File1 DS FILE Path$ DB "/usr/doc/",0 Name$ DB "Some",0 Ext$ DB ".txt",0 [.text] FileAssign File1,Path$,Name$,Ext$ FileAssign File2,0 ; Standard input/output, by default redirected to console. FileAssign File3,="/dev/prn" ; Output to a line printer.
FileAssign %MACRO theFile,Name$1,Name$2,,, Size=-1, Unicode=%^UNICODE
   %IF %#<2                                                                 ; >
     %ERROR ID=5941, 'File name missing in macro "FileAssign".'
     %EXITMACRO FileAssign
   %ENDIF
   PUSHQ 0                   ; End-of-arguments marker.
   ArgNr %FOR %#..2,STEP=-1
     PUSHQ %*{%ArgNr}        ; Pointers to strings, start with the last one.
   %ENDFOR ArgNr
   PUSHQ %Size, %theFile, RSP
    ADDQ [RSP],(2+%#)*8
    CALL FileAssign@RT::
   POP RSP                   ; Restore stack to equilibrum.
FileAssign@RT:: PROC1
   PUSH RAX,RBX,RCX,RDX,RBP,RSI,RDI
    MOV RBX,[RSP+9*8]        ; %theFile
    LEA RBP,[RSP+11*8]       ; Pointer to the 1st namepointer.
    LEA RDI,[RBX+FILE64.Name]
    LEA RDX,[RDI+SIZE#FILE64.Name] ; End of reserved room.
.10:XCHG RBP,RSI
     LODSQ                   ; Load pointer to namestring.
     MOV RBP,RAX
    XCHG RSI,RBP
    TEST RAX                 ; Check the end of pointers.
    JZ .50:
    MOV RCX,[RSP+10*8]       ; Parameter %Size=.
.20:LODSB
    CMP AL,0
    JE .10:
    CMP RDI,RDX
    JNB .40:
    STOSB
    DEC RCX
    JNZ .20:
    JMP .10:
.40:SUB EAX,EAX
    STC ; Overflow.
.50:MOV RCX,RDI
    STOSB
    LEA RDX,[RBX+FILE64.Name]
    PUSHF
      SUB RCX,RDX
      FileNameParse RDX,Size=RCX
      LEA RDX,[RBX+FILE64.Name]
      SUB RAX,RDX
      SUB RCX,RDX
      MOV [RBX+FILE64.NameOffs],EAX
      MOV [RBX+FILE64.ExtOffs],ECX
    POPF
    POP RDI,RSI,RBP,RDX,RCX,RBX,RAX
    RET
ENDPROC1 FileAssign@RT::

%ENDMACRO FileAssign
FileExists? theFile
will test if the given regular file with assigned name exists on disk. File may be opened or closed. Wildcard characters * ? are allowed in the file name.
This macro can test the presence of a directory, too.
Input
theFile is pointer to FILE64 object which was assigned with the name of file or directory.
Output
CF=1 if the file | directory does not exist.
CF=0 ZF=1 if the file exists.
CF=0 ZF=0 if the directory exists.
Example
FileExists? ="./Config.ini" JC ErrorIniNotFound
FileExists? %MACRO theFile
     PUSHQ %theFile
     CALL FileExists?@RT::
FileExists?@RT:: PROC1
    PUSH RAX,RBX,RCX,RDX,RSI,RDI,R11
     MOV RBX,[RSP+8*8] ; theFile.
     LEA RDI,[RBX+FILE64.Name]
     MOV ESI,O_RDONLY+O_DIRECTORY
     XOR EDX,EDX
     LinABI open,RDI,RSI,RDX, Fastmode=Yes ; Try to open a directory.
     MOV RDI,RAX ; Returned fd or error.
     SAL RAX     ; Copy SF to CF.
     JNC .80:    ; Return with CF=0,ZF=0 if directory exists.
     MOV ESI,O_RDONLY
     LEA RDI,[RBX+FILE64.Name]
     LinABI open,RDI,RSI,RDX, Fastmode=Yes ; Try to open a file.
     MOV RDI,RAX ; Returned fd or error.
     SAL RAX     ; Copy SF to CF.
     JC .90:
     SetSt [RBX+FILE64.Status],fi64StFound
     XOR EDX,EDX ; Set CF=0, ZF=1 if file exists.
.80: PUSHFQ
      LinABI close,RDI,Fastmode=Yes
     POPFQ
.90:POP R11,RDI,RSI,RDX,RCX,RBX,RAX
    RET 1*8
  ENDPROC1 FileExists?@RT::
 %ENDMACRO FileExists?
FileMkDir theFile
will parse the file name and create all directories in its path if they didn't exist.
The last portion of assigned name is treated as directory only if
it is terminated with slash.
Input
theFile is pointer to FILE64 object with assigned name.
Output
CF=0
RAX=0 if the directory was created or it existed before.
Error
CF=1
RAX=last error if CreateDirectory failed.
Example
FileAssign SomeFile, ="/var/lib/mydir/file.txt" FileMkDir SomeFile ; will create folders /var/lib/ and /var/lib/mydir/. FileAssign SomeFile, ="/var/lib/mydir/file.txt/" FileMkDir SomeFile ; will create folders /var/lib/, /var/lib/mydir/, /var/lib/mydir/file.txt/.
FileMkDir %MACRO theFile
     PUSHQ %theFile
     CALL FileMkDir@RT::
FileMkDir@RT:: PROC1
   PUSH RBX,RCX,RBP,RSI,RDI,R11
     MOV RBX,[RSP+7*8] ; theFile.
     LEA RBX,[RBX+FILE64.Name]
     SUB ECX,ECX
     MOV RDI,RBX
     DEC RCX
     XOR EAX,EAX
     REPNE SCASB
     MOV RBP,RDI      ; ASCIIZ FileName is now RBX..RBP.
     MOV RDI,RBX
.20: MOV RCX,RBP
     MOV AL,'/'
     CMP [RDI],AL
     JNE .30:
     INC RDI
.30: SUB RCX,RDI
     REPNE SCASB      ; Search for the next slash.
     MOV AL,0
     CLC
     JNE .90:         ; Done when no more slashes left in FileName.
     MOV [RDI-1],AL   ; Temporarily replace slash with NULL.
     MOV ESI,00777q
     XCHG RBX,RDI
      LinABI mkdir,RDI,RSI,Fastmode=Yes
     XCHG RDI,RBX
     MOVB [RDI-1],'/' ; Restore original slash.
     TEST EAX
     JZ .20:
     CMP EAX,-EEXIST  ; EEXIST=17 is the only tolerated error.
     JE .20:
.80: STC
.90:POP R11,RDI,RSI,RBP,RCX,RBX
    RET 1*8
  ENDPROC1 FileMkDir@RT::
%ENDMACRO FileMkDir
FileGetSize FileHandle
is a service macro used internally in FileOpen, FileCreate, FileMap* to obtain the size of opened file.
Then it may be obtained faster as FILE64.Size.
Input
FileHandle is file descriptor of file opened for read or write.
Output
CF=0
RAX= file size in bytes.
Error
CF=1
RAX= error code.
FileGetSize %MACRO FileHandle
      PUSHQ %FileHandle
      CALL FileGetSize@RT::
FileGetSize@RT:: PROC1
    PUSH RCX,RBP,RSI,RDI,R11
     MOV RBP,RSP
     MOV RDI,[RBP+6*8]    ; FileHandle.
     MOV ECX,SIZE# STAT
     ADD ECX,7
     AND ECX,~7
     SUB RSP,RCX
     MOV RSI,RSP          ; STAT
     LinABI fstat,RDI,RSI,Fastmode=Yes
     MOV RCX,[RSI+STAT.st_size]
     MOV RSP,RBP
     CMP RAX,-ERR_MAX
     CMC
     JC  .90:
     MOV RAX,RCX
.90:POP R11,RDI,RSI,RBP,RCX
    RET 1*8
 ENDPROC1 FileGetSize@RT::
%ENDMACRO FileGetSize
FileOpen theFile
opens the assigned file for reading.
Input
theFile is pointer to a FILE64 object with assigned filename.
Output
CF=0
RAX= file size.
Error
CF=1
RAX= is errorCode.
Depends on
FileGetSize
FileOpen %MACRO theFile
         PUSHQ %theFile
         CALL FileOpen@RT::
FileOpen@RT:: PROC1
    PUSH RBX,RCX,RDX,RSI,RDI,R11
     MOV RBX,[RSP+7*8]          ; theFile.
     LEA RDI,[RBX+FILE64.Name]
     XOR EDX,EDX
     MOV [RBX+FILE64.Size],RDX
     MOV [RBX+FILE64.Pos],RDX
     MOV [RBX+FILE64.Ptr],RDX
     MOV [RBX+FILE64.Top],RDX
     LinABI open,RDI,O_RDONLY,RDX,Fastmode=Yes
     CMP RAX,-ERR_MAX
     CMC
     JC .90:
     SetSt [RBX+FILE64.Status],fi64StOpened+fi64StFound
     MOV [RBX+FILE64.Handle],RAX
     FileGetSize RAX
     JC .90:
     MOV [RBX+FILE64.Size],RAX
     MOV [RBX+FILE64.Top],RAX
.90:POP R11,RDI,RSI,RDX,RCX,RBX
    RET 1*8
  ENDPROC1 FileOpen@RT::
 %ENDMACRO FileOpen
FileCreate theFile
creates a new file or rewrites an existing file for writing.
Input
theFile is pointer to a FILE64 object with assigned filename.
Output
CF=0
EAX=0 (size of just rewritten file).
Error
CF=1
EAX=errorCode.
Depends on
FileGetSize
FileCreate %MACRO theFile
         PUSHQ %theFile
         CALL FileCreate@RT::
FileCreate@RT:: PROC1
    PUSH RBX,RCX,RDX,RSI,RDI,R11
     MOV RBX,[RSP+7*8]             ; ^theFile.
     XOR EAX,EAX
     MOV [RBX+FILE64.Ptr],RAX
     MOV [RBX+FILE64.Top],RAX
     LEA RDI,[RBX+FILE64.Name]
     MOV ESI,O_CREAT|O_WRONLY|O_TRUNC
     JNSt [RBX+FILE64.Status],fi64StAppend,.10:
     MOV ESI,O_CREAT|O_RDWR|O_APPEND ; The macro is used by FileAppend.
.10: LinABI open,RDI,RSI,777q,Fastmode=Yes
     CMP RAX,-ERR_MAX
     CMC
     JC .90:
     SetSt [RBX+FILE64.Status],fi64StCreated
     MOV [RBX+FILE64.Handle],RAX
     FileGetSize RAX
     JC .90:
     MOV [RBX+FILE64.Size],RAX
     MOV [RBX+FILE64.Pos],RAX
.90:POP R11,RDI,RSI,RDX,RCX,RBX
    RET 1*8
  ENDPROC1 FileCreate@RT::
%ENDMACRO FileCreate
FileAppend theFile
Macro FileAppend creates a new file or opens an existing file for writing and sets file pointer to its end.
Input
theFile is pointer to a FILE64 object with assigned filename.
Output
CF=0
RAX= file size.
Error
CF=1
RAX=errorCode as returned from GetLastError.
Depends on
FileCreate
FileAppend %MACRO theFile
       PUSHQ %theFile
       CALL FileAppend@RT::
 FileAppend@RT:: PROC1
     PUSH RBX
       MOV RBX,[RSP+2*8]         ; ^theFile
       SetSt [RBX+FILE64.Status],fi64StAppend
       FileCreate RBX
     POP RBX
     RET 1*8
   ENDPROC1 FileAppend@RT::
 %ENDMACRO FileAppend
FileFlush theFile
is a helper macro used internally in FileClose, FileStreamWrite* to write the contents of file buffer on disk. There is no reason to invoke this macro explicitly by the programmer.
Output
CF=0
RAX= number of flushed bytes.
Error
CF=1
RAX= errorCode (file not created for write).
FileFlush %MACRO theFile
      PUSHQ %theFile
      CALL FileFlush@RT::
FileFlush@RT:: PROC1
    PUSH RBX,RCX,RDX,RSI,RDI,R11
     MOV RBX,[RSP+7*8]           ; theFile.
     MOV RAX,-EBADFD             ; Error: file is not open for write.
     JNSt [RBX+FILE64.Status],fi64StAllocated,.80:
     JNSt [RBX+FILE64.Status],fi64StCreated,  .80:
     MOV RSI,[RBX+FILE64.BufPtr] ; Start of buffer.
     MOV RDX,[RBX+FILE64.Ptr]    ; Next free position in buffer.
     MOV [RBX+FILE64.Ptr],RSI
     SUB RDX,RSI
     MOV RAX,RDX
     JZ .90:                     ; If nothing to flush.
     MOV RDI,[RBX+FILE64.Handle]
     LinABI write,RDI,RSI,RDX,Fastmode=Yes
     CMP RAX,-ERR_MAX
     CMC
     JNC .90:
.80: STC
.90:POP R11,RDI,RSI,RDX,RCX,RBX
    RET 1*8
 ENDPROC1 FileFlush@RT::
%ENDMACRO FileFlush
FileClose theFile1, theFile2,,,
Macro FileClose will flush and deallocate the buffer, close file mapping, close the file, clear pointers in the FILE structure.
FileClose does not clear the name assignment, so the closed file may be reopen with the same name without invoking FileAssign again.
Input
theFile is pointer to a FILE64 object. More than one file may be specified simultaneously.
Output
-
Error
-
Depends on
FileFlush
FileClose %MACRO theFile
  ArgNr %FOR 1..%#
       PUSHQ %*{%ArgNr}
       CALL FileClose@RT::
     %ENDFOR ArgNr
FileClose@RT:: PROC1
    PUSH RAX,RBX,RCX,RSI,RDI,R11
     MOV RBX,[RSP+7*8]        ; theFile
     JSt [RBX+FILE64.Status],fi64StMapped,.10:
     FileFlush RBX
     JMPS .20:
.10: LinABI munmap,[RBX+FILE64.MapHandle],[RBX+FILE64.Size],Fastmode=Yes
.20: JNSt [RBX+FILE64.Status],fi64StAllocated,.30:
     LinABI munmap,[RBX+FILE64.BufPtr],[RBX+FILE64.BufSize],Fastmode=Yes
.30: JNSt [RBX+FILE64.Status],fi64StOpened|fi64StCreated, .40:
     LinABI close,[RBX+FILE64.Handle],Fastmode=Yes
.40: LEA RCX,[RBX+FILE64.NameOffs]
     SUB RCX,RBX
     SHR ECX,2
     XOR EAX,EAX
     MOV RDI,RBX
     REP STOSD           ; Clear the FILE object except for Name and Offs.
    POP R11,RDI,RSI,RCX,RBX,RAX
    RET 1*8
  ENDPROC1 FileClose@RT::
%ENDMACRO FileClose
FileMove SourceFile, DestinationFile
FileMove renames directory on the same volume or moves the source file to the destination. Files will be closed first, if necessarry. The destination file will be erased if it existed before.
Directories in the destination file name will be maked, if necessarry. Both files must have been assigned.
Input
SourceFile and DestinationFile are pointers to assigned FILE64 objects.
Output
CF=0
RAX=0
Error
CF=1
RAX= error code.
Depends on
FileClose, FileMkDir
FileMove %MACRO SourceFile, DestinationFile
       PUSHQ %DestinationFile, %SourceFile
       CALL FileMove@RT::
FileMove@RT:: PROC1
     PUSH RCX,RSI,RDI,R11
      MOV RSI,[RSP+5*8] ; SourceFile.
      MOV RDI,[RSP+6*8] ; DestinationFile.
      FileClose RSI,RDI
      FileMkDir RDI
      JC .90:
      LEA RSI,[RSI+FILE64.Name]
      LEA RDI,[RDI+FILE64.Name]
      XCHG RSI,RDI
      LinABI rename,RDI,RSI,Fastmode=Yes
      MOV ECX,EAX
      SAL ECX,1        ; Copy SF to CF.
.90: POP R11,RDI,RSI,RCX
     RET 2*8
   ENDPROC1 FileMove@RT::
 %ENDMACRO FileMove
FileDelete theFile1, theFile2,,,
will close and erase the disk file(s).
FileDelete does not clear the name assignment, so the deleted file may be reopen with the same name without invoking FileAssign again.
Input
theFile* is pointer to a FILE64object. More than one file may be specified simultaneously.
Output
CF=0,
RAX=0 if the last file was succesfully deleted.
Error
CF=1
RAX= error code.
Depends on
FileClose
FileDelete %MACRO theFile
ArgNr %FOR 1..%#
       PUSHQ %*{%ArgNr}
       CALL FileDelete@RT::
      %ENDFOR ArgNr
FileDelete@RT:: PROC1
     PUSH RCX,RDI,R11
      MOV RDI,[RSP+4*8] ; theFile.
      FileClose RDI
      LEA RDI,[RDI+FILE64.Name]
      LinABI unlink,RDI,Fastmode=Yes
      MOV ECX,EAX
      SAL ECX,1         ; Copy SF to CF.
     POP R11,RDI,RCX
     RET 1*8
   ENDPROC1 FileDelete@RT::
 %ENDMACRO FileDelete
FileEach theFile, CallbackProc
Macro FileEach expects the file object assigned with file name which can contain wildcard characters * and ?. FileEach will resolve the mask and performs callback procedure with each such filename. If no file matches the mask, CallbackProc is never called.
Input
theFile is a pointer to FILE64 object which must have assigned the requested file path and file name mask.
CallbackProc is the address of callback procedure.
Output
RAX=content of RAX at the last CallbackProc exit, or 0 if the CallbackProc was never called.
CallbackProc
is called with register calling convention. CallbackProc should return CF=0 to let FileEach continue with the next file, otherwise FileEach stops searching.
CallbackProc input registers:
RBX=%theFile where the mask in FILE64.Name is replaced with the resolved file name found in directory. The file is not open.
RSI=pointer to the file name without path inside RBX+FILE64.Name.
RBP=RBP at FileEach macro entry. This allows to address local stack variables of the procedure which invoked FileEach.
Other registers are undefined at CallbackProc entry.
CallbackProc output registers:
RAX is passed through. FileEach returns RAX value from the last called CallbackProc, or 0 if it was never called.
CF=0 to continue with the next file
CF=1 to break further searching.
CallbackProc may destroy RBX,RCX,RDX,RBP,RSI,RDI.
Depends on
FileNameParse
Example
MyFile DS FILE FileAssign MyFile,="/var/lib/t??_*.txt" FileEach MyFile, ListFile TerminateProgram ListFile PROC StdOutput RSI,Eol=Yes RET ENDP ListFile
FileEach %MACRO theFile, CallbackProc
     PUSHQ %CallbackProc, %theFile
     CALL FileEach@RT::
FileEach@RT:: PROC1
%FileEachMaskSize %SETA (SIZE# FILE64.Name + 7) & ~7 ; Local buffer for the filename mask.
%FileEachBufSize  %SETA (SIZE# DIRENT64    + 7) & ~7 ; Local buffer for DIRENT64 records.
      PUSH RAX,RBX,RCX,RDX,RSI,RDI,R9,R11
       MOV RBX,[RSP+9*8]   ; RBX=^theFile.
       MOV ECX,%FileEachMaskSize
       SUB EAX,EAX
       MOV [RSP+7*8],RAX   ; Initialize returned RAX with NULL.
       SUB RSP,RCX
       ADD EAX,[RBX+FILE64.NameOffs]
       MOV RDI,RSP
       LEA RSI,[RAX+RBX+FILE64.Name]
       REP MOVSB           ; Copy the ASCIIZ mask without path to LocalVar %FileEachMask$.
       JNZ .10:            ; Test if theFile.NameOffs=0.
       ; The mask was specified without path, e.g. doc*.txt.
       ; Default path ./ will be injected to FILE64.Name, i.e. ./doc*.txt.
       MOV ECX,SIZE#FILE64.Name-2
       LEA RSI,[RCX+RBX+FILE64.Name-1]
       LEA RDI,[RSI+2]
       STD
        REP MOVSB
       CLD
       DEC RDI
       MOVW [RDI],'./'
       MOVB [RDI+SIZE#FILE64.Name-1],0
       FileNameParse RDI
       SUB RAX,RDI
       SUB RCX,RDI
       MOV [RBX+FILE64.NameOffs],EAX
       MOV [RBX+FILE64.ExtOffs],ECX
.10:   LEA RDI,[RBX+FILE64.Name]    ; RAX=FILE64.NameOffs.
       MOVB [RDI+RAX-1],0           ; Temporary replace / with NULL.
       MOV R9,RDI
       LinABI open,RDI,O_RDONLY+O_DIRECTORY+O_NOATIME,0,Fastmode=Yes
       MOV EDX,[RBX+FILE64.NameOffs]
       MOVB [R9+RDX-1],'/'          ; Replace temporary NULL back with slash in the mask name.
       MOV EDX,%FileEachBufSize
       SUB RSP,RDX                  ; RDX=Size of temporary buffer.
       MOV RDI,RAX                  ; Directory descriptor (or error code from sys_open).
.20:   MOV RSI,RSP                  ; Pointer to temporary buffer for DIRENT64 records.
       LinABI getdents64,RDI,RSI,RDX,Fastmode=Yes
       TEST EAX
       JZ .End:                     ; When there are no more dir entries.
       CMP RAX,-ERR_MAX
       JNC .End:                    ; When error occured.
       LEA RCX,[RSI+RAX]            ; End of DIRENT64 records in buffer.
.30:   CMP RSI,RCX
       JNB .20:                     ; Go to read the next portion of dir entries.
       CALL .DirEnt:                ; Process the DIRENT64 record at RSI. Keep all GPR.
       JC .End:
       MOVZX EAX,[RSI+DIRENT64.d_reclen]
       ADD RSI,RAX
       JMP .30:

.DirEnt:PROC ; If the resolved name [RSI+DIRENT64.d_name] complies with %FileEachMask$,
  ; update FILE64.Name at [%Param1] with the resolved name and then call [%Param2].
  ; Input: RSI=^DIRENT64
  ;        RBX=^FILE64
  ; Output:CF and RAX as returned from callback. Other registers are unchanged.
         PUSH RBX,RCX,RDX,RBP,RSI,RDI
          CMP [RSI+DIRENT64.d_type],DT_REG
          JNE .NoMatch:                      ; Skip sockets, pipes, devices and other nonregular files.
          LEA RDI,[RSI+DIRENT64.d_name]      ; ^name from the directory.
          MOV RDX,RDI
          LEA RSI,[RSP+7*8+%FileEachBufSize] ; ^file mask without path.
.D1:      LODSB                     ; Byte from file mask.
          MOV AH,[RDI]              ; Byte from file name.
          INC RDI
          Dispatch AL,0x00,0x2A,0x3F; Test on end-of-mask and wildcard.
          CMP AL,AH                 ; Ordinary character match?
          JE .D1:
          JMP .NoMatch:
.0x00:    CMP AH,0
          JE .Match:
          JMP .NoMatch:
.0x3F:    CMP AH,0      ; Question mark '?' in mask complies with one not-nul UTF8 character.
          JE .NoMatch:
          NOT EAX       ; Invert bits in UTF8 AH.
          SUB ECX,ECX
          BSR CX,AX     ; Scan AH, start with MSbit.
          SUB RCX,15
          JZ .D1:
          INC RCX
          SUB RDI,RCX   ; Advance RDI by the size of UTF8 character - 1.
          JMP .D1:
.0x2A:    ; Asterix '*' complies with zero or more UTF8 characters.
          LODSB         ; The mask character/byte which follows '*'.
          Dispatch AL,0x2A,0x3F,0n00
.D3:      CMP AH,0
          JE .NoMatch:
          CMP AL,AH
          JE .D1:
          MOV AH,[RDI]
          INC RDI
          JMP .D3:
.NoMatch: CLC
          JMP .D9:
.Match:   ; File name at RDX complies with the file mask. Perform callback.
.0n00:    MOV RSI,RDX
          MOV ECX,SIZE# FILE64.Name
          MOV EAX,[RBX+FILE64.NameOffs]
          SUB ECX,EAX
          JNA .NoMatch:
          LEA RDI,[RBX+FILE64.Name+RAX]
          MOV RDX,RDI
          REP MOVSB
          MOV RSI,RDX           ; Pointer to resolved file name without path.
          MOV RAX,[RSP+17*8+%FileEachBufSize+%FileEachMaskSize] ; ^CallbackProc.
          CALL RAX              ; Perform the callback.
          MOV [RSP+14*8+%FileEachMaskSize+%FileEachBufSize],RAX ; Pass the returned RAX.
.D9:     POP RDI,RSI,RBP,RDX,RCX,RBX
         RET
        ENDP .DirEnt:
.End:  LinABI close,RDI, Fastmode=On
       ADD RSP,%FileEachMaskSize+%FileEachBufSize
      POP R11,R9,RDI,RSI,RDX,RCX,RBX,RAX
      RET 2*8
 ENDPROC1 FileEach@RT:
%ENDMACRO FileEach
FileLoad theFile
will allocate memory buffer from OS, open the file, read entire file content to a block of memory allocated by FileLoad and then close the file.
Although the file handle is closed immediately, you should always use FileClose to free allocated buffer when the file content is no longer needed.
Input
theFile is pointer to an assigned existing FILE64 object.
Output
CF=0
RAX= file size,
RSI= pointer to the file contents in allocated memory.
Error
CF=1
RAX= errorCode.
RSI= is undefined.
Depends on
FileOpen, FileClose
FileLoad %MACRO theFile
    PUSHQ %theFile
    CALL FileLoad@RT::
FileLoad@RT:: PROC1
    PUSH RBX,RCX,RDX,RDI,R8,R9,R10,R11
     MOV RBX,[RSP+9*8]      ; ^theFile.
     FileOpen RBX           ; Returns CF=0,RAX=file size.
     JC .80:
     MOV [RBX+FILE64.BufSize],RAX
     TEST RAX               ; Zero-sized files are not supported.
     JZ .80:
     MOV RSI,RAX
     LinABI mmap,0,RSI,PROT_READ+PROT_WRITE,MAP_PRIVATE+MAP_ANONYMOUS,-1,0,Fastmode=Yes
     CMP RAX,-ERR_MAX
     CMC
     JC .80:
     MOV [RBX+FILE64.BufPtr],RAX
     MOV [RBX+FILE64.Ptr],RAX
     ADD [RBX+FILE64.Top],RAX
     SetSt [RBX+FILE64.Status],fi64StAllocated
     MOV RSI,RAX
     LinABI read,[RBX+FILE64.Handle],RSI,[RBX+FILE64.BufSize],Fastmode=Yes
     CMP RAX,-ERR_MAX
     CMC
.80: PUSHFQ                 ; Save CF.
      PUSH RAX
       LinABI close,[RBX+FILE64.Handle]
       RstSt [RBX+FILE64.Status],fi64StCreated+fi64StOpened
      POP RAX
     POPFQ                  ; Restore CF.
    POP R11,R10,R9,R8,RDI,RDX,RCX,RBX
    RET 1*8
 ENDPROC1 FileLoad@RT::
%ENDMACRO FileLoad
 
FileStore theFile, DataPtr, DataSize
Macro FileStore will open the file, write data and close the file.
Input
theFile is pointer to an assigned unopened FILE64 object,
DataPtr is pointer to the data to be written,
DataSize is size of the data in bytes, i.e. future file size.
Output
CF=0
RAX= is the size of written data.
Error
CF=1
EAX= is error code.
Depends on
FileCreate, FileClose
Example
FileStore File1, MyDataPtr, MyDataEnd-MyDataPtr
FileStore %MACRO theFile,DataPtr,DataSize
      PUSHQ %DataSize,%DataPtr,%theFile
      CALL FileStore@RT::
FileStore@RT:: PROC1
    PUSH RBX,RCX,RDX,RSI,RDI,R11
     MOV RBX,[RSP+7*8]    ; ^theFile.
     FileCreate RBX
     JC .90:
     MOV RSI,[RSP+8*8]    ; DataPtr.
     MOV RDX,[RSP+9*8]    ; DataSize.
     LinABI write,[RBX+FILE64.Handle],RSI,RDX,Fastmode=Yes
     CMP RAX,-ERR_MAX
     CMC
     JC .90:
     MOV [RBX+FILE64.Size],RAX
     ADD [RBX+FILE64.Pos],RAX
     FileClose RBX
.90:POP R11,RDI,RSI,RDX,RCX,RBX
   RET 3*8
 ENDPROC1 FileStore@RT::
%ENDMACRO FileStore
FileReset theFile, Position
Macro FileReset will reset internal file pointers to a new Position in the file.
Input
theFile is a pointer to a FILE64 object, which must have been opened with FileOpen, FileMapOpen or FileStreamOpen.
Position specifies the number of bytes from the beginning of theFile. Zero is used if omitted.
Output
CF=0
EAX=Position
Error
CF=1
EAX= error code.
FileReset %MACRO theFile, Position
     %IF "%Position" === ""
       PUSHQ 0
     %ELSE
       PUSHQ %Position
     %ENDIF    
     PUSHQ %theFile
     CALL FileReset@RT::
FileReset@RT:: PROC1
     PUSH RBX,RCX,RDX,RSI,RDI,R11
      MOV RBX,[RSP+7*8]   ; theFile.
      MOV RSI,[RSP+8*8]   ; Position.
      MOV RAX,-EBADF      ; Error code "file is not opened".
      JNSt [RBX+FILE64.Status],fi64StOpened,.90:
      LinABI lseek,[RBX+FILE64.Handle],RSI,SEEK_SET,Fastmode=Yes
      CMP RAX,-ERR_MAX
      CMC
      JC .90:
      MOV [RBX+FILE64.Pos],RAX
      MOV RSI,[RBX+FILE64.BufPtr]
      ADD RSI,RAX
      MOV [RBX+FILE64.Ptr],RSI
      JSt [RBX+FILE64.Status],fi64StMapOpened,.90:
      MOV [RBX+FILE64.Top],RSI
.90: POP R11,RDI,RSI,RDX,RCX,RBX
     RET 2*8
    ENDPROC1 FileReset@RT::
 %ENDMACRO FileReset
FileRead theFile, DataPtr, DataSize
reads from an opened file to the memory provided by caller.
Input
theFile is pointer to a FILE64 object opened for reading.
DataPtr is pointer where the data will be read,
DataSize is the requested number of bytes.
Output
CF=0
ZF=0
RAX= the actually read size (may be less than DataSize when the file is not large enough).
End of file
CF=0
ZF=1
RAX=0 if all data have been read from the file (EOF).
Error
CF=1
RAX= errorCode.
Example
FileRead InpFile,aLine,80 JC .ErrorReadingFile JZ .EOF
FileRead %MACRO theFile,DataPtr,DataSize
       PUSHQ %DataSize,%DataPtr,%theFile
       CALL FileRead@RT::
FileRead@RT:: PROC1
    PUSH RBX,RCX,RDX,RSI,RDI,R11
     MOV RBX,[RSP+7*8]      ; theFile.
     MOV RAX, -EBADFD       ; Error code: file is not open.
     TEST [RBX+FILE64.Status],fi64StOpened
     STC
     JZ .90:
     MOV RSI,[RSP+8*8]      ; DataPtr.
     MOV RDX,[RSP+9*8]      ; DataSize.
     LinABI read,[EBX+FILE64.Handle],RSI,RDX,Fastmode=Yes
     CMP RAX,-ERR_MAX
     CMC
     JC .90:
     ADD [RBX+FILE64.Pos],RAX
     TEST RAX               ; Check ZF=EOF.
.90:POP R11,RDI,RSI,RDX,RCX,RBX
    RET 3*8
  ENDPROC1 FileRead@RT::
 %ENDMACRO FileRead
FileWriteRT the File, DataPtr1, DataSize1, DataPtr2,DataSize2,,,
is a runtime macro used internally by FileWrite*. It declares runtime procedure FileWrite@RT with variable number of parameters
Input
theFile is pointer to a FILE64 object opened for write by FileCreate or FileAppend.
DataPtr* is pointer to data being written,
DataSize* is the number of bytes in data.
Output
CF=0
RAX is the number of total written bytes. Other registers are preserved.
Error
CF=1
RAX is error code.
FileWriteRT %MACRO ; Common runtime procedure declaration for macros FileWrite*
    %IF %# & 1 = 0
      %ERROR ID=5946, 'Macro FileWrite expects odd number of arguments.'
      %EXITMACRO FileWriteRT
    %ENDIF
    PUSHQ 0                     ; Mark the end of arguments.
    ArgNr %FOR %#..2,STEP=-2
      PUSHQ %*{%ArgNr}, %*{%ArgNr-1}
    %ENDFOR ArgNr
    PUSHQ %theFile,RSP
      ADDQ [RSP],(%#+1)*8
      CALL FileWrite@RT::
    POP RSP
FileWrite@RT::PROC1
    PUSH RBX,RCX,RDX,RBP,RSI,RDI
     MOV RBX,[RSP+8*8]         ; theFile.
     MOV RAX,-EBADFD           ; File was not opened.
     TESTD [RBX+FILE64.Status],fi64StCreated
     STC
     JZ .90:
     PUSHQ 0                    ; Returned RAX will accumulate written size.
      LEA RBP,[RSP+10*8]        ; Pointer to the first DataPtr.
.20:  XCHG RBP,RSI
      LODSQ                     ; DataPtr.
      MOV RBP,RAX
      TEST RAX                  ; Test if it's the end of pointers.
      JZ .80:
      LODSQ                     ; DataSize.
      XCHG RSI,RBP
      MOV RDX,RAX
      INC RAX
      JNZ .30:
      MOV RCX,RDX               ; DataSize=-1, let's find the actual size.
      MOV RDI,RSI
      REPNE SCASB
      SUB RDI,RSI
      LEA RDX,[RDI-1]
.30:  LinABI write,[RBX+FILE64.Handle],RSI,RDX,Fastmode=Yes
      CMP RAX,-ERR_MAX
      JC .40:
      STC
      LEA RSP,[RSP+1*8]          ; Keep CF and RAX=error code.
      JMP .90:
.40:  ADD [RBX+FILE64.Size],RAX
      ADD [RBX+FILE64.Pos],RAX
      ADD [RSP+0*8],RAX          ; Accumulate total written size.
      JMP .20:
.80: POP RAX
.90:POP RDI,RSI,RBP,RDX,RCX,RBX
    RET
   ENDP1 FileWrite@RT
%ENDMACRO FileWriteRT
FileWrite theFile, DataPtr1, DataSize1, DataPtr2, DataSize2,,,
This macro writes data to the file previously opened for writing with FileCreate or FileAppend.
Multiple data may be written in one macro invocation.
Input
theFile is pointer to an open FILE64 object,
DataPtr* points to the data to be written,
DataSize* is the size of data in bytes.
Output
CF=0
RAX=total written size in bytes.
Error
CF=1
RAX= error code.
Depends on
FileWriteRT
FileWrite %MACRO theFile,DataPtr,DataSize,,,,
      FileWriteRT %*
  %ENDMACRO FileWrite
FileWriteLn theFile, DataPtr1, DataSize1, DataPtr2, DataSize2,,,
Macro FileWriteLn writes data to the file previously opened for writing with FileCreate or FileAppend.
Multiple data may be written in one macro invocation. End of line (LineFeed) character 0x0A is written in the end.
Input
theFile is pointer to a FILE64 object opened for write,
DataPtr* points to the data to be written,
DataSize* is size of data in bytes.
Output
CF=0
RAX= is the total written size including LF.
Error
CF=1
RAX= error code.
Depends on
FileWriteRT
FileWriteLn %MACRO theFile,DataPtr,DataSize,,,
    FileWrite %*, =B 0x0A, 1
 %ENDMACRO FileWriteLn
FileWrite$ theFile, DataPtr$1, DataPtr$2,,,
This macro writes zero terminated ANSI string(s) to the file previously opened for writing with FileCreate or FileAppend.
More than one string may be written in one macro invocation. The terminating zeros are not written to the file.
Input
theFile is pointer to an open FILE64 object,
DataPtr$* are pointers to zero terminated strings to be written.
Output
CF=0
RAX= total written size in bytes.
Error
CF=1
RAX= error code.
Depends on
FileWriteRT
FileWrite$ %MACRO theFile,DataPtr1,DataPtr2,DataPtr3,,,
%ArgList %SET %theFile
    ArgNr %FOR 2..%#
    %ArgList %SET %ArgList,%*{%ArgNr},-1
          %ENDFOR ArgNr
    FileWriteRT %ArgList
  %ENDMACRO FileWrite$
FileEnclose theFile, DataPtr1, DataSize1, DataPtr2, DataSize2,,,
This macro writes data at the end of existing file or creates a new one, and then closes the file.
Multiple data can be appended with one invocation.
The file should be assigned but not open.
Input
theFile is pointer to FILE64 object with assigned name,
DataPtr is pointer to the data to be written,
DataSize is size of the data in bytes.
Output
CF=0
EAX= it total written size in bytes.
Error
CF=1
EAX= errorCode.
Depends on
FileAppend, FileWrite, FileClose,
Example
FileEnclose LogFile,Datum,SIZE#Datum
FileEnclose %MACRO theFile,DataPtr,DataSize,,,,
    FileAppend %theFile
    JC FileEnclose%.Abort:
    FileWrite %*
    JC FileEnclose%.Abort:
    FileClose %theFile
FileEnclose%.Abort:
 %ENDMACRO FileEnclose
FileEncloseLn theFile, DataPtr1, DataSize1, DataPtr2, DataSize2,,,
This macro writes data at the end of existing file or creates a new one and then closes the file.
More than one data item can be appended with one invocation.
When all data have been written, it appends end-of-line character LF to the file.
The file should be assigned but not open.
Input
theFile is pointer to FILE64 object with assigned name,
DataPtr is pointer to the data to be written,
DataSize is size of the data in bytes.
Output
CF=0
EAX= it total written size in bytes, including CR+LF.
Error
CF=1
EAX= errorCode.
Depends on
FileAppend, FileWriteLn, FileClose,
FileEncloseLn %MACRO theFile,DataPtr,DataSize,DataPtr2,DataSize2,,,
    FileAppend %theFile
    JC FileEncloseLn%.Abort:
    FileWriteLn %*
    JC FileEncloseLn%.Abort:
    FileClose %theFile
FileEncloseLn%.Abort:
 %ENDMACRO FileEncloseLn
FileEnclose$ theFile, DataPtr$1, DataPtr$2,,,
This macro writes one or more zero-terminated data strings at the end of existing file or it creates a new one, and then closes the file.
The file should be assigned but not open.
More than one string can be appended with one invocation. The terminating NULL is not written.
Input
theFile is pointer to FILE64 object with assigned name,
DataPtr$* are pointers to zero-terminated ANSI strings. Terminating zeroes are not written to the file.
Output
CF=0
EAX= total written size.
Error
CF=1
EAX= is errorCode.
Depends on
FileAppend, FileWrite$, FileClose,
Example
FileEnclose$ LogFile, Time$, =" Job started"
FileEnclose$ %MACRO theFile,DataPtr1,DataPtr2,DataPtr3,,,
    FileAppend %theFile
    JC FileEnclose$%.Abort:
    FileWrite$ %*
    JC FileEnclose$%.Abort:
    FileClose %theFile
FileEnclose$%.Abort:
  %ENDMACRO FileEnclose$
FileMapOpen theFile
opens an existing regular file for reading and creates file mapping to memory.
Content of the file will be available for reading and pointed to with RSI.
The file cannot be assigned with device, pipe or empty name.
Input
theFile is pointer to an assigned FILE64 object.
Output
CF=0
RAX= file size,
RSI= pointer to the memory-mapped file contents.
Error
CF=1
RSI=0
RAX= errorCode.
Depends on
FileOpen
FileMapOpen %MACRO theFile
      PUSHQ %theFile
      CALL FileMapOpen@RT::
FileMapOpen@RT:: PROC1
     PUSH RBX,RCX,RDX,RDI,R8,R9,R10,R11
      MOV RBX,[RSP+9*8]            ; theFile.
      XOR ESI,ESI
      FileOpen RBX
      JC .End:
      TEST EAX
      JZ .End:                     ; If the file has size=0.
      LinABI mmap,0,RAX,PROT_READ+PROT_EXEC,MAP_SHARED,[RBX+FILE64.Handle],0,Fastmode=Yes
      CMP RAX,-ERR_MAX
      CMC
      JC .End:
      MOV RSI,RAX
      MOV [RBX+FILE64.Ptr],RAX
      MOV [RBX+FILE64.Top],RAX
      MOV [RBX+FILE64.BufPtr],RAX
      MOV [RBX+FILE64.MapHandle],RAX
      MOV RAX,[RBX+FILE64.Size]
      MOV [RBX+FILE64.BufSize],RAX
      ADD [RBX+FILE64.Top],RAX
      SetSt [RBX+FILE64.Status],fi64StMapped+fi64StMapOpened
.End:POP R11,R10,R9,R8,RDI,RDX,RCX,RBX
    RET 1*8
  ENDPROC1 FileMapOpen@RT::
%ENDMACRO FileMapOpen
FileMapCreate theFile, FileSize
Macro FileMapCreate will create or rewrite an existing file for writing and create file mapping. Size of the file being created should be specified with FileSize.
File content can be copied to the mapped memory returned in RDI but not more than FileSize bytes.
The file cannot be assigned with device, pipe or empty name.
Input
theFile is pointer to a FILE64 object with assigned name.
FileSize is the requested size of memory mapped file. It may be omitted or set to 0 when FileMapCreate opens an existing file.
Output
CF=0
RAX=FileSize
RDI= is pointer to the memory mapped file content.
Error
CF=1
RDI=undefined,
RAX= errorCode as returned from GetLastError.
Depends on
FileAppend
FileMapCreate %MACRO theFile,FileSize
       %IF %# > 1
         PUSHQ %FileSize
       %ELSE
         PUSHQ 0
       %ENDIF
       PUSHQ %theFile
       CALL FileMapCreate@RT::
FileMapCreate@RT:: PROC1
      PUSH RBX,RCX,RDX,RSI,R8,R9,R10,R11
       MOV RBX,[RSP+9*8]        ; theFile.
       FileAppend RBX
       JC .90:
       MOV RSI,RAX              ; Current file size.
       MOV RCX,[RSP+10*8]       ; Requested FileSize.
       JRCXZ .10:
       MOV RSI,RCX
.10:   LinABI ftruncate,[RBX+FILE64.Handle],RSI,Fastmode=Yes
       TEST EAX
       STC
       JNZ .90:
       LinABI mmap,RAX,RSI,PROT_READ+PROT_WRITE+PROT_EXEC,MAP_SHARED,[RBX+FILE64.Handle],RAX,Fastmode=Yes
       CMP RAX,-ERR_MAX
       CMC
       JC .90:
       SetSt [RBX+FILE64.Status],fi64StMapCreated+fi64StMapped+fi64StAllocated+fi64StCreated
       MOV RDI,RAX
       MOV [RBX+FILE64.Size],RSI
       MOV [RBX+FILE64.MapHandle],RAX
       MOV [RBX+FILE64.BufPtr],RAX
       ADD RAX,RSI
       MOV [RBX+FILE64.Ptr],RAX
       MOV [RBX+FILE64.Top],RAX
       XCHG RAX,RSI
.90: POP R11,R10,R9,R8,RSI,RDX,RCX,RBX
     RET 2*8
   ENDPROC1 FileMapCreate@RT::
 %ENDMACRO FileMapCreate
FileStreamOpen theFile, BufSize=16K
This macro opens an existing file for reading and allocates memory buffer from OS heap. Buffer will be read from file on the FileStreamRead* request.
Input
theFile is pointer to a FILE64 object with assigned name.
BuffSize= specifies the buffer size.
Output
CF=0
RAX= file size.
Error
CF=1
RAX= error code.
Depends on
FileOpen
FileStreamOpen %MACRO theFile,BufSize=16K
       PUSHQ %BufSize,%theFile
       CALL FileStreamOpen@RT::
FileStreamOpen@RT:: PROC1
     PUSH RBX,RCX,RDX,RSI,RDI,R8,R9,R10,R11
      MOV RBX,[RSP+10*8]  ; theFile.
      FileOpen RBX
      JC .90:
      MOV RSI,[RSP+11*8]  ; BufSize.
      MOV [RBX+FILE64.BufSize],RSI
      XOR EDI,EDI
      LinABI mmap,RDI,RSI,PROT_READ+PROT_WRITE,MAP_PRIVATE+MAP_ANONYMOUS,-1,RDI,Fastmode=Yes
      CMP RAX,-ERR_MAX
      CMC
      JC .90:
      SetSt [RBX+FILE64.Status],fi64StAllocated
      MOV [RBX+FILE64.MapHandle],RAX
      MOV [RBX+FILE64.BufPtr],RAX
      MOV [RBX+FILE64.Ptr],RAX
      MOV [RBX+FILE64.Top],RAX
      MOV RAX,[RBX+FILE64.Size]
.90: POP R11,R10,R9,R8,RDI,RSI,RDX,RCX,RBX
     RET 2*8
  ENDPROC1 FileStreamOpen@RT::
 %ENDMACRO FileStreamOpen
FileStreamRead theFile, DataPtr, DataSize
reads data from the file opened with FileStreamOpen.
Input
theFile is pointer to a FILE64 object.
DataPtr points to a memory area allocated by the caller,
DataSize is amount of bytes to read.
Output
CF=0
ZF=0
RAX= how many bytes was read (may be less the DataSize).
End of file
CF=0
ZF=1
RAX= 0 when there are no more bytes in the file (EOF).
Error
CF=1
RAX= error code.
FileStreamRead %MACRO theFile,DataPtr,DataSize
       PUSHQ %DataSize,%DataPtr,%theFile
       CALL FileStreamRead@RT::
FileStreamRead@RT:: PROC1
     PUSH RBX,RCX,RDX,RSI,RDI,R11
       SUB EDX,EDX
       MOV RBX,[RSP+7*8]      ; theFile.
       MOV RAX,-EBADFD        ; Error: file is not open.
       TESTD [RBX+FILE64.Status],fi64StOpened
       STC
       JZ .90:
       TESTD [RBX+FILE64.Status],fi64StAllocated
       STC
       JZ .90:
       MOV RDI,[RSP+8*8]      ; DataPtr.
.10:   MOV RSI,[RBX+FILE64.Ptr]
.20:   MOV RCX,[RBX+FILE64.Top]
       SUB RCX,RSI            ; How many bytes is left in buffer.
       JNA .50:
       CMP RCX,[RSP+9*8]      ; Is it enough for the requested DataSize?
       JA .60:
       SUB [RSP+9*8],RCX
       ADD RDX,RCX
       REP MOVSB
       MOV [RBX+FILE64.Ptr],RSI
       JMP .20:
.50:   MOV RSI,[RBX+FILE64.BufPtr]
       MOV [RBX+FILE64.Ptr],RSI
       MOV [RBX+FILE64.Top],RSI
       LinABI read,[RBX+FILE64.Handle],RSI,[RBX+FILE64.BufSize],Fastmode=Yes
       CMP RAX,-ERR_MAX
       CMC
       JC .90:
       ADD [RBX+FILE64.Top],RAX
       JMP .20:
.60:   MOV RCX,[RSP+9*8]       ; DataSize.
       ADD RDX,RCX
       REP MOVSB
       MOV [RBX+FILE64.Ptr],RSI
.70:   MOV RAX,RDX
       ADD [RBX+FILE64.Pos],RDX
       TEST RAX
.90: POP R11,RDI,RSI,RDX,RCX,RBX
     RET 3*8
 ENDPROC1 FileStreamRead@RT::
%ENDMACRO FileStreamRead
FileStreamReadLn theFile
reads one LineFeed-terminated physical line from the file opened with FileStreamOpen.
When the size of physical line exceeds the size of buffer allocated with FileStreamOpen, returned data may not terminate with 0x0A (LineFeed) and FileStreamReadLn should be invoked again - per partes reading.
Input
theFile is pointer to a FILE64 object.
Output
CF=0
ZF=0
RAX= line size (never bigger than theFILE64.BufSize)
RSI= pointer to the line in buffer.
End of file
CF=0
ZF=1
RAX=0 when there are no more data in file (EOF).
RSI= undefined
Error
CF=1
RAX= error code.
RSI= undefined.
FileStreamReadLn %MACRO theFile
      PUSHQ %theFile
      CALL FileStreamReadLn@RT::
FileStreamReadLn@RT:: PROC1
    PUSH RBX,RCX,RDX,RSI,RDI,R11
      MOV RBX,[RSP+7*8]     ; theFile.
      MOV RAX,-EBADFD       ; Error: file is not open.
      TESTD [RBX+FILE64.Status],fi64StOpened
      STC
      JZ .90:
      TESTD [RBX+FILE64.Status],fi64StAllocated
      STC
      JZ .90:
.10:  MOV RDI,[RBX+FILE64.Ptr]
      MOV RCX,[RBX+FILE64.Top]
      MOV [RSP+2*8],RDI       ; Returned ESI.
      MOV RDX,RDI
      SUB RCX,RDI
      JNA .30:
      MOV AL,10             ; Search for LineFeed.
      REPNE SCASB
      JE .50:
      CMP RDX,[RBX+FILE64.BufPtr]
      JE .50:
      ; When EOL is out of buffer and start of line is not
      ;  at buffer's beginning, the buffer will be reloaded with the current line.
      MOV RCX,RDX
      SUB RCX,RDI
      LinABI lseek,[RBX+FILE64.Handle],RCX,SEEK_CUR,Fastmode=Yes
      CMP RAX,-ERR_MAX
      CMC
      JC .90:
.30:  MOV RSI,[RBX+FILE64.BufPtr]
      MOV [RBX+FILE64.Ptr],RSI
      MOV [RBX+FILE64.Top],RSI
      LinABI read,[RBX+FILE64.Handle],RSI,[RBX+FILE64.BufSize],Fastmode=Yes
      CMP RAX,-ERR_MAX
      CMC
      JC .90:
      TEST RAX
      JZ .90:                ; End of file.
      ADD RAX,RSI
      MOV [RBX+FILE64.Top],RAX
      JMP .10:
.50:  MOV [RBX+FILE64.Ptr],RDI
      MOV RAX,RDI
      SUB RAX,RDX
      ADD [RBX+FILE64.Pos],RAX
.90:POP R11,RDI,RSI,RDX,RCX,RBX
    RET 1*8
 ENDPROC1 FileStreamReadLn@RT::
%ENDMACRO FileStreamReadLn
FileStreamReadByte theFile
reads one byte from the file opened with FileStreamOpen.
Input
theFile is pointer to a FILE64 object.
Output
CF=0
ZF=0
AL= the byte read from file. Other bytes in RAX are preserved.
End of file
CF=0
ZF=1
RAX= unchanged, when there are no more bytes in the file (EOF).
Error
CF=1
RAX= error code.
Remark
if CF=0
FileStreamReadByte %MACRO theFile
     PUSHQ %theFile
     CALL FileStreamReadByte@RT::
FileStreamReadByte@RT:: PROC1
     PUSH RBX,RCX,RDX,RBP,RSI,RDI,R11
      MOV RBX,[RSP+8*8]       ; theFile.
.10:  MOV RSI,[RBX+FILE64.Ptr]
      CMP RSI,[RBX+FILE64.Top]
      JB .50:
      MOV RSI,[RBX+FILE64.BufPtr]
      MOV [RBX+FILE64.Ptr],RSI
      MOV [RBX+FILE64.Top],RSI
      MOV RBP,RAX
      LinABI read,[RBX+FILE64.Handle],RSI,[RBX+FILE64.BufSize],Fastmode=Yes
      CMP RAX,-ERR_MAX
      CMC
      JC .90:
      ADD [RBX+FILE64.Top],RAX
      TEST RAX
      MOV RAX,RBP
      JZ .90:
      JMP .10:              ; This time it will not fail.
.50:  LODSB
      MOV [RBX+FILE64.Ptr],RSI
      INCQ [RBX+FILE64.Pos]
      CLC
.90: POP R11,RDI,RSI,RBP,RDX,RCX,RBX
     RET 1*8
  ENDPROC1 FileStreamReadByte@RT::
 %ENDMACRO FileStreamReadByte
FileStreamCreate theFile, BufSize=16K
This macro creates a new file or rewrites an existing file for writing and allocates memory buffer from OS heap. The buffer will be automatically written to the file whenever it is completely filled with FileStreamWrite*.
Input
theFile is pointer to a FILE64 object with assigned filename.
BuffSize= specifies the buffer size.
Output
CF=0
RAX=0 (size of just rewritten file).
Error
CF=1
EAX= errorCode.
Depends on
FileCreate
FileStreamCreate %MACRO theFile,BufSize=16K
       PUSHQ %BufSize,%theFile
       CALL FileStreamCreate@RT::
FileStreamCreate@RT:: PROC1
    PUSH RBX,RCX,RDX,RSI,RDI,R8,R9,R10,R11
     MOV RBX,[RSP+10*8]     ; theFile.
     RstSt [RBX+FILE64.Status],fi64StAppend
     FileCreate RBX
     JC .90:
     MOV RSI,[RSP+11*8]     ; BufSize.
     XOR EAX,EAX
     LinABI mmap,RAX,RSI,PROT_READ+PROT_WRITE+PROT_EXEC,MAP_PRIVATE+MAP_ANONYMOUS,-1,RAX,Fastmode=Yes
     CMP RAX,-ERR_MAX
     CMC
     JC .90:
     MOV [RBX+FILE64.BufSize],RSI
     MOV [RBX+FILE64.BufPtr],RAX
     MOV [RBX+FILE64.Ptr],RAX
     ADD RAX,RSI
     MOV [RBX+FILE64.Top],RAX
     SetSt [RBX+FILE64.Status],fi64StAllocated
     MOV RAX,[RBX+FILE64.Size]
.90:POP R11,R10,R9,R8,RDI,RSI,RDX,RCX,RBX
    RET 2*8
  ENDPROC1 FileStreamCreate@RT::
%ENDMACRO FileStreamCreate
FileStreamAppend theFile, BufSize=16K
This macro creates a new file or rewrites an existing file for writing at its end and allocates memory buffer from heap. Buffer will be written to file every time it is completely filled with FileStreamWrite*.
Input
theFile is pointer to a FILE64 object,
BuffSize= specifies the buffer size.
Output
CF=0
EAX= is the old file size.
Error
CF=1
EAX= errorCode.
Depends on
FileStreamCreate
FileStreamAppend %MACRO theFile,BufSize=16K
       PUSHQ %BufSize,%theFile
       CALL FileStreamAppend@RT::
FileStreamAppend@RT:: PROC1
    PUSH RBX,RCX,RDX,RSI,RDI,R8,R9,R10,R11
     MOV RBX,[RSP+10*8]     ; theFile.
     SetSt [RBX+FILE64.Status],fi64StAppend
     FileCreate RBX
     JC .90:
     MOV RSI,[RSP+11*8]     ; BufSize.
     XOR EAX,EAX
     LinABI mmap,RAX,RSI,PROT_READ+PROT_WRITE+PROT_EXEC,MAP_PRIVATE+MAP_ANONYMOUS,-1,RAX,Fastmode=Yes
     CMP RAX,-ERR_MAX
     CMC
     JC .90:
     MOV [RBX+FILE64.BufSize],RSI
     MOV [RBX+FILE64.BufPtr],RAX
     MOV [RBX+FILE64.Ptr],RAX
     ADD RAX,RSI
     MOV [RBX+FILE64.Top],RAX
     SetSt [RBX+FILE64.Status],fi64StAllocated
     MOV RAX,[RBX+FILE64.Size]
.90:POP R11,R10,R9,R8,RDI,RSI,RDX,RCX,RBX
    RET 2*8
   ENDPROC1 FileStreamAppend@RT::
 %ENDMACRO FileStreamAppend
FileStreamWriteByte theFile
This macro writes one byte from AL to the file opened with FileStreamCreate or FileStreamAppend.
Input
theFile is pointer to a FILE64 object,
AL contains the data byte to write.
Output
CF=0, registers unchanged.
Error
CF=1
RAX= error code.
Depends on
FileFlush
FileStreamWriteByte %MACRO theFile
      PUSHQ %theFile
      CALL FileStreamWriteByte@RT::
FileStreamWriteByte@RT:: PROC1
     PUSH RAX,RBX,RDI
      MOV RBX,[RSP+4*8]          ; theFile.
.10:  MOV RDI,[RBX+FILE64.Ptr]
      CMP RDI,[RBX+FILE64.Top]
      JB .50
      FileFlush RBX              ; Write the buffer if it is full.
      JNC .10:
      MOV [RSP+2*8],RAX          ; Returned RAX on error.
      JMP .90:
.50:  STOSB
      MOV RAX,[RBX+FILE64.Pos]
      MOV [RBX+FILE64.Ptr],RDI
      INC RAX
      MOV [RBX+FILE64.Pos],RAX
      MOV [RBX+FILE64.Size],RAX
      CLC
.90: POP RDI,RBX,RAX
     RET 1*8
  ENDPROC1 FileStreamWriteByte@RT::
 %ENDMACRO FileStreamWriteByte
FileStreamWriteWord theFile
This macro writes one word from AX to the file opened with FileStreamCreate or FileStreamAppend.
Input
theFile is pointer to a FILE64 object,
AX contains the data word to write.
Output
CF=0, registers unchanged.
Error
CF=1
RAX= error code.
Depends on
FileFlush
FileStreamWriteWord %MACRO theFile
      PUSHQ %theFile
      CALL FileStreamWriteWord@RT::
FileStreamWriteWord@RT:: PROC1
     PUSH RAX,RBX,RCX,RDI
      MOV RBX,[RSP+5*8]           ; theFile.
.10:  MOV RDI,[RBX+FILE64.Ptr]
      LEA RCX,[RDI+1]
      CMP RCX,[RBX+FILE64.Top]
      JB .50:
      FileFlush RBX              ; Write the buffer if it is full.
      JNC .10:
      MOV [RSP+3*8],RAX           ; Returned RAX on error.
      JMP .90:
.50:  STOSW
      MOV RAX,[RBX+FILE64.Pos]
      MOV [RBX+FILE64.Ptr],RDI
      ADD EAX,2
      MOV [RBX+FILE64.Pos],RAX
      MOV [RBX+FILE64.Size],RAX
      CLC
.90: POP RDI,RCX,RBX,RAX
     RET 1*8
  ENDPROC1 FileStreamWriteWord@RT::
 %ENDMACRO FileStreamWriteWord
FileStreamWriteDword theFile
This macro writes one doubleword from EAX to the file opened with FileStreamCreate or FileStreamAppend.
Input
theFile is pointer to a FILE64 object,
EAX contains the data word to write.
Output
CF=0, registers unchanged.
Error
CF=1
EAX= errorCode .
Depends on
FileFlush
FileStreamWriteDword %MACRO theFile
      PUSHQ %theFile
      CALL FileStreamWriteDword@RT::
FileStreamWriteDword@RT:: PROC1
     PUSH RAX,RBX,RCX,RDI
      MOV RBX,[RSP+5*8]           ; the File.
.10:  MOV RDI,[RBX+FILE64.Ptr]
      LEA RCX,[RDI+3]
      CMP RCX,[RBX+FILE64.Top]
      JB .50
      FileFlush RBX               ; Write the buffer if it is full.
      JNC .10:
      MOV [RSP+3*8],RAX           ; Returned RAX on error.
      JMP .90:
.50:  STOSD
      MOV RAX,[RBX+FILE64.Pos]
      MOV [RBX+FILE64.Ptr],RDI
      ADD EAX,4
      MOV [RBX+FILE64.Pos],RAX
      MOV [RBX+FILE64.Size],RAX
      CLC
.90: POP RDI,RCX,RBX,RAX
     RET 1*8
  ENDPROC1 FileStreamWriteDword@RT::
 %ENDMACRO FileStreamWriteDword
FileStreamWriteRT theFile, DataPtr1, DataSize1, DataPtr2,DataSize2,,,
is a runtime defining macro used internally by FileStreamWrite*.
It declares runtime procedure FileWrite@RT with variable number of parameters.
Input
theFile is pointer to a FILE64 object opened by FileStreamCreate or FileStreamAppend.
DataPtr* is pointer to data being written,
DataSize* is the number of bytes in data.
Output
CF=0
RAX is the number of written bytes. Other registers are preserved.
Error
CF=1
RAX is error code.
Depends on
FileFlush
FileStreamWriteRT %MACRO ; Common runtime procedure for macros FileStreamWrite*
    %IF %# & 1 = 0
      %ERROR ID=5946, 'Macro FileStreamWrite expects odd number of arguments.'
      %EXITMACRO FileStreamWriteRT
    %ENDIF
    PUSHQ 0                     ; Mark the end of arguments.
    ArgNr %FOR %#..2,STEP=-2
    PUSHQ %*{%ArgNr}, %*{%ArgNr-1}
    %ENDFOR ArgNr
    PUSHQ %theFile,RSP
      ADDQ [RSP],(%#+1)*8
      CALL FileStreamWrite@RT::
    POP RSP
FileStreamWrite@RT::PROC1
    PUSH RBX,RCX,RDX,RBP,RSI,RDI
     MOV RBX,[RSP+8*8]         ; theFile.
     MOV RAX,-EBADFD           ; File was not opened.
     TESTD [RBX+FILE64.Status],fi64StCreated
     STC
     JZ .90:
     TESTD [RBX+FILE64.Status],fi64StAllocated
     STC
     JZ .90:
     PUSHQ 0                    ; Returned RAX will accumulate written size.
      LEA RBP,[RSP+10*8]        ; Pointer to the first DataPtr.
.20:  XCHG RBP,RSI
      LODSQ                     ; DataPtr.
      MOV RBP,RAX
      TEST RAX                  ; Test if it's the end of pointers.
      JZ .80:
      LODSQ                     ; DataSize.
      XCHG RSI,RBP
      MOV RDX,RAX
      INC RAX
      JNZ .30:
      MOV RCX,RDX               ; DataSize=-1, let's find the actual size.
      MOV RDI,RSI
      REPNE SCASB
      SUB RDI,RSI
      LEA RDX,[RDI-1]
.30:  MOV RDI,[RBX+FILE64.Ptr]  ; RDX is DataSize.
      MOV RCX,[RBX+FILE64.Top]
      SUB RCX,RDI
      JA .40:
      FileFlush RBX
      JNC .30:
      LEA RSP,[RSP+1*8]         ; Keep CF and RAX=error code.
      JMP .90:
.40:  SUB RDX,RCX
      JAE .50:
      ADD RCX,RDX
.50:  ADD [RBX+FILE64.Pos],RCX
      ADD [RBX+FILE64.Size],RCX
      ADD [RSP+0*8],RCX         ; Accumulate total written size.
      REP MOVSB
      MOV [RBX+FILE64.Ptr],RDI
      CMP RDX,RCX
      JG  .30
      JMP .20:
.80: POP RAX
.90:POP RDI,RSI,RBP,RDX,RCX,RBX
    RET
   ENDP1 FileStreamWrite@RT::
   %ENDMACRO FileStreamWriteRT
FileStreamWrite theFile, DataPtr1, DataSize1, DataPtr2, DataSize2,,,
This macro writes data to the file previously opened with FileStreamCreate or FileStreamAppend.
Multiple data portions may be written in one macro invocation.
Input
theFile is pointer to an open FILE64 object,
DataPtr* is pointer to the data to be written.
DataSize* is the size of the data in bytes to be written. It may be bigger than the buffer size specified on opening the file.
Output
CF=0
RAX= total written size in bytes.
Error
CF=1
RAX= error code.
Depends on
FileStreamWriteRT
FileStreamWrite %MACRO theFile,DataPtr1,DataSize1,DataPtr2,DataSize2,,,
      FileStreamWriteRT %*
 %ENDMACRO FileStreamWrite
FileStreamWriteLn theFile, DataPtr1, DataSize1, DataPtr2, DataSize2,,,
This macro writes data to the file previously opened with FileStreamCreate or FileStreamAppend.
Multiple data portions may be written in one macro invocation. End of line LF character is written in the end.
Input
theFile is pointer to an open FILE64 object,
DataPtr* is pointer to the data to be written,
DataSize* is the size of the data to be written. It may be bigger than the buffer size specified on opening the file.
Output
CF=0
RAX= total written size including LF.
Error
CF=1
RAX= error code.
Depends on
FileStreamWriteRT
FileStreamWriteLn %MACRO theFile,DataPtr1,DataSize1,DataPtr2,DataSize2,,,
    FileStreamWriteRT %*, =B 0x0A, 1
 %ENDMACRO FileStreamWriteLn
FileStreamWrite$ theFile, DataPtr$1, DataPtr$2,,,
This macro writes one or more zero terminated strings to the file previously opened with FileStreamCreate or FileStreamAppend.
Multiple ASCIIZ strings may be written in one macro invocation. Their terminating zeros are not written to the file.
Input
theFile is pointer to an open FILE64 object,
DataPtr$* are pointers to the zero terminated strings to be written.
Output
CF=0
RAX= total written size.
Error
CF=1
RAX= error code.
Depends on
FileStreamWriteRT
FileStreamWrite$ %MACRO theFile,DataPtr$1,DataPtr$2,DataPtr$3,,,
%ArgList %SET %theFile
    ArgNr %FOR 2..%#
    %ArgList %SET %ArgList,%*{%ArgNr},-1
          %ENDFOR ArgNr
    FileStreamWriteRT %ArgList
  %ENDMACRO FileStreamWrite$
  ENDHEAD linf64

▲Back to the top▲