CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

PROFILE.CPP (29170B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /* $Header: /CounterStrike/PROFILE.CPP 1     3/03/97 10:25a Joe_bostic $ */
     17 /***********************************************************************************************
     18  ***              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               ***
     19  ***********************************************************************************************
     20  *                                                                                             *
     21  *                 Project Name : Command & Conquer                                            *
     22  *                                                                                             *
     23  *                    File Name : PROFILE.CPP                                                  *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : September 10, 1993                                           *
     28  *                                                                                             *
     29  *                  Last Update : September 10, 1993   [JLB]                                   *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   WWGetPrivateProfileInt -- Fetches integer value from INI.                                 *
     34  *   WWGetPrivateProfileString -- Fetch string from INI.                                       *
     35  *   WWWritePrivateProfileInt -- Write a profile int to the profile data block.                *
     36  *   WWWritePrivateProfileString -- Write a string to the profile data block.                  *
     37  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     38 
     39 #include	"function.h"
     40 
     41 
     42 static char * WriteBinBuffer = NULL;
     43 static int WriteBinBufferLen = 0;
     44 static int WriteBinBufferPos = 0;
     45 static int WriteBinBufferMax = 0;
     46 static char * ReadBinBuffer = NULL;
     47 static int ReadBinBufferLen = 0;
     48 static int ReadBinBufferPos = 0;
     49 static int ReadBinBufferMax = 0;
     50 
     51 
     52 /***************************************************************************
     53  * Read_Private_Config_Struct -- Fetches override integer value.           *
     54  *                                                                         *
     55  * INPUT:                                                                  *
     56  * OUTPUT:                                                                 *
     57  * WARNINGS:                                                               *
     58  * HISTORY:                                                                *
     59  *   08/05/1992 JLB : Created.                                             *
     60  *=========================================================================*/
     61 bool Read_Private_Config_Struct(FileClass & file, NewConfigType * config)
     62 {
     63 	INIClass ini;
     64 	ini.Load(file);
     65 
     66 	config->DigitCard 	= ini.Get_Hex("Sound", "Card", 0);
     67 	config->IRQ 			= ini.Get_Int("Sound", "IRQ", 0);
     68 	config->DMA 			= ini.Get_Int("Sound", "DMA", 0);
     69 	config->Port 			= ini.Get_Hex("Sound", "Port", 0);
     70 	config->BitsPerSample= ini.Get_Int("Sound", "BitsPerSample", 0);
     71 	config->Channels 		= ini.Get_Int("Sound", "Channels", 0);
     72 	config->Reverse      = ini.Get_Int("Sound", "Reverse", 0);
     73 	config->Speed        = ini.Get_Int("Sound", "Speed", 0);
     74 	ini.Get_String("Language", "Language", NULL, config->Language, sizeof(config->Language));
     75 
     76 
     77 //	config->DigitCard 	= WWGetPrivateProfileHex("Sound", "Card", 			 profile);
     78 //	config->IRQ 			= WWGetPrivateProfileInt("Sound", "IRQ", 			 0,profile);
     79 //	config->DMA 			= WWGetPrivateProfileInt("Sound", "DMA", 			 0,profile);
     80 //	config->Port 			= WWGetPrivateProfileHex("Sound", "Port", 			 profile);
     81 //	config->BitsPerSample= WWGetPrivateProfileInt("Sound", "BitsPerSample",0,profile);
     82 //	config->Channels 		= WWGetPrivateProfileInt("Sound", "Channels",		 0,profile);
     83 //	config->Reverse      = WWGetPrivateProfileInt("Sound", "Reverse", 		 0,profile);
     84 //	config->Speed        = WWGetPrivateProfileInt("Sound", "Speed", 		 0,profile);
     85 //	WWGetPrivateProfileString("Language", "Language", NULL, config->Language, 3, profile);
     86 
     87 	return((config->DigitCard == 0) && (config->IRQ == 0) && (config->DMA == 0));
     88 }
     89 
     90 
     91 /***************************************************************************
     92  * Get_Private_Profile_Hex -- Fetches override integer value.              *
     93  *                                                                         *
     94  * INPUT:                                                                  *
     95  * OUTPUT:                                                                 *
     96  * WARNINGS:                                                               *
     97  * HISTORY:                                                                *
     98  *   08/05/1992 MML : Created.                                             *
     99  *=========================================================================*/
    100 unsigned WWGetPrivateProfileHex (char const * section, char const * entry, char * profile)
    101 {
    102 	char	buffer[16];					// Integer staging buffer.
    103 	unsigned card;
    104 
    105 	memset (buffer, '0', sizeof(buffer));		// MAX_ENTRY_SIZE = 15
    106 	buffer[sizeof(buffer)-1] = '\0';
    107 
    108 	WWGetPrivateProfileString(section, entry, "0", buffer, sizeof(buffer), profile);
    109 
    110 	if (strlen (buffer) > 0) {
    111 		sscanf (buffer, "%x", &card);
    112 	} else {
    113 		card = 0;
    114 	}
    115 
    116 	return(card);
    117 }
    118 
    119 
    120 /***********************************************************************************************
    121  * WWGetPrivateProfileInt -- Fetches integer value.                                            *
    122  *                                                                                             *
    123  * INPUT:                                                                                      *
    124  *      section      section to read from                                                      *
    125  *                                                                                             *
    126  *      entry         name of entry to read                                                    *
    127  *                                                                                             *
    128  *      def         default value, if entry isn't found                                        *
    129  *                                                                                             *
    130  *      profile      buffer containing INI data                                                *
    131  *                                                                                             *
    132  * OUTPUT:                                                                                     *
    133  *      integer requested                                                                      *
    134  *                                                                                             *
    135  * WARNINGS:                                                                                   *
    136  *      none.                                                                                  *
    137  *                                                                                             *
    138  * HISTORY:                                                                                    *
    139  *   08/05/1992 JLB : Created.                                                                 *
    140  *=============================================================================================*/
    141 int WWGetPrivateProfileInt(char const * section, char const * entry, int def, char * profile)
    142 {
    143 	char	buffer[16];			// Integer staging buffer.
    144 
    145 	/*
    146 	**	Store the default in the buffer.
    147 	*/
    148 	sprintf(buffer, "%d", def);
    149 
    150 	/*
    151 	**	Get the buffer; use itself as the default.
    152 	*/
    153 	WWGetPrivateProfileString(section, entry, buffer, buffer, sizeof(buffer)-1, profile);
    154 
    155 	/*
    156 	**	Convert to int & return.
    157 	*/
    158 	return(atoi(buffer));
    159 }
    160 
    161 
    162 /***********************************************************************************************
    163  * WWWritePrivateProfileInt -- Write a profile int to the profile data block.                  *
    164  *                                                                                             *
    165  * INPUT:                                                                                      *
    166  *      section      section name to write to                                                  *
    167  *                                                                                             *
    168  *      entry         name of entry to write; if NULL, the entire section is deleted           *
    169  *                                                                                             *
    170  *      value         value to write                                                           *
    171  *                                                                                             *
    172  *      profile      INI buffer                                                                *
    173  *                                                                                             *
    174  * OUTPUT:                                                                                     *
    175  *      true = success, false = failure                                                        *
    176  *                                                                                             *
    177  * WARNINGS:                                                                                   *
    178  *      none.                                                                                  *
    179  *                                                                                             *
    180  * HISTORY:                                                                                    *
    181  *   10/07/1992 JLB : Created.                                                                 *
    182  *=============================================================================================*/
    183 bool WWWritePrivateProfileInt(char const * section, char const * entry, int value, char * profile)
    184 {
    185 	char	buffer[250];			// Working section buffer.
    186 
    187 	/*
    188 	**	Just return if nothing to do.
    189 	*/
    190 	if (!profile || !section) {
    191 		return(true);
    192 	}
    193 
    194 	/*
    195 	**	Generate string to save.
    196 	*/
    197 	sprintf(buffer, "%d", value);
    198 
    199 	/*
    200 	**	Save the string.
    201 	*/
    202 	return(WWWritePrivateProfileString(section, entry, buffer, profile));
    203 }
    204 
    205 
    206 /***********************************************************************************************
    207  * WWGetPrivateProfileString -- Fetch game override string.                                    *
    208  *                                                                                             *
    209  * INPUT:                                                                                      *
    210  *      section      section name to read from                                                 *
    211  *                                                                                             *
    212  *      entry         name of entry to read; if NULL, all entry names are returned             *
    213  *                                                                                             *
    214  *      def         default string to use if not found; can be NULL                            *
    215  *                                                                                             *
    216  *      retbuffer   buffer to store result in                                                  *
    217  *                                                                                             *
    218  *      retlen      max length of return buffer                                                *
    219  *                                                                                             *
    220  *      profile      INI buffer                                                                *
    221  *                                                                                             *
    222  * OUTPUT:                                                                                     *
    223  *      ptr to entry found in INI buf; NULL if not found                                       *
    224  *                                                                                             *
    225  * WARNINGS:                                                                                   *
    226  *      On the PC, the "\n" (10) is translated to "\r\n" (13,10) when it's written             *
    227  *      to disk. This routine must take this into consideration, by searching                  *
    228  *      for \n when scanning backward, and for \r when scanning forward.                       *
    229  *                                                                                             *
    230  * HISTORY:                                                                                    *
    231  *   08/05/1992 JLB : Created.                                                                 *
    232  *=============================================================================================*/
    233 char * WWGetPrivateProfileString(char const * section, char const * entry, char const * def, char * retbuffer, int retlen, char const * profile)
    234 {
    235 	char const * workptr;		// Working pointer into profile block.
    236 	char * altworkptr;	// Alternate work pointer.
    237 	char	sec[50];			// Working section buffer.
    238 	char	const * retval;			// Start of section or entry pointer.
    239 	char	* next;			// Pointer to start of next section (or EOF).
    240 	char	c,c2;				// Working character values.
    241 	int	len;				// Working substring length value.
    242 	int	entrylen;		// Byte length of specified entry.
    243 	char * orig_retbuf;	// original retbuffer ptr
    244 
    245 //	if (!retlen) return(NULL);
    246 
    247 	/*
    248 	**	Fill in the default value just in case the entry could not be found.
    249 	*/
    250 	if (retbuffer) {
    251 		retbuffer[0] = '\0';
    252 		if (retlen > 1 || retlen == 0) retbuffer[1] = '\0';
    253 		if (def) {
    254 			strncpy(retbuffer, def, retlen);
    255 		}
    256 		retbuffer[retlen-1] = '\0';
    257 		orig_retbuf = retbuffer;
    258 	}
    259 
    260 	/*
    261 	**	Make sure a profile string was passed in
    262 	*/
    263 	if (!profile || !section) {
    264 		return(retbuffer);
    265 	}
    266 
    267 	/*
    268 	**	Build section string to match file image.
    269 	*/
    270 	sprintf(sec, "[%s]", section);	// sec = section name including []'s
    271 	strupr(sec);
    272 	len = strlen(sec);					// len = section name length, incl []'s
    273 
    274 	/*
    275 	**	Scan for a matching section
    276 	*/
    277 	retval = profile;
    278 	workptr = profile;
    279 	for (;;) {
    280 
    281 		/*
    282 		**	'workptr' = start of next section
    283 		*/
    284 		workptr = strchr(workptr, '[');
    285 
    286 		/*
    287 		**	If the end has been reached without finding the desired section
    288 		**	then abort with a failure flag.
    289 		*/
    290 		if (!workptr) {
    291 			return(NULL);
    292 		}
    293 
    294 		/*
    295 		**	'c' = character just before the '['
    296 		*/
    297 		if (workptr==profile) {
    298 			c = '\n';
    299 		} else {
    300 			c = *(workptr-1);
    301 		}
    302 
    303 		/*
    304 		**	If this is the section name & the character before is a newline,
    305 		**	process this section
    306 		*/
    307 		if (memicmp(workptr, sec, len) == 0 && (c == '\n')) {
    308 
    309 			/*
    310 			**	Skip work pointer to start of first valid entry.
    311 			*/
    312 			workptr += len;
    313 			while (isspace(*workptr)) {
    314 				workptr++;
    315 			}
    316 
    317 			/*
    318 			**	If the section name is empty, we will have stepped onto the start
    319 			**	of the next section name; inserting new entries here will leave
    320 			**	a blank line between this section's name & 1st entry. So, check
    321 			**	for 2 newlines in a row & step backward.
    322 			*/
    323 			if (workptr - profile > 4) {
    324 				if ( *(workptr-1)=='\n' && *(workptr-3)=='\n')
    325 					workptr -= 2;
    326 			}
    327 
    328 			/*
    329 			**	'next = end of section or end of file.
    330 			*/
    331 			next = (char*)strchr(workptr, '[');
    332 			for (;;) {
    333 				if (next) {
    334 
    335 					c = *(next-1);
    336 
    337 					/*
    338 					**	If character before '[' is newline, this is the start of the
    339 					**	next section
    340 					*/
    341 					if (c == '\n') {
    342 						if (*(next-1)=='\n' && *(next-3)=='\n') {
    343 							next -= 2;
    344 						}
    345 						break;
    346 					}
    347 
    348 					/*
    349 					**	This bracket was in the section; keep looking
    350 					*/
    351 					next = strchr(next+1, '[');
    352 				} else {
    353 
    354 					/*
    355 					**	No bracket found; set 'next' to the end of the file
    356 					*/
    357 					next = (char*)workptr + strlen(workptr)-1;
    358 					break;
    359 				}
    360 			}
    361 
    362 			/*
    363 			**	If a specific entry was specified then return with the associated
    364 			**	string.
    365 			*/
    366 			if (entry) {
    367 				retval = workptr;
    368 				entrylen = strlen(entry);
    369 
    370 				for (;;) {
    371 					/*
    372 					** Search for the 1st character of the entry
    373 					*/
    374 					workptr = strchr(workptr, *entry);
    375 
    376 					/*
    377 					**	If the end of the file has been reached or we have spilled
    378 					**	into the next section, then abort
    379 					*/
    380 					if (!workptr || workptr >= next) {
    381 						return(NULL);
    382 					}
    383 
    384 					/*
    385 					**	'c' = character before possible entry; must be a newline
    386 					**	'c2' = character after possible entry; must be '=' or space
    387 					*/
    388 					c = *(workptr-1);
    389 					c2 = *(workptr+entrylen);
    390 
    391 					/*
    392 					**	Entry found; extract it
    393 					*/
    394 					if (memicmp(workptr, entry, entrylen) == 0 && (c == '\n') &&
    395 						(c2 == '=' || isspace(c2))) {
    396 						retval = workptr;
    397 						workptr += entrylen;							// skip entry name
    398 						workptr = strchr(workptr, '=');			// find '='
    399 
    400 						/*
    401 						** 'altworkptr' = next newline; \r is used here since we're
    402 						** scanning forward!
    403 						*/
    404 						if (workptr) {
    405 							altworkptr = (char*)strchr(workptr, '\r');	// find next newline
    406 						}
    407 
    408 						/*
    409 						**	Return if there was no '=', or if the newline is before
    410 						**	the next '='
    411 						*/
    412 						if (workptr == NULL || altworkptr < workptr) {
    413 							return((char *)retval);
    414 						}
    415 
    416 						/*
    417 						**	Skip any white space after the '=' and before the first
    418 						**	valid character of the parameter.
    419 						*/
    420 						workptr++;										// Skip the '='.
    421 						while (isspace(*workptr)) {
    422 
    423 							/*
    424 							**	Just return if there's no entry past the '='.
    425 							*/
    426 							if (workptr >= altworkptr)
    427 								return((char*)retval);
    428 
    429 							workptr++;									// Skip the whitespace
    430 						}
    431 
    432 						/*
    433 						**	Copy the entry into the return buffer.
    434 						*/
    435 						len = (int)(altworkptr - workptr);
    436 						if (len > retlen-1) {
    437 							len = retlen-1;
    438 						}
    439 
    440 						if (retbuffer) {
    441 							memcpy(retbuffer, workptr, len);
    442 							*(retbuffer + len) = '\0';		// Insert trailing null.
    443 							strtrim(retbuffer);
    444 						}
    445 						return((char*)retval);
    446 					}
    447 
    448 					/*
    449 					**	Entry was not found; go to the next one
    450 					*/
    451 					workptr++;
    452 				}
    453 			} else {
    454 
    455 				/*
    456 				**	No entry was specified, so build a list of all entries.
    457 				**	'workptr' is at 1st entry after section name
    458 				**	'next' is next bracket, or end of file
    459 				*/
    460 				retval = workptr;
    461 
    462 				if (retbuffer) {
    463 
    464 					/*
    465 					**	Keep accumulating the identifier strings in the retbuffer.
    466 					*/
    467 					while (workptr && workptr < next) {
    468 						altworkptr = (char*)strchr(workptr, '=');		// find '='
    469 
    470 						if (altworkptr && altworkptr < next) {
    471 							int	length;								// Length of ID string.
    472 
    473 							length = (int)(altworkptr - workptr);
    474 
    475 							/*
    476 							**	Make sure we don't write past the end of the retbuffer;
    477 							**	add '3' for the 3 NULL's at the end
    478 							*/
    479 							if (retbuffer - orig_retbuf + length + 3 < retlen) {
    480 								memcpy(retbuffer, workptr, length);	// copy entry name
    481 								*(retbuffer+length) = '\0';			// NULL-terminate it
    482 								strtrim(retbuffer);						// trim spaces
    483 								retbuffer += strlen(retbuffer)+1;	// next pos in dest buf
    484 							} else {
    485 								break;
    486 							}
    487 
    488 							/*
    489 							**	Advance the work pointer to the start of the next line
    490 							**	by skipping the end of line character.
    491 							*/
    492 							workptr = strchr(altworkptr, '\n');
    493 							if (!workptr) {
    494 								break;
    495 							}
    496 							workptr++;
    497 						} else {
    498 
    499 							/*
    500 							**	If no '=', break out of loop
    501 							*/
    502 							break;
    503 						}
    504 					}
    505 
    506 					/*
    507 					**	Final trailing terminator. Make double sure the double
    508 					**	trailing null is added.
    509 					*/
    510 					*retbuffer++ = '\0';
    511 					*retbuffer++ = '\0';
    512 				}
    513 				break;
    514 			}
    515 		} else {
    516 
    517 			/*
    518 			**	Section name not found; go to the next bracket & try again
    519 			**	Advance past '[' and keep scanning.
    520 			*/
    521 			workptr++;
    522 		}
    523 	}
    524 
    525 	return((char*)retval);
    526 }
    527 
    528 
    529 /***********************************************************************************************
    530  * WritePrivateProfileString -- Write a string to the profile data block.                      *
    531  *                                                                                             *
    532  * INPUT:                                                                                      *
    533  *      section      section name to write to                                                  *
    534  *      entry         name of entry to write; if NULL, the section is deleted                  *
    535  *      string      string to write; if NULL, the entry is deleted                             *
    536  *      profile      INI buffer                                                                *
    537  *                                                                                             *
    538  * OUTPUT:                                                                                     *
    539  *      true = success, false = failure                                                        *
    540  *                                                                                             *
    541  * WARNINGS:                                                                                   *
    542  *      This function has to translate newlines into \r\n sequences.                           *
    543  *                                                                                             *
    544  * HISTORY:                                                                                    *
    545  *   10/07/1992 JLB : Created.                                                                 *
    546  *=============================================================================================*/
    547 bool WWWritePrivateProfileString(char const * section, char const * entry, char const * string, char * profile)
    548 {
    549 	char	buffer[250];			// Working section buffer
    550 	char const * offset;
    551 	char const * next;						// ptr to next section
    552 	char	c;							// Working character value
    553 
    554 	/*
    555 	**	Just return if nothing to do.
    556 	*/
    557 	if (!profile || !section) {
    558 		return(true);
    559 	}
    560 
    561 	/*
    562 	**	Try to find the section. WWGetPrivateProfileString with NULL entry name
    563 	**	will return all entry names in the given buffer, truncated to the given
    564 	**	buffer length. 'offset' will point to 1st entry in the section, NULL if
    565 	**	section not found.
    566 	*/
    567 	offset = WWGetPrivateProfileString(section, NULL, NULL, NULL, 0, profile);
    568 
    569 	/*
    570 	**	If the section could not be found, then add it to the end. Don't add
    571 	**	anything if a removal of an entry is requested (it is obviously already
    572 	**	non-existent). Make sure two newlines precede the section name.
    573 	*/
    574 	if (!offset && entry) {
    575 		sprintf(buffer, "\r\n[%s]\r\n", section);
    576 		strcat(profile, buffer);
    577 	}
    578 
    579 	/*
    580 	**	If the section is there and 'entry' is NULL, remove the entire section
    581 	*/
    582 	if (offset && !entry) {
    583 
    584 		/*
    585 		**	'next = end of section or end of file.
    586 		*/
    587 		next = strchr(offset, '[');
    588 		for (;;) {
    589 			if (next) {
    590 				c = *(next-1);
    591 
    592 				/*
    593 				**	If character before '[' is newline, this is the start of the
    594 				**	next section
    595 				*/
    596 				if (c == '\n') {
    597 					if ( *(next-1)=='\n' && *(next-3)=='\n') {
    598 						next -= 2;
    599 					}
    600 					break;
    601 				}
    602 
    603 				/*
    604 				**	This bracket was in the section; keep looking
    605 				*/
    606 				next = strchr(next+1, '[');
    607 			} else {
    608 
    609 				/*
    610 				**	No bracket found; set 'next' to the end of the file
    611 				*/
    612 				next = offset + strlen(offset);
    613 				break;
    614 			}
    615 		}
    616 
    617 		/*
    618 		**	Remove the section
    619 		*/
    620 		strcpy((char*)offset, (char*)next);
    621 
    622 		return(true);
    623 	}
    624 
    625 	/*
    626 	**	Find the matching entry within the desired section. A NULL return buffer
    627 	**	with 0 length will just return the offset of the found entry, NULL if
    628 	**	entry not found.
    629 	*/
    630 	offset = WWGetPrivateProfileString(section, entry, NULL, NULL, 0, profile);
    631 
    632 	/*
    633 	**	Remove any existing entry
    634 	*/
    635 	if (offset) {
    636 		int	eol;			// Working EOL offset.
    637 
    638 		/*
    639 		**	Get # characters up to newline; \n is used since we're after the end
    640 		**	of this line
    641 		*/
    642 		eol = strcspn(offset, "\n");
    643 
    644 		/*
    645 		**	Erase the entry by strcpy'ing the entire INI file over this entry
    646 		*/
    647 		if (eol) {
    648 			strcpy((char*)offset, offset + eol + 1);
    649 		}
    650 	} else {
    651 
    652 		/*
    653 		**	Entry doesn't exist, so point 'offset' to the 1st entry position in
    654 		**	the section.
    655 		*/
    656 		offset = WWGetPrivateProfileString(section, NULL, NULL, NULL, 0, profile);
    657 	}
    658 
    659 	/*
    660 	**	Add the desired entry.
    661 	*/
    662 	if (entry && string) {
    663 
    664 		/*
    665 		**	Generate entry string.
    666 		*/
    667 		sprintf(buffer, "%s=%s\r\n", entry, string);
    668 
    669 		/*
    670 		**	Make room for new entry.
    671 		*/
    672 		memmove((char*)offset+strlen(buffer), offset, strlen(offset)+1);
    673 
    674 		/*
    675 		**	Copy the entry into the INI buffer.
    676 		*/
    677 		memcpy((char*)offset, buffer, strlen(buffer));
    678 	}
    679 
    680 	return(true);
    681 }
    682 
    683 
    684 char * Read_Bin_Buffer( void )
    685 {
    686 	return( ReadBinBuffer );
    687 }
    688 
    689 
    690 bool Read_Bin_Init( char * buffer, int length )
    691 {
    692 	ReadBinBuffer = buffer;
    693 	ReadBinBufferLen = length;
    694 	ReadBinBufferPos = 0;
    695 	ReadBinBufferMax = 0;
    696 	return( true );
    697 }
    698 
    699 
    700 int Read_Bin_Length( char * buffer )
    701 {
    702 	if (buffer != ReadBinBuffer) {
    703 		return( -1 );
    704 	} else {
    705 		return( ReadBinBufferMax );
    706 	}
    707 }
    708 
    709 
    710 bool Read_Bin_Num( void * num, int length, char * buffer )
    711 {
    712 	char * ptr;
    713 
    714 	if (buffer != ReadBinBuffer || length <= 0 || length > 4 ||
    715 		 (ReadBinBufferPos + length) >= ReadBinBufferLen) {
    716 		return( false );
    717 	} else {
    718 		ptr = ReadBinBuffer + ReadBinBufferPos;
    719 		memcpy( num, ptr, length );
    720 		ReadBinBufferPos += length;
    721 
    722 		if (ReadBinBufferPos > ReadBinBufferMax) {
    723 			ReadBinBufferMax = ReadBinBufferPos;
    724 		}
    725 
    726 		return( true );
    727 	}
    728 }
    729 
    730 
    731 int Read_Bin_Pos( char * buffer )
    732 {
    733 	if (buffer != ReadBinBuffer) {
    734 		return( -1 );
    735 	} else {
    736 		return( ReadBinBufferPos );
    737 	}
    738 }
    739 
    740 
    741 int Read_Bin_PosSet( unsigned int pos, char * buffer )
    742 {
    743 	if (buffer != ReadBinBuffer) {
    744 		return( -1 );
    745 	} else {
    746 		ReadBinBufferPos = pos;
    747 		return( ReadBinBufferPos );
    748 	}
    749 }
    750 
    751 
    752 bool Read_Bin_String( char * string, char * buffer )
    753 {
    754 	char * ptr;
    755 	unsigned char length;
    756 
    757 	if (buffer != ReadBinBuffer ||
    758 		 ReadBinBufferPos >= ReadBinBufferLen) {
    759 		return( false );
    760 	} else {
    761 		ptr = ReadBinBuffer + ReadBinBufferPos;
    762 		length = (unsigned char)*ptr++;
    763 		if ( (ReadBinBufferPos + length + 2) <= ReadBinBufferLen) {
    764 			memcpy( string, ptr, (unsigned int)(length + 1) );
    765 			ReadBinBufferPos += (length + 2);
    766 
    767 			if (ReadBinBufferPos > ReadBinBufferMax) {
    768 				ReadBinBufferMax = ReadBinBufferPos;
    769 			}
    770 
    771 			return( true );
    772 		} else {
    773 			return( false );
    774 		}
    775 	}
    776 }
    777 
    778 
    779 char * Write_Bin_Buffer( void )
    780 {
    781 	return( WriteBinBuffer );
    782 }
    783 
    784 
    785 bool Write_Bin_Init( char * buffer, int length )
    786 {
    787 	WriteBinBuffer = buffer;
    788 	WriteBinBufferLen = length;
    789 	WriteBinBufferPos = 0;
    790 	WriteBinBufferMax = 0;
    791 	return( true );
    792 }
    793 
    794 
    795 int Write_Bin_Length( char * buffer )
    796 {
    797 	if (buffer != WriteBinBuffer) {
    798 		return( -1 );
    799 	} else {
    800 		return( WriteBinBufferMax );
    801 	}
    802 }
    803 
    804 
    805 bool Write_Bin_Num( void * num, int length, char * buffer )
    806 {
    807 	char * ptr;
    808 
    809 	if (buffer != WriteBinBuffer || length <= 0 || length > 4 ||
    810 		 (WriteBinBufferPos + length) > WriteBinBufferLen) {
    811 		return( false );
    812 	} else {
    813 		ptr = WriteBinBuffer + WriteBinBufferPos;
    814 		memcpy( ptr, num, length );
    815 		WriteBinBufferPos += length;
    816 
    817 		if (WriteBinBufferPos > WriteBinBufferMax) {
    818 			WriteBinBufferMax = WriteBinBufferPos;
    819 		}
    820 
    821 		return( true );
    822 	}
    823 }
    824 
    825 
    826 int Write_Bin_Pos( char * buffer )
    827 {
    828 	if (buffer != WriteBinBuffer) {
    829 		return( -1 );
    830 	} else {
    831 		return( WriteBinBufferPos );
    832 	}
    833 }
    834 
    835 
    836 int Write_Bin_PosSet( unsigned int pos, char * buffer )
    837 {
    838 	if (buffer != WriteBinBuffer) {
    839 		return( -1 );
    840 	} else {
    841 		WriteBinBufferPos = pos;
    842 		return( WriteBinBufferPos );
    843 	}
    844 }
    845 
    846 
    847 bool Write_Bin_String( char * string, int length, char * buffer )
    848 {
    849 	char * ptr;
    850 
    851 	if (buffer != WriteBinBuffer || length < 0 || length > 255 ||
    852 		 (WriteBinBufferPos + length + 2) > WriteBinBufferLen) {
    853 		return( false );
    854 	} else {
    855 		ptr = WriteBinBuffer + WriteBinBufferPos;
    856 		*ptr++ = (char)length;
    857 		memcpy( ptr, string, (length + 1) );
    858 		WriteBinBufferPos += (length + 2);
    859 
    860 		if (WriteBinBufferPos > WriteBinBufferMax) {
    861 			WriteBinBufferMax = WriteBinBufferPos;
    862 		}
    863 
    864 		return( true );
    865 	}
    866 }
    867