Difference between revisions of "Libs-dev/libini"

From KolibriOS wiki
Jump to navigation Jump to search
m
m
 
(7 intermediate revisions by one other user not shown)
Line 1: Line 1:
INI files are structured human-readable text files. Each file consists of one or more sections (text within square braces), each having several keys (text before "=" sign) with corresponding values (text after "=" sign). Here's the example of such file:
+
[http://en.wikipedia.org/wiki/INI_file INI files] are structured human-readable text files. Each file consists of one or more sections, each having several keys with values. Here's the example of such file:
  
 
<source lang="ini">
 
<source lang="ini">
[fruits]
+
[fruit colors]
 
banana = yellow
 
banana = yellow
 
orange = orange
 
orange = orange
 
strawberry = red
 
strawberry = red
  
[vegetables]
+
[vegetable colors]
 
cucumber = green
 
cucumber = green
 
</source>
 
</source>
  
Section names should be unique within file scope. Key names should be unique within section scope. This means, there could be keys with same names located in different sections, but no two sections with same name within a file.
+
Section names are embraced with square braces and are one-line strings which may contain any characters. Sections divide file into parts, where keys and their corresponding values are specified. In the begining of file (before the first section) there may also be keys and values found which aren't in any section. Keys and values are also one-line strings which are separated from each other with equality sign "=". Key name of course can't contain "=" character. Key value is the string after first "=" character found in line till the end on line.
 +
 
 +
Section names, key names and key values are trimmed i.e. space characters are deleted from the beginning and end of the strings during comparison.
 +
 
 +
If each section identifies the set of keys, each key in turn identifies one value. Section and key names don't have to be unique, but if there're two keys (within a section) with the same name, value will be read and written from the one which appears earlier in the file.
 +
 
 +
For all file operations, '''libini''' uses [[Libs-dev/libio|libio]].
  
 
=Functions (enumerating entities)=
 
=Functions (enumerating entities)=
Line 22: Line 28:
  
 
Arguments:
 
Arguments:
:<tt>_f_name</tt>
+
:<tt>_f_name</tt> &rarr; asciiz
::ini filename <asciiz>
+
::ini filename
 
:<tt>_callback</tt>
 
:<tt>_callback</tt>
 
::callback function address: func(f_name, sec_name), where
 
::callback function address: func(f_name, sec_name), where
::<tt>f_name</tt>
+
::<tt>f_name</tt> &rarr; asciiz
:::ini filename (as passed to the function) <asciiz>
+
:::ini filename (as passed to the function)
::<tt>sec_name</tt>
+
::<tt>sec_name</tt> &rarr; asciiz
:::section name found <asciiz>
+
:::section name found
  
 
Result:
 
Result:
:<tt>eax</tt>
+
:<tt>eax</tt> &rarr; dword
 
::-1 (error) / 0
 
::-1 (error) / 0
  
Line 42: Line 48:
  
 
Arguments:
 
Arguments:
:<tt>_f_name</tt>
+
:<tt>_f_name</tt> &rarr; asciiz
::ini filename <asciiz>
+
::ini filename
:<tt>_sec_name</tt>
+
:<tt>_sec_name</tt> &rarr; asciiz
::section name <asciiz>
+
::section name
 
:<tt>_callback</tt>
 
:<tt>_callback</tt>
 
::callback function address: func(f_name, sec_name, key_name, key_value), where
 
::callback function address: func(f_name, sec_name, key_name, key_value), where
::<tt>f_name</tt>
+
::<tt>f_name</tt> &rarr; asciiz
:::ini filename (as passed to the function) <asciiz>
+
:::ini filename (as passed to the function)
::<tt>sec_name</tt>
+
::<tt>sec_name</tt> &rarr; asciiz
:::section name (as passed to the function) <asciiz>
+
:::section name (as passed to the function)
::<tt>key_name</tt>
+
::<tt>key_name</tt> &rarr; asciiz
:::key name found <asciiz>
+
:::key name found
::<tt>key_value</tt>
+
::<tt>key_value</tt> &rarr; asciiz
:::value of key found <asciiz>
+
:::value of key found
  
 
Result:
 
Result:
:<tt>eax</tt>
+
:<tt>eax</tt> &rarr; dword
 
::-1 (error) / 0
 
::-1 (error) / 0
  
Line 71: Line 77:
  
 
Arguments:
 
Arguments:
:<tt>_f_name</tt>
+
:<tt>_f_name</tt> &rarr; asciiz
::ini filename <asciiz>
+
::ini filename
:<tt>_sec_name</tt>
+
:<tt>_sec_name</tt> &rarr; asciiz
::section name <asciiz>
+
::section name
:<tt>_key_name</tt>
+
:<tt>_key_name</tt> &rarr; asciiz
::key name <asciiz>
+
::key name
:<tt>_buffer</tt>
+
:<tt>_buffer</tt> &rarr; byte*
::destination buffer address <byte*>
+
::destination buffer address
:<tt>_buf_len</tt>
+
:<tt>_buf_len</tt> &rarr; dword
::buffer size (maximum bytes to read) <dword>
+
::buffer size (maximum bytes to read)
:<tt>_def_val</tt>
+
:<tt>_def_val</tt> &rarr; asciiz
::default value to return if no key, section or file found <asciiz>
+
::default value to return if no key, section or file found
  
 
Result:
 
Result:
:<tt>eax</tt>
+
:<tt>eax</tt> &rarr; dword
 
::-1 (error) / 0
 
::-1 (error) / 0
:<tt>[_buffer]</tt>
+
:<tt>[_buffer]</tt> &rarr; asciiz
::[_def_val] (error) / found key value <asciiz>
+
::[_def_val] (error) / found key value
  
 
==ini_set_str==
 
==ini_set_str==
Line 97: Line 103:
  
 
Arguments:
 
Arguments:
:<tt>_f_name</tt>
+
:<tt>_f_name</tt> &rarr; asciiz
::ini filename <asciiz>
+
::ini filename
:<tt>_sec_name</tt>
+
:<tt>_sec_name</tt> &rarr; asciiz
::section name <asciiz>
+
::section name
:<tt>_key_name</tt>
+
:<tt>_key_name</tt> &rarr; asciiz
::key name <asciiz>
+
::key name
:<tt>_buffer</tt>
+
:<tt>_buffer</tt> &rarr; byte*
::source buffer address <byte*>
+
::source buffer address
:<tt>_buf_len</tt>
+
:<tt>_buf_len</tt> &rarr; dword
::buffer size (bytes to write) <dword>
+
::buffer size (bytes to write)
  
 
Result:
 
Result:
:<tt>eax</tt>
+
:<tt>eax</tt> &rarr; dword
 
::-1 (error) / 0
 
::-1 (error) / 0
  
Line 119: Line 125:
  
 
Arguments:
 
Arguments:
:<tt>_f_name</tt>
+
:<tt>_f_name</tt> &rarr; asciiz
::ini filename <asciiz>
+
::ini filename
:<tt>_sec_name</tt>
+
:<tt>_sec_name</tt> &rarr; asciiz
::section name <asciiz>
+
::section name
:<tt>_key_name</tt>
+
:<tt>_key_name</tt> &rarr; asciiz
::key name <asciiz>
+
::key name
:<tt>_def_val</tt>
+
:<tt>_def_val</tt> &rarr; dword
::default value to return if no key, section or file found <dword>
+
::default value to return if no key, section or file found
  
 
Result:
 
Result:
:<tt>eax</tt>
+
:<tt>eax</tt> &rarr; dword
::[_def_val] (error) / found key value <dword>
+
::[_def_val] (error) / found key value
  
 
==ini_set_int==
 
==ini_set_int==
Line 139: Line 145:
  
 
Arguments:
 
Arguments:
:<tt>_f_name</tt>
+
:<tt>_f_name</tt> &rarr; asciiz
::ini filename <asciiz>
+
::ini filename
:<tt>_sec_name</tt>
+
:<tt>_sec_name</tt> &rarr; asciiz
::section name <asciiz>
+
::section name
:<tt>_key_name</tt>
+
:<tt>_key_name</tt> &rarr; asciiz
::key name <asciiz>
+
::key name
:<tt>_val</tt>
+
:<tt>_val</tt> &rarr; dword
::value <dword>
+
::value
  
 
Result:
 
Result:
:<tt>eax</tt>
+
:<tt>eax</tt> &rarr; dword
 
::-1 (error) / 0
 
::-1 (error) / 0
  
Line 159: Line 165:
  
 
Arguments:
 
Arguments:
:<tt>_f_name</tt>
+
:<tt>_f_name</tt> &rarr; asciiz
::ini filename <asciiz>
+
::ini filename
:<tt>_sec_name</tt>
+
:<tt>_sec_name</tt> &rarr; asciiz
::section name <asciiz>
+
::section name
:<tt>_key_name</tt>
+
:<tt>_key_name</tt> &rarr; asciiz
::key name <asciiz>
+
::key name
:<tt>_def_val</tt>
+
:<tt>_def_val</tt> &rarr; dword
::default value to return if no key, section or file found <dword>
+
::default value to return if no key, section or file found
  
 
Result:
 
Result:
:<tt>eax</tt>
+
:<tt>eax</tt> &rarr; dword
::[_def_val] (error) / found key value <dword>
+
::[_def_val] (error) / found key value
  
 
==ini_set_color==
 
==ini_set_color==
Line 179: Line 185:
  
 
Arguments:
 
Arguments:
:<tt>_f_name</tt>
+
:<tt>_f_name</tt> &rarr; asciiz
::ini filename <asciiz>
+
::ini filename
:<tt>_sec_name</tt>
+
:<tt>_sec_name</tt> &rarr; asciiz
::section name <asciiz>
+
::section name
:<tt>_key_name</tt>
+
:<tt>_key_name</tt> &rarr; asciiz
::key name <asciiz>
+
::key name
:<tt>_val</tt>
+
:<tt>_val</tt> &rarr; dword
::value <dword>
+
::value
  
 
Result:
 
Result:
:<tt>eax</tt>
+
:<tt>eax</tt> &rarr; dword
 
::-1 (error) / 0
 
::-1 (error) / 0
  
Line 199: Line 205:
  
 
Arguments:
 
Arguments:
:<tt>_f_name</tt>
+
:<tt>_f_name</tt> &rarr; asciiz
::ini filename <asciiz>
+
::ini filename
:<tt>_sec_name</tt>
+
:<tt>_sec_name</tt> &rarr; asciiz
::section name <asciiz>
+
::section name
:<tt>_key_name</tt>
+
:<tt>_key_name</tt> &rarr; asciiz
::key name <asciiz>
+
::key name
:<tt>_def_val</tt>
+
:<tt>_def_val</tt> &rarr; dword
::default value to return if no key, section or file found <dword>
+
::default value to return if no key, section or file found
:<tt>_modifiers</tt>
+
:<tt>_modifiers</tt> &rarr; dword*
::pointer to dword variable which receives modifiers state as in 66.4 <dword*>
+
::pointer to dword variable which receives modifiers state as in 66.4
  
 
Result:
 
Result:
:<tt>eax</tt>
+
:<tt>eax</tt> &rarr; dword
::[_def_val] (error) / shortcut key value as scancode <int>
+
::[_def_val] (error) / shortcut key value as scancode
:<tt><nowiki>[[_modifiers]]</nowiki></tt>
+
:<tt><nowiki>[[_modifiers]]</nowiki></tt> &rarr; dword
::unchanged (error) / modifiers state for this shortcut <int>
+
::unchanged (error) / modifiers state for this shortcut
 +
 
 +
=Usage examples=
 +
 
 +
This one enumerates sections, and then enumerates keys for each section in its callback. Note that we use "invoke" here since the call is indirect.
 +
 
 +
<source line>
 +
; ...
 +
 
 +
        invoke  ini_enum_sections, filename, ini_section_callback
 +
 
 +
; ...
 +
 
 +
proc ini_section_callback _filename, _section_name
 +
        ; this function is being called by library for each section found in the file
 +
 
 +
        invoke  ini_enum_keys, [_filename], [_section_name], ini_key_callback
 +
 
 +
        ; ...
 +
 
 +
        ret
 +
endp
 +
 
 +
proc ini_key_callback _filename, _section_name, _key_name, _key_value
 +
        ; this function is being called by library for each key of each section found in the file
 +
 
 +
        ; ...
 +
 
 +
        ret
 +
endp
 +
 
 +
; ...
 +
 
 +
filename db '/hd0/1/a.ini', 0
 +
</source>
  
 
[[Category:Coding]][[Category:Manuals]]
 
[[Category:Coding]][[Category:Manuals]]
 +
[[Category:Libraries]]

Latest revision as of 21:51, 27 July 2010

INI files are structured human-readable text files. Each file consists of one or more sections, each having several keys with values. Here's the example of such file:

[fruit colors]
banana = yellow
orange = orange
strawberry = red

[vegetable colors]
cucumber = green

Section names are embraced with square braces and are one-line strings which may contain any characters. Sections divide file into parts, where keys and their corresponding values are specified. In the begining of file (before the first section) there may also be keys and values found which aren't in any section. Keys and values are also one-line strings which are separated from each other with equality sign "=". Key name of course can't contain "=" character. Key value is the string after first "=" character found in line till the end on line.

Section names, key names and key values are trimmed i.e. space characters are deleted from the beginning and end of the strings during comparison.

If each section identifies the set of keys, each key in turn identifies one value. Section and key names don't have to be unique, but if there're two keys (within a section) with the same name, value will be read and written from the one which appears earlier in the file.

For all file operations, libini uses libio.

Functions (enumerating entities)

ini_enum_sections

Enumerate sections, calling callback function for each of them.

Prototype:

proc ini.enum_sections _f_name, _callback

Arguments:

_f_name → asciiz
ini filename
_callback
callback function address: func(f_name, sec_name), where
f_name → asciiz
ini filename (as passed to the function)
sec_name → asciiz
section name found

Result:

eax → dword
-1 (error) / 0

ini_enum_keys

Enumerate keys within a section, calling callback function for each of them.

Prototype:

proc ini.enum_keys _f_name, _sec_name, _callback

Arguments:

_f_name → asciiz
ini filename
_sec_name → asciiz
section name
_callback
callback function address: func(f_name, sec_name, key_name, key_value), where
f_name → asciiz
ini filename (as passed to the function)
sec_name → asciiz
section name (as passed to the function)
key_name → asciiz
key name found
key_value → asciiz
value of key found

Result:

eax → dword
-1 (error) / 0

Functions (getting and setting values)

All the getter functions are fail-safe, returning supplied default value on any error.

ini_get_str

Read string.

Prototype:

proc ini.get_str _f_name, _sec_name, _key_name, _buffer, _buf_len, _def_val

Arguments:

_f_name → asciiz
ini filename
_sec_name → asciiz
section name
_key_name → asciiz
key name
_buffer → byte*
destination buffer address
_buf_len → dword
buffer size (maximum bytes to read)
_def_val → asciiz
default value to return if no key, section or file found

Result:

eax → dword
-1 (error) / 0
[_buffer] → asciiz
[_def_val] (error) / found key value

ini_set_str

Write string.

Prototype:

proc ini.set_str _f_name, _sec_name, _key_name, _buffer, _buf_len

Arguments:

_f_name → asciiz
ini filename
_sec_name → asciiz
section name
_key_name → asciiz
key name
_buffer → byte*
source buffer address
_buf_len → dword
buffer size (bytes to write)

Result:

eax → dword
-1 (error) / 0

ini_get_int

Read integer.

Prototype:

proc ini.get_int _f_name, _sec_name, _key_name, _def_val

Arguments:

_f_name → asciiz
ini filename
_sec_name → asciiz
section name
_key_name → asciiz
key name
_def_val → dword
default value to return if no key, section or file found

Result:

eax → dword
[_def_val] (error) / found key value

ini_set_int

Write integer.

Prototype:

proc ini.set_int _f_name, _sec_name, _key_name, _val

Arguments:

_f_name → asciiz
ini filename
_sec_name → asciiz
section name
_key_name → asciiz
key name
_val → dword
value

Result:

eax → dword
-1 (error) / 0

ini_get_color

Read color.

Prototype:

proc ini.get_color _f_name, _sec_name, _key_name, _def_val

Arguments:

_f_name → asciiz
ini filename
_sec_name → asciiz
section name
_key_name → asciiz
key name
_def_val → dword
default value to return if no key, section or file found

Result:

eax → dword
[_def_val] (error) / found key value

ini_set_color

Write color.

Prototype:

proc ini.set_color _f_name, _sec_name, _key_name, _val

Arguments:

_f_name → asciiz
ini filename
_sec_name → asciiz
section name
_key_name → asciiz
key name
_val → dword
value

Result:

eax → dword
-1 (error) / 0

ini_get_shortcut

Read shortcut key.

Prototype:

proc ini.get_shortcut _f_name, _sec_name, _key_name, _def_val, _modifiers

Arguments:

_f_name → asciiz
ini filename
_sec_name → asciiz
section name
_key_name → asciiz
key name
_def_val → dword
default value to return if no key, section or file found
_modifiers → dword*
pointer to dword variable which receives modifiers state as in 66.4

Result:

eax → dword
[_def_val] (error) / shortcut key value as scancode
[[_modifiers]] → dword
unchanged (error) / modifiers state for this shortcut

Usage examples

This one enumerates sections, and then enumerates keys for each section in its callback. Note that we use "invoke" here since the call is indirect.

; ...

        invoke  ini_enum_sections, filename, ini_section_callback

; ...

proc ini_section_callback _filename, _section_name
        ; this function is being called by library for each section found in the file

        invoke  ini_enum_keys, [_filename], [_section_name], ini_key_callback

        ; ...

        ret
endp 

proc ini_key_callback _filename, _section_name, _key_name, _key_value
        ; this function is being called by library for each key of each section found in the file

        ; ...

        ret
endp

; ...

filename db '/hd0/1/a.ini', 0