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)

Language: 
Dark Basic Pro
Code: 
`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 ""
2
Average: 2 (1 vote)