This FileIO Data Engine can load, modify, and save files in a format similar to the Windows INI. This is the syntax:
BOF
[field1]
key1: parameter1, parameter2, parameter3
key2: parameter1, parameter2, parameter3
[field2]
key1: parameter1, parameter2, parameter3
key2: parameter1, parameter2, parameter3
EOF
These are the functions for loading, saving, modifing, and extracting data from the engine.
Fio_init() - call this first
Fio_reset() - erase all data
Fio_addfield(name$) - add a field, call with field name
*Fio_addkey(name$, field, parameters) - add a key, call with key name, field number, and comma separated values for parameters
*Fio_deletefield(number) - delete field with said number
*Fio_deletekey(number) - delete key with said number
Fio_load(filename, handle) - load a file into the data engine
Fio_save(filename, handle) - save data engine to a file
Fio_findkey(name$, field) - returns the number of a key with said name in said field
*Fio_getparam(field, key, parameter_number) - returns a parameter in said key
Fio_paramcount(field, key) - returns the number of parameters in said key
*Fio_setparam(field, key, parameter_number, parameter) - sets a key's parameter, call with field and key number, parameter number and the parameter itself
Fio_totalfields() - returns the total number of fields
*Fio_totalkeys(field) - returns the total number of keys in said field
*Fio_getkeyname(field, key) - returns the name of the key in said field with said number
Fio_getfieldname(field) - returns the name of said field
* There are alternate versions of these functions which take string parameters instead of numbers. This is so you don't have to constantly use Fio_findkey() and Fio_findfield() to figure out the numbers of the fields and keys, you can just use the keys. To use these functions replace Fio_ with Fiostr_ in your function call.
This is a very complex system so it may take awhile to learn how to use it. (It took me about 4 hours to write it)
`EXAMPLE ` `this creates a field called Hello World `and adds a key called Hi with 5 parameters `then saves the file and executes it so you can `see the output set dir "C:\" if path exist("temp") = 0 then make directory "temp" set dir "temp" Fio_init() Fio_addfield("Hello World") Fiostr_addkey("Hi", "Hello World", "1, 2, 3, 4, 5") Fio_save("Hello World.txt", 1) execute file "Hello World.txt", "", "" end `**************************** `**** FileIO Data Engine **** `**** **** `**** by Code Dragon **** `**************************** type Fiocache key as integer endtype function Fiocache_init() dim Fiocache_vals() as string Fio.cache.key = -1 endfunction function Fiocache_reset() empty array Fiocache_vals() Fio.cache.key = -1 endfunction `loads a key's parameters into the cache function Fiocache_load(key as dword) local keyparam as string `check for cache hit if Fio.cache.key = key then exitfunction `prevent overwrite of the old cachekey Fiocache_save() `clear out old cache and set the new one to this key empty array Fiocache_vals() Fio.cache.key = key `give the parameters to the csv system Csv_reset() Csv_addval(Fio_Keys(key).params) do `retrive the parameter value from the csv system and exit if it's empty keyparam = Csv_getval() if keyparam = "CSV_EMPTY" then exit `add the value to the cache array array insert at bottom Fiocache_vals() Fiocache_vals() = keyparam loop endfunction `saves the cache to it's key function Fiocache_save() local totalvals as integer local valnum as integer `you can't save a key if it doesn't know what key to save it as if Fio.cache.key = -1 then exitfunction `get the total number of parameters totalvals = array count(Fiocache_vals()) `put each cached parameter into the key Fio_Keys(Fio.cache.key).params = "" while valnum <= totalvals Fio_Keys(Fio.cache.key).params = Fio_Keys(Fio.cache.key).params + Fiocache_vals(valnum) + "," inc valnum endwhile `delete the last comma Fio_Keys(Fio.cache.key).params = left$(Fio_Keys(Fio.cache.key).params, len(Fio_Keys(Fio.cache.key).params) - 1) endfunction type Fio cache as Fiocache endtype type Fio_field name as string firstkey as integer `when this is -1 the field is empty endtype type Fio_key name as string params as string `the key parameters are a simple comma separated values string endtype `initialize the system function Fio_init() global Fio as Fio dim Fio_Fields() as Fio_Field dim Fio_Keys() as Fio_key Fiocache_init() endfunction `reset the system function Fio_reset() empty array Fio_Keys() empty array Fio_Fields() Fiocache_reset() endfunction `add a field to the data engine function Fio_addfield(name as string) array insert at bottom Fio_Fields() Fio_Fields().name = lower$(name) Fio_Fields().firstkey = -1 endfunction `add a key to the data engine function Fio_addkey(name as string, field as integer, params as string) local totalfields as integer local totalkeys as integer totalfields = array count(Fio_Fields()) totalkeys = array count(Fio_Keys()) if field > totalfields or field < 0 then exitfunction `find the location the key should be inserted in and add it if field = totalfields or Fio_Fields(field).firstkey = -1 key = totalkeys + 1 array insert at bottom Fio_Keys() else key = Fio_Fields(field + 1).firstkey array insert at element Fio_Keys(), key endif `add the key data Fio_Keys().name = lower$(name) Fio_Keys().params = params `if this is the first key added to this field, set this key as the first if Fio_Fields(field).firstkey = -1 then Fio_Fields(field).firstkey = key `shuffle all the rest of the fields' key pointers down one while field < totalfields inc field inc Fio_Fields(field).firstkey endwhile endfunction `remove a field from the data engine function Fio_deletefield(field as integer) local totalfields as integer local totalkeys as integer local key as dword local keys as dword local count as dword if Fio_Fields(field).firstkey > -1 totalfields = array count(Fio_Fields()) totalkeys = array count(Fio_Keys()) `find the first key we need to delete key = Fio_Fields(field).firstkey `find out how many keys we need to delete keys = Fio_getlastkey(field) - key `keep deleting the same key because the rest of them will suffle upward for count = 0 to keys Fio_deletekey(key) next count endif `delete the field array delete element Fio_Fields(), field endfunction `remove a key from the data engine function Fio_deletekey(key as dword) local totalfields as integer local field as dword totalfields = array count(Fio_Fields()) `find out which field this key is in while key > Fio_getlastkey(field) inc field endwhile `delete the key array delete element Fio_Keys(), key `suffle all the rest of the fields' key pointers up one while field <= totalfields dec Fio_Fields(field).firstkey inc field endwhile endfunction `load a file into the data engine function Fio_load(filename as string, handle as dword) local str as string local field as dword = -1 open to read handle, filename while file end(handle) = 0 read string handle, str `remove whitespace and blank lines str = trim(str) if len(str) if left$(str, 2) <> "//" if left$(str, 1) = "[" and right$(str, 1) = "]" `this is a field Fio_addfield(str_get_middle(str, 2, len(str) - 3)) inc field else `this is a key if str_find_char(str, ":", 1) = len(str) `this key has no parameters Fio_addkey(left$(str, len(str) - 1), field, "") else `this key has parameters Fio_addkey(str_get_left_from(str, ":"), field, str_get_right_from(str, ":")) endif endif endif endif endwhile close file handle endfunction `save the data engine to a file function Fio_save(filename as string, handle as dword) local totalfields as integer local totalkeys as dword local field as dword local fieldnum as dword local key as dword local lastkey as dword totalfields = array count(Fio_Fields()) totalkeys = array count(Fio_Keys()) `save the cache so the cached key's data is correct Fiocache_save() `file must be deleted in order to overwrite if file exist(filename) then delete file filename open to write handle, filename `don't bother writing if there's no data if totalfields > -1 while field <= totalfields `don't write empty fields if Fio_Fields(field).firstkey > -1 `write field name write string handle, "[" + Fio_Fields(field).name + "]" `find the last key in this field lastkey = Fio_getlastkey(field) while key <= lastkey `write key write string handle, Fio_Keys(key).name + ":" + Fio_Keys(key).params inc key endwhile endif inc field endwhile endif close file handle endfunction `finds the last key in a field function Fio_getlastkey(field as integer) local totalfields as integer local totalkeys as integer local fieldnum as dword local lastkey as integer totalfields = array count(Fio_Fields()) totalkeys = array count(Fio_Keys()) if field => totalfields then exitfunction totalkeys `skip over empty fields fieldnum = field repeat if fieldnum = totalfields then exitfunction totalkeys inc fieldnum lastkey = Fio_Fields(fieldnum).firstkey until lastkey > -1 dec lastkey endfunction lastkey `returns the number of the field with said name `returns -1 if the field does not exist function Fio_findfield(name as string) local totalfields as integer local field as integer totalfields = array count(Fio_Fields()) `make search case insensitive name = lower$(name) while field <= totalfields if Fio_Fields(field).name = name then exitfunction field inc field endwhile `if the code didn't exit by now the field was not found endfunction -1 `returns the number of the key with said name and in said field `returns -1 if the field does not exist `if the field to search in is -1 then all fields will be searched function Fio_findkey(name as string, field as dword) local totalfields as integer local totalkeys as integer totalfields = array count(Fio_Fields()) totalkeys = array count(Fio_Keys()) `make seach case insensitive name = lower$(name) `find where the search should start and stop if field = -1 `search all fields and every last key lastkey = totalkeys else `the first key to search is the first key in this field key = Fio_Fields(field).firstkey lastkey = Fio_getlastkey(field) endif while key <= lastkey if Fio_Keys(key).name = name `calculate key offset dec key, Fio_Fields(field).firstkey exitfunction key endif inc key endwhile `if the code didn't exit by now the key was not found endfunction -1 `returns said parameter from said key function Fio_getparam(field as dword, key as dword, paramnum as dword) local parameter as string `calculate key absolute inc key, Fio_Fields(field).firstkey Fiocache_load(key) if paramnum > array count(Fiocache_vals()) or array count(Fiocache_vals()) = -1 `if the parameter number is illegal then return nothing parameter = "" else `get the respective parameter from the cache parameter = Fiocache_vals(paramnum) endif endfunction parameter `returns the number of parameters in a key function Fio_paramcount(field as dword, key as dword) local totalvals as dword `calculate key absolute inc key, Fio_Fields(field).firstkey Fiocache_load(key) `get the total number of parameters totalvals = array count(Fiocache_vals()) + 1 endfunction totalvals `sets a key's parameter to said argument function Fio_setparam(field as dword, key as dword, paramnum as dword, parameter as string) local totalvals as dword `calculate key absolute inc key, Fio_Fields(field).firstkey Fiocache_load(key) `get the total number of parameters totalvals = array count(Fiocache_vals()) `if the parameter doesn't exist then create it while paramnum > totalvals array insert at bottom Fiocache_vals() inc totalvals endwhile `set the parameter Fiocache_vals(paramnum) = parameter `the changes are not saved immediatly because it would be much more `effiecent to save once all the parameters in one key were set `instead of saving after each parameter was set endfunction `returns the total number of fields function Fio_totalfields() local fields as dword fields = array count(Fio_Fields()) endfunction fields `returns the total number of keys in a field function Fio_totalkeys(field as integer) local keys as dword if field > array count(Fio_Fields()) or field < 0 then exitfunction -1 keys = Fio_getlastkey(field) - Fio_Fields(field).firstkey endfunction keys `returns the name of the key function Fio_getkeyname(field as dword, key as dword) local keyname as string `cacluate key absolute inc key, Fio_Fields(field).firstkey keyname = Fio_Keys(key).name endfunction keyname `returns the name of the field function Fio_getfieldname(field as dword) local fieldname as string fieldname = Fio_Fields(field).name endfunction fieldname `add a key to the data engine function Fiostr_addkey(name as string, fieldname as string, params as string) local field as integer field = Fio_findfield(fieldname) Fio_addkey(name, field, params) endfunction `remove a key from the data engine function Fiostr_deletekey(fieldname as string, keyname as string) local field as dword local key as dword field = Fio_findfield(fieldname) `calculate key absolute key = Fio_findkey(keyname, field) + Fio_Fields(field).firstkey Fio_deletekey(key) endfunction `remove a field from the data engine function Fiostr_deletefield(fieldname as string) Fio_deletefield(Fio_findfield(fieldname)) endfunction `returns said parameter from said key function Fiostr_getparam(fieldname as string, keyname as string, paramnum as dword) local parameter as string local field as dword field = Fio_findfield(fieldname) parameter = Fio_getparam(field, Fio_findkey(keyname, field), paramnum) endfunction parameter `sets a key's parameter to said argument function Fiostr_setparam(fieldname as string, keyname as string, paramnum as dword, parameter as string) local field as dword field = Fio_findfield(fieldname) Fio_setparam(field, Fio_findkey(keyname, field), paramnum, parameter) endfunction `returns the total number of keys in a field function Fiostr_totalkeys(fieldname as string) local keys as integer keys = Fio_totalkeys(Fio_findfield(fieldname)) endfunction keys `returns the name of the key function Fiostr_getkeyname(key as dword, fieldname as string) local keyname as string keyname = Fio_getkeyname(key, Fio_findfield(fieldname)) endfunction keyname `******************************** `******* HELPER FUNCTIONS ******* `******************************** global Csv_str as string `adds one or more values to the csv system function Csv_addval(str as string) if len(Csv_str) `add a preceding comma if there already are values str = "," + str endif Csv_str = Csv_str + str endfunction `retrives a value from the csv system function Csv_getval() local value as string local firstcomma as dword `return "Csv_EMPTY" if there are no values left if len(Csv_str) = 0 then exitfunction "CSV_EMPTY" firstcomma = str_find_char(Csv_str, ",", 1) if firstcomma `there is more than one value, so return everything left of the comma value = left$(Csv_str, firstcomma-1) Csv_str = right$(Csv_str, len(Csv_str) - firstcomma - 1) else `this is the last value, so return all that's left value = Csv_str Csv_reset() endif value = trim(value) endfunction value `resets the csv system function Csv_reset() Csv_str = "" endfunction function ltrim(str as string) local char as dword local length as dword length = len(str) repeat inc char if asc(mid$(str, char)) <> 9 and asc(mid$(str, char)) <> 32 str = right$(str, length - char + 1) exit endif until char > length endfunction str function rtrim(str as string) local char as dword local length as dword length = len(str) char = length repeat if asc(mid$(str, char)) <> 9 and asc(mid$(str, char)) <> 32 str = left$(str, char) exit endif dec char until char = 0 endfunction str function trim(str as string) str = rtrim(ltrim(str)) endfunction str `**** The rest of the functions are manually coded functions that exist in extends `**** If you have extends you can delete these and replace the calls to them with `**** calls to the extends commands `find a character `this function is same in extends besides the fact that it doesn't use the counter parameter function str_find_char(str as string, char as string, null as dword) local t as dword for t = 1 to len(char) if mid$(str, t) = char then exitfunction t next t endfunction 0 `this function by Shortwind `http://www.thegamecreators.com/?m=codebase_view&i=519cfa6bff4ec29f532edbf85f489c14 function str_get_middle(str as string, position as dword, length as dword) if len(str)<length then length=len(str)-position+1 ReturnValue$=right$(left$(str,position+length-1),length) endfunction ReturnValue$ function str_get_right_from(str as string, char as string) local t as dword for t = 1 to len(str) if mid$(str, t) = char exitfunction right$(str, len(str) - t - 1) endif next t endfunction "" function str_get_left_from(str as string, char as string) local t as dword for t = len(str) to 1 step -1 if mid$(str, t) = char exitfunction left$(str, t - 1) endif next t endfunction ""
Mon, 07/09/2007 - 03:44
Why are BOF and EOF necessary?
Wed, 07/11/2007 - 01:25
They're not, don't really know why I put them there. I was probably thinking REALLY technically after debugging things for a half hour when I posted.