Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Самый быстрый INI ридер/райтер
- ЧТО ЭТО
- - Это инклуд-файл для PAWN скриптов мультиплеера GTA San Andreas (SA-MP)
- КАК ИСПОЛЬЗОВАТЬ
- - Поместить этот файл в папку include, которая лежит рядом с компилятором
- - В самом верху вашего скрипта добавить #include <mxINI>
- АВТОР
- MX_Master
- ВЕРСИЯ
- 0.2 от 08.12.2009
- ДОСТУПНЫЕ ИНСТРУМЕНТЫ
- более подробные описания даны перед каждой функцией ниже в коде
- ini_createFile ( "путь/к/файлу.ini", "Содержимое файла по умолчанию" )
- . вернет ИД_открытого_файла или отрицательное значение при ошибке
- ini_openFile ( "путь/к/файлу.ini" )
- . вернет ИД_открытого_файла или отрицательное значение при ошибке
- ini_closeFile ( ИД_открытого_файла )
- . вернет 0 при успехе или отрицательное значение при ошибке
- . если ИД_открытого_файла верен и файл был изменен - запишет файл из ОЗУ на диск
- --
- ini_setString ( ИД_открытого_файла, "имя_ключа", "текстовое значение" )
- . вернет отрицательное значение при ошибке или 0 при успехе
- ini_setInteger ( ИД_открытого_файла, "имя_ключа", 123456 )
- . вернет отрицательное значение при ошибке или 0 при успехе
- ini_setFloat ( ИД_открытого_файла, "имя_ключа", 3.1416 )
- . вернет отрицательное значение при ошибке или 0 при успехе
- --
- ini_getString ( ИД_открытого_файла, "имя_ключа", returnValue )
- . вернет отрицательное значение при ошибке или 0 при успехе
- . значение ключа будет помещено в returnValue, который вы должны предварительно создать
- ini_getInteger ( ИД_открытого_файла, "имя_ключа", returnValue )
- . вернет отрицательное значение при ошибке или 0 при успехе
- . целочисленное значение ключа будет помещено в returnValue, который вы должны предварительно создать
- ini_getFloat ( ИД_открытого_файла, "имя_ключа", returnValue )
- . вернет отрицательное значение при ошибке или 0 при успехе
- . дробное численное значение ключа будет помещено в returnValue, который вы должны предварительно создать
- ПРИМЕРЫ
- new iniFile = ini_createFile ( "test4268.ini" );
- if ( iniFile != INI_OK )
- iniFile = ini_openFile ( "test4268.ini" );
- if ( iniFile == INI_OK )
- {
- new returnString[32], returnNumber, Float: returnFloat;
- ini_setString ( iniFile, "ключ_со_строкой", "текстовое значение" );
- ini_setInteger ( iniFile, "ключ_с_числом", 123456 );
- ini_setFloat ( iniFile, "ключ_с_дробью", 3.1416 );
- ini_getString ( iniFile, "ключ_со_строкой", returnString );
- ini_getInteger ( iniFile, "ключ_с_числом", returnNumber );
- ini_getFloat ( iniFile, "ключ_с_дробью", returnFloat );
- ini_closeFile ( iniFile );
- printf ( "\n `ключ_со_строкой` = `%s`,\n `ключ_с_числом` = `%d`,\n `ключ_с_дробью` = `%f` \n",
- returnString, returnNumber, returnFloat );
- }
- else print( "\n Не удалось открыть INI файл \n" );
- */
- const
- // настройки
- // РЕКОМЕНДУЕТСЯ ИЗМЕНИТЬ ПОД СЕБЯ
- INI_MAX_OPENED_FILES = 10, // максимум открытых файлов
- INI_MAX_FILE_SIZE = 32768, // байт, макс. размер файла
- INI_MAX_FILENAME_SIZE = 128, // символов, макс. размер пути к файлу
- INI_MAX_KEYS_IN_FILE = 2048, // максимум ключей в открытом файле
- // в ОЗУ будет выделено для временного хранения файлов примерно вот столько байт:
- // INI_MAX_OPENED_FILES * ( INI_MAX_FILE_SIZE + INI_MAX_FILENAME_SIZE*4 + INI_MAX_KEYS_IN_FILE*4 )
- // в начальной настройке это:
- // 10 * ( 32768 + 128*4 + 2048*4 ) = 414720 Байт ИЛИ 405 Кб ИЛИ 103680 pawn ячеек
- // это примерный, но показательный расчет
- // НЕЛЬЗЯ МЕНЯТЬ
- INI_INTEGER_SIZE = 12, // размер строки с целочисленным значением
- INI_FLOAT_SIZE = 40, // размер строки с дробным числовым значением
- INI_STRING_DELIMITER = '\n', // разделитель строк
- INI_DELIMITER = '=', // разделитель ключа и значения
- // коды ошибок, возвращаемые функциями
- // РЕКОМЕНДУЕТСЯ НЕ ИЗМЕНЯТЬ
- INI_OK = 0, // функция успешно выполнена
- // проверять на ошибку можно так:
- // if ( возвращаемое_значение < 0 ) ...
- INI_FILE_NOT_FOUND = -1, // файл не найден по указанному пути
- INI_FILE_ALREADY_EXIST = -2, // файл не найден по указанному пути
- INI_TOO_LARGE_FILE = -3, // размер файла превысил допустимый лимит
- INI_WRONG_PATH_SIZE = -4, // неправильный размер пути к файлу
- INI_READ_ERROR = -5, // ошибка чтения файла
- INI_WRITE_ERROR = -6, // ошибка при записи в файл
- INI_NO_FREE_SLOT = -7, // нет свободного слота для открытия файла
- INI_WRONG_SLOT = -8, // указан неверный слот открытого файла
- INI_KEY_NOT_FOUND = -9, // ключ в открытом файле не найден
- // другие вспомогательные константы
- // НЕЛЬЗЯ МЕНЯТЬ
- cellbytes = cellbits / charbits; // кол-во байт в одной ячейке
- // списки разных символов для оператора case в одной из функций
- // РЕКОМЕНДУЕТСЯ НЕ ИЗМЕНЯТЬ
- #define INI_SPACE_CHAR ' ', '\t' // строковые пробельные символы
- #define INI_KEY_STARTS ' ', '\t', '\r', '\0' // символы, перед началом ключа
- #define INI_STRING_ENDS '\r', '\n', '\0' // символы, завершающие значение
- #define INI_NUMBER_ENDS ' ', '\t', '\r', '\n', '\0' // символы, завершающие численное значение
- stock
- // временное хранилище открытых файлов
- _ini_nSlotUsed [ INI_MAX_OPENED_FILES ], // флаг: занят ли слот
- _ini_nFileChanged [ INI_MAX_OPENED_FILES ], // флаг: был ли изменен файл
- _ini_nFileBusy [ INI_MAX_OPENED_FILES ], // флаг: изменяется ли в данный момент содержимое файла
- _ini_nFileSize [ INI_MAX_OPENED_FILES ], // размер открытого файла
- _ini_nDelimPos [ INI_MAX_OPENED_FILES ] [ INI_MAX_KEYS_IN_FILE ], // список позиций INI_DELIMITER
- _ini_nKeysCount [ INI_MAX_OPENED_FILES ], // кол-во ключей открытого файла
- _ini_szFilePath [ INI_MAX_OPENED_FILES ] [ INI_MAX_FILENAME_SIZE ], // путь к файлу
- _ini_szFileContent [ INI_MAX_OPENED_FILES ] [ INI_MAX_FILE_SIZE char ]; // контент файла
- /*
- Создает и сразу открывает INI файл для чтения/записи.
- ПОДРОБНЕЕ
- Файл создается только в ОЗУ, и в него записывается строка szDefaultContent.
- В szDefaultContent могут быть и ключи, которые потом парсер также будет видеть.
- Только при закрытии файла, его содержимое будет записано на диск
- по указанному пути к файлу.
- ПАРАМЕТРЫ:
- szFilePath[] путь к файлу
- szDefaultContent контент файла по умолчанию, обычно, можно не указывать
- ВЕРНЕТ:
- код ошибки < 0 или ИД_открытого_файла
- */
- stock ini_createFile ( szFilePath[], szDefaultContent[] = "" )
- {
- //
- // несколько блоков с проверками
- //
- // ------------
- new nFileNameSize = strlen( szFilePath ); // узнаем размер пути
- // если размер пути неправильный
- if ( nFileNameSize <= 0 || nFileNameSize >= INI_MAX_FILENAME_SIZE )
- return INI_WRONG_PATH_SIZE; // вернем код ошибки
- // ------------
- // ------------
- if ( fexist( szFilePath ) ) // если файл уже существует
- return INI_FILE_ALREADY_EXIST; // вернем код ошибки - файл уже существует
- for ( new slot = 0; slot < INI_MAX_OPENED_FILES; slot++ ) // перебор всех слотов ОЗУ
- if // если уже есть такой открытый файл
- (
- _ini_nSlotUsed[slot] != 0
- && strcmp( szFilePath, _ini_szFilePath[slot], false ) == 0
- )
- return INI_FILE_ALREADY_EXIST; // вернем код ошибки - файл уже существует
- // ------------
- // ------------
- new nFileSize = strlen( szDefaultContent ); // узнаем размер контентa файла по умолчанию
- // если размер неправильный
- if ( nFileSize < 0 || nFileSize >= INI_MAX_FILE_SIZE )
- return INI_TOO_LARGE_FILE; // вернем код ошибки
- // ------------
- //
- // поиск свободного слота для записи в ОЗУ
- //
- for ( new slot = 0; slot < INI_MAX_OPENED_FILES; slot++ ) // перебор всех слотов ОЗУ
- {
- if ( _ini_nSlotUsed[slot] != 1 ) // если слот найден
- {
- // ------------
- _ini_nSlotUsed[slot] = 1; // застолбим найденное место
- _ini_nFileChanged[slot] = 0; // файл не был изменен
- _ini_nFileSize[slot] = nFileSize; // скопируем размер файла в слот
- _ini_nKeysCount[slot] = 0; // кол-во ключей выставим 0
- // ------------
- // ------------
- // скопируем в ОЗУ весь файл,
- // запомнив все позиции INI_DELIMITER и их кол-во
- for ( new i = 0; i < nFileSize && i < INI_MAX_FILE_SIZE; i++ )
- {
- if (
- szDefaultContent[i] == INI_DELIMITER // если символ это INI_DELIMITER
- && _ini_nKeysCount[slot] < INI_MAX_KEYS_IN_FILE // и лимит ключей еще не исчерпан
- ) {
- _ini_nDelimPos[slot][ _ini_nKeysCount[slot] ] = i; // добавим еще одну позицию INI_DELIMITER
- _ini_nKeysCount[slot]++; // увеличим кол-во найденных ключей
- }
- _ini_szFileContent[slot]{i} = szDefaultContent[i];
- }
- _ini_szFileContent[slot]{nFileSize} = 0; // символ конца строки для контента
- // ------------
- // ------------
- // скопируем в озу путь к файлу
- memcpy( _ini_szFilePath[slot], szFilePath, 0, nFileNameSize * cellbytes );
- _ini_szFilePath[slot][nFileNameSize] = 0; // символ конца строки для пути
- // ------------
- return slot; // вернем ИД слота
- }
- }
- //
- // если свободный слот в памяти не найден
- //
- return INI_NO_FREE_SLOT; // вернем код ошибки
- // ------------
- }
- /*
- Открывает INI файл для чтения/записи, если он существует.
- ПОДРОБНЕЕ
- Копирует в ОЗУ с диска всё содержимое файла, если его размер не превышает
- допустимый. Если кол-во ключей в файле больше допустимого, ошибки никакой не будет,
- просто при чтении/записи значений, парсер не будет видеть лишние ключи.
- ПАРАМЕТРЫ:
- szFilePath[] путь к файлу
- ВЕРНЕТ:
- код ошибки < 0 или ИД_открытого_файла
- */
- stock ini_openFile ( szFilePath[] )
- {
- //
- // несколько блоков с проверками
- //
- // ------------
- new nFileNameSize = strlen( szFilePath ); // узнаем размер пути
- // если размер пути неправильный
- if ( nFileNameSize <= 0 || nFileNameSize >= INI_MAX_FILENAME_SIZE )
- return INI_WRONG_PATH_SIZE; // вернем код ошибки
- // ------------
- if ( ! fexist( szFilePath ) ) // если файл не найден
- return INI_FILE_NOT_FOUND; // вернем код ошибки
- // ------------
- // проверка - открыт ли уже файл с таким именем
- for ( new slot = 0; slot < INI_MAX_OPENED_FILES; slot++ ) // перебор всех слотов ОЗУ
- if // если уже есть такой открытый файл
- (
- _ini_nSlotUsed[slot] != 0
- && strcmp( szFilePath, _ini_szFilePath[slot], false ) == 0
- )
- return slot; // просто вернем его слот
- // ------------
- // ------------
- new File: pFile = fopen( szFilePath, io_read ); // пытаемся открыть файл для чтения
- if ( ! pFile ) // если файл не открылся
- return INI_READ_ERROR; // вернем код ошибки
- // ------------
- // ------------
- new nFileSize = flength( pFile ); // узнаем размер файла
- if ( nFileSize >= INI_MAX_FILE_SIZE ) // если размер файла слишком большой
- {
- fclose(pFile); // закроем файл
- return INI_TOO_LARGE_FILE; // вернем код ошибки
- }
- // ------------
- //
- // поиск свободного слота для записи в ОЗУ
- //
- // ------------
- for ( new slot = 0; slot < INI_MAX_OPENED_FILES; slot++ ) // перебор всех слотов ОЗУ
- {
- if ( _ini_nSlotUsed[slot] != 1 ) // если слот найден
- {
- // ------------
- _ini_nSlotUsed[slot] = 1; // застолбим найденное место
- _ini_nFileChanged[slot] = 0; // файл не был изменен
- _ini_nFileSize[slot] = nFileSize; // скопируем размер файла в слот
- _ini_nKeysCount[slot] = 0; // кол-во ключей выставим 0
- // ------------
- // ------------
- // скопируем в ОЗУ весь файл,
- // запомнив все позиции INI_DELIMITER и их кол-во
- for ( new i = 0, symbol; i < nFileSize && i < INI_MAX_FILE_SIZE; i++ )
- {
- symbol = fgetchar( pFile, 0, false ); // читаем из файла следующий символ
- if (
- symbol == INI_DELIMITER // если символ это INI_DELIMITER
- && _ini_nKeysCount[slot] < INI_MAX_KEYS_IN_FILE // и лимит ключей еще не исчерпан
- ) {
- _ini_nDelimPos[slot][ _ini_nKeysCount[slot] ] = i; // добавим еще одну позицию INI_DELIMITER
- _ini_nKeysCount[slot]++; // увеличим кол-во найденных ключей
- }
- _ini_szFileContent[slot]{i} = symbol;
- }
- _ini_szFileContent[slot]{nFileSize} = 0; // символ конца строки для контента
- fclose(pFile); // закроем файл
- // ------------
- // ------------
- // скопируем в озу путь к файлу
- memcpy( _ini_szFilePath[slot], szFilePath, 0, nFileNameSize * cellbytes );
- _ini_szFilePath[slot][nFileNameSize] = 0; // символ конца строки для пути
- // ------------
- return slot; // вернем ИД слота
- }
- }
- // ------------
- //
- // если свободный слот в памяти не найден
- //
- // ------------
- fclose(pFile); // закроем файл
- return INI_NO_FREE_SLOT; // вернем код ошибки
- // ------------
- }
- /*
- Закрывает INI файл, если он был открыт.
- ПОДРОБНЕЕ
- Если файл не был изменен - освободит слот для хранения файла в ОЗУ.
- Если файл был изменен - полностью перезапишет файл на диске.
- ПАРАМЕТРЫ:
- nFilePointer ИД_открытого_файла, полученный от ini_openFile / ini_createFile
- ВЕРНЕТ:
- код ошибки < 0 или 0 при успехе
- */
- stock ini_closeFile ( nFilePointer )
- {
- if
- ( // если ИД открытого файла указан верно
- nFilePointer >= 0
- && nFilePointer < INI_MAX_OPENED_FILES
- && _ini_nSlotUsed[nFilePointer] != 0
- )
- {
- if ( _ini_nFileChanged[nFilePointer] != 0 ) // если файл был изменен
- {
- new File: pFile = fopen( _ini_szFilePath[nFilePointer], io_write ); // пытаемся открыть файл для записи
- if ( ! pFile ) // если файл не открылся
- return INI_WRITE_ERROR; // вернем код ошибки
- // запишем контент файла из ОЗУ на диск
- for ( new i = 0; i < _ini_nFileSize[nFilePointer]; i++ )
- fputchar( pFile, _ini_szFileContent[nFilePointer]{i}, false );
- fclose(pFile); // закроем файл
- }
- _ini_nSlotUsed[nFilePointer] = 0; // освободить слот открытого файла
- return INI_OK; // вернуть код об успешном выполнении функции
- }
- return INI_WRONG_SLOT; // вернуть код: неверный указатель на открытый файл
- }
- /*
- Получает из открытого INI файла значение указанного ключа.
- ПОДРОБНЕЕ
- Парсер ищет в ОЗУ в контенте файла указанный ключ и помещает в
- szReturnValue его строковое значение. szReturnValue нужно создать заранее.
- nSizeOfReturn можно не указывать, если только не нужно точное кол-во
- возвращаемых символов в строке.
- Как ключ так и значение в файле, могут быть любой длины и
- могут содержать любые символы, кроме 2 символов конца строки \r и \n.
- Парсер не видит пробелы и знаки табуляции вокруг имени ключа и
- перед значением, он считает их отступами.
- ПАРАМЕТРЫ:
- nFilePointer ИД_открытого_файла, полученный от ini_openFile / ini_createFile
- szKeyName[] имя ключа
- szReturnValue[] сюда будет помещено значение ключа в виде строки
- nSizeOfReturn макс. размер возвращаемой строки, обычно, это размер szReturnValue
- ВЕРНЕТ:
- код ошибки < 0 или 0 при успехе
- */
- stock ini_getString ( nFilePointer, szKeyName[], szReturnValue[], nSizeOfReturn = sizeof(szReturnValue) )
- {
- // ----------------
- if // если ИД открытого файла указан неверно
- (
- nFilePointer < 0
- || nFilePointer >= INI_MAX_OPENED_FILES
- || _ini_nSlotUsed[nFilePointer] != 1
- )
- return INI_WRONG_SLOT; // вернуть код: неверный указатель на открытый файл
- // ----------------
- // ----------------
- new nKeyLen = strlen(szKeyName); // узнаем длину имени указанного ключа
- if ( nKeyLen <= 0 ) // если указан пустой ключ
- return INI_KEY_NOT_FOUND;
- // ----------------
- // ----------------
- for // перебор и сравнение всех ключей файла с указанным ключом
- (
- new kPos = 0, curFilePos, found = 0;
- kPos < _ini_nKeysCount[nFilePointer];
- kPos++
- )
- {
- // ----------------
- found = 0; // флаг, найдена ли позиция конца ключа = 0
- for // ищем позицию конца ключа
- (
- curFilePos = _ini_nDelimPos[nFilePointer][kPos] - 1; // текущ. поз. файла = поз. текущ. INI_DELIMITER - 1
- curFilePos >= 0; // продолжать пока поз. файла >= 0
- curFilePos-- // после каждого повтора текущ. поз. файла -= 1
- )
- {
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} ) // узнаем что за символ в текущ. поз. файла
- {
- case INI_SPACE_CHAR : continue; // если это пробельный символ, перейдем к пред. символу файла
- case INI_STRING_DELIMITER : break; // если это конец строки
- default : // если это другой символ
- {
- found = 1; // позиция конца ключа найдена
- break; // конец цикла
- }
- }
- }
- // если позиция конца ключа не найдена, переход к след. позиции INI_DELIMITER
- if ( found != 1 ) continue;
- // ----------------
- // сравниваем посимвольно текущий ключ файла и указанный ключ
- for ( new curKeyPos = nKeyLen - 1; curKeyPos >= 0; curFilePos--, curKeyPos-- )
- {
- if
- (
- curFilePos < 0 // если поз файла стала < 0
- || _ini_szFileContent[nFilePointer]{curFilePos} != szKeyName[curKeyPos] // если символы из ключей не равны
- || _ini_szFileContent[nFilePointer]{curFilePos} == INI_STRING_DELIMITER // если символ из ключа это INI_STRING_DELIMITER
- )
- {
- found = 0; // флаг, ключ не найден
- break; // конец сравнения
- }
- }
- // ----------------
- if ( found != 0 ) // если указанный ключ найден в файле
- {
- // ----------------
- // текущая позиция в файле будет на 1 больше текущей позиции INI_DELIMITER
- curFilePos = _ini_nDelimPos[nFilePointer][kPos] + 1;
- // ищем позицию начала значения, она будет помещена в curFilePos
- for ( ; ; curFilePos++ )
- {
- if ( curFilePos >= _ini_nFileSize[nFilePointer] ) break;
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} )
- {
- case INI_SPACE_CHAR : continue; // если это пробельный символ, перейдем к след. символу
- default : break; // если это другой символ
- }
- }
- // ----------------
- // ----------------
- // скопируем посимвольно в szReturnValue значение ключа из файла
- // воспользуемся созданной переменной found как позицией в возвращаемом значении
- for ( found = 0; found < nSizeOfReturn; found++, curFilePos++ )
- {
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} )
- {
- case INI_STRING_ENDS : // если это символ конца значения
- {
- szReturnValue[found] = 0; // запишем символ конца строки
- break; // конец копирования
- }
- default :
- // копируем символ из файла в szReturnValue
- szReturnValue[found] = _ini_szFileContent[nFilePointer]{curFilePos};
- }
- }
- szReturnValue[nSizeOfReturn - 1] = 0; // на всякий случай обрежем правильно строку
- return INI_OK;
- // ----------------
- }
- // ----------------
- }
- // ----------------
- // ----------------
- return INI_KEY_NOT_FOUND;
- // ----------------
- }
- /*
- Получает из открытого INI файла целочисленное значение указанного ключа.
- ПОДРОБНЕЕ
- Парсер ищет в ОЗУ в контенте файла указанный ключ и помещает в
- nReturnValue его целочисленное значение. nReturnValue нужно создать заранее.
- Имя ключа в файле может быть любой длины, а также может содержать
- любые символы, кроме 2 символов конца строки \r и \n.
- Значение может быть только фиксированной длины, которая равна INI_INTEGER_SIZE - 1.
- Парсер не видит пробелы и знаки табуляции вокруг имени ключа/значения,
- он считает их отступами.
- ПАРАМЕТРЫ:
- nFilePointer ИД_открытого_файла, полученный от ini_openFile / ini_createFile
- szKeyName[] имя ключа
- nReturnValue сюда будет помещено значение ключа в виде целого числа
- ВЕРНЕТ:
- код ошибки < 0 или 0 при успехе
- */
- stock ini_getInteger ( nFilePointer, szKeyName[], & nReturnValue )
- {
- // ----------------
- if // если ИД открытого файла указан неверно
- (
- nFilePointer < 0
- || nFilePointer >= INI_MAX_OPENED_FILES
- || _ini_nSlotUsed[nFilePointer] != 1
- )
- return INI_WRONG_SLOT; // вернуть код: неверный указатель на открытый файл
- // ----------------
- // ----------------
- new nKeyLen = strlen(szKeyName); // узнаем длину имени указанного ключа
- if ( nKeyLen <= 0 ) // если указан пустой ключ
- return INI_KEY_NOT_FOUND;
- // ----------------
- // ----------------
- for // перебор и сравнение всех ключей файла с указанным ключом
- (
- new kPos = 0, curFilePos, found = 0;
- kPos < _ini_nKeysCount[nFilePointer];
- kPos++
- )
- {
- // ----------------
- found = 0; // флаг, найдена ли позиция конца ключа = 0
- for // ищем позицию конца ключа
- (
- curFilePos = _ini_nDelimPos[nFilePointer][kPos] - 1; // текущ. поз. файла = поз. текущ. INI_DELIMITER - 1
- curFilePos >= 0; // продолжать пока поз. файла >= 0
- curFilePos-- // после каждого повтора текущ. поз. файла -= 1
- )
- {
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} ) // узнаем что за символ в текущ. поз. файла
- {
- case INI_SPACE_CHAR : continue; // если это пробельный символ, перейдем к пред. символу файла
- case INI_STRING_DELIMITER : break; // если это конец строки
- default : // если это другой символ
- {
- found = 1; // позиция конца ключа найдена
- break; // конец цикла
- }
- }
- }
- // если позиция конца ключа не найдена, переход к след. позиции INI_DELIMITER
- if ( found != 1 ) continue;
- // ----------------
- // сравниваем посимвольно текущий ключ файла и указанный ключ
- for ( new curKeyPos = nKeyLen - 1; curKeyPos >= 0; curFilePos--, curKeyPos-- )
- {
- if
- (
- curFilePos < 0 // если поз файла стала < 0
- || _ini_szFileContent[nFilePointer]{curFilePos} != szKeyName[curKeyPos] // если символы из ключей не равны
- || _ini_szFileContent[nFilePointer]{curFilePos} == INI_STRING_DELIMITER // если символ из ключа это INI_STRING_DELIMITER
- )
- {
- found = 0; // флаг, ключ не найден
- break; // конец сравнения
- }
- }
- // ----------------
- if ( found != 0 ) // если указанный ключ найден в файле
- {
- // ----------------
- // текущая позиция в файле будет на 1 больше текущей позиции INI_DELIMITER
- curFilePos = _ini_nDelimPos[nFilePointer][kPos] + 1;
- // ищем позицию начала значения, она будет помещена в curFilePos
- for ( ; ; curFilePos++ )
- {
- if ( curFilePos >= _ini_nFileSize[nFilePointer] ) break;
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} )
- {
- case INI_SPACE_CHAR : continue; // если это пробельный символ, перейдем к след. символу
- default : break; // если это другой символ
- }
- }
- // ----------------
- // ----------------
- new strValue[INI_INTEGER_SIZE]; // временная строка для численного значения
- // скопируем посимвольно в strValue значение ключа из файла
- // воспользуемся созданной переменной found как позицией в возвращаемом значении
- for ( found = 0; found < INI_INTEGER_SIZE; found++, curFilePos++ )
- {
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} )
- {
- case INI_NUMBER_ENDS : // если это символ конца численного значения
- {
- strValue[found] = 0; // запишем символ конца строки
- break; // конец копирования
- }
- default :
- // копируем символ из файла в strValue
- strValue[found] = _ini_szFileContent[nFilePointer]{curFilePos};
- }
- }
- strValue[INI_INTEGER_SIZE - 1] = 0; // на всякий случай обрежем правильно строку
- nReturnValue = strval(strValue); // запишем в nReturnValue численное значение ключа
- return INI_OK;
- // ----------------
- }
- // ----------------
- }
- // ----------------
- // ----------------
- return INI_KEY_NOT_FOUND;
- // ----------------
- }
- /*
- Получает из открытого INI файла дробное численное значение указанного ключа.
- ПОДРОБНЕЕ
- Парсер ищет в ОЗУ в контенте файла указанный ключ и помещает в
- fReturnValue его дробное значение. fReturnValue нужно создать заранее.
- Имя ключа в файле может быть любой длины, а также может содержать
- любые символы, кроме 2 символов конца строки \r и \n.
- Значение может быть только фиксированной длины, которая равна INI_FLOAT_SIZE - 1.
- Парсер не видит пробелы и знаки табуляции вокруг имени ключа/значения,
- он считает их отступами.
- ПАРАМЕТРЫ:
- nFilePointer ИД_открытого_файла, полученный от ini_openFile / ini_createFile
- szKeyName[] имя ключа
- fReturnValue сюда будет помещено значение ключа в виде дробного числа
- ВЕРНЕТ:
- код ошибки < 0 или 0 при успехе
- */
- stock ini_getFloat ( nFilePointer, szKeyName[], & Float: fReturnValue )
- {
- // ----------------
- if // если ИД открытого файла указан неверно
- (
- nFilePointer < 0
- || nFilePointer >= INI_MAX_OPENED_FILES
- || _ini_nSlotUsed[nFilePointer] != 1
- )
- return INI_WRONG_SLOT; // вернуть код: неверный указатель на открытый файл
- // ----------------
- // ----------------
- new nKeyLen = strlen(szKeyName); // узнаем длину имени указанного ключа
- if ( nKeyLen <= 0 ) // если указан пустой ключ
- return INI_KEY_NOT_FOUND;
- // ----------------
- // ----------------
- for // перебор и сравнение всех ключей файла с указанным ключом
- (
- new kPos = 0, curFilePos, found = 0;
- kPos < _ini_nKeysCount[nFilePointer];
- kPos++
- )
- {
- // ----------------
- found = 0; // флаг, найдена ли позиция конца ключа = 0
- for // ищем позицию конца ключа
- (
- curFilePos = _ini_nDelimPos[nFilePointer][kPos] - 1; // текущ. поз. файла = поз. текущ. INI_DELIMITER - 1
- curFilePos >= 0; // продолжать пока поз. файла >= 0
- curFilePos-- // после каждого повтора текущ. поз. файла -= 1
- )
- {
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} ) // узнаем что за символ в текущ. поз. файла
- {
- case INI_SPACE_CHAR : continue; // если это пробельный символ, перейдем к пред. символу файла
- case INI_STRING_DELIMITER : break; // если это конец строки
- default : // если это другой символ
- {
- found = 1; // позиция конца ключа найдена
- break; // конец цикла
- }
- }
- }
- // если позиция конца ключа не найдена, переход к след. позиции INI_DELIMITER
- if ( found != 1 ) continue;
- // ----------------
- // сравниваем посимвольно текущий ключ файла и указанный ключ
- for ( new curKeyPos = nKeyLen - 1; curKeyPos >= 0; curFilePos--, curKeyPos-- )
- {
- if
- (
- curFilePos < 0 // если поз файла стала < 0
- || _ini_szFileContent[nFilePointer]{curFilePos} != szKeyName[curKeyPos] // если символы из ключей не равны
- || _ini_szFileContent[nFilePointer]{curFilePos} == INI_STRING_DELIMITER // если символ из ключа это INI_STRING_DELIMITER
- )
- {
- found = 0; // флаг, ключ не найден
- break; // конец сравнения
- }
- }
- // ----------------
- if ( found != 0 ) // если указанный ключ найден в файле
- {
- // ----------------
- // текущая позиция в файле будет на 1 больше текущей позиции INI_DELIMITER
- curFilePos = _ini_nDelimPos[nFilePointer][kPos] + 1;
- // ищем позицию начала значения, она будет помещена в curFilePos
- for ( ; ; curFilePos++ )
- {
- if ( curFilePos >= _ini_nFileSize[nFilePointer] ) break;
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} )
- {
- case INI_SPACE_CHAR : continue; // если это пробельный символ, перейдем к след. символу
- default : break; // если это другой символ
- }
- }
- // ----------------
- // ----------------
- new strValue[INI_FLOAT_SIZE]; // временная строка для дробного значения
- // скопируем посимвольно в strValue значение ключа из файла
- // воспользуемся созданной переменной found как позицией в возвращаемом значении
- for ( found = 0; found < INI_INTEGER_SIZE; found++, curFilePos++ )
- {
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} )
- {
- case INI_NUMBER_ENDS : // если это символ конца численного значения
- {
- strValue[found] = 0; // запишем символ конца строки
- break; // конец копирования
- }
- default :
- // копируем символ из файла в strValue
- strValue[found] = _ini_szFileContent[nFilePointer]{curFilePos};
- }
- }
- strValue[INI_FLOAT_SIZE - 1] = 0; // на всякий случай обрежем правильно строку
- fReturnValue = floatstr(strValue); // запишем в fReturnValue дробное значение ключа
- return INI_OK;
- // ----------------
- }
- // ----------------
- }
- // ----------------
- // ----------------
- return INI_KEY_NOT_FOUND;
- // ----------------
- }
- /*
- Изменяет/добавляет в открытый INI файл указанный ключ и его значение.
- ПОДРОБНЕЕ
- Парсер ищет в ОЗУ в контенте файла указанный ключ и изменяет его
- строковое значение на szKeyValue. Форматирование файла не меняется,
- если только указанное имя ключа не было найдено, тогда ключ и значение
- будут добавлены в конец файла.
- Имя ключа/значение в файле может быть любой длины, а также может содержать
- любые символы, кроме 2 символов конца строки \r и \n. Если эти символы есть
- в имени ключа или в значении, вы должны должны хорошо знать и осознавать
- последствия.
- ПАРАМЕТРЫ:
- nFilePointer ИД_открытого_файла, полученный от ini_openFile / ini_createFile
- szKeyName[] имя ключа
- szKeyValue[] строка со значением ключа
- ВЕРНЕТ:
- код ошибки < 0 или 0 при успехе
- */
- stock ini_setString ( nFilePointer, szKeyName[], szKeyValue[] )
- {
- // ----------------
- if // если ИД открытого файла указан неверно
- (
- nFilePointer < 0
- || nFilePointer >= INI_MAX_OPENED_FILES
- || _ini_nSlotUsed[nFilePointer] != 1
- )
- return INI_WRONG_SLOT; // вернуть код: неверный указатель на открытый файл
- // ----------------
- // ----------------
- new nKeyLen = strlen(szKeyName); // узнаем длину имени указанного ключа
- if ( nKeyLen <= 0 ) // если указан пустой ключ
- return INI_KEY_NOT_FOUND;
- // ----------------
- // ----------------
- for // перебор и сравнение всех ключей файла с указанным ключом
- (
- new kPos = 0, curFilePos, found;
- kPos < _ini_nKeysCount[nFilePointer];
- kPos++
- )
- {
- // ----------------
- found = 0; // флаг, найдена ли позиция конца ключа = 0
- for // ищем позицию конца ключа
- (
- curFilePos = _ini_nDelimPos[nFilePointer][kPos] - 1; // текущ. поз. файла = поз. текущ. INI_DELIMITER - 1
- curFilePos >= 0; // продолжать пока поз. файла >= 0
- curFilePos-- // после каждого повтора текущ. поз. файла -= 1
- )
- {
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} ) // узнаем что за символ в текущ. поз. файла
- {
- case INI_SPACE_CHAR : continue; // если это пробельный символ, перейдем к пред. символу файла
- case INI_STRING_DELIMITER : break; // если это конец строки
- default : // если это другой символ
- {
- found = 1; // позиция конца ключа найдена
- break; // конец цикла
- }
- }
- }
- // если позиция конца ключа не найдена, переход к след. позиции INI_DELIMITER
- if ( found != 1 ) continue;
- // ----------------
- // сравниваем посимвольно текущий ключ файла и указанный ключ
- for ( new curKeyPos = nKeyLen - 1; curKeyPos >= 0; curFilePos--, curKeyPos-- )
- {
- if
- (
- curFilePos < 0 // если поз файла стала < 0
- || _ini_szFileContent[nFilePointer]{curFilePos} != szKeyName[curKeyPos] // если символы из ключей не равны
- || _ini_szFileContent[nFilePointer]{curFilePos} == INI_STRING_DELIMITER // если символ из ключа это INI_STRING_DELIMITER
- )
- {
- found = 0; // флаг, ключ не найден
- break; // конец сравнения
- }
- }
- if ( found != 0 ) // если указанный ключ НАЙДЕН в файле
- {
- // ----------------
- // текущая позиция в файле будет на 1 больше текущей позиции INI_DELIMITER
- curFilePos = _ini_nDelimPos[nFilePointer][kPos] + 1;
- // ищем позицию начала значения, она будет помещена в curFilePos
- for ( ; ; curFilePos++ )
- {
- if ( curFilePos >= _ini_nFileSize[nFilePointer] ) break;
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} )
- {
- case INI_SPACE_CHAR : continue; // если это пробельный символ, перейдем к след. символу
- default : break; // если это другой символ
- }
- }
- // ----------------
- // ----------------
- new nValueLen = strlen(szKeyValue); // узнаем размер значения указанного ключа
- // если будущий размер файла превышает лимит
- if ( ( curFilePos + nValueLen ) >= INI_MAX_FILE_SIZE )
- return INI_TOO_LARGE_FILE; // вернем код ошибки о переполнении файла
- // ----------------
- // ----------------
- new fileValueStartPos = curFilePos; // сохраним позицию начала значения
- // ищем позицию конца значения, она будет помещена в curFilePos
- for ( ; ; curFilePos++ )
- {
- if ( curFilePos >= _ini_nFileSize[nFilePointer] ) break;
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} )
- {
- case INI_STRING_ENDS : break; // если это конец строки - стоп
- default : continue; // если это другой символ, перейдем к след. символу
- }
- }
- // вычислим смещение оставшихся позиций для INI_DELIMITER после изменения значения
- new filePosOffset = nValueLen - ( /*текущ длина значения*/ curFilePos - fileValueStartPos );
- // ----------------
- if ( _ini_nFileBusy[nFilePointer] != 0 ) // если прямо сейчас файл изменяется другой функцией
- return INI_WRITE_ERROR; // вернем код ошибки при записи в файл
- // ----------------
- _ini_nFileBusy[nFilePointer] = 1; // флаг: файл изменяется = 1
- if ( filePosOffset != 0 ) // если длины старого и нового значений разные
- {
- if ( filePosOffset < 0 ) // если длина нового значения меньше
- {
- for // копируем символы, стоящие после текущего значения на их новые места,
- ( // которые теперь будут ближе к началу файла
- ;
- curFilePos < _ini_nFileSize[nFilePointer];
- curFilePos++
- )
- _ini_szFileContent[nFilePointer]{ curFilePos + filePosOffset } =
- _ini_szFileContent[nFilePointer]{curFilePos};
- }
- else if ( filePosOffset > 0 ) // если длина нового значения больше
- {
- new fileValueEndPos = curFilePos;
- for // копируем символы, стоящие после текущего значения на их новые места,
- ( // начиная с конца файла
- curFilePos = _ini_nFileSize[nFilePointer] - 1;
- curFilePos >= fileValueEndPos;
- curFilePos--
- )
- _ini_szFileContent[nFilePointer]{ curFilePos + filePosOffset } =
- _ini_szFileContent[nFilePointer]{curFilePos};
- }
- // изменим позиции всех INI_DELIMITER, которые находились после текущего INI_DELIMITER
- for ( kPos++; kPos < _ini_nKeysCount[nFilePointer]; kPos++ )
- _ini_nDelimPos[nFilePointer][kPos] += filePosOffset;
- _ini_nFileSize[nFilePointer] += filePosOffset; // изменим размер файла
- _ini_szFileContent[nFilePointer]{ _ini_nFileSize[nFilePointer] } = 0; // конец строки для конца файла
- }
- curFilePos = fileValueStartPos; // текущ поз файла = поз начала старого значения
- for // запишем новое значение поверх старого
- (
- new valuePos = 0;
- valuePos < nValueLen;
- curFilePos++, valuePos++
- )
- _ini_szFileContent[nFilePointer]{curFilePos} = szKeyValue[valuePos];
- _ini_nFileChanged[nFilePointer] = 1; // флаг: файл изменен = 1
- _ini_nFileBusy[nFilePointer] = 0; // флаг: файл изменяется = 0
- return INI_OK;
- // ----------------
- }
- }
- // ----------------
- //
- // если указанный ключ НЕ НАЙДЕН в файле
- //
- // ----------------
- new nValueLen = strlen(szKeyValue); // узнаем размер значения ключа
- // если будущий размер файла превышает лимит
- if ( ( _ini_nFileSize[nFilePointer] + 5 + nKeyLen + nValueLen ) >= INI_MAX_FILE_SIZE )
- return INI_TOO_LARGE_FILE; // вернем код ошибки о переполнении файла
- // ----------------
- // ----------------
- if ( _ini_nFileBusy[nFilePointer] != 0 ) // если прямо сейчас файл изменяется другой функцией
- return INI_WRITE_ERROR; // вернем код ошибки при записи в файл
- _ini_nFileBusy[nFilePointer] = 1; // флаг: файл изменяется = 1
- // ----------------
- // ----------------
- if // если последний символ файла не является разделителем строк
- (
- _ini_nFileSize[nFilePointer] > 0
- && _ini_szFileContent[nFilePointer]{ _ini_nFileSize[nFilePointer] - 1 } != INI_STRING_DELIMITER
- )
- {
- // вставим в конец файла перевод каретки и разделитель строк
- _ini_szFileContent[nFilePointer]{ _ini_nFileSize[nFilePointer] } = '\r';
- _ini_szFileContent[nFilePointer]{ _ini_nFileSize[nFilePointer] + 1 } = INI_STRING_DELIMITER;
- _ini_nFileSize[nFilePointer] += 2; // увеличим размер файла на 2
- }
- new curFilePos, strPos; // будут временным хранилищами позиций в файле/ключе/значении
- for // добавим посимвольно имя ключа в файл
- (
- curFilePos = _ini_nFileSize[nFilePointer], strPos = 0;
- strPos < nKeyLen;
- curFilePos++, strPos++
- )
- _ini_szFileContent[nFilePointer]{curFilePos} = szKeyName[strPos];
- _ini_szFileContent[nFilePointer]{ curFilePos++ } = ' '; // после ключа добавим пробел
- _ini_nDelimPos[nFilePointer][ _ini_nKeysCount[nFilePointer] ] = curFilePos; // добавим новую позицию INI_DELIMITER
- _ini_nKeysCount[nFilePointer]++; // кол-во ключей в файле +1
- _ini_szFileContent[nFilePointer]{ curFilePos++ } = INI_DELIMITER; // после пробела выше добавим INI_DELIMITER
- _ini_szFileContent[nFilePointer]{ curFilePos++ } = ' '; // после INI_DELIMITER добавим пробел
- // добавим посимвольно значение ключа в файл
- for ( strPos = 0; strPos < nValueLen; curFilePos++, strPos++ )
- _ini_szFileContent[nFilePointer]{curFilePos} = szKeyValue[strPos];
- _ini_szFileContent[nFilePointer]{curFilePos} = 0; // добавим символ конца строки
- _ini_nFileSize[nFilePointer] = curFilePos; // изменим размер файла
- _ini_nFileChanged[nFilePointer] = 1; // флаг: файл изменен = 1
- _ini_nFileBusy[nFilePointer] = 0; // флаг: файл изменяется = 0
- return INI_OK;
- // ----------------
- }
- /*
- Изменяет/добавляет в открытый INI файл указанный ключ и его целочисленное значение.
- ПОДРОБНЕЕ
- Парсер ищет в ОЗУ в контенте файла указанный ключ и изменяет его
- целочисленное значение на nKeyValue. Форматирование файла не меняется,
- если только указанное имя ключа не было найдено, тогда ключ и значение
- будут добавлены в конец файла.
- Имя ключа в файле может быть любой длины, а также может содержать
- любые символы, кроме 2 символов конца строки \r и \n. Если вы в качестве
- значения указываете число больше, чем cellmax или меньше, чем cellmin,
- вы должны должны хорошо знать и осознавать последствия.
- ПАРАМЕТРЫ:
- nFilePointer ИД_открытого_файла, полученный от ini_openFile / ini_createFile
- szKeyName[] имя ключа
- nKeyValue целочисленное значение ключа
- ВЕРНЕТ:
- код ошибки < 0 или 0 при успехе
- */
- stock ini_setInteger ( nFilePointer, szKeyName[], nKeyValue )
- {
- // ----------------
- if // если ИД открытого файла указан неверно
- (
- nFilePointer < 0
- || nFilePointer >= INI_MAX_OPENED_FILES
- || _ini_nSlotUsed[nFilePointer] != 1
- )
- return INI_WRONG_SLOT; // вернуть код: неверный указатель на открытый файл
- // ----------------
- // ----------------
- new nKeyLen = strlen(szKeyName); // узнаем длину имени указанного ключа
- if ( nKeyLen <= 0 ) // если указан пустой ключ
- return INI_KEY_NOT_FOUND;
- // ----------------
- // ----------------
- for // перебор и сравнение всех ключей файла с указанным ключом
- (
- new kPos = 0, curFilePos, found;
- kPos < _ini_nKeysCount[nFilePointer];
- kPos++
- )
- {
- // ----------------
- found = 0; // флаг, найдена ли позиция конца ключа = 0
- for // ищем позицию конца ключа
- (
- curFilePos = _ini_nDelimPos[nFilePointer][kPos] - 1; // текущ. поз. файла = поз. текущ. INI_DELIMITER - 1
- curFilePos >= 0; // продолжать пока поз. файла >= 0
- curFilePos-- // после каждого повтора текущ. поз. файла -= 1
- )
- {
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} ) // узнаем что за символ в текущ. поз. файла
- {
- case INI_SPACE_CHAR : continue; // если это пробельный символ, перейдем к пред. символу файла
- case INI_STRING_DELIMITER : break; // если это конец строки
- default : // если это другой символ
- {
- found = 1; // позиция конца ключа найдена
- break; // конец цикла
- }
- }
- }
- // если позиция конца ключа не найдена, переход к след. позиции INI_DELIMITER
- if ( found != 1 ) continue;
- // ----------------
- // сравниваем посимвольно текущий ключ файла и указанный ключ
- for ( new curKeyPos = nKeyLen - 1; curKeyPos >= 0; curFilePos--, curKeyPos-- )
- {
- if
- (
- curFilePos < 0 // если поз файла стала < 0
- || _ini_szFileContent[nFilePointer]{curFilePos} != szKeyName[curKeyPos] // если символы из ключей не равны
- || _ini_szFileContent[nFilePointer]{curFilePos} == INI_STRING_DELIMITER // если символ из ключа это INI_STRING_DELIMITER
- )
- {
- found = 0; // флаг, ключ не найден
- break; // конец сравнения
- }
- }
- if ( found != 0 ) // если указанный ключ НАЙДЕН в файле
- {
- // ----------------
- // текущая позиция в файле будет на 1 больше текущей позиции INI_DELIMITER
- curFilePos = _ini_nDelimPos[nFilePointer][kPos] + 1;
- // ищем позицию начала значения, она будет помещена в curFilePos
- for ( ; ; curFilePos++ )
- {
- if ( curFilePos >= _ini_nFileSize[nFilePointer] ) break;
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} )
- {
- case INI_SPACE_CHAR : continue; // если это пробельный символ, перейдем к след. символу
- default : break; // если это другой символ
- }
- }
- // ----------------
- // ----------------
- new szKeyValue[INI_INTEGER_SIZE]; // создадим строку для хранения целочисленного значения
- valstr( szKeyValue, nKeyValue, false ); // поместим строковое значение nKeyValue в szKeyValue
- // ----------------
- // ----------------
- new nValueLen = strlen(szKeyValue); // узнаем размер значения указанного ключа
- // если будущий размер файла превышает лимит
- if ( ( curFilePos + nValueLen ) >= INI_MAX_FILE_SIZE )
- return INI_TOO_LARGE_FILE; // вернем код ошибки о переполнении файла
- // ----------------
- // ----------------
- new fileValueStartPos = curFilePos; // сохраним позицию начала значения
- // ищем позицию конца значения, она будет помещена в curFilePos
- for ( ; ; curFilePos++ )
- {
- if ( curFilePos >= _ini_nFileSize[nFilePointer] ) break;
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} )
- {
- case INI_NUMBER_ENDS : break; // если это конец числа - стоп
- default : continue; // если это другой символ, перейдем к след. символу
- }
- }
- // вычислим смещение оставшихся позиций для INI_DELIMITER после изменения значения
- new filePosOffset = nValueLen - ( /*текущ длина значения*/ curFilePos - fileValueStartPos );
- // ----------------
- if ( _ini_nFileBusy[nFilePointer] != 0 ) // если прямо сейчас файл изменяется другой функцией
- return INI_WRITE_ERROR; // вернем код ошибки при записи в файл
- // ----------------
- _ini_nFileBusy[nFilePointer] = 1; // флаг: файл изменяется = 1
- if ( filePosOffset != 0 ) // если длины старого и нового значений разные
- {
- if ( filePosOffset < 0 ) // если длина нового значения меньше
- {
- for // копируем символы, стоящие после текущего значения на их новые места,
- ( // которые теперь будут ближе к началу файла
- ;
- curFilePos < _ini_nFileSize[nFilePointer];
- curFilePos++
- )
- _ini_szFileContent[nFilePointer]{ curFilePos + filePosOffset } =
- _ini_szFileContent[nFilePointer]{curFilePos};
- }
- else if ( filePosOffset > 0 ) // если длина нового значения больше
- {
- new fileValueEndPos = curFilePos;
- for // копируем символы, стоящие после текущего значения на их новые места,
- ( // начиная с конца файла
- curFilePos = _ini_nFileSize[nFilePointer] - 1;
- curFilePos >= fileValueEndPos;
- curFilePos--
- )
- _ini_szFileContent[nFilePointer]{ curFilePos + filePosOffset } =
- _ini_szFileContent[nFilePointer]{curFilePos};
- }
- // изменим позиции всех INI_DELIMITER, которые находились после текущего INI_DELIMITER
- for ( kPos++; kPos < _ini_nKeysCount[nFilePointer]; kPos++ )
- _ini_nDelimPos[nFilePointer][kPos] += filePosOffset;
- _ini_nFileSize[nFilePointer] += filePosOffset; // изменим размер файла
- _ini_szFileContent[nFilePointer]{ _ini_nFileSize[nFilePointer] } = 0; // конец строки для конца файла
- }
- curFilePos = fileValueStartPos; // текущ поз файла = поз начала старого значения
- for // запишем новое значение поверх старого
- (
- new valuePos = 0;
- valuePos < nValueLen;
- curFilePos++, valuePos++
- )
- _ini_szFileContent[nFilePointer]{curFilePos} = szKeyValue[valuePos];
- _ini_nFileChanged[nFilePointer] = 1; // флаг: файл изменен = 1
- _ini_nFileBusy[nFilePointer] = 0; // флаг: файл изменяется = 0
- return INI_OK;
- // ----------------
- }
- }
- // ----------------
- //
- // если указанный ключ НЕ НАЙДЕН в файле
- //
- // ----------------
- new szKeyValue[INI_INTEGER_SIZE]; // создадим строку для хранения целочисленного значения
- valstr( szKeyValue, nKeyValue, false ); // поместим строковое значение nKeyValue в szKeyValue
- // ----------------
- // ----------------
- new nValueLen = strlen(szKeyValue); // узнаем размер значения ключа
- // если будущий размер файла превышает лимит
- if ( ( _ini_nFileSize[nFilePointer] + 5 + nKeyLen + nValueLen ) >= INI_MAX_FILE_SIZE )
- return INI_TOO_LARGE_FILE; // вернем код ошибки о переполнении файла
- // ----------------
- // ----------------
- if ( _ini_nFileBusy[nFilePointer] != 0 ) // если прямо сейчас файл изменяется другой функцией
- return INI_WRITE_ERROR; // вернем код ошибки при записи в файл
- _ini_nFileBusy[nFilePointer] = 1; // флаг: файл изменяется = 1
- // ----------------
- // ----------------
- if // если последний символ файла не является разделителем строк
- (
- _ini_nFileSize[nFilePointer] > 0
- && _ini_szFileContent[nFilePointer]{ _ini_nFileSize[nFilePointer] - 1 } != INI_STRING_DELIMITER
- )
- {
- // вставим в конец файла перевод каретки и разделитель строк
- _ini_szFileContent[nFilePointer]{ _ini_nFileSize[nFilePointer] } = '\r';
- _ini_szFileContent[nFilePointer]{ _ini_nFileSize[nFilePointer] + 1 } = INI_STRING_DELIMITER;
- _ini_nFileSize[nFilePointer] += 2; // увеличим размер файла на 2
- }
- new curFilePos, strPos; // будут временным хранилищами позиций в файле/ключе/значении
- for // добавим посимвольно имя ключа в файл
- (
- curFilePos = _ini_nFileSize[nFilePointer], strPos = 0;
- strPos < nKeyLen;
- curFilePos++, strPos++
- )
- _ini_szFileContent[nFilePointer]{curFilePos} = szKeyName[strPos];
- _ini_szFileContent[nFilePointer]{ curFilePos++ } = ' '; // после ключа добавим пробел
- _ini_nDelimPos[nFilePointer][ _ini_nKeysCount[nFilePointer] ] = curFilePos; // добавим новую позицию INI_DELIMITER
- _ini_nKeysCount[nFilePointer]++; // кол-во ключей в файле +1
- _ini_szFileContent[nFilePointer]{ curFilePos++ } = INI_DELIMITER; // после пробела выше добавим INI_DELIMITER
- _ini_szFileContent[nFilePointer]{ curFilePos++ } = ' '; // после INI_DELIMITER добавим пробел
- // добавим посимвольно значение ключа в файл
- for ( strPos = 0; strPos < nValueLen; curFilePos++, strPos++ )
- _ini_szFileContent[nFilePointer]{curFilePos} = szKeyValue[strPos];
- _ini_szFileContent[nFilePointer]{curFilePos} = 0; // добавим символ конца строки
- _ini_nFileSize[nFilePointer] = curFilePos; // изменим размер файла
- _ini_nFileChanged[nFilePointer] = 1; // флаг: файл изменен = 1
- _ini_nFileBusy[nFilePointer] = 0; // флаг: файл изменяется = 0
- return INI_OK;
- // ----------------
- }
- /*
- Изменяет/добавляет в открытый INI файл указанный ключ и его дробное численное значение.
- ПОДРОБНЕЕ
- Парсер ищет в ОЗУ в контенте файла указанный ключ и изменяет его
- дробное значение на fKeyValue. Форматирование файла не меняется,
- если только указанное имя ключа не было найдено, тогда ключ и значение
- будут добавлены в конец файла.
- Имя ключа в файле может быть любой длины, а также может содержать
- любые символы, кроме 2 символов конца строки \r и \n. Если вы в качестве
- значения указываете очень большое/маленькое дробное число, вы должны
- хорошо знать и осознавать последствия.
- ПАРАМЕТРЫ:
- nFilePointer ИД_открытого_файла, полученный от ini_openFile / ini_createFile
- szKeyName[] имя ключа
- fKeyValue дробное численное значение ключа
- ВЕРНЕТ:
- код ошибки < 0 или 0 при успехе
- */
- stock ini_setFloat ( nFilePointer, szKeyName[], Float: fKeyValue )
- {
- // ----------------
- if // если ИД открытого файла указан неверно
- (
- nFilePointer < 0
- || nFilePointer >= INI_MAX_OPENED_FILES
- || _ini_nSlotUsed[nFilePointer] != 1
- )
- return INI_WRONG_SLOT; // вернуть код: неверный указатель на открытый файл
- // ----------------
- // ----------------
- new nKeyLen = strlen(szKeyName); // узнаем длину имени указанного ключа
- if ( nKeyLen <= 0 ) // если указан пустой ключ
- return INI_KEY_NOT_FOUND;
- // ----------------
- // ----------------
- for // перебор и сравнение всех ключей файла с указанным ключом
- (
- new kPos = 0, curFilePos, found;
- kPos < _ini_nKeysCount[nFilePointer];
- kPos++
- )
- {
- // ----------------
- found = 0; // флаг, найдена ли позиция конца ключа = 0
- for // ищем позицию конца ключа
- (
- curFilePos = _ini_nDelimPos[nFilePointer][kPos] - 1; // текущ. поз. файла = поз. текущ. INI_DELIMITER - 1
- curFilePos >= 0; // продолжать пока поз. файла >= 0
- curFilePos-- // после каждого повтора текущ. поз. файла -= 1
- )
- {
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} ) // узнаем что за символ в текущ. поз. файла
- {
- case INI_SPACE_CHAR : continue; // если это пробельный символ, перейдем к пред. символу файла
- case INI_STRING_DELIMITER : break; // если это конец строки
- default : // если это другой символ
- {
- found = 1; // позиция конца ключа найдена
- break; // конец цикла
- }
- }
- }
- // если позиция конца ключа не найдена, переход к след. позиции INI_DELIMITER
- if ( found != 1 ) continue;
- // ----------------
- // сравниваем посимвольно текущий ключ файла и указанный ключ
- for ( new curKeyPos = nKeyLen - 1; curKeyPos >= 0; curFilePos--, curKeyPos-- )
- {
- if
- (
- curFilePos < 0 // если поз файла стала < 0
- || _ini_szFileContent[nFilePointer]{curFilePos} != szKeyName[curKeyPos] // если символы из ключей не равны
- || _ini_szFileContent[nFilePointer]{curFilePos} == INI_STRING_DELIMITER // если символ из ключа это INI_STRING_DELIMITER
- )
- {
- found = 0; // флаг, ключ не найден
- break; // конец сравнения
- }
- }
- if ( found != 0 ) // если указанный ключ НАЙДЕН в файле
- {
- // ----------------
- // текущая позиция в файле будет на 1 больше текущей позиции INI_DELIMITER
- curFilePos = _ini_nDelimPos[nFilePointer][kPos] + 1;
- // ищем позицию начала значения, она будет помещена в curFilePos
- for ( ; ; curFilePos++ )
- {
- if ( curFilePos >= _ini_nFileSize[nFilePointer] ) break;
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} )
- {
- case INI_SPACE_CHAR : continue; // если это пробельный символ, перейдем к след. символу
- default : break; // если это другой символ
- }
- }
- // ----------------
- // ----------------
- new szKeyValue[INI_FLOAT_SIZE]; // создадим строку для хранения дробного значения
- format( szKeyValue, INI_FLOAT_SIZE, "%f", fKeyValue ); // поместим строковое значение fKeyValue в szKeyValue
- // ----------------
- // ----------------
- new nValueLen = strlen(szKeyValue); // узнаем размер значения указанного ключа
- // если будущий размер файла превышает лимит
- if ( ( curFilePos + nValueLen ) >= INI_MAX_FILE_SIZE )
- return INI_TOO_LARGE_FILE; // вернем код ошибки о переполнении файла
- // ----------------
- // ----------------
- new fileValueStartPos = curFilePos; // сохраним позицию начала значения
- // ищем позицию конца значения, она будет помещена в curFilePos
- for ( ; ; curFilePos++ )
- {
- if ( curFilePos >= _ini_nFileSize[nFilePointer] ) break;
- switch ( _ini_szFileContent[nFilePointer]{curFilePos} )
- {
- case INI_NUMBER_ENDS : break; // если это конец числа - стоп
- default : continue; // если это другой символ, перейдем к след. символу
- }
- }
- // вычислим смещение оставшихся позиций для INI_DELIMITER после изменения значения
- new filePosOffset = nValueLen - ( /*текущ длина значения*/ curFilePos - fileValueStartPos );
- // ----------------
- if ( _ini_nFileBusy[nFilePointer] != 0 ) // если прямо сейчас файл изменяется другой функцией
- return INI_WRITE_ERROR; // вернем код ошибки при записи в файл
- // ----------------
- _ini_nFileBusy[nFilePointer] = 1; // флаг: файл изменяется = 1
- if ( filePosOffset != 0 ) // если длины старого и нового значений разные
- {
- if ( filePosOffset < 0 ) // если длина нового значения меньше
- {
- for // копируем символы, стоящие после текущего значения на их новые места,
- ( // которые теперь будут ближе к началу файла
- ;
- curFilePos < _ini_nFileSize[nFilePointer];
- curFilePos++
- )
- _ini_szFileContent[nFilePointer]{ curFilePos + filePosOffset } =
- _ini_szFileContent[nFilePointer]{curFilePos};
- }
- else if ( filePosOffset > 0 ) // если длина нового значения больше
- {
- new fileValueEndPos = curFilePos;
- for // копируем символы, стоящие после текущего значения на их новые места,
- ( // начиная с конца файла
- curFilePos = _ini_nFileSize[nFilePointer] - 1;
- curFilePos >= fileValueEndPos;
- curFilePos--
- )
- _ini_szFileContent[nFilePointer]{ curFilePos + filePosOffset } =
- _ini_szFileContent[nFilePointer]{curFilePos};
- }
- // изменим позиции всех INI_DELIMITER, которые находились после текущего INI_DELIMITER
- for ( kPos++; kPos < _ini_nKeysCount[nFilePointer]; kPos++ )
- _ini_nDelimPos[nFilePointer][kPos] += filePosOffset;
- _ini_nFileSize[nFilePointer] += filePosOffset; // изменим размер файла
- _ini_szFileContent[nFilePointer]{ _ini_nFileSize[nFilePointer] } = 0; // конец строки для конца файла
- }
- curFilePos = fileValueStartPos; // текущ поз файла = поз начала старого значения
- for // запишем новое значение поверх старого
- (
- new valuePos = 0;
- valuePos < nValueLen;
- curFilePos++, valuePos++
- )
- _ini_szFileContent[nFilePointer]{curFilePos} = szKeyValue[valuePos];
- _ini_nFileChanged[nFilePointer] = 1; // флаг: файл изменен = 1
- _ini_nFileBusy[nFilePointer] = 0; // флаг: файл изменяется = 0
- return INI_OK;
- // ----------------
- }
- }
- // ----------------
- //
- // если указанный ключ НЕ НАЙДЕН в файле
- //
- // ----------------
- new szKeyValue[INI_FLOAT_SIZE]; // создадим строку для хранения дробного значения
- format( szKeyValue, INI_FLOAT_SIZE, "%f", fKeyValue ); // поместим строковое значение fKeyValue в szKeyValue
- // ----------------
- // ----------------
- new nValueLen = strlen(szKeyValue); // узнаем размер значения ключа
- // если будущий размер файла превышает лимит
- if ( ( _ini_nFileSize[nFilePointer] + 5 + nKeyLen + nValueLen ) >= INI_MAX_FILE_SIZE )
- return INI_TOO_LARGE_FILE; // вернем код ошибки о переполнении файла
- // ----------------
- // ----------------
- if ( _ini_nFileBusy[nFilePointer] != 0 ) // если прямо сейчас файл изменяется другой функцией
- return INI_WRITE_ERROR; // вернем код ошибки при записи в файл
- _ini_nFileBusy[nFilePointer] = 1; // флаг: файл изменяется = 1
- // ----------------
- // ----------------
- if // если последний символ файла не является разделителем строк
- (
- _ini_nFileSize[nFilePointer] > 0
- && _ini_szFileContent[nFilePointer]{ _ini_nFileSize[nFilePointer] - 1 } != INI_STRING_DELIMITER
- )
- {
- // вставим в конец файла перевод каретки и разделитель строк
- _ini_szFileContent[nFilePointer]{ _ini_nFileSize[nFilePointer] } = '\r';
- _ini_szFileContent[nFilePointer]{ _ini_nFileSize[nFilePointer] + 1 } = INI_STRING_DELIMITER;
- _ini_nFileSize[nFilePointer] += 2; // увеличим размер файла на 2
- }
- new curFilePos, strPos; // будут временным хранилищами позиций в файле/ключе/значении
- for // добавим посимвольно имя ключа в файл
- (
- curFilePos = _ini_nFileSize[nFilePointer], strPos = 0;
- strPos < nKeyLen;
- curFilePos++, strPos++
- )
- _ini_szFileContent[nFilePointer]{curFilePos} = szKeyName[strPos];
- _ini_szFileContent[nFilePointer]{ curFilePos++ } = ' '; // после ключа добавим пробел
- _ini_nDelimPos[nFilePointer][ _ini_nKeysCount[nFilePointer] ] = curFilePos; // добавим новую позицию INI_DELIMITER
- _ini_nKeysCount[nFilePointer]++; // кол-во ключей в файле +1
- _ini_szFileContent[nFilePointer]{ curFilePos++ } = INI_DELIMITER; // после пробела выше добавим INI_DELIMITER
- _ini_szFileContent[nFilePointer]{ curFilePos++ } = ' '; // после INI_DELIMITER добавим пробел
- // добавим посимвольно значение ключа в файл
- for ( strPos = 0; strPos < nValueLen; curFilePos++, strPos++ )
- _ini_szFileContent[nFilePointer]{curFilePos} = szKeyValue[strPos];
- _ini_szFileContent[nFilePointer]{curFilePos} = 0; // добавим символ конца строки
- _ini_nFileSize[nFilePointer] = curFilePos; // изменим размер файла
- _ini_nFileChanged[nFilePointer] = 1; // флаг: файл изменен = 1
- _ini_nFileBusy[nFilePointer] = 0; // флаг: файл изменяется = 0
- return INI_OK;
- // ----------------
- }
- //
- // Если вы хотите использовать другие имена функций в своем скрипте,
- // измените указанные ниже макросы замены на свои и раскомментируйте нужные строки
- //
- // ваше оригинал
- //
- //#define iniCreate ini_createFile
- //#define iniOpen ini_openFile
- //#define iniClose ini_closeFile
- //#define iniSet ini_setString
- //#define iniSetInt ini_setInteger
- //#define iniSetFloat ini_setFloat
- //#define iniGet ini_getString
- //#define iniGetInt ini_getInteger
- //#define iniGetFloat ini_getFloat
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement