-
-
Save Nixtren/c5957fa88da565c8ab70 to your computer and use it in GitHub Desktop.
eINI (Nixtren mod)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Edited by Nixtren - http://forum.sa-mp.com/showpost.php?p=3563553&postcount=25 | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
//eXtended INI Processor | |
// | |
//Known as eINI in short, is an INI File Processor, which parses any INI File which follows the required | |
//standards and makes reading, writing and many other INI related manipulations easier. | |
// | |
//Version:1.0.5 | |
// | |
//License: | |
//Copyright (C) <2015> <Yashas Samaga> | |
// | |
// This program is free software: you can redistribute it and/or modify | |
// it under the terms of the GNU General Public License as published by | |
// the Free Software Foundation, either version 3 of the License, or | |
// (at your option) any later version. | |
// | |
// This program is distributed in the hope that it will be useful, | |
// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
// GNU General Public License for more details. | |
// | |
// You should have received a copy of the GNU General Public License | |
// along with this program. If not, see <http://www.gnu.org/licenses/>. | |
// | |
//Credits: | |
//Yashas <yashas_2010@yahoo.com> | |
// | |
//Thanks to: | |
//Y_Less,Dracoblue,Slick,Neufox and everyone else for their INI Readers which helped me a lot | |
//Slice,Y_Less and many others who used to amaze me every time | |
// | |
//Special Thanks to: | |
//Y_Less a.k.a Alex "Y_Less" Cole | |
//Kye/Kalcor & the whole SA-MP Team | |
//Thiadmer for PAWN | |
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/* | |
native INI:INI::CreateINI(const fname[]); | |
native INI:INI::OpenINI(const fname[],mode=INI_READ_WRITE); | |
native _:INI::IsValidHandle(INI:handle); | |
native _:INI::CloseINI(INI:filehandle,bool:savebuffer=true); | |
native _:INI::WriteBuffer(INI:filehandle); | |
native _:INI::ParseINI(INI:filehandle,const LoadFunction[] = "",bool:dynamic=false,extra=0,bool:pass_extra=false,bool:func_with_key=false); | |
native | |
native _:INI::ReadString(INI:filehandle,result[],const key[],const section[],keyid=-1,sectionid=-1,result_size=sizeof(result),section_size=sizeof(section),key_size=sizeof(key)) | |
native _:INI::ReadBool(INI:filehandle,&bool:variable,const key[]="",const section[]="",keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::ReadInteger(INI:filehandle,&variable,const key[]="",const section[]="",keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::ReadFloat(INI:filehandle,&Float:variable,const key[]="",const section[]="",keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::ReadHex(INI:filehandle,&variable,const key[]="",const section[]="",keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::ReadBinary(INI:filehandle,&variable,const key[]="",const section[]="",keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::ReadArray(INI:filehandle,array[],const key[]="",const section[]="",keyid=-1,sectionid=-1,array_size=sizeof(array),section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::ReadEnum(INI:filehandle,enum_entity[],enum_size,const key[]="",const section[]="",keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::ReadFormat(INI:filehandle,sectionid,const format[],{Float,_}:...); | |
native _:INI::Replace(const src[],dest[],const ReplacementFunction[]="",extra=0,bool:pass_extra=false,sz=sizeof(src),sz_dest=sizeof(dest),sz_rf=sizeof(ReplacementFunction)); | |
native _:INI::SetReplacementString(src[]); | |
native | |
native _:INI::WriteString(INI:filehandle,const data[],const key[],const section[],keyid=-1,sectionid=-1,data_size=sizeof(data),section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::WriteBool(INI:filehandle,bool:variable,const key[],const section[],keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::WriteInteger(INI:filehandle,variable,const key[],const section[],keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::WriteFloat(INI:filehandle,Float:variable,const key[],const section[],keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::WriteHex(INI:filehandle,variable,const key[],const section[],keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::WriteBinary(INI:filehandle,variable,const key[],const section[],keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::WriteArray(INI:filehandle,array[],const key[]="",const section[]="",keyid=-1,sectionid=-1,array_size=sizeof(array),section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::WriteEnum(INI:filehandle,enum_entity[],enum_size,const key[]="",const section[]="",keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::WriteFormat(INI:filehandle,sectionid,const format[],{Float,_}:...); | |
native | |
native _:INI::DeleteSection(INI:filehandle,const section[]="",sectionid=-1,section_size=sizeof(section)); | |
native _:INI::DeleteKey(INI:filehandle,const key[],const section[]="",keyid=-1,sectionid=-1,key_size=sizeof(key),section_size=sizeof(section)); | |
native _:INI::GetSectionID(INI:filehandle,const section[],section_size=sizeof(section)); | |
native _:INI::GetKeyID(INI:filehandle,const key[],const section[]="",sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)); | |
native _:INI::GetSectionName(INI:filehandle,result[],sectionid,result_size=sizeof(result)); | |
native _:INI::GetKeyName(INI:filehandle,result[],keyid,result_size=sizeof(result)); | |
native _:INI::DumpINI(INI:filehandle); | |
*/ | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
//#define INI_CAREFUL_MODE //define to enable Careful Mode | |
//#define INI_LIBERAL_MODE //define to enable liberal mode | |
//#define INI_ASSUME_FORMATTED_INI //define to enable assume formatted mode | |
//#define INI_DISABLE_CASE_SENSITIVITY | |
//#define INI_DISABLE_WARNINGS //define to disable warnings | |
//#define INI_DISABLE_ERRORS //define to disable warnings | |
//#define INI_DISABLE_NOTICES //define to disable warnings | |
//#define INI_ENABLE_WHITESPACE //define to enable whitespaces in names | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
#if defined __INCLUDED_EINI__ | |
#endinput | |
#endif | |
#define __INCLUDED_EINI__ | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
#if defined INI:: | |
#undef INI | |
#endif | |
#define INI:: eINI_ | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
#if !defined INI_MAX_MULTI_FILES | |
#define INI_MAX_MULTI_FILES 2 //Maximum number of files that can be opened simultaneously | |
#else | |
#assert (INI_MAX_MULTI_FILES > 0) | |
#endif | |
#if !defined INI_MAX_LINES | |
#define INI_MAX_LINES 128 //Maximum number of lines per INI File | |
#else | |
#assert (INI_MAX_LINES > 0) | |
#endif | |
#if !defined INI_MAX_SECTIONS | |
#define INI_MAX_SECTIONS 32 //Maximum number of sections per INI File | |
#else | |
#assert (INI_MAX_LINES > INI_MAX_SECTIONS > 0) | |
#endif | |
#if !defined INI_MAX_KEYS | |
#define INI_MAX_KEYS INI_MAX_LINES //Maximum number of keys per INI File | |
#else | |
#assert (INI_MAX_LINES > INI_MAX_KEYS > 0) | |
#endif | |
#if !defined INI_NAME_VALUE_DELIMITER | |
#define INI_NAME_VALUE_DELIMITER '=' //Key=Value delimiter (separator) | |
#else | |
#assert (INI_NAME_VALUE_DELIMITER == '=' || INI_NAME_VALUE_DELIMITER == ':') | |
#endif | |
#if !defined INI_ESCAPE_CHARACTER //Escape Sequence delimiter (\n,\r,etc) | |
#define INI_ESCAPE_CHARACTER '\\' | |
#else | |
#assert (INI_ESCAPE_CHARACTER == '\\') | |
#endif | |
#if !defined INI_MAX_LINE_LENGTH | |
#define INI_MAX_LINE_LENGTH 256 //Maximum number of characters per INI Line | |
#else | |
#assert (INI_MAX_LINE_LENGTH > 1) | |
#endif | |
#if !defined INI_MAX_FILE_NAME_LENGTH | |
#define INI_MAX_FILE_NAME_LENGTH 32 //INI File Name Length | |
#else | |
#assert (INI_MAX_FILE_NAME_LENGTH > 0) | |
#endif | |
#if !defined INI_MAX_SECTION_NAME_LENGTH | |
#define INI_MAX_SECTION_NAME_LENGTH 32 //Length of Section Name | |
#else | |
#assert (INI_MAX_SECTION_NAME_LENGTH > 0) | |
#endif | |
#if !defined INI_MAX_KEY_NAME_LENGTH | |
#define INI_MAX_KEY_NAME_LENGTH 64 //Maximum number of characters for a key name | |
#else | |
#assert (INI_MAX_KEY_NAME_LENGTH > 0) | |
#endif | |
#if !defined INI_MAX_KEY_VALUE_LENGTH | |
#define INI_MAX_KEY_VALUE_LENGTH INI_MAX_LINE_LENGTH //Maximum number of characters for a key value | |
#else | |
#assert (INI_MAX_KEY_VALUE_LENGTH > 0) | |
#endif | |
#if !defined INI_MAX_REPLACEMENT_TAG | |
#define INI_MAX_REPLACEMENT_TAG 24 //Maximum Length of Replacement Tag | |
#else | |
#assert (INI_MAX_REPLACEMENT_TAG > 0) | |
#endif | |
#if !defined INI_MAX_REPLACEMENT_TEXT | |
#define INI_MAX_REPLACEMENT_TEXT 64 //Maximum Length of Replacement Text | |
#else | |
#assert (INI_MAX_REPLACEMENT_TEXT < INI_MAX_KEY_VALUE_LENGTH) | |
#endif | |
#if !defined INI_FLOATING_POINT_PRECISION | |
#define INI_FLOATING_POINT_PRECISION 16 //Number of cells need to store the largest floating point number | |
#else | |
#assert (24 > INI_FLOATING_POINT_PRECISION > 0) | |
#endif | |
#if !defined INI_INTEGER_DIGITS | |
#define INI_INTEGER_DIGITS 10 //Number of cells in the longest integer + 1 | |
#else | |
#assert (17 > INI_INTEGER_DIGITS > 0) | |
#endif | |
#if !defined INI_HEX_DIGITS | |
#define INI_HEX_DIGITS 8 //Number of cells need to store the largest hexadecimal number | |
#else | |
#assert (16 > INI_HEX_DIGITS > 0) | |
#endif | |
#if !defined INI_BIN_DIGITS | |
#define INI_BIN_DIGITS 32 //Number of cells need to store the largest binary number | |
#else | |
#assert (33 > INI_BIN_DIGITS > 0) | |
#endif | |
#if !defined INI_MAX_FUNCTION_NAME_LENGTH | |
#define INI_MAX_FUNCTION_NAME_LENGTH 32 //Length of Function Identifier that can be given to CallLocalFunction | |
#else | |
#assert (128 > INI_MAX_FUNCTION_NAME_LENGTH > 0) | |
#endif | |
#if !defined INI_WRITE_FALSE_VALUE | |
#define INI_WRITE_FALSE_VALUE "false" //String to be saved when WriteBool is called | |
#define INI_WRITE_FALSE_VALUE_SIZE 6 //Size of INI_WRITE_FALSE_VALUE | |
#endif | |
#if !defined INI_WRITE_TRUE_VALUE | |
#define INI_WRITE_TRUE_VALUE "true" //String to be saved when WriteBool is called | |
#define INI_WRITE_TRUE_VALUE_SIZE 5 //Size of INI_WRITE_TRUE_VALUE | |
#endif | |
#if !defined INI_DISABLE_CASE_SENSITIVITY | |
#define _INI_CS false | |
#else | |
#define _INI_CS true | |
#endif | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
//Must be distinct negative numbers | |
#define INI_ERR_FAILED_TO_OPEN -1 | |
#define INI_ERR_FILE_DOES_NOT_EXIST -2 | |
#define INI_ERR_FILE_ALREADY_EXISTS -3 | |
#define INI_ERR_FILE_CREATION_FAILED -4 | |
#define INI_ERR_MAX_FILE_LIMIT -5 | |
#define INI_ERR_INVALID_HANDLE -6 | |
#define INI_ERR_SYNTAX -7 | |
#define INI_ERR_INVALID_ID -8 | |
#define INI_ERR_INVALID_BOOL -9 | |
#define INI_ERR_PARSING_FAILED -17 | |
#define INI_SECTION_NOT_FOUND -10 | |
#define INI_KEY_CREATE_FAILED -11 | |
#define INI_SECTION_CREATED -12 | |
#define INI_SECTION_CREATE_FAILED -13 | |
#define INI_KEY_CREATED -14 | |
#define INI_KEY_NOT_FOUND -15 | |
#define INI_KEY_FOUND -16 | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
#define INI_UNUSED 0 //Must be zero | |
#define INI_READ_WRITE 1 | |
#define INI_READ 2 | |
#define INI_WRITE 3 | |
#define INI_WRITE_NEW 4 | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
#define INI_LINE_EMPTY 1 | |
#define INI_LINE_COMMENT 2 | |
#define INI_LINE_SECTION_KEY 3 | |
#define INI_LINE_SECTION_TAG 4 | |
#define INI_LINE_GLOBAL_KEY 5 | |
#define INI_LINE_EOF 6 | |
#define INI_LINE_RETAIN 1 | |
#define INI_LINE_DELETE 2 | |
#define INI_LINE_MODIFIED 3 | |
#define INI_DEFAULT_FILL -1 | |
#define INI_LINKED_LIST_NULL -1 | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
#if !defined INI_DISABLE_ERRORS | |
#define INI_Error(%0); printf(%0); | |
#else | |
#define INI_Error(%0); | |
#endif | |
#if !defined INI_DISABLE_WARNINGS | |
#define INI_Warning(%0); printf(%0); | |
#else | |
#define INI_Warning(%0); | |
#endif | |
#if !defined INI_DISABLE_NOTICES | |
#define INI_Notice(%0); printf(%0); | |
#else | |
#define INI_Notice(%0); | |
#endif | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
#define eINI_IsValidHandle(%0) (INI:INI_MAX_MULTI_FILES > %0 > INI:-1) | |
#define IsFileHandleInUse(%0) (INI_File[%0][E_INI_FILE_mode]) | |
#define InvalidateFileHandle(%0) (INI_File[%0][E_INI_FILE_mode] = INI_UNUSED) | |
#if defined INI_ENABLE_WHITESPACE | |
#define IsValidNameChar(%0) (('A' <= %0 <= 'Z') || ('a' <= %0 <= 'z') || (%0 == '_') || ('0' <= %0 <= '9') || (%0 == ' ')) | |
#else | |
#define IsValidNameChar(%0) (('A' <= %0 <= 'Z') || ('a' <= %0 <= 'z') || (%0 == '_') || ('0' <= %0 <= '9')) | |
#endif | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
enum E_INI_FILE | |
{ | |
E_INI_FILE_filename[INI_MAX_FILE_NAME_LENGTH char], | |
E_INI_FILE_LoadedSections, | |
E_INI_FILE_LoadedKeys, | |
E_INI_FILE_lines, | |
E_INI_FILE_start_lineid, | |
E_INI_FILE_end_lineid, | |
E_INI_FILE_mode, | |
bool:E_INI_FILE_parsed | |
} | |
enum E_INI_LINE | |
{ | |
E_INI_LINE_type, | |
E_INI_LINE_id, | |
E_INI_LINE_previous, | |
E_INI_LINE_next, | |
E_INI_LINE_Content[INI_MAX_LINE_LENGTH] | |
} | |
enum E_INI_SECTION | |
{ | |
E_INI_SECTION_name[INI_MAX_SECTION_NAME_LENGTH], | |
E_INI_SECTION_name_size, | |
E_INI_SECTION_sectionid, | |
E_INI_SECTION_lineid, | |
E_INI_SECTION_keystart | |
} | |
enum E_INI_KEY | |
{ | |
E_INI_KEY_name[INI_MAX_KEY_NAME_LENGTH], | |
E_INI_KEY_value[INI_MAX_KEY_VALUE_LENGTH], | |
E_INI_KEY_name_size, | |
E_INI_KEY_sectionid, | |
E_INI_KEY_lineid, | |
E_INI_KEY_previous, | |
E_INI_KEY_next | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
static stock INI_File[INI_MAX_MULTI_FILES][E_INI_FILE]; | |
static stock INI_Line[INI_MAX_MULTI_FILES*INI_MAX_LINES][E_INI_LINE]; | |
static stock INI_Section[INI_MAX_MULTI_FILES*INI_MAX_SECTIONS][E_INI_SECTION]; | |
static stock INI_Key[INI_MAX_MULTI_FILES*INI_MAX_KEYS][E_INI_KEY]; | |
new INI_ReplacementText[INI_MAX_REPLACEMENT_TEXT]; | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
stock BinaryToDecimal(const str[]) | |
{ | |
new value = 0,i; | |
if((str[0] | 0x20) == 'b' ) i = 1; | |
for(;;) | |
{ | |
switch(str[i++]) | |
{ | |
case '1': value = (value<<1) | 1; | |
case '0': value <<= 1; | |
case 'b','B',' ': continue; | |
default: break; | |
} | |
} | |
return value; | |
} | |
stock HexadecimalToDecimal(const str[]) | |
{ | |
new value = 0,i = -1; | |
if(str[0] == '0' && ((str[1] | 0x20) == 'x')) i = 1; | |
for(;;) | |
{ | |
switch(str[++i]) | |
{ | |
case '0'..'9': value = (value<<4) | (str[i] - '0'); | |
case 'a'..'f': value = (value<<4) | (str[i] - 'a' + 10); | |
case 'A'..'F': value = (value<<4) | (str[i] - 'A' + 10); | |
case ' ': continue; | |
default: break; | |
} | |
} | |
return value; | |
} | |
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/******************************************************************************************************************************* | |
<summary>CreateINI</summary> | |
<para>Creates an INI File</para> | |
<param name="fname">Location where the file should be created</param> | |
<returns> | |
Returns INI Handle on success or an error code if failed | |
(INI_ERR_FILE_ALREADY_EXISTS/INI_ERR_MAX_FILE_LIMIT) | |
</returns> | |
<remarks> | |
The location where the file should be created should be relative to the scriptfiles folder | |
</remarks> | |
<example> | |
<code> | |
CreateFile("config\\new_file.ini"); //Creates a file in scriptfiles\config\new_file.ini | |
</code> | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI:INI::CreateINI(const fname[]) | |
{ | |
if(fexist(fname)) | |
{ | |
INI_Error("[INI]CreateINI:File already exists(%s)",fname); | |
return INI:INI_ERR_FILE_ALREADY_EXISTS; | |
} | |
else | |
{ | |
for(new i = 0;i < INI_MAX_MULTI_FILES;i++) | |
{ | |
if(!IsFileHandleInUse(i)) | |
{ | |
new tmp = INI_MAX_KEYS*(i+1); | |
for(new j = INI_MAX_KEYS*i;j < tmp;j++) | |
INI_Key[j][E_INI_KEY_sectionid] = INI_DEFAULT_FILL; | |
tmp = INI_MAX_SECTIONS*(i+1); | |
for(new j = INI_MAX_SECTIONS*i;j < tmp;j++) | |
INI_Section[j][E_INI_SECTION_sectionid] = INI_DEFAULT_FILL; | |
tmp = INI_MAX_LINES*(i+1); | |
for(new j = INI_MAX_LINES*i;j < tmp;j++) | |
{ | |
INI_Line[j][E_INI_LINE_type] = INI_DEFAULT_FILL; | |
INI_Line[j][E_INI_LINE_previous] = INI_Line[j][E_INI_LINE_next] = INI_LINKED_LIST_NULL; | |
} | |
INI_File[i][E_INI_FILE_mode] = INI_WRITE_NEW; | |
INI_File[i][E_INI_FILE_LoadedSections] = INI_File[i][E_INI_FILE_LoadedKeys] = 0; | |
INI_File[i][E_INI_FILE_lines] = 1; | |
INI_File[i][E_INI_FILE_end_lineid] = INI_File[i][E_INI_FILE_start_lineid] = INI_MAX_LINES*i; | |
INI_Line[INI_MAX_LINES*i][E_INI_LINE_type] = INI_LINE_EOF; | |
INI_File[i][E_INI_FILE_parsed] = true; | |
strpack(INI_File[i][E_INI_FILE_filename],fname,INI_MAX_FILE_NAME_LENGTH); | |
return INI:i; | |
} | |
} | |
INI_Error("[INI]CreateINI:Maximum Open Files Limit Reached(%s)",fname); | |
return INI:INI_ERR_MAX_FILE_LIMIT; | |
} | |
} | |
/******************************************************************************************************************************* | |
<summary>OpenINI</summary> | |
<para>Opens an INI</para> | |
<param name="fname">Location of the file to open</param> | |
<param name="mode">Depending on the file usage, the mode is set(INI_READ_WRITE/INI_WRITE/INI_READ)</param> | |
<returns> | |
Returns INI Handle on success or an error code if failed | |
(INI_ERR_MAX_FILE_LIMIT/INI_ERR_FILE_DOES_NOT_EXIST) | |
</returns> | |
<remarks> | |
The location of the file to be opened should be relative to the scriptfiles folder | |
</remarks> | |
<example> | |
<code> | |
OpenINI("config\\new_file.ini"); //Opens a file from scriptfiles\config\new_ini | |
</code> | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI:INI::OpenINI(const fname[],mode=INI_READ_WRITE) | |
{ | |
if(fexist(fname)) | |
{ | |
#if !defined INI_DISABLE_WARNINGS | |
for(new i = 0;i < INI_MAX_MULTI_FILES;i++) | |
{ | |
if(IsFileHandleInUse(i)) | |
if(!strcmp(fname,INI_File[i][E_INI_FILE_filename])) | |
INI_Warning("[INI]Warning:Creating another instance of the same file(%s)",fname); | |
} | |
#endif | |
for(new i = 0;i < INI_MAX_MULTI_FILES;i++) | |
{ | |
if(!IsFileHandleInUse(i)) | |
{ | |
new tmp = INI_MAX_KEYS*(i+1); | |
for(new j = INI_MAX_KEYS*i;j < tmp;j++) | |
INI_Key[j][E_INI_KEY_sectionid] = INI_DEFAULT_FILL; | |
tmp = INI_MAX_SECTIONS*(i+1); | |
for(new j = INI_MAX_SECTIONS*i;j < tmp;j++) | |
INI_Section[j][E_INI_SECTION_sectionid] = INI_DEFAULT_FILL; | |
tmp = INI_MAX_LINES*(i+1); | |
for(new j = INI_MAX_LINES*i;j < tmp;j++) | |
{ | |
INI_Line[j][E_INI_LINE_type] = INI_DEFAULT_FILL; | |
INI_Line[j][E_INI_LINE_previous] = INI_Line[j][E_INI_LINE_next] = INI_LINKED_LIST_NULL; | |
} | |
INI_File[i][E_INI_FILE_mode] = mode; | |
INI_File[i][E_INI_FILE_LoadedSections] = INI_File[i][E_INI_FILE_LoadedKeys] = INI_File[i][E_INI_FILE_lines] = 0; | |
INI_File[i][E_INI_FILE_end_lineid] = INI_File[i][E_INI_FILE_start_lineid] = INI_MAX_LINES*i; | |
INI_File[i][E_INI_FILE_parsed] = false; | |
strpack(INI_File[i][E_INI_FILE_filename],fname,INI_MAX_FILE_NAME_LENGTH); | |
return INI:i; | |
} | |
} | |
INI_Error("[INI]OpenINI:Maximum Open Files Limit Reached(%s)",fname); | |
return INI:INI_ERR_MAX_FILE_LIMIT; | |
} | |
else | |
{ | |
INI_Error("[INI]OpenINI:File doesn't exist (%s)",fname); | |
return INI:INI_ERR_FILE_DOES_NOT_EXIST; | |
} | |
} | |
/******************************************************************************************************************************* | |
<summary>CloseINI</summary> | |
<para>Saves the file then invalidates the INI Handle</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="savebuffer">Set to true to save the buffer to the file(true by default)</param> | |
<returns> | |
Returns 0 on success or an error code if failed | |
(INI_ERR_INVALID_HANDLE/INI_ERR_PARSING_FAILED) | |
</returns> | |
<remarks> | |
The buffer can be manually saved by calling WriteBuffer. | |
</remarks> | |
<example> | |
new INI:handle = INI::OpenINI("eINI.ini"); //Opens a file for read/write | |
INI::WriteBuffer(handle); //Saves the file | |
Close(handle,false); //Invalidates the handle without saving since its already saved | |
</example> | |
<seealso>INI::WriteBuffer<seealso> | |
*******************************************************************************************************************************/ | |
stock INI::CloseINI(INI:filehandle,bool:savebuffer=true) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]CloseINI:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]CloseINI:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
if(savebuffer) | |
if(INI::WriteBuffer(filehandle) == INI_ERR_PARSING_FAILED) return INI_ERR_PARSING_FAILED; | |
InvalidateFileHandle(_:filehandle); | |
return 0; | |
} | |
/******************************************************************************************************************************* | |
<summary>WriteBuffer</summary> | |
<para>When any changes are made to the INI ,the file is not updated automatically until CloseINI is called.WriteBuffer | |
forcefully updates the file.</para> | |
<param name="filehandle">INI Handle</param> | |
<returns> | |
Returns 0 on success or an error code | |
(INI_ERR_INVALID_HANDLE/INI_ERR_FILE_CREATION_FAILED/INI_ERR_PARSING_FAILED/INI_ERR_FAILED_TO_OPEN) | |
</returns> | |
<remarks> | |
The buffer is saved automatically when CloseINI is called until it is explicitly told not to save. | |
</remarks> | |
<example> | |
new INI:handle = INI::OpenINI("eINI.ini"); //Opens a file for read/write | |
INI::WriteBuffer(handle); //Saves the file | |
INI::Close(handle,false); //Invalidates the handle without saving since its already saved | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::WriteBuffer(INI:filehandle) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]WriteBuffer:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]WriteBuffer:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
new str[INI_MAX_FILE_NAME_LENGTH]; | |
new File:wfile; | |
strunpack(str,INI_File[_:filehandle][E_INI_FILE_filename]); | |
if(!INI_File[_:filehandle][E_INI_FILE_parsed]) | |
if(INI::ParseINI(filehandle)) | |
{ | |
INI_Error("[INI]WriteBuffer:Failed to parse file(%s)>>Write Aborted",str); | |
return INI_ERR_PARSING_FAILED; | |
} | |
switch(INI_File[_:filehandle][E_INI_FILE_mode]) | |
{ | |
case INI_READ: return 0; | |
case INI_WRITE_NEW: | |
{ | |
if(fexist(str)) | |
fremove(str); | |
if(!(wfile = fopen(str,io_write))) | |
{ | |
INI_Error("[INI]WriteBuffer:Failed to create file(%s)",str); | |
return INI_ERR_FILE_CREATION_FAILED; | |
} | |
} | |
default: | |
{ | |
if(fexist(str)) | |
fremove(str); | |
if(!(wfile = fopen(str,io_write))) | |
{ | |
INI_Error("[INI]WriteBuffer:Failed to open file(%s) for writing.",str); | |
return INI_ERR_FAILED_TO_OPEN; | |
} | |
} | |
} | |
for(new i = INI_File[_:filehandle][E_INI_FILE_start_lineid];INI_Line[i][E_INI_LINE_type] != INI_LINE_EOF;i = INI_Line[i][E_INI_LINE_next]) | |
{ fwrite(wfile,INI_Line[i][E_INI_LINE_Content]); } | |
fclose(wfile); | |
return 0; | |
} | |
/******************************************************************************************************************************* | |
<summary>ParseINI</summary> | |
<para>Parses the whole file and stores all the data in a buffer for fast reading and writing</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="LoadFunction>Function to be called if dynamic loading used(null by default)</param> | |
<param name="dynamic">Set true to enable dynamic loading (false by default)</param> | |
<param name="extra">Extra value to be passed to the dynamic loading function (0 by default)</param> | |
<param name="pass_extra">Set to true if extra paramter is used (false by default)</param> | |
<param name="func_with_key">If false,first occurrence of %s in LoadFunction will be replaced with section name only | |
If true,the first two occurrences of %s in LoadFunction will be replaced with section | |
name followed by key name respectively (false by default)</param> | |
<returns> | |
Returns error code if INI syntax was unacceptable | |
Returns 0 for normal execution | |
It also returns 0 if file was not meant to be parsed(in case of a new file) | |
INI_ERR_INVALID_HANDLE | |
INI_ERR_SYNTAX | |
</returns> | |
<remarks> | |
The default value of extra paramter has no effect on the function | |
</remarks> | |
<example> | |
INI::ParseINI(myhandle); //Normal Parsing | |
INI::ParseINI(myhandle,"Load_%s",true); //Parsing with dynamic loading.The %s will be replaced with the section name | |
INI::ParseINI(myhandle,"Load_%s",true,playerid,true); //Parsing with dynamic loading with extra parameter | |
INI::ParseINI(myhandle,"Load_%s_%s",true,random_number,false,true); //Parsing with dynamic loading.The %s will be replaced with section and | |
//key name | |
INI::ParseINI(myhandle,"Load_%s_%s",playerid,true,true); //Parsing with dynamic loading with extra paramter | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::ParseINI(INI:filehandle,const LoadFunction[] = "",bool:dynamic=false,extra=0,bool:pass_extra=false,bool:func_with_key=false, bool:passSectionParameter = false) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]ParseINI:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]ParseINI:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
new File:rfile,fmode = INI_File[_:filehandle][E_INI_FILE_mode]; | |
new line[INI_MAX_LINE_LENGTH],len; | |
new KeyID = 0,SectionID = 0,LineID = INI_MAX_LINES*_:filehandle; | |
new tmp,index,bool:keystart = true,bool:wspace = false,func[INI_MAX_FUNCTION_NAME_LENGTH]; | |
switch(fmode) | |
{ | |
case INI_WRITE_NEW: return 0; | |
default: | |
{ | |
strunpack(line,INI_File[_:filehandle][E_INI_FILE_filename]); | |
if(!(rfile = fopen(line,io_read))) | |
{ | |
INI_Error("[INI]ParseINI:Failed to open file(%s) for reading.",line); | |
return INI_ERR_FAILED_TO_OPEN; | |
} | |
} | |
} | |
while((len = fread(rfile,line))) | |
{ | |
for(new i = 0;;i++) | |
{ | |
switch(line[i]) | |
{ | |
case '[': | |
{ | |
#if !defined INI_ASSUME_FORMATTED_INI | |
do | |
{ | |
switch(line[++i]) | |
{ | |
case '\r','\n',0,']': | |
{ | |
#if defined INI_LIBERAL_MODE | |
goto comment_line; | |
#else | |
strunpack(line,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Error("[INI]Parser:Syntax Error in line %d in %s >> empty section",LineID + 1 - INI_MAX_LINES*_:filehandle,line); | |
INI::CloseINI(filehandle,false); | |
fclose(rfile); | |
return INI_ERR_SYNTAX; | |
#endif | |
} | |
} | |
}while(line[i] == ' '); | |
#endif | |
#if !defined INI_ASSUME_FORMATTED_INI | |
index = i; | |
#else | |
index = ++i; | |
#endif | |
tmp = INI_MAX_SECTIONS*_:filehandle + ++SectionID; | |
INI_Line[LineID][E_INI_LINE_type] = INI_LINE_SECTION_TAG; | |
INI_Line[LineID][E_INI_LINE_id] = tmp; | |
INI_Section[tmp][E_INI_SECTION_lineid] = LineID; | |
INI_Section[tmp][E_INI_SECTION_sectionid] = SectionID; | |
wspace = false; | |
for(;;i++) | |
{ | |
if(IsValidNameChar(line[i])) | |
{ | |
#if defined INI_ENABLE_WHITESPACE | |
switch(line[i]) | |
{ | |
case ' ': | |
{ | |
if(!wspace) | |
{ | |
wspace = true; | |
strmid(INI_Section[tmp][E_INI_SECTION_name],line,index,i,INI_MAX_SECTION_NAME_LENGTH); | |
INI_Section[tmp][E_INI_SECTION_name_size] = i - index; | |
} | |
} | |
default: wspace = false; | |
} | |
#else | |
#if !defined INI_ASSUME_FORMATTED_INI | |
if(wspace) | |
{ | |
#if defined INI_LIBERAL_MODE | |
SectionID--; | |
goto comment_line; | |
#else | |
strunpack(line,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Error("[INI]Parser:Syntax Error in line %d in %s >> whitespace found in section name",LineID+1 - INI_MAX_LINES*_:filehandle,line); | |
INI::CloseINI(filehandle,false); | |
fclose(rfile); | |
return INI_ERR_SYNTAX; | |
#endif | |
} | |
#endif | |
#endif | |
continue; | |
} | |
switch(line[i]) | |
{ | |
case ']': | |
{ | |
if(wspace) break; | |
strmid(INI_Section[tmp][E_INI_SECTION_name],line,index,i,INI_MAX_SECTION_NAME_LENGTH); | |
INI_Section[tmp][E_INI_SECTION_name_size] = i - index; | |
break; | |
} | |
#if !defined INI_ASSUME_FORMATTED_INI | |
case ' ': | |
{ | |
if(wspace) continue; | |
wspace = true; | |
strmid(INI_Section[tmp][E_INI_SECTION_name],line,index,i,INI_MAX_SECTION_NAME_LENGTH); | |
INI_Section[tmp][E_INI_SECTION_name_size] = i - index; | |
continue; | |
} | |
case '\r','\n',0: | |
{ | |
#if defined INI_LIBERAL_MODE | |
if(wspace) break; | |
strmid(INI_Section[tmp][E_INI_SECTION_name],line,index,i,INI_MAX_SECTION_NAME_LENGTH); | |
INI_Section[tmp][E_INI_SECTION_name_size] = i - index; | |
break; | |
#else | |
strunpack(line,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Error("[INI]Parser:Syntax Error in line %d in %s >> non-terminated section tag",LineID+1 - INI_MAX_LINES*_:filehandle,line); | |
INI::CloseINI(filehandle,false); | |
fclose(rfile); | |
return INI_ERR_SYNTAX; | |
#endif | |
} | |
default: | |
{ | |
#if defined INI_LIBERAL_MODE | |
continue; | |
#else | |
strunpack(line,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Error("[INI]Parser:Syntax Error in line %d in %s >> invalid character",LineID + 1 - INI_MAX_LINES*_:filehandle,line); | |
INI::CloseINI(filehandle,false); | |
fclose(rfile); | |
return INI_ERR_SYNTAX; | |
#endif | |
} | |
#endif | |
} | |
} | |
#if !defined INI_DISABLE_WARNINGS | |
for(new j = 1;j < SectionID;j++) | |
{ | |
if(!strcmp(INI_Section[tmp][E_INI_SECTION_name],INI_Section[tmp-j][E_INI_SECTION_name],_INI_CS)) | |
{ | |
strunpack(func,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Warning("[INI]Warning:Duplicate Section %s(Will be ignored) in file (%s)",INI_Section[tmp][E_INI_SECTION_name],func); | |
break; | |
} | |
} | |
#endif | |
if(!keystart) | |
{ | |
if(KeyID) | |
INI_Key[INI_MAX_KEYS*_:filehandle + KeyID - 1][E_INI_KEY_next] = INI_LINKED_LIST_NULL; | |
keystart = true; | |
} | |
else if(SectionID) INI_Section[INI_MAX_SECTIONS*_:filehandle + SectionID][E_INI_SECTION_keystart] = -1; | |
break; | |
} | |
case ';','#': | |
{ | |
comment_line: | |
INI_Line[LineID][E_INI_LINE_type] = INI_LINE_COMMENT; | |
break; | |
} | |
case '\r','\n',0: | |
{ | |
INI_Line[LineID][E_INI_LINE_type] = INI_LINE_EMPTY; | |
break; | |
} | |
case ' ': continue; | |
default: | |
{ | |
tmp = INI_MAX_KEYS*_:filehandle + KeyID++; | |
if(SectionID) | |
{ | |
INI_Line[LineID][E_INI_LINE_type] = INI_LINE_SECTION_KEY; | |
INI_Key[tmp][E_INI_KEY_sectionid] = SectionID; | |
} | |
else | |
{ | |
INI_Line[LineID][E_INI_LINE_type] = INI_LINE_GLOBAL_KEY; | |
INI_Key[tmp][E_INI_KEY_sectionid] = 0; | |
} | |
INI_Key[tmp][E_INI_KEY_lineid] = LineID; | |
INI_Line[LineID][E_INI_LINE_id] = tmp; | |
index = i; | |
wspace = false; | |
for(;;i++) | |
{ | |
if(IsValidNameChar(line[i])) | |
{ | |
#if defined INI_ENABLE_WHITESPACE | |
switch(line[i]) | |
{ | |
case ' ': | |
{ | |
if(!wspace) | |
{ | |
wspace = true; | |
strmid(INI_Key[tmp][E_INI_KEY_name],line,index,i,INI_MAX_KEY_NAME_LENGTH); | |
INI_Key[tmp][E_INI_KEY_name_size] = i - index; | |
} | |
} | |
default: wspace = false; | |
} | |
#else | |
#if !defined INI_ASSUME_FORMATTED_INI | |
if(wspace) | |
{ | |
#if defined INI_LIBERAL_MODE | |
KeyID--; | |
goto comment_line; | |
#else | |
strunpack(line,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Error("[INI]Parser:Syntax Error in line %d in %s >> whitespace found in key name",LineID+1 - INI_MAX_LINES*_:filehandle,line); | |
INI::CloseINI(filehandle,false); | |
fclose(rfile); | |
return INI_ERR_SYNTAX; | |
#endif | |
} | |
#endif | |
#endif | |
continue; | |
} | |
switch(line[i]) | |
{ | |
case INI_NAME_VALUE_DELIMITER: | |
{ | |
if(wspace) break; | |
strmid(INI_Key[tmp][E_INI_KEY_name],line,index,i,INI_MAX_KEY_NAME_LENGTH); | |
INI_Key[tmp][E_INI_KEY_name_size] = i - index; | |
break; | |
} | |
case ' ': | |
{ | |
if(wspace) continue; | |
wspace = true; | |
strmid(INI_Key[tmp][E_INI_KEY_name],line,index,i,INI_MAX_KEY_NAME_LENGTH); | |
INI_Key[tmp][E_INI_KEY_name_size] = i - index; | |
continue; | |
} | |
#if !defined INI_ASSUME_FORMATTED_INI | |
case '\r','\n',0: | |
{ | |
#if defined INI_LIBERAL_MODE | |
if(wspace) break; | |
KeyID--; | |
goto comment_line; | |
break; | |
#else | |
strunpack(line,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Error("[INI]Parser:Syntax Error in line %d in %s >> invalid line",LineID+1 - INI_MAX_LINES*_:filehandle,line); | |
INI::CloseINI(filehandle,false); | |
fclose(rfile); | |
return INI_ERR_SYNTAX; | |
#endif | |
} | |
default: | |
{ | |
#if defined INI_LIBERAL_MODE | |
continue; | |
#else | |
strunpack(line,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Error("[INI]Parser:Syntax Error in line %d in %s >> invalid character in key name",LineID + 1 - INI_MAX_LINES*_:filehandle,line); | |
INI::CloseINI(filehandle,false); | |
fclose(rfile); | |
return INI_ERR_SYNTAX; | |
#endif | |
} | |
#endif | |
} | |
} | |
if(keystart) | |
{ | |
keystart = false; | |
INI_Section[INI_MAX_SECTIONS*_:filehandle + SectionID][E_INI_SECTION_keystart] = tmp; | |
INI_Key[tmp][E_INI_KEY_previous] = INI_LINKED_LIST_NULL; | |
} | |
else | |
{ | |
INI_Key[tmp-1][E_INI_KEY_next] = tmp; | |
INI_Key[tmp][E_INI_KEY_previous] = tmp-1; | |
} | |
if(fmode == INI_WRITE) break; | |
#if !defined INI_ASSUME_FORMATTED_INI | |
do | |
{ | |
#if !defined INI_DISABLE_WARNINGS | |
switch(line[++i]) | |
{ | |
case ';','#','\r','\n',0: | |
{ | |
INI_Key[tmp][E_INI_KEY_value][0] = '\0'; | |
strunpack(func,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Warning("[INI]Warning:Empty Valued Key in line %d in %s",LineID+1-INI_MAX_LINES*_:filehandle,func); | |
} | |
} | |
}while(line[i] == ' '); | |
#else | |
}while(line[++i] == ' '); | |
#endif | |
#endif | |
#if defined INI_ASSUME_FORMATTED_INI | |
index = ++i; | |
#else | |
index = i; | |
#endif | |
for(;;) | |
{ | |
switch(line[++i]) | |
{ | |
case INI_ESCAPE_CHARACTER: i += 2; | |
case ';','#': | |
{ | |
strmid(INI_Key[tmp][E_INI_KEY_value],line,index,i,INI_MAX_KEY_VALUE_LENGTH); | |
break; | |
} | |
case '\r','\n',0: | |
{ | |
strmid(INI_Key[tmp][E_INI_KEY_value],line,index,i,INI_MAX_KEY_VALUE_LENGTH); | |
break; | |
} | |
} | |
} | |
if(dynamic) | |
{ | |
if(func_with_key) | |
{ | |
if(SectionID == 0) format(func,sizeof(func),LoadFunction,"",INI_Key[tmp][E_INI_KEY_name]); | |
else format(func,sizeof(func),LoadFunction,INI_Section[INI_MAX_SECTIONS*_:filehandle + SectionID][E_INI_SECTION_name],INI_Key[tmp][E_INI_KEY_name]); | |
if(pass_extra) | |
CallRemoteFunction(func,"si",INI_Key[tmp][E_INI_KEY_value],extra); | |
else | |
CallRemoteFunction(func,"s",INI_Key[tmp][E_INI_KEY_value]); | |
} | |
else | |
{ | |
if(SectionID == 0) format(func,sizeof(func),LoadFunction,""); | |
else format(func,sizeof(func),LoadFunction,INI_Section[INI_MAX_SECTIONS*_:filehandle + SectionID][E_INI_SECTION_name]); | |
if(pass_extra) | |
CallRemoteFunction(func,"ssi",INI_Key[tmp][E_INI_KEY_name],INI_Key[tmp][E_INI_KEY_value],extra); | |
else if(passSectionParameter) | |
CallRemoteFunction(func,"ssis",INI_Key[tmp][E_INI_KEY_name],INI_Key[tmp][E_INI_KEY_value], 0, INI_Section[INI_MAX_SECTIONS*_:filehandle + SectionID][E_INI_SECTION_name]); | |
else | |
CallRemoteFunction(func,"ss",INI_Key[tmp][E_INI_KEY_name],INI_Key[tmp][E_INI_KEY_value]); | |
} | |
} | |
#if !defined INI_DISABLE_WARNINGS | |
for(new j = INI_Section[INI_MAX_SECTIONS*_:filehandle + SectionID][E_INI_SECTION_keystart];j < tmp;j++) | |
{ | |
if(!strcmp(INI_Key[tmp][E_INI_KEY_name],INI_Key[j][E_INI_KEY_name],_INI_CS)) | |
{ | |
strunpack(func,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Warning("[INI]Warning:Duplicate Key %s(Will be ignored) in section %s of file (%s)",INI_Key[tmp][E_INI_KEY_name],INI_Section[INI_MAX_SECTIONS*_:filehandle + SectionID][E_INI_SECTION_name],func); | |
break; | |
} | |
} | |
#endif | |
break; | |
} | |
} | |
} | |
if(line[len-1] != '\n') strcat(line,"\r\n"); | |
INI_Line[LineID][E_INI_LINE_Content] = line; | |
INI_Line[LineID][E_INI_LINE_next] = ++LineID; | |
INI_Line[LineID][E_INI_LINE_previous] = LineID-1; | |
} | |
fclose(rfile); | |
if((INI_File[_:filehandle][E_INI_FILE_LoadedKeys] = KeyID)) | |
INI_Key[INI_MAX_KEYS*_:filehandle + KeyID - 1][E_INI_KEY_next] = INI_LINKED_LIST_NULL; | |
INI_Line[LineID][E_INI_LINE_type] = INI_LINE_EOF; | |
INI_Line[LineID][E_INI_LINE_next] = INI_LINKED_LIST_NULL; | |
INI_Line[INI_MAX_LINES*_:filehandle][E_INI_LINE_previous] = INI_LINKED_LIST_NULL; | |
INI_File[_:filehandle][E_INI_FILE_end_lineid] = LineID; | |
INI_File[_:filehandle][E_INI_FILE_lines] = LineID - INI_MAX_LINES*_:filehandle; | |
INI_File[_:filehandle][E_INI_FILE_LoadedSections] = SectionID; | |
INI_File[_:filehandle][E_INI_FILE_LoadedKeys] = KeyID; | |
INI_File[_:filehandle][E_INI_FILE_parsed] = true; | |
#if defined INI_ASSUME_FORMATTED_INI || !defined INI_LIBERAL_MODE | |
#pragma unused comment_line | |
#endif | |
return 0; | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/******************************************************************************************************************************* | |
<summary>ReadString</summary> | |
<para>Gets the value of a key</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="result">The array to store the value</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Key ID relative to the handle(see remarks).Set to -1 if keyid not known</param> | |
<param name="sectionid">Section ID relative to the handle(see remarks).Set to -1 if the sectionid is not known</param> | |
<param name="result_size">Size of result paramter</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid(relative to filehandle) if the key is found or an error code | |
INI_KEY_NOT_FOUND | |
INI_ERR_INVALID_HANDLE | |
INI_ERR_PARSING_FAILED | |
</returns> | |
<remarks> | |
The first key of the file is given a key id 0,the next 1 and so on. | |
The keyid paramter takes these numbers. | |
</remarks> | |
<example> | |
INI::ReadString(handle,res,"KEY","SECTION"); //Searches for KEY in SECTION | |
INI::ReadString(handle,res,"KEY"); //Searches for KEY in the global section | |
INI::ReadString(handle,res,"KEY","",-1,sectionid); //Searches for KEY in section with id sectionid | |
INI::ReadString(handle,res,"","",1); //Gets the value of key with keyid 1 | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::ReadString(INI:filehandle,result[],const key[],const section[]="",keyid=-1,sectionid=-1,result_size=sizeof(result),section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]ReadString:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]ReadString:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
if(!INI_File[_:filehandle][E_INI_FILE_parsed]) | |
if(INI::ParseINI(filehandle)) | |
{ | |
new str[INI_MAX_FILE_NAME_LENGTH]; | |
strunpack(str,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Error("[INI]ReadString:Failed to parse file(%s)>>Read Failed",str); | |
return INI_ERR_PARSING_FAILED; | |
} | |
if(--key_size) //removing the null character | |
{ | |
if(--section_size) //removing the null character | |
{ | |
for(new i = INI_MAX_SECTIONS*_:filehandle + 1,j = i + INI_File[_:filehandle][E_INI_FILE_LoadedSections];i <= j;i++) | |
{ | |
if(INI_Section[i][E_INI_SECTION_name_size] == section_size) | |
{ | |
if(!strcmp(section,INI_Section[i][E_INI_SECTION_name],_INI_CS)) | |
{ | |
//SECTION FOUND | |
if((i = INI_Section[i][E_INI_SECTION_keystart]) != -1) | |
{ | |
do | |
{ | |
if(key_size == INI_Key[i][E_INI_KEY_name_size]) | |
{ | |
if(!strcmp(key,INI_Key[i][E_INI_KEY_name],_INI_CS)) | |
{ | |
//KEY FOUND | |
result[0] = '\0'; | |
strcat(result,INI_Key[i][E_INI_KEY_value],result_size); | |
return (i - INI_MAX_KEYS*_:filehandle); | |
} | |
} | |
}while((i = INI_Key[i][E_INI_KEY_next]) != INI_LINKED_LIST_NULL); | |
} | |
break; | |
} | |
} | |
} | |
INI_Notice("[INI]ReadString:Key %s not found in section %s",key,section); | |
return INI_KEY_NOT_FOUND; | |
} | |
else if(sectionid > -1) | |
{ | |
if(sectionid <= INI_File[_:filehandle][E_INI_FILE_LoadedSections]) | |
{ | |
new i = INI_Section[INI_MAX_SECTIONS*_:filehandle + sectionid][E_INI_SECTION_keystart]; | |
if(i != -1) | |
{ | |
do | |
{ | |
if(key_size == INI_Key[i][E_INI_KEY_name_size]) | |
{ | |
if(!strcmp(key,INI_Key[i][E_INI_KEY_name],_INI_CS)) | |
{ | |
//KEY FOUND | |
result[0] = '\0'; | |
strcat(result,INI_Key[i][E_INI_KEY_value],result_size); | |
return (i - INI_MAX_KEYS*_:filehandle); | |
} | |
} | |
}while((i = INI_Key[i][E_INI_KEY_next]) != INI_LINKED_LIST_NULL); | |
} | |
} | |
else | |
{ | |
INI_Error("[INI]ReadString:Invalid Section ID (%d)",sectionid); | |
return INI_ERR_INVALID_ID; | |
} | |
INI_Notice("[INI]ReadString:Key(%s) not found in section ID %d ",key,sectionid); | |
return INI_KEY_NOT_FOUND; | |
} | |
else | |
{ | |
new i = INI_Section[INI_MAX_SECTIONS*_:filehandle][E_INI_SECTION_keystart]; | |
if(i != -1) | |
{ | |
do | |
{ | |
if(key_size == INI_Key[i][E_INI_KEY_name_size]) | |
{ | |
if(!strcmp(key,INI_Key[i][E_INI_KEY_name],_INI_CS)) | |
{ | |
//KEY FOUND | |
result[0] = '\0'; | |
strcat(result,INI_Key[i][E_INI_KEY_value],result_size); | |
return (i - INI_MAX_KEYS*_:filehandle); | |
} | |
} | |
}while((i = INI_Key[i][E_INI_KEY_next]) != INI_LINKED_LIST_NULL); | |
} | |
INI_Notice("[INI]ReadString:Key(%s) not found in global section",key); | |
return INI_KEY_NOT_FOUND; | |
} | |
} | |
else if(keyid > -1) | |
{ | |
if(-1 < keyid < INI_File[_:filehandle][E_INI_FILE_LoadedKeys]) | |
{ | |
new tmp = INI_MAX_KEYS*_:filehandle + keyid; | |
if(INI_Key[tmp][E_INI_KEY_sectionid] > -1) | |
{ | |
result[0] = '\0'; | |
strcat(result,INI_Key[tmp][E_INI_KEY_value],result_size); | |
return keyid; | |
} | |
} | |
else | |
{ | |
INI_Error("[INI]ReadString:Non-existant Key ID (%d)",keyid); | |
return INI_KEY_NOT_FOUND; | |
} | |
} | |
INI_Error("[INI]ReadString:Invalid Parameters",key,sectionid); | |
return INI_KEY_NOT_FOUND; | |
} | |
/******************************************************************************************************************************* | |
<summary>ReadBool</summary> | |
<para>Interprets the value of a key and sets variable to the appropriate value</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="variable">The variable in which the value has to be stored</param> | |
<param name="key">Key from which the value has to be interpreted</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Key ID relative to the handle(see remarks).Set to -1 if keyid not known</param> | |
<param name="sectionid">Section ID relative to the handle(see remarks).Set to -1 if the sectionid is not known</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid(relative to filehandle) if the key is found or an error code | |
INI_KEY_NOT_FOUND | |
INI_ERR_INVALID_HANDLE | |
INI_ERR_INVALID_BOOL | |
</returns> | |
<remarks> | |
The first key of the file is given a key id 0,the next 1 and so on. | |
The keyid paramter takes these numbers. | |
Similarly sectionid. | |
variable is set to true if the value of the key is equal to 'true' or '1' | |
variable is set to false if the value of the key is equal to 'false' or '0' | |
</remarks> | |
<example> | |
INI::ReadBool(handle,res,"KEY","SECTION"); //Searches for KEY in SECTION | |
INI::ReadBool(handle,res,"KEY"); //Searches for KEY in the global section | |
INI::ReadBool(handle,res,"KEY","",-1,sectionid); //Searches for KEY in section with id sectionid | |
INI::ReadBool(handle,res,"","",1); //Gets the value of key with keyid 1 | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::ReadBool(INI:filehandle,&bool:variable,const key[]="",const section[]="",keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
#if INI_WRITE_TRUE_VALUE_SIZE > INI_WRITE_FALSE_VALUE_SIZE | |
new result[INI_WRITE_TRUE_VALUE_SIZE]; | |
#else | |
new result[INI_WRITE_FALSE_VALUE_SIZE]; | |
#endif | |
new ret_num = INI::ReadString(filehandle,result,key,section,keyid,sectionid,sizeof(result),section_size,key_size); | |
if(ret_num > -1) | |
{ | |
if(!strcmp(result,INI_WRITE_TRUE_VALUE,true) || !strcmp(result,"1")) variable = true; | |
else if(!strcmp(result,INI_WRITE_FALSE_VALUE,true) && !strcmp(result,"0")) variable = false; | |
else return INI_ERR_INVALID_BOOL; | |
} | |
return ret_num; | |
} | |
/******************************************************************************************************************************* | |
<summary>ReadInteger</summary> | |
<para>Reads the value of a key and sets variable to the value</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="variable">The value of the key will be saved here</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Key ID relative to the handle(see remarks).Set to -1 if keyid not known</param> | |
<param name="sectionid">Section ID relative to the handle(see remarks).Set to -1 if the sectionid is not known</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid(relative to filehandle) if the key is found or an error code | |
INI_KEY_NOT_FOUND | |
INI_ERR_INVALID_HANDLE | |
variable left unchanged if an error occured | |
can abuse this by setting variable to a value that this function would not set variable to | |
and check if an error had occured | |
</returns> | |
<remarks> | |
The first key of the file is given a key id 0,the next 1 and so on. | |
The keyid paramter takes these numbers. | |
Similarly sectionid. | |
</remarks> | |
<example> | |
INI::ReadInteger(handle,res,"KEY","SECTION"); //Searches for KEY in SECTION | |
INI::ReadInteger(handle,res,"KEY"); //Searches for KEY in the global section | |
INI::ReadInteger(handle,res,"KEY","",-1,sectionid); //Searches for KEY in section with id sectionid | |
INI::ReadInteger(handle,res,"","",1); //Gets the value of key with keyid 1 | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::ReadInteger(INI:filehandle,&variable,const key[]="",const section[]="",keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
new result[INI_INTEGER_DIGITS]; | |
new ret_num = INI::ReadString(filehandle,result,key,section,keyid,sectionid,sizeof(result),section_size,key_size); | |
if(ret_num > -1) variable = strval(result); | |
return ret_num; | |
} | |
/******************************************************************************************************************************* | |
<summary>ReadFloat</summary> | |
<para>Reads the value of a key and sets variable to the value</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="variable">The value of the key will be saved here</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Key ID relative to the handle(see remarks).Set to -1 if keyid not known</param> | |
<param name="sectionid">Section ID relative to the handle(see remarks).Set to -1 if the sectionid is not known</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid(relative to filehandle) if the key is found or an error code | |
INI_KEY_NOT_FOUND | |
INI_ERR_INVALID_HANDLE | |
variable left unchanged if an error occured | |
can abuse this by setting variable to a value that this function would not set variable to | |
and check if an error had occured | |
</returns> | |
<remarks> | |
The first key of the file is given a key id 0,the next 1 and so on. | |
The keyid paramter takes these numbers. | |
Similarly sectionid. | |
</remarks> | |
<example> | |
INI::ReadFloat(handle,res,"KEY","SECTION"); //Searches for KEY in SECTION | |
INI::ReadFloat(handle,res,"KEY"); //Searches for KEY in the global section | |
INI::ReadFloat(handle,res,"KEY","",-1,sectionid); //Searches for KEY in section with id sectionid | |
INI::ReadFloat(handle,res,"","",1); //Gets the value of key with keyid 1 | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::ReadFloat(INI:filehandle,&Float:variable,const key[]="",const section[]="",keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
new result[INI_FLOATING_POINT_PRECISION]; | |
new ret_num = INI::ReadString(filehandle,result,key,section,keyid,sectionid,sizeof(result),section_size,key_size); | |
if(ret_num > -1) variable = floatstr(result); | |
return ret_num; | |
} | |
/******************************************************************************************************************************* | |
<summary>ReadHex</summary> | |
<para>Reads the value of a key and sets variable to the value</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="variable">The value of the key will be saved here</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Key ID relative to the handle(see remarks).Set to -1 if keyid not known</param> | |
<param name="sectionid">Section ID relative to the handle(see remarks).Set to -1 if the sectionid is not known</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid(relative to filehandle) if the key is found or an error code | |
INI_KEY_NOT_FOUND | |
INI_ERR_INVALID_HANDLE | |
variable left unchanged if an error occured | |
can abuse this by setting variable to a value that this function would not set variable to | |
and check if an error had occured | |
</returns> | |
<remarks> | |
The first key of the file is given a key id 0,the next 1 and so on. | |
The keyid paramter takes these numbers. | |
Similarly sectionid. | |
</remarks> | |
<example> | |
INI::ReadHex(handle,res,"KEY","SECTION"); //Searches for KEY in SECTION | |
INI::ReadHex(handle,res,"KEY"); //Searches for KEY in the global section | |
INI::ReadHex(handle,res,"KEY","",-1,sectionid); //Searches for KEY in section with id sectionid | |
INI::ReadHex(handle,res,"","",1); //Gets the value of key with keyid 1 | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::ReadHex(INI:filehandle,&variable,const key[]="",const section[]="",keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
new result[INI_HEX_DIGITS]; | |
new ret_num = INI::ReadString(filehandle,result,key,section,keyid,sectionid,sizeof(result),section_size,key_size); | |
if(ret_num > -1) variable = HexadecimalToDecimal(result); | |
return ret_num; | |
} | |
/******************************************************************************************************************************* | |
<summary>ReadBinary</summary> | |
<para>Reads the value of a key and sets variable to the value</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="variable">The value of the key will be saved here</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Key ID relative to the handle(see remarks).Set to -1 if keyid not known</param> | |
<param name="sectionid">Section ID relative to the handle(see remarks).Set to -1 if the sectionid is not known</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid(relative to filehandle) if the key is found or an error code | |
INI_KEY_NOT_FOUND | |
INI_ERR_INVALID_HANDLE | |
variable left unchanged if an error occured | |
can abuse this by setting variable to a value that this function would not set variable to | |
and check if an error had occured | |
</returns> | |
<remarks> | |
The first key of the file is given a key id 0,the next 1 and so on. | |
The keyid paramter takes these numbers. | |
Similarly sectionid. | |
</remarks> | |
<example> | |
INI::ReadBinary(handle,res,"KEY","SECTION"); //Searches for KEY in SECTION | |
INI::ReadBinary(handle,res,"KEY"); //Searches for KEY in the global section | |
INI::ReadBinary(handle,res,"KEY","",-1,sectionid); //Searches for KEY in section with id sectionid | |
INI::ReadBinary(handle,res,"","",1); //Gets the value of key with keyid 1 | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::ReadBinary(INI:filehandle,&variable,const key[]="",const section[]="",keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
new result[INI_BIN_DIGITS]; | |
new ret_num = INI::ReadString(filehandle,result,key,section,keyid,sectionid,sizeof(result),section_size,key_size); | |
if(ret_num > -1) variable = BinaryToDecimal(result); | |
return ret_num; | |
} | |
/******************************************************************************************************************************* | |
<summary>ReadArray</summary> | |
<para>Parses a array key and sets up the given array</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="array">The array where the data is to be saved</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Key ID relative to the handle(see remarks).Set to -1 if keyid not known</param> | |
<param name="sectionid">Section ID relative to the handle(see remarks).Set to -1 if the sectionid is not known</param> | |
<param name="array_size">Size of array paramter</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid(relative to filehandle) if the key is found or an error code | |
INI_KEY_NOT_FOUND | |
INI_ERR_INVALID_HANDLE | |
</returns> | |
<remarks> | |
The first key of the file is given a key id 0,the next 1 and so on. | |
The keyid paramter takes these numbers. | |
</remarks> | |
<example> | |
INI::ReadArray(handle,arr,"KEY","SECTION"); //Searches for KEY in SECTION | |
INI::ReadArray(handle,arr,"KEY"); //Searches for KEY in the global section | |
INI::ReadArray(handle,arr,"KEY","",-1,sectionid); //Searches for KEY in section with id sectionid | |
INI::ReadArray(handle,arr,"","",1); //Gets the value of key with keyid 1 | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::ReadArray(INI:filehandle,array[],const key[]="",const section[]="",keyid=-1,sectionid=-1,array_size=sizeof(array),section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
new result[INI_MAX_KEY_VALUE_LENGTH]; | |
new ret_num = INI::ReadString(filehandle,result,key,section,keyid,sectionid,sizeof(result),section_size,key_size); | |
if(ret_num > -1) | |
{ | |
new val; | |
for(new i = 0,j = 0;j < array_size;) | |
{ | |
switch(result[i]) | |
{ | |
case ',': | |
{ | |
array[j++] = val; | |
val = 0; | |
i++; | |
} | |
default: | |
{ | |
switch(result[i++]) | |
{ | |
case ' ':continue; | |
case '0': val = val*10 + 0; | |
case '1': val = val*10 + 1; | |
case '2': val = val*10 + 2; | |
case '3': val = val*10 + 3; | |
case '4': val = val*10 + 4; | |
case '5': val = val*10 + 5; | |
case '6': val = val*10 + 6; | |
case '7': val = val*10 + 7; | |
case '8': val = val*10 + 8; | |
case '9': val = val*10 + 9; | |
default: | |
{ | |
array[j++] = val; | |
val = 0; | |
i++; | |
return ret_num; | |
} | |
} | |
} | |
} | |
} | |
} | |
return ret_num; | |
} | |
/******************************************************************************************************************************* | |
<summary>ReadEnum</summary> | |
<para>Parses a enum key and sets up the given enum array</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="enum_array">The enum index where the data has to be loaded</param> | |
<param name="enum_size">Size of unit enum</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Key ID relative to the handle(see remarks).Set to -1 if keyid not known</param> | |
<param name="sectionid">Section ID relative to the handle(see remarks).Set to -1 if the sectionid is not known</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid(relative to filehandle) if the key is found or an error code | |
INI_KEY_NOT_FOUND | |
INI_ERR_INVALID_HANDLE | |
</returns> | |
<remarks> | |
The first key of the file is given a key id 0,the next 1 and so on. | |
The keyid paramter takes these numbers. | |
</remarks> | |
<example> | |
INI::ReadArray(handle,arr,"KEY","SECTION"); //Searches for KEY in SECTION | |
INI::ReadArray(handle,arr,"KEY"); //Searches for KEY in the global section | |
INI::ReadArray(handle,arr,"KEY","",-1,sectionid); //Searches for KEY in section with id sectionid | |
INI::ReadArray(handle,arr,"","",1); //Gets the value of key with keyid 1 | |
</example> | |
*******************************************************************************************************************************/ | |
#define INI_ReadEnum(%0,%1,%2,%3,%4,%5,%6,%7,%8,%9) ReadArray(%0,%1,%3,%4,%5,%6,%7,%2,%8,%9) | |
/******************************************************************************************************************************* | |
<summary>ReadFormat</summary> | |
<para>Reads multiple values and stores in the variables given</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="sectionid">Section ID relative to the handle(see remarks)</param> | |
<param name="format">Type of each data(see example)</param> | |
<params>Give the variable arguments in this format:variable1,key1,variable2,key2</params> | |
<returns> | |
Returns 0 on success or an error code | |
INI_ERR_INVALID_HANDLE | |
</returns> | |
<remarks> | |
The first section of the file is given a section id 0,the next 1 and so on. | |
The sectionid paramter takes these numbers.This is called relative section id. | |
Specifiers: | |
d,i => integer | |
s => string | |
f => float | |
b => binary | |
x,X => hexadecimal number | |
T,F => boolean number | |
Note that keys must always be valid, the only way to check if there was a failure while reading a key | |
is by setting the arguments to a default value.This will remain unchanged in case of an error. | |
The parsing will stop if an invalid character is found or any other exception occurs | |
</remarks> | |
<example> | |
new pInfo[MAX_PLAYERS][e_pInfo]; | |
INI::ReadEnum(handle,sid,"isf",myint,"KeyInt",mystr,"KeyStr",myfloat,"KeyFloat"); //Searches for KEY in SECTION | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::ReadFormat(INI:filehandle,sectionid,const format[],{Float,_}:...) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]ReadFormat:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]ReadFormat:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
new k,result[INI_MAX_KEY_VALUE_LENGTH],key[INI_MAX_KEY_NAME_LENGTH],val1,Float:val2,bool:val3; | |
for(new i = 0,j = numargs();(4 + i*2) < j;i++) | |
{ | |
k = 0; | |
do | |
{ | |
key[k] = getarg(4 + i*2,k); | |
}while(key[k++] != '\0'); | |
switch(format[i]) | |
{ | |
case '\0': return 0; | |
case 'd','i': | |
{ | |
INI::ReadInteger(filehandle,val1,key,"",-1,sectionid,1,k); | |
setarg(3 + i*2,0,val1); | |
} | |
case 's': | |
{ | |
INI::ReadString(filehandle,result,key,"",-1,sectionid,INI_MAX_KEY_VALUE_LENGTH,1,k); | |
k = 0; | |
do | |
{ | |
setarg(3 + i*2,k,result[k]); | |
}while(result[k++] != '\0'); | |
} | |
case 'f': | |
{ | |
INI::ReadFloat(filehandle,val2,key,"",-1,sectionid,1,k); | |
setarg(3 + i*2,0,_:val2); | |
} | |
case 'b': | |
{ | |
INI::ReadBinary(filehandle,val1,key,"",-1,sectionid,1,k); | |
setarg(3 + i*2,0,val1); | |
} | |
case 'x','X': | |
{ | |
INI::ReadHex(filehandle,val1,key,"",-1,sectionid,1,k); | |
setarg(3 + i*2,0,val1); | |
} | |
case 'T','F': | |
{ | |
INI::ReadBool(filehandle,val3,key,"",-1,sectionid,1,k); | |
setarg(3 + i*2,0,val3); | |
} | |
default: return 0; | |
} | |
} | |
return 0; | |
} | |
/******************************************************************************************************************************* | |
<summary>Replace</summary> | |
<para>Replaces escape characters with their real ASCII Value.Also does custom replacements.</para> | |
<param name="src">Soruce Text</param> | |
<param name="dest">Destination Array</param> | |
<param name="ReplacementFunction">Local Function to be called for Custom Replacement</param> | |
<param name="extra">Extra Value to be passed to the Replacement Function</param> | |
<param name="pass_extra">Set to true if extra is used</param> | |
<param name="sz">Size of src</param> | |
<returns> | |
Returns 0 always | |
</returns> | |
<remarks> | |
Destination array should be large enough to hold the string after replacement | |
</remarks> | |
<example> | |
INI::Replace(src,dest); //Does all the standard replacements | |
INI::Replace(src,dest,"MyFunc",0,false); | |
INI::Replace(src,dest,"MyFunc",playerid,true); | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::Replace(const src[],dest[],const ReplacementFunction[]="",extra=0,bool:pass_extra=false,sz=sizeof(src),sz_dest=sizeof(dest),sz_rf=sizeof(ReplacementFunction)) | |
{ | |
new pos; | |
for(new i = 0,j = 0;i < sz;i++) | |
{ | |
switch(src[i]) | |
{ | |
case '\\': | |
{ | |
switch(src[++i]) | |
{ | |
case '\\': dest[i - ++j] = '\\'; | |
case '0': dest[i - ++j] = '\0'; | |
case 't': dest[i - ++j] = '\t'; | |
case 'r': dest[i - ++j] = '\r'; | |
case 'n': dest[i - ++j] = '\n'; | |
case ';': dest[i - ++j] = ';'; | |
case '#': dest[i - ++j] = '#'; | |
case '[': dest[i - ++j] = '['; | |
case ']': dest[i - ++j] = ']'; | |
} | |
} | |
case '[': | |
{ | |
if(sz_rf > 1) | |
{ | |
new rtext[INI_MAX_REPLACEMENT_TAG]; | |
pos = strfind(src,"]",false,i); | |
if(pos == -1) | |
{ | |
dest[i-j] = '['; | |
continue; | |
} | |
else | |
{ | |
strmid(rtext,src,++i,pos); | |
if(pass_extra) | |
{ | |
if(CallLocalFunction(ReplacementFunction,"is",extra,rtext)) | |
{ | |
j += pos - i - strcat(dest,INI_ReplacementText,sz_dest) + 2; | |
i = pos; | |
} | |
else | |
{ | |
dest[i-j] = '['; | |
continue; | |
} | |
} | |
else | |
{ | |
if(CallLocalFunction(ReplacementFunction,"s",rtext)) | |
{ | |
j += pos - i - strcat(dest,INI_ReplacementText,sz_dest) + 2; | |
i = pos; | |
} | |
else | |
{ | |
dest[i-j] = '['; | |
continue; | |
} | |
} | |
} | |
} | |
else dest[i - j] = src[i]; | |
} | |
default: | |
{ | |
dest[i - j] = src[i]; | |
} | |
} | |
} | |
return 0; | |
} | |
stock INI::SetReplacementText(const text[],sz=sizeof(text)) | |
{ | |
return memcpy(INI_ReplacementText,text,0,sz*4 + 4); | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/******************************************************************************************************************************* | |
<summary>WriteString</summary> | |
<para>Sets the value of a key.The key and the section will be created if they don't exist.</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="data">data to be written (a.k.a value)</param> | |
<param name="key">The key whose data is to be changed</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Relative Key ID if known</param> | |
<param name="sectionid">Relative Section ID if known</param> | |
<param name="data_size">Size of data paramter</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid of the updated/created key or an error code | |
INI_ERR_INVALID_HANDLE | |
INI_KEY_NOT_FOUND | |
INI_ERR_PARSING_FAILED | |
</returns> | |
<remarks> | |
This function will create the key if it doesn't exist | |
</remarks> | |
<example> | |
INI::WriteString(handle,data,"KEY","SECTION"); //Changes the value of KEY in SECTION (will be created if it doesn't exist) | |
INI::WriteString(handle,data,"KEY"); //Changes the value of KEY in global section (will be created if it doesn't exist) | |
INI::WriteString(handle,data,"KEY","",-1,sectionid); //Changes the value of KEY in the given section id(Error if it doesn't exist) | |
INI::WriteString(handle,data,"","",1); //Changes the value of the key having the given keyid | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::WriteString(INI:filehandle,const data[],const key[],const section[],keyid=-1,sectionid=-1,data_size=sizeof(data),section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]WriteString:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]WriteString:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
if(!INI_File[_:filehandle][E_INI_FILE_parsed]) | |
if(INI::ParseINI(filehandle)) | |
{ | |
new str[INI_MAX_FILE_NAME_LENGTH]; | |
strunpack(str,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Error("[INI]ReadString:Failed to parse file(%s)>>Read Failed",str); | |
return INI_ERR_PARSING_FAILED; | |
} | |
if(--key_size) //removing the null character | |
{ | |
if(--section_size) //removing the null character | |
{ | |
new i = INI_MAX_SECTIONS*_:filehandle; | |
for(new j = i + INI_File[_:filehandle][E_INI_FILE_LoadedSections];i++ < j;) | |
{ | |
if(INI_Section[i][E_INI_SECTION_name_size] == section_size) | |
{ | |
if(!strcmp(section,INI_Section[i][E_INI_SECTION_name],_INI_CS)) | |
{ | |
//SECTION FOUND | |
if((j = INI_Section[i][E_INI_SECTION_keystart]) != -1) | |
{ | |
do | |
{ | |
if(key_size == INI_Key[j][E_INI_KEY_name_size]) | |
{ | |
if(!strcmp(key,INI_Key[j][E_INI_KEY_name],_INI_CS)) | |
{ | |
//KEY FOUND | |
memcpy(INI_Key[j][E_INI_KEY_value],data,0,data_size*4 + 4,INI_MAX_KEY_VALUE_LENGTH); | |
format(INI_Line[INI_Key[j][E_INI_KEY_lineid]][E_INI_LINE_Content],INI_MAX_LINE_LENGTH,"%s=%s\r\n",key,data); | |
return (j - INI_MAX_KEYS*_:filehandle); | |
} | |
} | |
}while((j = INI_Key[j][E_INI_KEY_next]) != INI_LINKED_LIST_NULL); | |
return ini_internal_CreateKey(filehandle,key,data,i,key_size); | |
} | |
} | |
} | |
} | |
if((i = ini_internal_CreateSection(filehandle,section,section_size+1)) > -1) | |
return ini_internal_CreateKey(filehandle,key,data,i,key_size); | |
else return INI_SECTION_CREATE_FAILED; | |
} | |
else if(sectionid > -1) | |
{ | |
if(-1 < sectionid <= INI_File[_:filehandle][E_INI_FILE_LoadedSections]) | |
{ | |
new j = INI_Section[INI_MAX_SECTIONS*_:filehandle + sectionid][E_INI_SECTION_keystart]; | |
if(j != -1) | |
{ | |
do | |
{ | |
if(key_size == INI_Key[j][E_INI_KEY_name_size]) | |
{ | |
if(!strcmp(key,INI_Key[j][E_INI_KEY_name],_INI_CS)) | |
{ | |
//KEY FOUND | |
memcpy(INI_Key[j][E_INI_KEY_value],data,0,data_size*4 + 4,INI_MAX_KEY_VALUE_LENGTH); | |
format(INI_Line[INI_Key[j][E_INI_KEY_lineid]][E_INI_LINE_Content],INI_MAX_LINE_LENGTH,"%s=%s\r\n",key,data); | |
return (j - INI_MAX_KEYS*_:filehandle); | |
} | |
} | |
}while((j=INI_Key[j][E_INI_KEY_next]) != INI_LINKED_LIST_NULL); | |
} | |
return ini_internal_CreateKey(filehandle,key,data,sectionid,key_size); | |
} | |
else | |
{ | |
INI_Error("[INI]WriteString:Invalid Section ID (%d)",sectionid); | |
return INI_ERR_INVALID_ID; | |
} | |
} | |
else | |
{ | |
new i = INI_Section[0][E_INI_SECTION_keystart]; | |
if(i != -1) | |
{ | |
do | |
{ | |
if(key_size == INI_Key[i][E_INI_KEY_name_size]) | |
{ | |
if(!strcmp(key,INI_Key[i][E_INI_KEY_name],_INI_CS)) | |
{ | |
//KEY FOUND | |
memcpy(INI_Key[i][E_INI_KEY_value],data,0,data_size*4 + 4,INI_MAX_KEY_VALUE_LENGTH); | |
format(INI_Line[INI_Key[i][E_INI_KEY_lineid]][E_INI_LINE_Content],INI_MAX_LINE_LENGTH,"%s=%s\r\n",key,data); | |
return (i - INI_MAX_KEYS*_:filehandle); | |
} | |
} | |
}while((i = INI_Key[i][E_INI_KEY_next]) != INI_LINKED_LIST_NULL); | |
} | |
return ini_internal_CreateKey(filehandle,key,data,0,key_size); | |
} | |
} | |
else if(keyid > -1) | |
{ | |
if(-1 < keyid < INI_File[_:filehandle][E_INI_FILE_LoadedKeys]) | |
{ | |
new tmp = INI_MAX_KEYS*_:filehandle + keyid; | |
if(INI_Key[tmp][E_INI_KEY_sectionid] > -1) | |
{ | |
memcpy(INI_Key[tmp][E_INI_KEY_value],data,0,data_size*4 + 4,INI_MAX_KEY_VALUE_LENGTH); | |
format(INI_Line[INI_Key[tmp][E_INI_KEY_lineid]][E_INI_LINE_Content],INI_MAX_LINE_LENGTH,"%s=%s\r\n",INI_Key[tmp][E_INI_KEY_name],data); | |
return keyid; | |
} | |
} | |
else | |
{ | |
INI_Error("[INI]WriteString:Non-existant Key ID (%d)",keyid); | |
return INI_KEY_NOT_FOUND; | |
} | |
} | |
INI_Notice("[INI]WriteString:Invalid Parameters"); | |
return INI_KEY_NOT_FOUND; | |
} | |
/******************************************************************************************************************************* | |
<summary>WriteBool</summary> | |
<para>Sets the value of a key to the given boolean value</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="variable">value to be set</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Relative Key ID if known</param> | |
<param name="sectionid">Relative Section ID if known</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid of the updated/created key or an error code | |
INI_ERR_INVALID_HANDLE | |
INI_KEY_NOT_FOUND | |
INI_ERR_PARSING_FAILED | |
</returns> | |
<example> | |
INI::WriteBool(handle,var,"KEY","SECTION"); //Changes the value of KEY in SECTION (will be created if it doesn't exist) | |
INI::WriteBool(handle,var,"KEY"); //Changes the value of KEY in global section (will be created if it doesn't exist) | |
INI::WriteBool(handle,var,"KEY","",-1,sectionid); //Changes the value of KEY in the given section id(Error if it doesn't exist) | |
INI::WriteBool(handle,var,"","",1); //Changes the value of the key having the given keyid | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::WriteBool(INI:filehandle,bool:variable,const key[],const section[],keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
if(variable) | |
return INI::WriteString(filehandle,INI_WRITE_TRUE_VALUE,key,section,keyid,sectionid,INI_WRITE_TRUE_VALUE_SIZE,section_size,key_size); | |
else | |
return INI::WriteString(filehandle,INI_WRITE_FALSE_VALUE,key,section,keyid,sectionid,INI_WRITE_TRUE_VALUE_SIZE,section_size,key_size); | |
} | |
/******************************************************************************************************************************* | |
<summary>WriteInteger</summary> | |
<para>Sets the value of the key to the given integer</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="variable">value to be set</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Relative Key ID if known</param> | |
<param name="sectionid">Relative Section ID if known</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid of the updated/created key or an error code | |
INI_ERR_INVALID_HANDLE | |
INI_KEY_NOT_FOUND | |
INI_ERR_PARSING_FAILED | |
</returns> | |
<example> | |
INI::WriteInteger(handle,var,"KEY","SECTION"); //Changes the value of KEY in SECTION (will be created if it doesn't exist) | |
INI::WriteInteger(handle,var,"KEY"); //Changes the value of KEY in global section (will be created if it doesn't exist) | |
INI::WriteInteger(handle,var,"KEY","",-1,sectionid); //Changes the value of KEY in the given section id(Error if it doesn't exist) | |
INI::WriteInteger(handle,var,"","",1); //Changes the value of the key having the given keyid | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::WriteInteger(INI:filehandle,variable,const key[],const section[],keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
new result[INI_INTEGER_DIGITS]; //Assuming integers to be of 32bit so it can go up to billion = 10 digits | |
valstr(result,variable); | |
return INI::WriteString(filehandle,result,key,section,keyid,sectionid,sizeof(result),section_size,key_size); | |
} | |
/******************************************************************************************************************************* | |
<summary>WriteFloat</summary> | |
<para>Sets the value of a key to the given float</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="variable">value to be set</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Set to -1 if the sectionid is not known</param> | |
<param name="sectionid">Set to -1 if the sectionid is not known</param> | |
<param name="data_size">Size of result paramter</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid of the updated/created key or an error code | |
INI_ERR_INVALID_HANDLE | |
INI_KEY_NOT_FOUND | |
INI_ERR_PARSING_FAILED | |
</returns> | |
<example> | |
INI::WriteFloat(handle,data,"KEY","SECTION"); //Changes the value of KEY in SECTION (will be created if it doesn't exist) | |
INI::WriteFloat(handle,data,"KEY"); //Changes the value of KEY in global section (will be created if it doesn't exist) | |
INI::WriteFloat(handle,data,"KEY","",-1,sectionid); //Changes the value of KEY in the given section id(Error if it doesn't exist) | |
INI::WriteFloat(handle,data,"","",1); //Changes the value of the key having the given keyid | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::WriteFloat(INI:filehandle,Float:variable,const key[],const section[],keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
new result[INI_FLOATING_POINT_PRECISION]; | |
format(result,INI_FLOATING_POINT_PRECISION,"%f",variable); | |
return INI::WriteString(filehandle,result,key,section,keyid,sectionid,sizeof(result),section_size,key_size); | |
} | |
/******************************************************************************************************************************* | |
<summary>WriteHex</summary> | |
<para>Sets the value of a key to the given integer in hexadecimal notation</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="variable">value to be set</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Set to -1 if the sectionid is not known</param> | |
<param name="sectionid">Set to -1 if the sectionid is not known</param> | |
<param name="data_size">Size of result paramter</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid of the updated/created key or an error code | |
INI_ERR_INVALID_HANDLE | |
INI_KEY_NOT_FOUND | |
INI_ERR_PARSING_FAILED | |
</returns> | |
<example> | |
INI::WriteHex(handle,data,"KEY","SECTION"); //Changes the value of KEY in SECTION (will be created if it doesn't exist) | |
INI::WriteHex(handle,data,"KEY"); //Changes the value of KEY in global section (will be created if it doesn't exist) | |
INI::WriteHex(handle,data,"KEY","",-1,sectionid); //Changes the value of KEY in the given section id(Error if it doesn't exist) | |
INI::WriteHex(handle,data,"","",1); //Changes the value of the key having the given keyid | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::WriteHex(INI:filehandle,variable,const key[],const section[],keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
new result[INI_HEX_DIGITS]; | |
format(result,INI_FLOATING_POINT_PRECISION,"0x%x",variable); | |
return INI::WriteString(filehandle,result,key,section,keyid,sectionid,sizeof(result),section_size,key_size); | |
} | |
/******************************************************************************************************************************* | |
<summary>WriteBinary</summary> | |
<para>Sets the value of a key to the given integer in binary form</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="variable">value to be set</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Set to -1 if the sectionid is not known</param> | |
<param name="sectionid">Set to -1 if the sectionid is not known</param> | |
<param name="data_size">Size of result paramter</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid of the updated/created key or an error code | |
INI_ERR_INVALID_HANDLE | |
INI_KEY_NOT_FOUND | |
INI_ERR_PARSING_FAILED | |
</returns> | |
<example> | |
INI::WriteBinary(handle,data,"KEY","SECTION"); //Changes the value of KEY in SECTION (will be created if it doesn't exist) | |
INI::WriteBinary(handle,data,"KEY"); //Changes the value of KEY in global section (will be created if it doesn't exist) | |
INI::WriteBinary(handle,data,"KEY","",-1,sectionid); //Changes the value of KEY in the given section id(Error if it doesn't exist) | |
INI::WriteBinary(handle,data,"","",1); //Changes the value of the key having the given keyid | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::WriteBinary(INI:filehandle,variable,const key[],const section[],keyid=-1,sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
new result[INI_FLOATING_POINT_PRECISION]; | |
format(result,INI_FLOATING_POINT_PRECISION,"%b",variable); | |
return INI::WriteString(filehandle,result,key,section,keyid,sectionid,sizeof(result),section_size,key_size); | |
} | |
/******************************************************************************************************************************* | |
<summary>WriteArray</summary> | |
<para>Sets an array key</para> | |
<param name="filehandle">File Handle ID of the file to be closed</param> | |
<param name="array">The array to be saved</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Key ID relative to the handle(see remarks).Set to -1 if keyid not known</param> | |
<param name="sectionid">Section ID relative to the handle(see remarks).Set to -1 if the sectionid is not known</param> | |
<param name="array_size">Size of array paramter</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid of the updated/created key or an error code | |
INI_ERR_INVALID_HANDLE | |
INI_KEY_NOT_FOUND | |
INI_ERR_PARSING_FAILED | |
</returns> | |
<remarks> | |
The first key of the file is given a key id 0,the next 1 and so on. | |
The keyid paramter takes these numbers. | |
Similarly sectionid. | |
</remarks> | |
<example> | |
INI::WriteArray(handle,arr,"KEY","SECTION"); //Searches for KEY in SECTION | |
INI::WriteArray(handle,arr,"KEY"); //Searches for KEY in the global section | |
INI::WriteArray(handle,arr,"KEY","",-1,sectionid); //Searches for KEY in section with id sectionid | |
INI::WriteArray(handle,arr,"","",1); //Gets the value of key with keyid 1 | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::WriteArray(INI:filehandle,array[],const key[]="",const section[]="",keyid=-1,sectionid=-1,array_size=sizeof(array),section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
new result[INI_MAX_KEY_VALUE_LENGTH],sint[INI_INTEGER_DIGITS]; | |
for(new i = 0; i < array_size;i++) | |
{ | |
if(i) strcat(result,","); | |
valstr(sint,array[i]); | |
strcat(result,sint); | |
} | |
return INI::WriteString(filehandle,result,key,section,keyid,sectionid,sizeof(result),section_size,key_size); | |
} | |
/******************************************************************************************************************************* | |
<summary>WriteEnum</summary> | |
<para>Parses a enum key and sets up the given enum array</para> | |
<param name="filehandle">File Handle ID of the file to be closed</param> | |
<param name="enum_array">The enum index where the data is present</param> | |
<param name="enum_size">Size of unit enum</param> | |
<param name="key">Key to search for</param> | |
<param name="section">The section where the key resides(leave null if the key is in global section)</param> | |
<param name="keyid">Key ID relative to the handle(see remarks).Set to -1 if keyid not known</param> | |
<param name="sectionid">Section ID relative to the handle(see remarks).Set to -1 if the sectionid is not known</param> | |
<param name="section_size">Size of section parameter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns keyid of the updated/created key or an error code | |
INI_ERR_INVALID_HANDLE | |
INI_KEY_NOT_FOUND | |
INI_ERR_PARSING_FAILED | |
</returns> | |
<example> | |
INI::WriteEnum(handle,arr[1],sizeof(arr[]),"KEY","SECTION"); //Searches for KEY in SECTION | |
INI::WriteEnum(handle,arr[2],sizeof(arr[]),"KEY"); //Searches for KEY in the global section | |
INI::WriteEnum(handle,arr[1],sizeof(arr[]),"KEY","",-1,sectionid); //Searches for KEY in section with id sectionid | |
INI::WriteEnum(handle,arr[4],sizeof(arr[]),"","",1); //Gets the value of key with keyid 1 | |
</example> | |
*******************************************************************************************************************************/ | |
#define ReadEnum(%0,%1,%2,%3,%4,%5,%6,%7,%8,%9) ReadArray(%0,%1,%3,%4,%5,%6,%7,%2,%8,%9) | |
/******************************************************************************************************************************* | |
<summary>WriteFormat</summary> | |
<para>Reads multiple values and stores in the variables given</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="sectionid">Section ID relative to the handle(see remarks)</param> | |
<param name="format">Type of each data(see example)</param> | |
<params>Write variable1,key1,variable2,key2</params> | |
<returns> | |
Returns 0 on success or an error code | |
INI_ERR_INVALID_HANDLE | |
</returns> | |
<remarks> | |
Specifiers: | |
d,i => integer | |
s => string | |
f => float | |
b => binary | |
x,X => hexadecimal number | |
T,F => boolean number | |
</remarks> | |
<example> | |
new pInfo[MAX_PLAYERS][e_pInfo]; | |
INI::ReadEnum(handle,sid,"isf",myint,"KeyInt",mystr,"KeyStr",myfloat,"KeyFloat"); //Searches for KEY in SECTION | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::WriteFormat(INI:filehandle,sectionid,const format[],{Float,_}:...) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]ReadFormat:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]ReadFormat:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
new k,result[INI_MAX_KEY_VALUE_LENGTH],key[INI_MAX_KEY_NAME_LENGTH]; | |
for(new i = 0,j = numargs();(4 + i*2) < j;i++) | |
{ | |
k = 0; | |
do | |
{ | |
key[k] = getarg(4 + i*2,k); | |
}while(key[k++] != '\0'); | |
switch(format[i]) | |
{ | |
case '\0': return 0; | |
case 'd','i': INI::WriteInteger(filehandle,getarg(3 + i*2,0),key,"",-1,sectionid,1,k); | |
case 's': | |
{ | |
k = 0; | |
do | |
{ | |
result[k] = getarg(3 + i*2,k); | |
}while(result[k++] != '\0'); | |
INI::WriteString(filehandle,result,key,"",-1,sectionid,INI_MAX_KEY_VALUE_LENGTH,1,k); | |
} | |
case 'f': INI::WriteFloat(filehandle,Float:getarg(3 + i*2,0),key,"",-1,sectionid,1,k); | |
case 'b': INI::WriteBinary(filehandle,getarg(3 + i*2,0),key,"",-1,sectionid,1,k); | |
case 'x','X': INI::WriteHex(filehandle,getarg(3 + i*2,0),key,"",-1,sectionid,1,k); | |
case 'T','F': INI::WriteBool(filehandle,bool:getarg(3 + i*2,0),key,"",-1,sectionid,1,k); | |
default: return 0; | |
} | |
} | |
return 0; | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/******************************************************************************************************************************* | |
<summary>DeleteSection</summary> | |
<para>Deletes a section</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="section">Section to delete (leave null to indicate global section)</param> | |
<param name="sectionid">relative section id if known</param> | |
<param name="section_size">Size of section parameter</param> | |
<returns> | |
Returns 0 on success or an error code | |
INI_ERR_INVALID_HANDLE | |
INI_SECTION_NOT_FOUND | |
INI_ERR_INVALID_ID | |
</returns> | |
<example> | |
new id = INI::DeleteSection(handle,"MYSECTION"); //Deletes MYSECTION | |
new id = INI::DeleteSection(handle,""); //Deletes Global Section | |
new id = INI::DeleteSection(handle,"",1); //Deletes Section with sectionid 1 | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::DeleteSection(INI:filehandle,const section[]="",sectionid=-1,section_size=sizeof(section)) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]DeleteSection:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]DeleteSection:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
if(--section_size) | |
{ | |
if((sectionid = INI::GetSectionID(filehandle,section,section_size+1)) < 0) return INI_SECTION_NOT_FOUND; | |
} | |
else if(sectionid > -1) | |
{ | |
if(sectionid > INI_File[_:filehandle][E_INI_FILE_LoadedSections]) | |
{ | |
INI_Error("[INI]WriteString:Invalid Section ID (%d)",sectionid); | |
return INI_ERR_INVALID_ID; | |
} | |
} | |
else | |
sectionid = 0; | |
new i = INI_MAX_SECTIONS*_:filehandle + sectionid; | |
new k,n = INI_Section[i][E_INI_SECTION_lineid]; | |
INI_Section[i][E_INI_SECTION_sectionid] = INI_DEFAULT_FILL; | |
new j = INI_Section[i][E_INI_SECTION_keystart]; | |
if(j == INI_LINKED_LIST_NULL) | |
{ | |
if(INI_Line[n][E_INI_LINE_previous] == INI_LINKED_LIST_NULL) | |
{ | |
INI_File[_:filehandle][E_INI_FILE_start_lineid] = INI_Line[n][E_INI_LINE_next]; | |
INI_Line[INI_Line[n][E_INI_LINE_next]][E_INI_LINE_previous] = INI_LINKED_LIST_NULL; | |
} | |
else | |
{ | |
INI_Line[INI_Line[n][E_INI_LINE_previous]][E_INI_LINE_next] = INI_Line[n][E_INI_LINE_next]; | |
INI_Line[INI_Line[n][E_INI_LINE_next]][E_INI_LINE_previous] = INI_Line[n][E_INI_LINE_previous]; | |
} | |
} | |
else | |
{ | |
for(;;) | |
{ | |
k = INI_Key[j][E_INI_KEY_lineid]; | |
INI_Line[k][E_INI_LINE_type] = INI_DEFAULT_FILL; | |
INI_Key[j][E_INI_KEY_sectionid] = INI_DEFAULT_FILL; | |
if((j = INI_Key[j][E_INI_KEY_next]) == INI_LINKED_LIST_NULL) | |
{ | |
if(INI_Line[n][E_INI_LINE_previous] == INI_LINKED_LIST_NULL) | |
{ | |
INI_File[_:filehandle][E_INI_FILE_start_lineid] = INI_Line[k][E_INI_LINE_next]; | |
INI_Line[INI_Line[k][E_INI_LINE_next]][E_INI_LINE_previous] = INI_LINKED_LIST_NULL; | |
} | |
else | |
{ | |
INI_Line[INI_Line[n][E_INI_LINE_previous]][E_INI_LINE_next] = INI_Line[k][E_INI_LINE_next]; | |
INI_Line[INI_Line[k][E_INI_LINE_next]][E_INI_LINE_previous] = INI_Line[n][E_INI_LINE_previous]; | |
} | |
INI_Line[k][E_INI_LINE_previous] = INI_Line[k][E_INI_LINE_next] = INI_LINKED_LIST_NULL; | |
break; | |
} | |
else | |
{ | |
INI_Line[k][E_INI_LINE_previous] = INI_Line[k][E_INI_LINE_next] = INI_LINKED_LIST_NULL; | |
} | |
} | |
INI_Line[n][E_INI_LINE_type] = INI_DEFAULT_FILL; | |
INI_Line[n][E_INI_LINE_previous] = INI_Line[n][E_INI_LINE_next] = INI_LINKED_LIST_NULL; | |
} | |
return 0; | |
} | |
/******************************************************************************************************************************* | |
<summary>DeleteKey</summary> | |
<para>Deletes a key</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="key">key to be deleted</param> | |
<param name="section">Section in which the key resides (leave null to indicate global section)</param> | |
<param name="keyid">relative key id if known</param> | |
<param name="sectionid">relative section id if known</param> | |
<param name="key_size">Size of key parameter</param> | |
<param name="section_size">Size of section parameter</param> | |
<returns> | |
Returns 0 on success or an error code | |
INI_ERR_INVALID_HANDLE | |
INI_KEY_NOT_FOUND | |
INI_ERR_INVALID_ID | |
</returns> | |
<example> | |
new id = INI::DeleteKey(handle,"MYKEY","MYSECTION"); //Deletes MYKEY from MYSECTION | |
new id = INI::DeleteKey(handle,"MYKEY"); //Deletes MYKEY from Global Section | |
new id = INI::DeleteKey(handle,"","",1); //Deletes the key with key id 1 | |
new id = INI::DeleteKey(handle,"MYKEY","","-1",1); //Deletes MYKEY from the section with id 1 | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::DeleteKey(INI:filehandle,const key[],const section[]="",keyid=-1,sectionid=-1,key_size=sizeof(key),section_size=sizeof(section)) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]DeleteKey:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]DeleteKey:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
if(key_size > 1) | |
{ | |
if((keyid = INI::GetKeyID(INI:filehandle,key,section,sectionid,section_size,key_size)) < 0) return INI_KEY_NOT_FOUND; | |
} | |
else if(keyid > -1) | |
{ | |
if(keyid > INI_File[_:filehandle][E_INI_FILE_LoadedKeys]) | |
{ | |
INI_Error("[INI]DeleteKey:Invalid Key ID (%d)",keyid); | |
return INI_ERR_INVALID_ID; | |
} | |
} | |
else | |
{ | |
INI_Notice("[INI]DeleteKey:Invalid Parameters"); | |
return INI_KEY_NOT_FOUND; | |
} | |
new i = INI_Key[keyid][E_INI_KEY_lineid]; | |
INI_Key[keyid][E_INI_KEY_sectionid] = INI_Line[i][E_INI_LINE_type] = INI_DEFAULT_FILL; | |
if(INI_Line[i][E_INI_LINE_previous] == INI_LINKED_LIST_NULL) | |
{ | |
INI_File[_:filehandle][E_INI_FILE_start_lineid] = INI_Line[i][E_INI_LINE_next]; | |
INI_Line[INI_Line[i][E_INI_LINE_next]][E_INI_LINE_previous] = INI_LINKED_LIST_NULL; | |
} | |
else | |
{ | |
INI_Line[INI_Line[i][E_INI_LINE_next]][E_INI_LINE_previous] = INI_Line[i][E_INI_LINE_previous]; | |
INI_Line[INI_Line[i][E_INI_LINE_previous]][E_INI_LINE_next] = INI_Line[i][E_INI_LINE_next]; | |
} | |
INI_Line[i][E_INI_LINE_next] = INI_Line[i][E_INI_LINE_previous] = INI_LINKED_LIST_NULL; | |
return 0; | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/******************************************************************************************************************************* | |
<summary>GetSectionID</summary> | |
<para>Finds the relative section id</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="section">Section whose relative id is required(leave null to search global section)</param> | |
<param name="section_size">Size of section parameter</param> | |
<returns> | |
Returns the relative section id or an error code | |
INI_ERR_INVALID_HANDLE | |
INI_SECTION_NOT_FOUND | |
</returns> | |
<example> | |
new id = INI::GetSectionID(handle,"MYSECTION"); | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::GetSectionID(INI:filehandle,const section[],section_size=sizeof(section)) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]GetSectionID:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]GetSectionID:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
if(!INI_File[_:filehandle][E_INI_FILE_parsed]) | |
if(INI::ParseINI(filehandle)) | |
{ | |
new str[INI_MAX_FILE_NAME_LENGTH]; | |
strunpack(str,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Error("[INI]ReadString:Failed to parse file(%s)>>Read Failed",str); | |
return INI_ERR_PARSING_FAILED; | |
} | |
if(--section_size) | |
{ | |
new i = INI_MAX_SECTIONS*_:filehandle; | |
for(new j = i + INI_File[_:filehandle][E_INI_FILE_LoadedSections];++i <= j;) | |
{ | |
if(INI_Section[i][E_INI_SECTION_name_size] == section_size) | |
{ | |
if(!strcmp(section,INI_Section[i][E_INI_SECTION_name],_INI_CS)) | |
return (i-INI_MAX_SECTIONS*_:filehandle); | |
} | |
} | |
return INI_SECTION_NOT_FOUND; | |
} | |
else return 0; | |
} | |
/******************************************************************************************************************************* | |
<summary>GetKeyID</summary> | |
<para>Finds the relative key id</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="key">Key whose relative id is required</param> | |
<param name="section">Section where the key resides if sectionid is not known</param> | |
<param name="sectionid">Section ID if known</param> | |
<param name="section_size">Size of section paramter</param> | |
<param name="key_size">Size of key parameter</param> | |
<returns> | |
Returns the relative section id or an error code | |
INI_ERR_INVALID_HANDLE | |
INI_KEY_NOT_FOUND | |
</returns> | |
<example> | |
new id = INI::GetKeyID(handle,"MYKEY","MYSECTION"); //Search for MYKEY in MYSECTION | |
new id = INI::GetKeyID(handle,"MYKEY"); //Search for MYKEY in global section | |
new id = INI::GetKeyID(handle,"MYKEY","",1); //Search for MYKEY in section with id 1 | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::GetKeyID(INI:filehandle,const key[],const section[]="",sectionid=-1,section_size=sizeof(section),key_size=sizeof(key)) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]GetSectionID:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]GetSectionID:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
if(--key_size) //removing the null character | |
{ | |
if(--section_size) //removing the null character | |
{ | |
new sid = INI::GetSectionID(filehandle,section,section_size+1); | |
if(sid < 0) return INI_SECTION_NOT_FOUND; | |
new i = INI_Section[INI_MAX_SECTIONS*_:filehandle + sid][E_INI_SECTION_keystart]; | |
do | |
{ | |
if(INI_Key[i][E_INI_KEY_name_size] == key_size) | |
{ | |
if(!strcmp(key,INI_Key[i][E_INI_KEY_name],_INI_CS)) | |
return (i-INI_MAX_KEYS*_:filehandle); | |
} | |
}while((i = INI_Key[i][E_INI_KEY_next]) != INI_LINKED_LIST_NULL); | |
INI_Notice("[INI]GetKeyID:Key not found (Key:%s Section:%s)",key,section); | |
return INI_KEY_NOT_FOUND; | |
} | |
else if(sectionid > -1) | |
{ | |
if(!INI_File[_:filehandle][E_INI_FILE_parsed]) | |
if(INI::ParseINI(filehandle)) | |
{ | |
new str[INI_MAX_FILE_NAME_LENGTH]; | |
strunpack(str,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Error("[INI]ReadString:Failed to parse file(%s)>>Read Failed",str); | |
return INI_ERR_PARSING_FAILED; | |
} | |
if(sectionid >= INI_File[_:filehandle][E_INI_FILE_LoadedSections]) | |
{ | |
INI_Error("[INI]GetKeyID:Invalid Section ID (%d)",sectionid); | |
return INI_ERR_INVALID_ID; | |
} | |
new i = INI_Section[INI_MAX_SECTIONS*_:filehandle + sectionid][E_INI_SECTION_keystart]; | |
do | |
{ | |
if(INI_Key[i][E_INI_KEY_name_size] == key_size) | |
{ | |
if(!strcmp(key,INI_Key[i][E_INI_KEY_name],_INI_CS)) | |
return (i-INI_MAX_KEYS*_:filehandle); | |
} | |
}while((i = INI_Key[i][E_INI_KEY_next]) != INI_LINKED_LIST_NULL); | |
INI_Notice("[INI]GetKeyID:Key not found (Key:%s Section:%s)",key,section); | |
return INI_KEY_NOT_FOUND; | |
} | |
else | |
{ | |
if(!INI_File[_:filehandle][E_INI_FILE_parsed]) | |
if(INI::ParseINI(filehandle)) | |
{ | |
new str[INI_MAX_FILE_NAME_LENGTH]; | |
strunpack(str,INI_File[_:filehandle][E_INI_FILE_filename]); | |
INI_Error("[INI]ReadString:Failed to parse file(%s)>>Read Failed",str); | |
return INI_ERR_PARSING_FAILED; | |
} | |
new i = INI_Section[INI_MAX_SECTIONS*_:filehandle][E_INI_SECTION_keystart]; | |
do | |
{ | |
if(INI_Key[i][E_INI_KEY_name_size] == key_size) | |
{ | |
if(!strcmp(key,INI_Key[i][E_INI_KEY_name],_INI_CS)) | |
return (i-INI_MAX_KEYS*_:filehandle); | |
} | |
}while((i = INI_Key[i][E_INI_KEY_next]) != INI_LINKED_LIST_NULL); | |
INI_Notice("[INI]GetKeyID:Key(%s) not found in global section ",key); | |
return INI_KEY_NOT_FOUND; | |
} | |
} | |
INI_Notice("[INI]GetKeyID:Invalid Parameters",key,sectionid); | |
return INI_KEY_NOT_FOUND; | |
} | |
/******************************************************************************************************************************* | |
<summary>GetKeyName</summary> | |
<para>Stores the name of the given key(keyid) in result</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="result">Array where the name should be stored</param> | |
<param name="keyid">Key ID of the key of which the name has to be obtained</param> | |
<param name="result_size">Size of result paramter</param> | |
<returns> | |
Returns INI_ERR_INVALID_ID if the given keyid is invalid | |
Returns 0 on sucess | |
</returns> | |
<example> | |
INI::GetKeyName(handle,res,2); | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::GetKeyName(INI:filehandle,result[],keyid,result_size=sizeof(result)) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]GetKeyName:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]GetKeyName:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
if(-1 < keyid < INI_File[_:filehandle][E_INI_FILE_LoadedKeys]) | |
{ | |
new i = INI_MAX_KEYS*_:filehandle + keyid; | |
if(INI_Key[i][E_INI_KEY_sectionid] != INI_DEFAULT_FILL) | |
{ | |
result[0] = '\0'; | |
strcat(result,INI_Key[i][E_INI_KEY_name],result_size); | |
return 0; | |
} | |
} | |
INI_Error("[INI]GetKeyName:Invalid Key ID (%d)",keyid); | |
return INI_ERR_INVALID_ID; | |
} | |
/******************************************************************************************************************************* | |
<summary>GetSectionName</summary> | |
<para>Stores the name of the given section(sectionid) in result</para> | |
<param name="filehandle">INI Handle</param> | |
<param name="result">Array where the name should be stored</param> | |
<param name="sectionid">Section ID of the key of which the name has to be obtained</param> | |
<param name="result_size">Size of result paramter</param> | |
<returns> | |
Returns INI_ERR_INVALID_ID if the given sectionid is invalid | |
Returns 0 on success | |
</returns> | |
<example> | |
INI::GetSectionName(handle,res,2); | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::GetSectionName(INI:filehandle,result[],sectionid,result_size=sizeof(result)) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]GetSectionName:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]GetSectionName:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
if(-1 < sectionid < INI_File[_:filehandle][E_INI_FILE_LoadedSections]) | |
{ | |
new i = INI_MAX_SECTIONS*_:filehandle + sectionid; | |
if(INI_Section[i][E_INI_SECTION_sectionid] != INI_DEFAULT_FILL) | |
{ | |
result[0] = '\0'; | |
strcat(result,INI_Section[i][E_INI_SECTION_name],result_size); | |
return 0; | |
} | |
} | |
INI_Error("[INI]GetSectionName:Invalid Key ID (%d)",sectionid); | |
return INI_ERR_INVALID_ID; | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/******************************************************************************************************************************* | |
<summary>DumpINI</summary> | |
<para>Dumps all the contents of the INI in the server window</para> | |
<param name="filehandle">INI Handle</param> | |
<returns> | |
Returns error id if an invalid handle is passed | |
Returns 0 on success | |
</returns> | |
<example> | |
INI::DumpINI(handle); | |
</example> | |
*******************************************************************************************************************************/ | |
stock INI::DumpINI(INI:filehandle) | |
{ | |
#if !defined INI_CAREFUL_MODE | |
if(INI:-1 < filehandle < INI:INI_MAX_MULTI_FILES) { if(!IsFileHandleInUse(_:filehandle)){ INI_Error("[INI]DumpINI:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } } | |
else { INI_Error("[INI]DumpINI:Invalid File Handle ID (%d)",_:filehandle); return INI_ERR_INVALID_HANDLE; } | |
#endif | |
if(!INI_File[_:filehandle][E_INI_FILE_parsed]) INI::ParseINI(filehandle); | |
for(new i = INI_File[_:filehandle][E_INI_FILE_start_lineid];INI_Line[i][E_INI_LINE_type] != INI_LINE_EOF;i = INI_Line[i][E_INI_LINE_next]) | |
printf("[DUMP] %s",INI_Line[i][E_INI_LINE_Content]); | |
return 0; | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
static stock ini_internal_CreateSection(INI:filehandle,const section[],section_size=sizeof(section)) | |
{ | |
new sid,j,i; | |
if(INI_File[_:filehandle][E_INI_FILE_lines] < (INI_MAX_LINES-1)) | |
i = INI_MAX_LINES*_:filehandle + ++INI_File[_:filehandle][E_INI_FILE_lines]; | |
else | |
{ | |
for(i = INI_MAX_LINES*_:filehandle,j = INI_MAX_LINES*(1+_:filehandle);;i++) | |
if(i < j) { if(INI_Line[i][E_INI_LINE_type] == INI_DEFAULT_FILL) break; } | |
else | |
{ | |
INI_Notice("[INI]Could not create section %s>>Maximum line limit reached",section); | |
return INI_SECTION_CREATE_FAILED; | |
} | |
} | |
if(INI_File[_:filehandle][E_INI_FILE_LoadedSections] < (INI_MAX_SECTIONS-1)) | |
sid = INI_MAX_SECTIONS*_:filehandle + ++INI_File[_:filehandle][E_INI_FILE_LoadedSections]; | |
else | |
{ | |
for(sid = INI_MAX_SECTIONS*_:filehandle,j = INI_MAX_SECTIONS*(1+_:filehandle);;sid++) | |
if(sid < j) { if(INI_Section[sid][E_INI_SECTION_sectionid] == INI_DEFAULT_FILL) break; } | |
else | |
{ | |
INI_Notice("[INI]Could not create section %s>>Maximum sections limit reached",section); | |
return INI_SECTION_CREATE_FAILED; | |
} | |
} | |
INI_Section[sid][E_INI_SECTION_sectionid] = sid - INI_MAX_SECTIONS*_:filehandle; | |
INI_Section[sid][E_INI_SECTION_keystart] = INI_LINKED_LIST_NULL; | |
INI_Section[sid][E_INI_SECTION_lineid] = i; | |
format(INI_Section[sid][E_INI_SECTION_name],INI_MAX_SECTION_NAME_LENGTH,"%s",section); | |
INI_Section[sid][E_INI_SECTION_name_size] = section_size-1; | |
INI_Line[i][E_INI_LINE_type] = INI_LINE_SECTION_TAG; | |
INI_Line[i][E_INI_LINE_id] = sid; | |
INI_Line[i][E_INI_LINE_Content][0] = '\0'; | |
format(INI_Line[i][E_INI_LINE_Content],INI_MAX_LINE_LENGTH,"[%s]\r\n",section); | |
j = INI_Line[i][E_INI_LINE_next] = INI_File[_:filehandle][E_INI_FILE_end_lineid]; | |
if(INI_Line[j][E_INI_LINE_previous] != INI_LINKED_LIST_NULL) | |
INI_Line[INI_Line[j][E_INI_LINE_previous]][E_INI_LINE_next] = i; | |
else | |
INI_File[_:filehandle][E_INI_FILE_start_lineid] = i; | |
INI_Line[i][E_INI_LINE_previous] = INI_Line[j][E_INI_LINE_previous]; | |
INI_Line[j][E_INI_LINE_previous] = i; | |
return sid; | |
} | |
static stock ini_internal_CreateKey(INI:filehandle,const key[],const value[],sectionid,key_size=sizeof(key)) | |
{ | |
new kid,j,i; | |
if(INI_File[_:filehandle][E_INI_FILE_lines] < (INI_MAX_LINES-1)) | |
i = INI_MAX_LINES*_:filehandle + ++INI_File[_:filehandle][E_INI_FILE_lines]; | |
else | |
{ | |
for(i = INI_MAX_LINES*_:filehandle,j = INI_MAX_LINES*(1+_:filehandle);;i++) | |
if(i < j) { if(INI_Line[i][E_INI_LINE_type] == INI_DEFAULT_FILL) break; } | |
else | |
{ | |
INI_Notice("[INI]Could not create key %s>>Maximum line limit reached",key); | |
return INI_KEY_CREATE_FAILED; | |
} | |
} | |
if(INI_File[_:filehandle][E_INI_FILE_LoadedKeys] < (INI_MAX_KEYS-1)) | |
kid = INI_MAX_KEYS*_:filehandle + INI_File[_:filehandle][E_INI_FILE_LoadedKeys]++; | |
else | |
{ | |
for(kid = INI_MAX_KEYS*_:filehandle,j = INI_MAX_KEYS*(1+_:filehandle);;kid++) | |
if(kid < j) { if(INI_Key[kid][E_INI_KEY_sectionid] == INI_DEFAULT_FILL) break; } | |
else | |
{ | |
INI_Notice("[INI]Could not create key %s>>Maximum keys limit reached",key); | |
return INI_KEY_CREATE_FAILED; | |
} | |
} | |
INI_Key[kid][E_INI_KEY_sectionid] = sectionid; | |
INI_Key[kid][E_INI_KEY_lineid] = i; | |
format(INI_Key[kid][E_INI_KEY_name],INI_MAX_KEY_NAME_LENGTH,"%s",key); | |
format(INI_Key[kid][E_INI_KEY_value],INI_MAX_KEY_VALUE_LENGTH,"%s",value); | |
INI_Key[kid][E_INI_KEY_name_size] = key_size; | |
if(sectionid == 0) | |
INI_Line[i][E_INI_LINE_type] = INI_LINE_GLOBAL_KEY; | |
else | |
INI_Line[i][E_INI_LINE_type] = INI_LINE_SECTION_KEY; | |
INI_Line[i][E_INI_LINE_id] = kid; | |
format(INI_Line[i][E_INI_LINE_Content],INI_MAX_LINE_LENGTH,"%s=%s\r\n",key,value); | |
if(INI_Section[sectionid][E_INI_SECTION_keystart] == INI_DEFAULT_FILL) | |
{ | |
INI_Key[kid][E_INI_KEY_next] = INI_LINKED_LIST_NULL; | |
INI_Key[kid][E_INI_KEY_previous] = INI_LINKED_LIST_NULL; | |
INI_Section[sectionid][E_INI_SECTION_keystart] = kid; | |
} | |
else | |
{ | |
new t = INI_Section[sectionid][E_INI_SECTION_keystart]; | |
INI_Key[kid][E_INI_KEY_next] = t; | |
INI_Key[t][E_INI_KEY_previous] = kid; | |
INI_Key[kid][E_INI_KEY_previous] = INI_LINKED_LIST_NULL; | |
INI_Section[sectionid][E_INI_SECTION_keystart] = kid; | |
} | |
if(sectionid) | |
{ | |
j = INI_Section[sectionid][E_INI_SECTION_lineid]; | |
INI_Line[i][E_INI_LINE_next] = INI_Line[j][E_INI_LINE_next]; | |
INI_Line[i][E_INI_LINE_previous] = j; | |
INI_Line[INI_Line[j][E_INI_LINE_next]][E_INI_LINE_previous] = INI_Line[j][E_INI_LINE_next] = i; | |
} | |
else | |
{ | |
j = INI_File[_:filehandle][E_INI_FILE_start_lineid]; | |
INI_Line[i][E_INI_LINE_next] = j; | |
INI_Line[i][E_INI_LINE_previous] = INI_LINKED_LIST_NULL; | |
INI_File[_:filehandle][E_INI_FILE_start_lineid] = INI_Line[j][E_INI_LINE_previous] = i; | |
} | |
return kid; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment