home *** CD-ROM | disk | FTP | other *** search
- /*
- GSAVEARRAY() and GLOADARRAY()
- Functions to save and load arrays from/to text files
- Copyright (c) 1990 Greg Lief - All Rights Reserved
- Special Thanks to Craig Yellick for his contributions!
- Clipper 5.x Version
- Compile instructions: clipper arrays /n/w/a
- */
-
- /* Stub program to test these functions */
-
- #ifdef TESTING
-
- function Main()
- local myarray
- local a := { 'one', 'two', 'three', NIL, ;
- { 'this', 'is a', {'another', 'test', {1,2,3} } }, ;
- { || "BLOCK TEST" }, .t., directory("*.EXE") }
- gsavearray(a, 'temp.txt')
- wait "Array saved to TEMP.TXT... press a key to continue."
- if len( myarray := gloadArray('temp.txt') ) > 0
- cls
- DumpArray(myarray)
- endif
- return nil
-
- function DumpArray(a_, level)
- /*
- List the contents of any array. Listing is indented to show nesting
- of subarrays. This function uses a recursive call to itself. Do not
- specify the level parameter, it is used internally during the
- recursive calls.
- */
- local i
- if level = nil
- level := 0
- endif
- for i := 1 to len(a_)
- ? space(level * 4) + str(i, 4) + ": "
- if valtype(a_[i]) = "A"
- ?? "{..}"
- DumpArray(a_[i], level + 1)
- else
- ?? a_[i]
- endif
- next i
- return nil
-
- #endif
-
- * end main stub program
- *--------------------------------------------------------------------*
-
- /*
- Function: GLoadArray()
- Copyright (c) 1990 Greg Lief - All Rights Reserved
- Purpose: load an array from a previously saved text file
- Syntax: LoadArray(<filename>)
- Parameters: <filename> is the name of the file from which to
- load the array.
-
- Return Value: The target array. If the load failed, the
- target array will have a length of zero.
-
- Sample call: myarray := LoadArray('array.txt')
-
- */
- function GLoadArray(fileName)
- local nHandle, aArray := {}
- if (nHandle := fopen(fileName)) != -1
- ElementIn(nHandle, aArray)
- endif
- fclose(nHandle)
- return aArray
-
- * end function GLoadArray()
- *--------------------------------------------------------------------*
-
- /*
- Function: ElementIn()
- Copyright (c) 1990 Greg Lief - All Rights Reserved
- (Converted to use L-string style element storage by Craig Yellick.)
- Purpose: actually reads each element of the array
- Internal Only!!
- */
- static function ElementIn(handle, a_)
- local buffer, i, cnt, iLen, iType := ' '
- //───── Read the overall array size
- buffer := space(2)
- if fread(handle, @buffer, 2) = 2
- //───── Process each array element stored in the file.
- cnt := bin2i(buffer)
- for i = 1 to cnt
- //───── Read the element's data type.
- //───── If element is a nested array-- recursion time!
- fread(handle, @iType, 1)
- if iType == "A"
- aadd(a_, {})
- ElementIn( handle, a_[ len(a_) ] )
- else
- //───── Read the length of the element.
- buffer := space(2)
- if fread(handle, @buffer, 2) = 2
- iLen := bin2i(buffer)
-
- //───── Read the actual element.
- buffer := space(iLen)
- if fread(handle, @buffer, iLen) = iLen
-
- //───── Convert from string to specified data type.
- do case
- /*
- Note that this will simply not work with code blocks.
- If you attempted to save one from an array, we will have
- empty space and thus must add a NIL to serve only as a
- placeholder.
- */
- case (iType = "B") .or. (iType = "Z")
- aadd(a_, nil)
- case iType = "C"
- aadd(a_, buffer)
- case iType = "D"
- aadd(a_, ctod(buffer))
- case iType = "L"
- aadd(a_, (buffer == "T"))
- case iType = "N"
- aadd(a_, val(buffer))
- endcase
- endif
- endif
- endif
- next i
- endif
- return nil
-
- * end static function ElementIn()
- *--------------------------------------------------------------------*
-
-
- /*
- Function: GSaveArray()
- Copyright (c) 1990 Greg Lief - All Rights Reserved
- Purpose: saves a specified array to a text file.
- Syntax: SaveArray(<array>, <filename>)
- Parameters: <array> is the name of the array to be saved.
- Do not enclose this in quotes!
-
- <filename> is the name of the file in which to
- save the array. Note that if this file exists,
- it will be overwritten!
-
- Returns: A logical True (.T.) if the save was successful;
- False (.F.) if it was not.
-
- Example: savearray(marray, 'array.txt')
- */
- function gsavearray(a_, fileName)
- local cnt := len(a_), handle := fcreate(fileName), success := .f.
- if handle != -1
- success := ElementOut(handle, a_)
- fclose(handle)
- endif
- return success
-
- * end function GSaveArray()
- *--------------------------------------------------------------------*
-
- /*
- Function: ElementOut()
- Copyright (c) 1990 Greg Lief - All Rights Reserved
- (Converted to use L-string style element storage by Craig Yellick.)
- Purpose: actually writes each element of the array
- Internal Only!!
- */
- static function ElementOut(handle, a_)
- local cnt := len(a_), i, buffer, success := .t.
- //───── Write the overall array size.
- fwrite(handle, i2bin(cnt))
-
- //───── Process each element in the array.
- for i = 1 to cnt
-
- //───── Special handling for the NIL and code block data types
- if (a_[i] = nil) .or. (valtype(a_[i]) = "B")
- buffer := "Z" +i2bin(1) +"Z"
- else
- /*
- Each element is encoded as follows.
- Type: C,D,L,N
- Width: Number of characters needed to store value
- Value: String version of the value.
- */
- buffer := valtype(a_[i])
- do case
- case buffer = "C"
- buffer += i2bin(len(a_[i])) +a_[i]
- case buffer = "D"
- buffer += i2bin(8) +dtoc(a_[i])
- case buffer = "L"
- buffer += i2bin(1) +if(a_[i], "T", "F")
- case buffer = "N"
- buffer += i2bin(len(str(a_[i]))) + str(a_[i])
- otherwise
- //───── Type "A" for arrays will be handled after we write the type
- endcase
- endif
- if fwrite(handle, buffer, len(buffer)) != len(buffer)
- success := .f.
- exit
- endif
- //───── if this is a nested array, recursion time!
- if left(buffer, 1) == "A"
- ElementOut( handle, a_[i] )
- endif
- next i
- return success
-
- * end static function ElementOut()
- *--------------------------------------------------------------------*
-
- * end of file ARRAYS.PRG
-