#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Run_Au3Stripper=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include-once #include ; open/create a DA file. ;Param1= variable previous created by user, ex: $file=0. It will be converted in an array, where all fle information is saved, including record fields. ;Param2= open mode = read (1) , read+write file (2), read+write+create (3). ; mode=1 => file must exists and can only be read. ; mode=2 => file + path will be created if do not exists. Record pointer will be after last record (so a write will be at fileīs end) ; mode 3 => a previous file will be erased. File + path will be created. ;Param3= flush at each "n" writes. If 0, there are no flushes. default = 10 = a flush at each 10 writes Func _fileDA_Open (ByRef $file, $filename, $mode, $flush=10 ) If ($mode < 1) And ($mode > 3) Then ;only open for read=1, write=2, read/write=3 Return SetError(1,0,-1) ;if open mode invalid, returns -1, @error=1 EndIf If (IsArray( $file )= False ) Or (UBound ($file) < 200) Then Dim $file[200] ;makes $file an array that holds all needed values to work with this file (max 188 fields) EndIf Switch $mode ;based on $mode, sets file open method acordinly Case 1 $file[2]= 1 $OpenMode= $FO_READ Case 2 $file[2]= 2 $OpenMode= $FO_APPEND + $FO_CREATEPATH Case 3 $file[2]= 3 $OpenMode= $FO_OVERWRITE + $FO_CREATEPATH EndSwitch $file[3]= $filename $file[4]= $flush $file[5]= $flush ;down counter for # writes for each flush $file[1]= FileOpen( $filename, $FO_ANSI + $FO_BINARY + $OpenMode ) ;open for read, write or both. Path is created if not exists If $file[1] = -1 Then Return SetError(2,0,-1) ;if by any reason open fails, returns -1, @error=2 Else Return SetError(0,0,0) ;open was sucessfull => returns 0 EndIf ;$file[1]= filehandle ;$file[2]= open mode ;$file[3]= filename ;$file[4]= flush at each "n" writes ;$file[5]= flush down-count ;$file[10]= number of fields ;$file[11]= record length (fields size sum) ;$file[12,13,..]= fields definitions: [12] = field1 type (int32 (=1), int64(=2), string(=3), double float(=4) ), [13] field1 lenght, ... EndFunc ;define record length and fields. ;Param1= array describing file, created by _fileDA_Open ;Param2= array [n][2]: n= # fields, [n][0]=field type, [n][1]= field lenght (used just if string, otherwise ignored) Func _FileDA_defineRecord(ByRef $file, $fields) $recordSize=0 For $K=0 to UBound($fields)-1 ;for each field defined => [0,0]= 1st field type, [0,1]= 1st field length (must be given just for strings) $I= $K*2+12 $file[$I]= $fields[$K][0] ;saves it's type (int32=1, int64=2, string=3, double float=4) Switch $fields[$K][0] Case 1 $file[$I+1] = 4 ;type 1= int32 => size= 4 bytes $recordSize = $recordSize + 4 Case 2 $file[$I+1] = 8 ;type 2= int64 => size= 8 bytes $recordSize = $recordSize + 8 Case 3 $file[$I+1]= $fields[$K][1] ;type 3= string ASCII => size user given $recordSize = $recordSize + $fields[$K][1] Case 4 $file[$I+1] = 8 ;type 4= double real => size= 8 bytes $recordSize = $recordSize + 8 Case Else Return SetError(3,0,-1) ; if invalid field type, returns -1, @error=3 EndSwitch Next $file[10]= $K ;number of fields $file[11]= $recordSize ;record length is the sum of the field sizes EndFunc ;writes a record. ;Param1= array describing file, created by _fileDA_Open ;Param2= array[n], n= number of recordÂīs fields. [0]= field1, [1]= field2... each field must have same definitionīs datatypes ;strings smaller than fieldīs size => will be filled with " ", bigger will be right trimmed (left n chars will remain) Func _fileDA_Write (ByRef $file, ByRef $record) If UBound ($record) < $file[10] Then Return SetError(4,0,-1) ;if $record array has less columns than number of fields, returns -1, @error=4 EndIf For $K= 0 To $file[10]-1 $I= $K*2+12 Switch $file[$I] Case 1 ;if field=int32, writes 4 bytes $stat= FileWrite( $file[1], Number( $record[$K], 1 ) ) Case 2 ;if field=int64, writes 8 bytes (user can use always int64 if donīt know if number can be higher $stat= FileWrite( $file[1], Number( $record[$K], 2 ) ) Case 3 $record[$K] &= StringLeft( " " , $file[$I+1]-StringLen($record[$K]) ) ;if string < filed definition, fills with " " $stat= FileWrite( $file[1], StringLeft( $record[$K], $file[$I+1] ) ) ;just left chars up to field length are recorded Case 4 ;real (floating point = 8 bytes) $stat= FileWrite( $file[1], Number($record[$K], 3 ) ) EndSwitch If $stat <> 1 Then Return SetError(5,0,-1) ;if record was not recorded by any reason, returns -1, @error=5 Next If $file[4] > 0 Then ;if flush requested... $file[5] -= 1 ;decrement # writes If $file[5] <= 0 Then ;if itīs time to flush (at each "n" writes) FileFlush( $file[1] ) ;flushes $file[5]= $file[4] ;replenish # writes up to next flush EndIf EndIf EndFunc ;reads next record ;Param1= array describing file, created by _fileDA_Open ;Param2= array with # columns >= # fields. Each arrayīs column receives a record field Func _fileDA_Read (ByRef $file, ByRef $record) If UBound ($record) < $file[10] Then Return SetError(4,0,-1) ;if $record array has less columns than number of fields, returns -1, @error=4 EndIf For $K= 0 To $file[10]-1 ;for each field in record, reads it acordingly to itīs type $I= $K*2+12 Switch $file[$I] Case 1 $X= FileRead( $file[1], 4) $stat= @error $record[$K]= int( $X ) Case 2 $X= FileRead( $file[1], 8) $stat= @error $record[$K]= Number( $X , 2 ) Case 3 $X= FileRead( $file[1], $file[$I+1]) $stat= @error $record[$K]= BinaryToString($X, $SB_ANSI ) Case 4 $X= FileRead( $file[1], 8) $stat= @error $record[$K]= Dec($X , 3 ) ;MsgBox(4096, "real", $I &@cr& "X:"&$X &@cr& "int:"&int($X) &@cr& "H:"&Hex($X) &@cr& "Dec:"&Dec( Hex($X) , 3 )) EndSwitch If $stat <> 0 Then Return SetError(6,0,-1) ;if record was not read by any reason, returns -1, @error=6 Next EndFunc ;Positions file pointer at next record to be read or write. ;Param1= array describing file, created by _fileDA_Open ;Param2= pointer position. ;Param3= type of positioning: 0= absolute form start (default), 1= relative to the current position Func _fileDA_Pos (ByRef $file, $pos, $origin=0) If $origin=0 Then $x= ($pos-1) * $file[11] ;position is record size dependent Else $x= $pos * $file[11] EndIf FileSetPos($file[1], $x, $origin) EndFunc ;Closes file. ;Param1= array describing file, created by _fileDA_Open ;Param2= type of close: 1 (defaut), clears $file array, so another file can be created on this variable. 0= another open is necessary, but defineRecord is not (ex: read) Func _fileDA_Close (ByRef $file, $free=1) FileFlush ($file[1]) FileClose ($file[1]) If $free=1 Then $file=0 EndFunc