| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284 |
- /*
- ** Command & Conquer Red Alert(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** 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/>.
- */
- /* $Header: /CounterStrike/INI.CPP 1 3/03/97 10:24a Joe_bostic $ */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : Command & Conquer *
- * *
- * File Name : INI.CPP *
- * *
- * Programmer : Joe L. Bostic *
- * *
- * Start Date : September 10, 1993 *
- * *
- * Last Update : November 2, 1996 [JLB] *
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * INIClass::Clear -- Clears out a section (or all sections) of the INI data. *
- * INIClass::Entry_Count -- Fetches the number of entries in a specified section. *
- * INIClass::Find_Entry -- Find specified entry within section. *
- * INIClass::Find_Section -- Find the specified section within the INI data. *
- * INIClass::Get_Bool -- Fetch a boolean value for the section and entry specified. *
- * INIClass::Get_Entry -- Get the entry identifier name given ordinal number and section name*
- * INIClass::Get_Fixed -- Fetch a fixed point number from the section & entry. *
- * INIClass::Put_Fixed -- Store a fixed point number to the INI database. *
- * INIClass::Get_Hex -- Fetches integer [hex format] from the section and entry specified. *
- * INIClass::Get_Int -- Fetch an integer entry from the specified section. *
- * INIClass::Get_PKey -- Fetch a key from the ini database. *
- * INIClass::Get_String -- Fetch the value of a particular entry in a specified section. *
- * INIClass::Get_TextBlock -- Fetch a block of normal text. *
- * INIClass::Get_UUBlock -- Fetch an encoded block from the section specified. *
- * INIClass::INISection::Find_Entry -- Finds a specified entry and returns pointer to it. *
- * INIClass::Load -- Load INI data from the file specified. *
- * INIClass::Load -- Load the INI data from the data stream (straw). *
- * INIClass::Put_Bool -- Store a boolean value into the INI database. *
- * INIClass::Put_Hex -- Store an integer into the INI database, but use a hex format. *
- * INIClass::Put_Int -- Stores a signed integer into the INI data base. *
- * INIClass::Put_PKey -- Stores the key to the INI database. *
- * INIClass::Put_String -- Output a string to the section and entry specified. *
- * INIClass::Put_TextBlock -- Stores a block of text into an INI section. *
- * INIClass::Put_UUBlock -- Store a binary encoded data block into the INI database. *
- * INIClass::Save -- Save the ini data to the file specified. *
- * INIClass::Save -- Saves the INI data to a pipe stream. *
- * INIClass::Section_Count -- Counts the number of sections in the INI data. *
- * INIClass::Strip_Comments -- Strips comments of the specified text line. *
- * INIClass::~INIClass -- Destructor for INI handler. *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include <string.h>
- #include <stdlib.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <ctype.h>
- #include "ini.h"
- #include "readline.h"
- #include "xpipe.h"
- #include "b64pipe.h"
- #include "xstraw.h"
- #include "b64straw.h"
- #ifdef FIXIT_FAST_LOAD
- #include "cstraw.h"
- #endif
- // Disable the "temporary object used to initialize a non-constant reference" warning.
- #pragma warning 665 9
- /***********************************************************************************************
- * INIClass::~INIClass -- Destructor for INI handler. *
- * *
- * This is the destructor for the INI class. It handles deleting all of the allocations *
- * it might have done. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- *=============================================================================================*/
- INIClass::~INIClass(void)
- {
- Clear();
- }
- /***********************************************************************************************
- * INIClass::Clear -- Clears out a section (or all sections) of the INI data. *
- * *
- * This routine is used to clear out the section specified. If no section is specified, *
- * then the entire INI data is cleared out. Optionally, this routine can be used to clear *
- * out just an individual entry in the specified section. *
- * *
- * INPUT: section -- Pointer to the section to clear out [pass NULL to clear all]. *
- * *
- * entry -- Pointer to optional entry specifier. If this parameter is specified, *
- * then only this specific entry (if found) will be cleared. Otherwise, *
- * the entire section specified will be cleared. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- * 08/21/1996 JLB : Optionally clears section too. *
- * 11/02/1996 JLB : Updates the index list. *
- *=============================================================================================*/
- bool INIClass::Clear(char const * section, char const * entry)
- {
- if (section == NULL) {
- SectionList.Delete();
- SectionIndex.Clear();
- } else {
- INISection * secptr = Find_Section(section);
- if (secptr != NULL) {
- if (entry != NULL) {
- INIEntry * entptr = secptr->Find_Entry(entry);
- if (entptr != NULL) {
- /*
- ** Remove the entry from the entry index list.
- */
- secptr->EntryIndex.Remove_Index(entptr->Index_ID());
- delete entptr;
- }
- } else {
- /*
- ** Remove this section index from the section index list.
- */
- SectionIndex.Remove_Index(secptr->Index_ID());
- delete secptr;
- }
- }
- }
- return(true);
- }
- /***********************************************************************************************
- * INIClass::Load -- Load INI data from the file specified. *
- * *
- * Use this routine to load the INI class with the data from the specified file. *
- * *
- * INPUT: file -- Reference to the file that will be used to fill up this INI manager. *
- * *
- * OUTPUT: bool; Was the file loaded successfully? *
- * *
- * WARNINGS: This routine allocates memory. *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- *=============================================================================================*/
- bool INIClass::Load(FileClass & file)
- {
- return(Load(FileStraw(file)));
- }
- /***********************************************************************************************
- * INIClass::Load -- Load the INI data from the data stream (straw). *
- * *
- * This will fetch data from the straw and build an INI database from it. *
- * *
- * INPUT: straw -- The straw that the data will be provided from. *
- * *
- * OUTPUT: bool; Was the database loaded ok? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/10/1996 JLB : Created. *
- *=============================================================================================*/
- #ifdef FIXIT_FAST_LOAD
- bool INIClass::Load(Straw & ffile)
- #else
- bool INIClass::Load(Straw & file)
- #endif
- {
- bool end_of_file = false;
- char buffer[MAX_LINE_LENGTH];
- #ifdef FIXIT_FAST_LOAD
- CacheStraw file;
- file.Get_From(ffile);
- #endif
- /*
- ** Prescan until the first section is found.
- */
- while (!end_of_file) {
- Read_Line(file, buffer, sizeof(buffer), end_of_file);
- if (end_of_file) return(false);
- if (buffer[0] == '[' && strchr(buffer, ']') != NULL) break;
- }
- /*
- ** Process a section. The buffer is prefilled with the section name line.
- */
- while (!end_of_file) {
- buffer[0] = ' ';
- char * ptr = strchr(buffer, ']');
- if (ptr) *ptr = '\0';
- strtrim(buffer);
- INISection * secptr = new INISection(strdup(buffer));
- if (secptr == NULL) {
- Clear();
- return(false);
- }
- /*
- ** Read in the entries of this section.
- */
- while (!end_of_file) {
- /*
- ** If this line is the start of another section, then bail out
- ** of the entry loop and let the outer section loop take
- ** care of it.
- */
- int len = Read_Line(file, buffer, sizeof(buffer), end_of_file);
- if (buffer[0] == '[' && strchr(buffer, ']') != NULL) break;
- /*
- ** Determine if this line is a comment or blank line. Throw it out if it is.
- */
- Strip_Comments(buffer);
- if (len == 0 || buffer[0] == ';' || buffer[0] == '=') continue;
- /*
- ** The line isn't an obvious comment. Make sure that there is the "=" character
- ** at an appropriate spot.
- */
- char * divider = strchr(buffer, '=');
- if (!divider) continue;
- /*
- ** Split the line into entry and value sections. Be sure to catch the
- ** "=foobar" and "foobar=" cases. These lines are ignored.
- */
- *divider++ = '\0';
- strtrim(buffer);
- if (!strlen(buffer)) continue;
- strtrim(divider);
- if (!strlen(divider)) continue;
- INIEntry * entryptr = new INIEntry(strdup(buffer), strdup(divider));
- if (entryptr == NULL) {
- delete secptr;
- Clear();
- return(false);
- }
- secptr->EntryIndex.Add_Index(entryptr->Index_ID(), entryptr);
- secptr->EntryList.Add_Tail(entryptr);
- }
- /*
- ** All the entries for this section have been parsed. If this section is blank, then
- ** don't bother storing it.
- */
- if (secptr->EntryList.Is_Empty()) {
- delete secptr;
- } else {
- SectionIndex.Add_Index(secptr->Index_ID(), secptr);
- SectionList.Add_Tail(secptr);
- }
- }
- return(true);
- }
- /***********************************************************************************************
- * INIClass::Save -- Save the ini data to the file specified. *
- * *
- * Use this routine to save the ini data to the file specified. All existing data in the *
- * file, if it was present, is replaced. *
- * *
- * INPUT: file -- Reference to the file to write the INI data to. *
- * *
- * OUTPUT: bool; Was the data written to the file? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- *=============================================================================================*/
- int INIClass::Save(FileClass & file) const
- {
- return(Save(FilePipe(file)));
- }
- /***********************************************************************************************
- * INIClass::Save -- Saves the INI data to a pipe stream. *
- * *
- * This routine will output the data of the INI file to a pipe stream. *
- * *
- * INPUT: pipe -- Reference to the pipe stream to pump the INI image to. *
- * *
- * OUTPUT: Returns with the number of bytes output to the pipe. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- *=============================================================================================*/
- int INIClass::Save(Pipe & pipe) const
- {
- int total = 0;
- INISection * secptr = SectionList.First();
- while (secptr && secptr->Is_Valid()) {
- /*
- ** Output the section identifier.
- */
- total += pipe.Put("[", 1);
- total += pipe.Put(secptr->Section, strlen(secptr->Section));
- total += pipe.Put("]", 1);
- total += pipe.Put("\r\n", strlen("\r\n"));
- /*
- ** Output all the entries and values in this section.
- */
- INIEntry * entryptr = secptr->EntryList.First();
- while (entryptr && entryptr->Is_Valid()) {
- total += pipe.Put(entryptr->Entry, strlen(entryptr->Entry));
- total += pipe.Put("=", 1);
- total += pipe.Put(entryptr->Value, strlen(entryptr->Value));
- total += pipe.Put("\r\n", strlen("\r\n"));
- entryptr = entryptr->Next();
- }
- /*
- ** After the last entry in this section, output an extra
- ** blank line for readability purposes.
- */
- total += pipe.Put("\r\n", strlen("\r\n"));
- secptr = secptr->Next();
- }
- total += pipe.End();
- return(total);
- }
- /***********************************************************************************************
- * INIClass::Find_Section -- Find the specified section within the INI data. *
- * *
- * This routine will scan through the INI data looking for the section specified. If the *
- * section could be found, then a pointer to the section control data is returned. *
- * *
- * INPUT: section -- The name of the section to search for. Don't enclose the name in *
- * brackets. Case is NOT sensitive in the search. *
- * *
- * OUTPUT: Returns with a pointer to the INI section control structure if the section was *
- * found. Otherwise, NULL is returned. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- * 11/02/1996 JLB : Uses index manager. *
- *=============================================================================================*/
- INIClass::INISection * INIClass::Find_Section(char const * section) const
- {
- if (section != NULL) {
- long crc = CRCEngine()(section, strlen(section));
- if (SectionIndex.Is_Present(crc)) {
- return(SectionIndex.Fetch_Index(crc));
- }
- }
- return(NULL);
- }
- /***********************************************************************************************
- * INIClass::Section_Count -- Counts the number of sections in the INI data. *
- * *
- * This routine will scan through all the sections in the INI data and return a count *
- * of the number it found. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: Returns with the number of sections recorded in the INI data. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- * 11/02/1996 JLB : Uses index manager. *
- *=============================================================================================*/
- int INIClass::Section_Count(void) const
- {
- return(SectionIndex.Count());
- }
- /***********************************************************************************************
- * INIClass::Entry_Count -- Fetches the number of entries in a specified section. *
- * *
- * This routine will examine the section specified and return with the number of entries *
- * associated with it. *
- * *
- * INPUT: section -- Pointer to the section that will be examined. *
- * *
- * OUTPUT: Returns with the number entries in the specified section. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- * 11/02/1996 JLB : Uses index manager. *
- *=============================================================================================*/
- int INIClass::Entry_Count(char const * section) const
- {
- INISection * secptr = Find_Section(section);
- if (secptr != NULL) {
- return(secptr->EntryIndex.Count());
- }
- return(0);
- }
- /***********************************************************************************************
- * INIClass::Find_Entry -- Find specified entry within section. *
- * *
- * This support routine will find the specified entry in the specified section. If found, *
- * a pointer to the entry control structure will be returned. *
- * *
- * INPUT: section -- Pointer to the section name to search under. *
- * *
- * entry -- Pointer to the entry name to search for. *
- * *
- * OUTPUT: If the entry was found, then a pointer to the entry control structure will be *
- * returned. Otherwise, NULL will be returned. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- *=============================================================================================*/
- INIClass::INIEntry * INIClass::Find_Entry(char const * section, char const * entry) const
- {
- INISection * secptr = Find_Section(section);
- if (secptr != NULL) {
- return(secptr->Find_Entry(entry));
- }
- return(NULL);
- }
- /***********************************************************************************************
- * INIClass::Get_Entry -- Get the entry identifier name given ordinal number and section name. *
- * *
- * This will return the identifier name for the entry under the section specified. The *
- * ordinal number specified is used to determine which entry to retrieve. The entry *
- * identifier is the text that appears to the left of the "=" character. *
- * *
- * INPUT: section -- The section to use. *
- * *
- * index -- The ordinal number to use when fetching an entry name. *
- * *
- * OUTPUT: Returns with a pointer to the entry name. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- *=============================================================================================*/
- char const * INIClass::Get_Entry(char const * section, int index) const
- {
- INISection * secptr = Find_Section(section);
- if (secptr != NULL && index < secptr->EntryIndex.Count()) {
- INIEntry * entryptr = secptr->EntryList.First();
- while (entryptr != NULL && entryptr->Is_Valid()) {
- if (index == 0) return(entryptr->Entry);
- index--;
- entryptr = entryptr->Next();
- }
- }
- return(NULL);
- }
- /***********************************************************************************************
- * INIClass::Put_UUBlock -- Store a binary encoded data block into the INI database. *
- * *
- * Use this routine to store an arbitrary length binary block of data into the INI database.*
- * This routine will covert the data into displayable form and then break it into lines *
- * that are stored in sequence to the section. A section used to store data in this *
- * fashion can not be used for any other entries. *
- * *
- * INPUT: section -- The section identifier to place the data into. *
- * *
- * block -- Pointer to the block of binary data to store. *
- * *
- * len -- The length of the binary data. *
- * *
- * OUTPUT: bool; Was the data stored to the database? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/03/1996 JLB : Created. *
- *=============================================================================================*/
- bool INIClass::Put_UUBlock(char const * section, void const * block, int len)
- {
- if (section == NULL || block == NULL || len < 1) return(false);
- Clear(section);
- BufferStraw straw(block, len);
- Base64Straw bstraw(Base64Straw::ENCODE);
- bstraw.Get_From(straw);
- int counter = 1;
- for (;;) {
- char buffer[71];
- char sbuffer[32];
- int length = bstraw.Get(buffer, sizeof(buffer)-1);
- buffer[length] = '\0';
- if (length == 0) break;
- sprintf(sbuffer, "%d", counter);
- Put_String(section, sbuffer, buffer);
- counter++;
- }
- return(true);
- }
- /***********************************************************************************************
- * INIClass::Get_UUBlock -- Fetch an encoded block from the section specified. *
- * *
- * This routine will take all the entries in the specified section and decompose them into *
- * a binary block of data that will be stored into the buffer specified. By using this *
- * routine [and the Put_UUBLock counterpart], arbitrary blocks of binary data may be *
- * stored in the INI file. A section processed by this routine can contain no other *
- * entries than those put there by a previous call to Put_UUBlock. *
- * *
- * INPUT: section -- The section name to process. *
- * *
- * block -- Pointer to the buffer that will hold the retrieved data. *
- * *
- * len -- The length of the buffer. The retrieved data will not fill past this *
- * limit. *
- * *
- * OUTPUT: Returns with the number of bytes decoded into the buffer specified. *
- * *
- * WARNINGS: If the number of bytes retrieved exactly matches the length of the buffer *
- * specified, then you might have a condition of buffer "overflow". *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- *=============================================================================================*/
- int INIClass::Get_UUBlock(char const * section, void * block, int len) const
- {
- if (section == NULL) return(0);
- Base64Pipe b64pipe(Base64Pipe::DECODE);
- BufferPipe bpipe(block, len);
- b64pipe.Put_To(&bpipe);
- int total = 0;
- int counter = Entry_Count(section);
- for (int index = 0; index < counter; index++) {
- char buffer[128];
- int length = Get_String(section, Get_Entry(section, index), "=", buffer, sizeof(buffer));
- int outcount = b64pipe.Put(buffer, length);
- total += outcount;
- }
- total += b64pipe.End();
- return(total);
- }
- /***********************************************************************************************
- * INIClass::Put_TextBlock -- Stores a block of text into an INI section. *
- * *
- * This routine will take an arbitrarily long block of text and store it into the INI *
- * database. The text is broken up into lines and each line is then stored as a numbered *
- * entry in the specified section. A section used to store text in this way can not be used *
- * to hold any other entries. The text is presumed to contain space characters scattered *
- * throughout it and that one space between words and sentences is natural. *
- * *
- * INPUT: section -- The section to place the text block into. *
- * *
- * text -- Pointer to a null terminated text string that holds the block of *
- * text. The length can be arbitrary. *
- * *
- * OUTPUT: bool; Was the text block placed into the database? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/03/1996 JLB : Created. *
- *=============================================================================================*/
- bool INIClass::Put_TextBlock(char const * section, char const * text)
- {
- if (section == NULL) return(false);
- Clear(section);
- int index = 1;
- while (text != NULL && *text != NULL) {
- char buffer[128];
- strncpy(buffer, text, 75);
- buffer[75] = '\0';
- char b[32];
- sprintf(b, "%d", index);
- /*
- ** Scan backward looking for a good break position.
- */
- int count = strlen(buffer);
- if (count > 0) {
- if (count >= 75) {
- while (count) {
- char c = buffer[count];
- if (isspace(c)) break;
- count--;
- }
- if (count == 0) {
- break;
- } else {
- buffer[count] = '\0';
- }
- }
- strtrim(buffer);
- Put_String(section, b, buffer);
- index++;
- text = ((char *)text) + count;
- } else {
- break;
- }
- }
- return(true);
- }
- /***********************************************************************************************
- * INIClass::Get_TextBlock -- Fetch a block of normal text. *
- * *
- * This will take all entries in the specified section and format them into a block of *
- * normalized text. That is, text with single spaces between each concatenated line. All *
- * entries in the specified section are processed by this routine. Use Put_TextBlock to *
- * build the entries in the section. *
- * *
- * INPUT: section -- The section name to process. *
- * *
- * buffer -- Pointer to the buffer that will hold the complete text. *
- * *
- * len -- The length of the buffer specified. The text will, at most, fill this *
- * buffer with the last character being forced to null. *
- * *
- * OUTPUT: Returns with the number of characters placed into the buffer. The trailing null *
- * is not counted. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- *=============================================================================================*/
- int INIClass::Get_TextBlock(char const * section, char * buffer, int len) const
- {
- if (len <= 0) return(0);
- buffer[0] = '\0';
- if (len <= 1) return(0);
- int elen = Entry_Count(section);
- int total = 0;
- for (int index = 0; index < elen; index++) {
- /*
- ** Add spacers between lines of fetched text.
- */
- if (index > 0) {
- *buffer++ = ' ';
- len--;
- total++;
- }
- Get_String(section, Get_Entry(section, index), "", buffer, len);
- int partial = strlen(buffer);
- total += partial;
- buffer += partial;
- len -= partial;
- if (len <= 1) break;
- }
- return(total);
- }
- /***********************************************************************************************
- * INIClass::Put_Int -- Stores a signed integer into the INI data base. *
- * *
- * Use this routine to store an integer value into the section and entry specified. *
- * *
- * INPUT: section -- The identifier for the section that the entry will be placed in. *
- * *
- * entry -- The entry identifier used for the integer number. *
- * *
- * number -- The integer number to store in the database. *
- * *
- * format -- The format to store the integer. The format is generally only a *
- * cosmetic affect. The Get_Int operation will interpret the value the *
- * same regardless of what format was used to store the integer. *
- * *
- * 0 : plain decimal digit *
- * 1 : hexadecimal digit (trailing "h") *
- * 2 : hexadecimal digit (leading "$") *
- * *
- * OUTPUT: bool; Was the number stored? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/03/1996 JLB : Created. *
- * 07/10/1996 JLB : Handles multiple integer formats. *
- *=============================================================================================*/
- bool INIClass::Put_Int(char const * section, char const * entry, int number, int format)
- {
- char buffer[MAX_LINE_LENGTH];
- switch (format) {
- default:
- case 0:
- sprintf(buffer, "%d", number);
- break;
- case 1:
- sprintf(buffer, "%Xh", number);
- break;
- case 2:
- sprintf(buffer, "$%X", number);
- break;
- }
- return(Put_String(section, entry, buffer));
- }
- /***********************************************************************************************
- * INIClass::Get_Int -- Fetch an integer entry from the specified section. *
- * *
- * This routine will fetch an integer value from the entry and section specified. If no *
- * entry could be found, then the default value will be returned instead. *
- * *
- * INPUT: section -- The section name to search under. *
- * *
- * entry -- The entry name to search for. *
- * *
- * defvalue -- The default value to use if the specified entry could not be found. *
- * *
- * OUTPUT: Returns with the integer value specified in the INI database or else returns the *
- * default value. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- * 07/10/1996 JLB : Handles multiple integer formats. *
- *=============================================================================================*/
- int INIClass::Get_Int(char const * section, char const * entry, int defvalue) const
- {
- /*
- ** Verify that the parameters are nominally correct.
- */
- if (section == NULL || entry == NULL) return(defvalue);
- INIEntry * entryptr = Find_Entry(section, entry);
- if (entryptr && entryptr->Value != NULL) {
- if (*entryptr->Value == '$') {
- sscanf(entryptr->Value, "$%x", &defvalue);
- } else {
- if (tolower(entryptr->Value[strlen(entryptr->Value)-1]) == 'h') {
- sscanf(entryptr->Value, "%xh", &defvalue);
- } else {
- defvalue = atoi(entryptr->Value);
- }
- }
- }
- return(defvalue);
- }
- /***********************************************************************************************
- * INIClass::Put_Hex -- Store an integer into the INI database, but use a hex format. *
- * *
- * This routine is similar to the Put_Int routine, but the number is stored as a hexadecimal*
- * number. *
- * *
- * INPUT: section -- The identifier for the section that the entry will be placed in. *
- * *
- * entry -- The entry identifier to tag to the integer number specified. *
- * *
- * number -- The number to assign the the specified entry and placed in the *
- * specified section. *
- * *
- * OUTPUT: bool; Was the number placed into the INI database? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/03/1996 JLB : Created. *
- *=============================================================================================*/
- bool INIClass::Put_Hex(char const * section, char const * entry, int number)
- {
- char buffer[MAX_LINE_LENGTH];
- sprintf(buffer, "%X", number);
- return(Put_String(section, entry, buffer));
- }
- /***********************************************************************************************
- * INIClass::Get_Hex -- Fetches integer [hex format] from the section and entry specified. *
- * *
- * This routine will search under the section specified, looking for a matching entry. The *
- * value is interpreted as a hexadecimal number and then returned. If no entry could be *
- * found, then the default value is returned instead. *
- * *
- * INPUT: section -- The section identifier to search under. *
- * *
- * entry -- The entry identifier to search for. *
- * *
- * defvalue -- The default value to use if the entry could not be located. *
- * *
- * OUTPUT: Returns with the integer value from the specified section and entry. If no entry *
- * could be found, then the default value will be returned instead. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- *=============================================================================================*/
- int INIClass::Get_Hex(char const * section, char const * entry, int defvalue) const
- {
- /*
- ** Verify that the parameters are nominally correct.
- */
- if (section == NULL || entry == NULL) return(defvalue);
- INIEntry * entryptr = Find_Entry(section, entry);
- if (entryptr && entryptr->Value != NULL) {
- sscanf(entryptr->Value, "%x", &defvalue);
- }
- return(defvalue);
- }
- /***********************************************************************************************
- * INIClass::Put_String -- Output a string to the section and entry specified. *
- * *
- * This routine will put an arbitrary string to the section and entry specified. Any *
- * previous matching entry will be replaced. *
- * *
- * INPUT: section -- The section identifier to place the string under. *
- * *
- * entry -- The entry identifier to identify this string [placed under the section]*
- * *
- * string -- Pointer to the string to assign to this entry. *
- * *
- * OUTPUT: bool; Was the entry assigned without error? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- * 11/02/1996 JLB : Uses index handler. *
- *=============================================================================================*/
- bool INIClass::Put_String(char const * section, char const * entry, char const * string)
- {
- if (section == NULL || entry == NULL) return(false);
- INISection * secptr = Find_Section(section);
- if (secptr == NULL) {
- secptr = new INISection(strdup(section));
- if (secptr == NULL) return(false);
- SectionList.Add_Tail(secptr);
- SectionIndex.Add_Index(secptr->Index_ID(), secptr);
- }
- /*
- ** Remove the old entry if found.
- */
- INIEntry * entryptr = secptr->Find_Entry(entry);
- if (entryptr != NULL) {
- secptr->EntryIndex.Remove_Index(entryptr->Index_ID());
- delete entryptr;
- }
- /*
- ** Create and add the new entry.
- */
- if (string != NULL && strlen(string) > 0) {
- entryptr = new INIEntry(strdup(entry), strdup(string));
- if (entryptr == NULL) {
- return(false);
- }
- secptr->EntryList.Add_Tail(entryptr);
- secptr->EntryIndex.Add_Index(entryptr->Index_ID(), entryptr);
- }
- return(true);
- }
- /***********************************************************************************************
- * INIClass::Get_String -- Fetch the value of a particular entry in a specified section. *
- * *
- * This will retrieve the entire text to the right of the "=" character. The text is *
- * found by finding a matching entry in the section specified. If no matching entry could *
- * be found, then the default value will be stored in the output string buffer. *
- * *
- * INPUT: section -- Pointer to the section name to search under. *
- * *
- * entry -- The entry identifier to search for. *
- * *
- * defvalue -- If no entry could be found, then this text will be returned. *
- * *
- * buffer -- Output buffer to store the retrieved string into. *
- * *
- * size -- The size of the output buffer. The maximum string length that could *
- * be retrieved will be one less than this length. This is due to the *
- * forced trailing zero added to the end of the string. *
- * *
- * OUTPUT: Returns with the length of the string retrieved. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- *=============================================================================================*/
- int INIClass::Get_String(char const * section, char const * entry, char const * defvalue, char * buffer, int size) const
- {
- /*
- ** Verify that the parameters are nominally legal.
- */
- if (buffer != NULL && size > 0) {
- buffer[0] = '\0';
- }
- if (buffer == NULL || !size || section == NULL || entry == NULL) return(0);
- /*
- ** Fetch the entry string if it is present. If not, then the normal default
- ** value will be used as the entry value.
- */
- INIEntry * entryptr = Find_Entry(section, entry);
- if (entryptr) {
- if (entryptr->Value) {
- defvalue = entryptr->Value;
- }
- }
- /*
- ** Fill in the buffer with the entry value and return with the length of the string.
- */
- if (defvalue == NULL) {
- buffer[0] = '\0';
- return(0);
- } else {
- strncpy(buffer, defvalue, size);
- buffer[size-1] = '\0';
- strtrim(buffer);
- return(strlen(buffer));
- }
- }
- /***********************************************************************************************
- * INIClass::Put_Bool -- Store a boolean value into the INI database. *
- * *
- * Use this routine to place a boolean value into the INI database. The boolean value will *
- * be stored as "yes" or "no". *
- * *
- * INPUT: section -- The section to place the entry and boolean value into. *
- * *
- * entry -- The entry identifier to tag to the boolean value. *
- * *
- * value -- The boolean value to place into the database. *
- * *
- * OUTPUT: bool; Was the boolean value placed into the database? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/03/1996 JLB : Created. *
- *=============================================================================================*/
- bool INIClass::Put_Bool(char const * section, char const * entry, bool value)
- {
- if (value) {
- return(Put_String(section, entry, "yes"));
- } else {
- return(Put_String(section, entry, "no"));
- }
- }
- /***********************************************************************************************
- * INIClass::Get_Bool -- Fetch a boolean value for the section and entry specified. *
- * *
- * This routine will search under the section specified, looking for a matching entry. If *
- * one is found, the value is interpreted as a boolean value and then returned. In the case *
- * of no matching entry, the default value will be returned instead. The boolean value *
- * is interpreted using the standard boolean conventions. e.g., "Yes", "Y", "1", "True", *
- * "T" are all consider to be a TRUE boolean value. *
- * *
- * INPUT: section -- The section to search under. *
- * *
- * entry -- The entry to search for. *
- * *
- * defvalue -- The default value to use if no matching entry could be located. *
- * *
- * OUTPUT: Returns with the boolean value of the specified section and entry. If no match *
- * then the default boolean value is returned. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/02/1996 JLB : Created. *
- *=============================================================================================*/
- bool INIClass::Get_Bool(char const * section, char const * entry, bool defvalue) const
- {
- /*
- ** Verify that the parameters are nominally correct.
- */
- if (section == NULL || entry == NULL) return(defvalue);
- INIEntry * entryptr = Find_Entry(section, entry);
- if (entryptr && entryptr->Value != NULL) {
- switch (toupper(*entryptr->Value)) {
- case 'Y':
- case 'T':
- case '1':
- return(true);
- case 'N':
- case 'F':
- case '0':
- return(false);
- }
- }
- return(defvalue);
- }
- /***********************************************************************************************
- * INIClass::INISection::Find_Entry -- Finds a specified entry and returns pointer to it. *
- * *
- * This routine scans the supplied entry for the section specified. This is used for *
- * internal database maintenance. *
- * *
- * INPUT: entry -- The entry to scan for. *
- * *
- * OUTPUT: Returns with a pointer to the entry control structure if the entry was found. *
- * Otherwise it returns NULL. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/03/1996 JLB : Created. *
- * 11/02/1996 JLB : Uses index handler. *
- *=============================================================================================*/
- INIClass::INIEntry * INIClass::INISection::Find_Entry(char const * entry) const
- {
- if (entry != NULL) {
- int crc = CRCEngine()(entry, strlen(entry));
- if (EntryIndex.Is_Present(crc)) {
- return(EntryIndex.Fetch_Index(crc));
- }
- }
- return(NULL);
- }
- /***********************************************************************************************
- * INIClass::Put_PKey -- Stores the key to the INI database. *
- * *
- * The key stored to the database will have both the exponent and modulus portions saved. *
- * Since the fast key only requires the modulus, it is only necessary to save the slow *
- * key to the database. However, storing the slow key stores the information necessary to *
- * generate the fast and slow keys. Because public key encryption requires one key to be *
- * completely secure, only store the fast key in situations where the INI database will *
- * be made public. *
- * *
- * INPUT: key -- The key to store the INI database. *
- * *
- * OUTPUT: bool; Was the key stored to the database? *
- * *
- * WARNINGS: Store the fast key for public INI database availability. Store the slow key if *
- * the INI database is secure. *
- * *
- * HISTORY: *
- * 07/08/1996 JLB : Created. *
- *=============================================================================================*/
- bool INIClass::Put_PKey(PKey const & key)
- {
- char buffer[512];
- int len = key.Encode_Modulus(buffer);
- Put_UUBlock("PublicKey", buffer, len);
- len = key.Encode_Exponent(buffer);
- Put_UUBlock("PrivateKey", buffer, len);
- return(true);
- }
- /***********************************************************************************************
- * INIClass::Get_PKey -- Fetch a key from the ini database. *
- * *
- * This routine will fetch the key from the INI database. The key fetched is controlled by *
- * the parameter. There are two choices of key -- the fast or slow key. *
- * *
- * INPUT: fast -- Should the fast key be retrieved? The fast key has the advantage of *
- * requiring only the modulus value. *
- * *
- * OUTPUT: Returns with the key retrieved. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/08/1996 JLB : Created. *
- *=============================================================================================*/
- PKey INIClass::Get_PKey(bool fast) const
- {
- PKey key;
- char buffer[512];
- /*
- ** When retrieving the fast key, the exponent is a known constant. Don't parse the
- ** exponent from the database.
- */
- if (fast) {
- BigInt exp = PKey::Fast_Exponent();
- exp.DEREncode((unsigned char *)buffer);
- key.Decode_Exponent(buffer);
- } else {
- Get_UUBlock("PrivateKey", buffer, sizeof(buffer));
- key.Decode_Exponent(buffer);
- }
- Get_UUBlock("PublicKey", buffer, sizeof(buffer));
- key.Decode_Modulus(buffer);
- return(key);
- }
- /***********************************************************************************************
- * INIClass::Get_Fixed -- Fetch a fixed point number from the section & entry. *
- * *
- * This routine will examine the section and entry specified and interpret the value *
- * as if it were a fixed point number. The format of the fixed point number can be *
- * percentage (e.g. 100%) or a floating point number (e.g., 1.7). *
- * *
- * INPUT: section -- Pointer to the section identifier to look under. *
- * *
- * entry -- Pointer to the entry identifier to examine. *
- * *
- * defvalue -- If the section and entry could not be found, then this value will *
- * be returned. *
- * *
- * OUTPUT: Returns with the fixed point number that occurs at the section and entry *
- * specified. If it could not be found, then the default value is returned. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/03/1996 JLB : Created. *
- *=============================================================================================*/
- fixed INIClass::Get_Fixed(char const * section, char const * entry, fixed defvalue) const
- {
- char buffer[128];
- fixed retval = defvalue;
- if (Get_String(section, entry, "", buffer, sizeof(buffer))) {
- retval = fixed(buffer);
- }
- return(retval);
- }
- /***********************************************************************************************
- * INIClass::Put_Fixed -- Store a fixed point number to the INI database. *
- * *
- * Use this routine to output a fixed point number to the database. The entry will be *
- * placed in the section and entry specified. If there was any existing entry, it will *
- * be replaced. *
- * *
- * INPUT: section -- Pointer to the section identifier. *
- * *
- * entry -- Pointer to the entry identifier to use for this value. *
- * *
- * value -- The value to store in the database. *
- * *
- * OUTPUT: bool; Was the data stored? *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/03/1996 JLB : Created. *
- *=============================================================================================*/
- bool INIClass::Put_Fixed(char const * section, char const * entry, fixed value)
- {
- return(Put_String(section, entry, value.As_ASCII()));
- }
- /***********************************************************************************************
- * INIClass::Strip_Comments -- Strips comments of the specified text line. *
- * *
- * This routine will scan the string (text line) supplied and if any comment portions are *
- * found, they will be trimmed off. Leading and trailing blanks are also removed. *
- * *
- * INPUT: buffer -- Pointer to the null terminate string to be processed. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/03/1996 JLB : Created. *
- *=============================================================================================*/
- void INIClass::Strip_Comments(char * buffer)
- {
- if (buffer != NULL) {
- char * comment = strchr(buffer, ';');
- if (comment) {
- *comment = '\0';
- strtrim(buffer);
- }
- }
- }
|