PROFILE.CPP 28 KB

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