lldatapacker.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:48k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lldatapacker.cpp
  3.  * @brief Data packer implementation.
  4.  *
  5.  * $LicenseInfo:firstyear=2006&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2006-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "linden_common.h"
  33. #include "lldatapacker.h"
  34. #include "llerror.h"
  35. #include "message.h"
  36. #include "v4color.h"
  37. #include "v4coloru.h"
  38. #include "v2math.h"
  39. #include "v3math.h"
  40. #include "v4math.h"
  41. #include "lluuid.h"
  42. // *NOTE: there are functions below which use sscanf and rely on this
  43. // particular value of DP_BUFSIZE. Search for '511' (DP_BUFSIZE - 1)
  44. // to find them if you change this number.
  45. const S32 DP_BUFSIZE = 512;
  46. static char DUMMY_BUFFER[128]; /*Flawfinder: ignore*/
  47. LLDataPacker::LLDataPacker() : mPassFlags(0), mWriteEnabled(FALSE)
  48. {
  49. }
  50. //virtual
  51. void LLDataPacker::reset()
  52. {
  53. llerrs << "Using unimplemented datapacker reset!" << llendl;
  54. }
  55. //virtual
  56. void LLDataPacker::dumpBufferToLog()
  57. {
  58. llerrs << "dumpBufferToLog not implemented for this type!" << llendl;
  59. }
  60. BOOL LLDataPacker::packFixed(const F32 value, const char *name,
  61.  const BOOL is_signed, const U32 int_bits, const U32 frac_bits)
  62. {
  63. BOOL success = TRUE;
  64. S32 unsigned_bits = int_bits + frac_bits;
  65. S32 total_bits = unsigned_bits;
  66. if (is_signed)
  67. {
  68. total_bits++;
  69. }
  70. S32 min_val;
  71. U32 max_val;
  72. if (is_signed)
  73. {
  74. min_val = 1 << int_bits;
  75. min_val *= -1;
  76. }
  77. else
  78. {
  79. min_val = 0;
  80. }
  81. max_val = 1 << int_bits;
  82. // Clamp to be within range
  83. F32 fixed_val = llclamp(value, (F32)min_val, (F32)max_val);
  84. if (is_signed)
  85. {
  86. fixed_val += max_val;
  87. }
  88. fixed_val *= 1 << frac_bits;
  89. if (total_bits <= 8)
  90. {
  91. packU8((U8)fixed_val, name);
  92. }
  93. else if (total_bits <= 16)
  94. {
  95. packU16((U16)fixed_val, name);
  96. }
  97. else if (total_bits <= 31)
  98. {
  99. packU32((U32)fixed_val, name);
  100. }
  101. else
  102. {
  103. llerrs << "Using fixed-point packing of " << total_bits << " bits, why?!" << llendl;
  104. }
  105. return success;
  106. }
  107. BOOL LLDataPacker::unpackFixed(F32 &value, const char *name,
  108.    const BOOL is_signed, const U32 int_bits, const U32 frac_bits)
  109. {
  110. //BOOL success = TRUE;
  111. //llinfos << "unpackFixed:" << name << " int:" << int_bits << " frac:" << frac_bits << llendl;
  112. BOOL ok = FALSE;
  113. S32 unsigned_bits = int_bits + frac_bits;
  114. S32 total_bits = unsigned_bits;
  115. if (is_signed)
  116. {
  117. total_bits++;
  118. }
  119. S32 min_val;
  120. U32 max_val;
  121. if (is_signed)
  122. {
  123. min_val = 1 << int_bits;
  124. min_val *= -1;
  125. }
  126. max_val = 1 << int_bits;
  127. F32 fixed_val;
  128. if (total_bits <= 8)
  129. {
  130. U8 fixed_8;
  131. ok = unpackU8(fixed_8, name);
  132. fixed_val = (F32)fixed_8;
  133. }
  134. else if (total_bits <= 16)
  135. {
  136. U16 fixed_16;
  137. ok = unpackU16(fixed_16, name);
  138. fixed_val = (F32)fixed_16;
  139. }
  140. else if (total_bits <= 31)
  141. {
  142. U32 fixed_32;
  143. ok = unpackU32(fixed_32, name);
  144. fixed_val = (F32)fixed_32;
  145. }
  146. else
  147. {
  148. fixed_val = 0;
  149. llerrs << "Bad bit count: " << total_bits << llendl;
  150. }
  151. //llinfos << "Fixed_val:" << fixed_val << llendl;
  152. fixed_val /= (F32)(1 << frac_bits);
  153. if (is_signed)
  154. {
  155. fixed_val -= max_val;
  156. }
  157. value = fixed_val;
  158. //llinfos << "Value: " << value << llendl;
  159. return ok;
  160. }
  161. //---------------------------------------------------------------------------
  162. // LLDataPackerBinaryBuffer implementation
  163. //---------------------------------------------------------------------------
  164. BOOL LLDataPackerBinaryBuffer::packString(const std::string& value, const char *name)
  165. {
  166. BOOL success = TRUE;
  167. S32 length = value.length()+1;
  168. success &= verifyLength(length, name);
  169. if (mWriteEnabled) 
  170. {
  171. htonmemcpy(mCurBufferp, value.c_str(), MVT_VARIABLE, length);  
  172. }
  173. mCurBufferp += length;
  174. return success;
  175. }
  176. BOOL LLDataPackerBinaryBuffer::unpackString(std::string& value, const char *name)
  177. {
  178. BOOL success = TRUE;
  179. S32 length = (S32)strlen((char *)mCurBufferp) + 1; /*Flawfinder: ignore*/
  180. success &= verifyLength(length, name);
  181. value = std::string((char*)mCurBufferp); // We already assume NULL termination calling strlen()
  182. mCurBufferp += length;
  183. return success;
  184. }
  185. BOOL LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const char *name)
  186. {
  187. BOOL success = TRUE;
  188. success &= verifyLength(size + 4, name);
  189. if (mWriteEnabled) 
  190. htonmemcpy(mCurBufferp, &size, MVT_S32, 4);  
  191. }
  192. mCurBufferp += 4;
  193. if (mWriteEnabled) 
  194. htonmemcpy(mCurBufferp, value, MVT_VARIABLE, size);  
  195. }
  196. mCurBufferp += size;
  197. return success;
  198. }
  199. BOOL LLDataPackerBinaryBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name)
  200. {
  201. BOOL success = TRUE;
  202. success &= verifyLength(4, name);
  203. htonmemcpy(&size, mCurBufferp, MVT_S32, 4);
  204. mCurBufferp += 4;
  205. success &= verifyLength(size, name);
  206. if (success)
  207. {
  208. htonmemcpy(value, mCurBufferp, MVT_VARIABLE, size);
  209. mCurBufferp += size;
  210. }
  211. else
  212. {
  213. llwarns << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << llendl;
  214. success = FALSE;
  215. }
  216. return success;
  217. }
  218. BOOL LLDataPackerBinaryBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name)
  219. {
  220. BOOL success = TRUE;
  221. success &= verifyLength(size, name);
  222. if (mWriteEnabled) 
  223. htonmemcpy(mCurBufferp, value, MVT_VARIABLE, size);  
  224. }
  225. mCurBufferp += size;
  226. return success;
  227. }
  228. BOOL LLDataPackerBinaryBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name)
  229. {
  230. BOOL success = TRUE;
  231. success &= verifyLength(size, name);
  232. htonmemcpy(value, mCurBufferp, MVT_VARIABLE, size);
  233. mCurBufferp += size;
  234. return success;
  235. }
  236. BOOL LLDataPackerBinaryBuffer::packU8(const U8 value, const char *name)
  237. {
  238. BOOL success = TRUE;
  239. success &= verifyLength(sizeof(U8), name);
  240. if (mWriteEnabled) 
  241. {
  242. *mCurBufferp = value;
  243. }
  244. mCurBufferp++;
  245. return success;
  246. }
  247. BOOL LLDataPackerBinaryBuffer::unpackU8(U8 &value, const char *name)
  248. {
  249. BOOL success = TRUE;
  250. success &= verifyLength(sizeof(U8), name);
  251. value = *mCurBufferp;
  252. mCurBufferp++;
  253. return success;
  254. }
  255. BOOL LLDataPackerBinaryBuffer::packU16(const U16 value, const char *name)
  256. {
  257. BOOL success = TRUE;
  258. success &= verifyLength(sizeof(U16), name);
  259. if (mWriteEnabled) 
  260. htonmemcpy(mCurBufferp, &value, MVT_U16, 2);  
  261. }
  262. mCurBufferp += 2;
  263. return success;
  264. }
  265. BOOL LLDataPackerBinaryBuffer::unpackU16(U16 &value, const char *name)
  266. {
  267. BOOL success = TRUE;
  268. success &= verifyLength(sizeof(U16), name);
  269. htonmemcpy(&value, mCurBufferp, MVT_U16, 2);
  270. mCurBufferp += 2;
  271. return success;
  272. }
  273. BOOL LLDataPackerBinaryBuffer::packU32(const U32 value, const char *name)
  274. {
  275. BOOL success = TRUE;
  276. success &= verifyLength(sizeof(U32), name);
  277. if (mWriteEnabled) 
  278. htonmemcpy(mCurBufferp, &value, MVT_U32, 4);  
  279. }
  280. mCurBufferp += 4;
  281. return success;
  282. }
  283. BOOL LLDataPackerBinaryBuffer::unpackU32(U32 &value, const char *name)
  284. {
  285. BOOL success = TRUE;
  286. success &= verifyLength(sizeof(U32), name);
  287. htonmemcpy(&value, mCurBufferp, MVT_U32, 4);
  288. mCurBufferp += 4;
  289. return success;
  290. }
  291. BOOL LLDataPackerBinaryBuffer::packS32(const S32 value, const char *name)
  292. {
  293. BOOL success = TRUE;
  294. success &= verifyLength(sizeof(S32), name);
  295. if (mWriteEnabled) 
  296. htonmemcpy(mCurBufferp, &value, MVT_S32, 4); 
  297. }
  298. mCurBufferp += 4;
  299. return success;
  300. }
  301. BOOL LLDataPackerBinaryBuffer::unpackS32(S32 &value, const char *name)
  302. {
  303. BOOL success = TRUE;
  304. success &= verifyLength(sizeof(S32), name);
  305. htonmemcpy(&value, mCurBufferp, MVT_S32, 4);
  306. mCurBufferp += 4;
  307. return success;
  308. }
  309. BOOL LLDataPackerBinaryBuffer::packF32(const F32 value, const char *name)
  310. {
  311. BOOL success = TRUE;
  312. success &= verifyLength(sizeof(F32), name);
  313. if (mWriteEnabled) 
  314. htonmemcpy(mCurBufferp, &value, MVT_F32, 4); 
  315. }
  316. mCurBufferp += 4;
  317. return success;
  318. }
  319. BOOL LLDataPackerBinaryBuffer::unpackF32(F32 &value, const char *name)
  320. {
  321. BOOL success = TRUE;
  322. success &= verifyLength(sizeof(F32), name);
  323. htonmemcpy(&value, mCurBufferp, MVT_F32, 4);
  324. mCurBufferp += 4;
  325. return success;
  326. }
  327. BOOL LLDataPackerBinaryBuffer::packColor4(const LLColor4 &value, const char *name)
  328. {
  329. BOOL success = TRUE;
  330. success &= verifyLength(16, name);
  331. if (mWriteEnabled) 
  332. htonmemcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); 
  333. }
  334. mCurBufferp += 16;
  335. return success;
  336. }
  337. BOOL LLDataPackerBinaryBuffer::unpackColor4(LLColor4 &value, const char *name)
  338. {
  339. BOOL success = TRUE;
  340. success &= verifyLength(16, name);
  341. htonmemcpy(value.mV, mCurBufferp, MVT_LLVector4, 16);
  342. mCurBufferp += 16;
  343. return success;
  344. }
  345. BOOL LLDataPackerBinaryBuffer::packColor4U(const LLColor4U &value, const char *name)
  346. {
  347. BOOL success = TRUE;
  348. success &= verifyLength(4, name);
  349. if (mWriteEnabled) 
  350. htonmemcpy(mCurBufferp, value.mV, MVT_VARIABLE, 4);  
  351. }
  352. mCurBufferp += 4;
  353. return success;
  354. }
  355. BOOL LLDataPackerBinaryBuffer::unpackColor4U(LLColor4U &value, const char *name)
  356. {
  357. BOOL success = TRUE;
  358. success &= verifyLength(4, name);
  359. htonmemcpy(value.mV, mCurBufferp, MVT_VARIABLE, 4);
  360. mCurBufferp += 4;
  361. return success;
  362. }
  363. BOOL LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *name)
  364. {
  365. BOOL success = TRUE;
  366. success &= verifyLength(8, name);
  367. if (mWriteEnabled) 
  368. htonmemcpy(mCurBufferp, &value.mV[0], MVT_F32, 4);  
  369. htonmemcpy(mCurBufferp+4, &value.mV[1], MVT_F32, 4);  
  370. }
  371. mCurBufferp += 8;
  372. return success;
  373. }
  374. BOOL LLDataPackerBinaryBuffer::unpackVector2(LLVector2 &value, const char *name)
  375. {
  376. BOOL success = TRUE;
  377. success &= verifyLength(8, name);
  378. htonmemcpy(&value.mV[0], mCurBufferp, MVT_F32, 4);
  379. htonmemcpy(&value.mV[1], mCurBufferp+4, MVT_F32, 4);
  380. mCurBufferp += 8;
  381. return success;
  382. }
  383. BOOL LLDataPackerBinaryBuffer::packVector3(const LLVector3 &value, const char *name)
  384. {
  385. BOOL success = TRUE;
  386. success &= verifyLength(12, name);
  387. if (mWriteEnabled) 
  388. htonmemcpy(mCurBufferp, value.mV, MVT_LLVector3, 12);  
  389. }
  390. mCurBufferp += 12;
  391. return success;
  392. }
  393. BOOL LLDataPackerBinaryBuffer::unpackVector3(LLVector3 &value, const char *name)
  394. {
  395. BOOL success = TRUE;
  396. success &= verifyLength(12, name);
  397. htonmemcpy(value.mV, mCurBufferp, MVT_LLVector3, 12);
  398. mCurBufferp += 12;
  399. return success;
  400. }
  401. BOOL LLDataPackerBinaryBuffer::packVector4(const LLVector4 &value, const char *name)
  402. {
  403. BOOL success = TRUE;
  404. success &= verifyLength(16, name);
  405. if (mWriteEnabled) 
  406. htonmemcpy(mCurBufferp, value.mV, MVT_LLVector4, 16);  
  407. }
  408. mCurBufferp += 16;
  409. return success;
  410. }
  411. BOOL LLDataPackerBinaryBuffer::unpackVector4(LLVector4 &value, const char *name)
  412. {
  413. BOOL success = TRUE;
  414. success &= verifyLength(16, name);
  415. htonmemcpy(value.mV, mCurBufferp, MVT_LLVector4, 16);
  416. mCurBufferp += 16;
  417. return success;
  418. }
  419. BOOL LLDataPackerBinaryBuffer::packUUID(const LLUUID &value, const char *name)
  420. {
  421. BOOL success = TRUE;
  422. success &= verifyLength(16, name);
  423. if (mWriteEnabled) 
  424. htonmemcpy(mCurBufferp, value.mData, MVT_LLUUID, 16);  
  425. }
  426. mCurBufferp += 16;
  427. return success;
  428. }
  429. BOOL LLDataPackerBinaryBuffer::unpackUUID(LLUUID &value, const char *name)
  430. {
  431. BOOL success = TRUE;
  432. success &= verifyLength(16, name);
  433. htonmemcpy(value.mData, mCurBufferp, MVT_LLUUID, 16);
  434. mCurBufferp += 16;
  435. return success;
  436. }
  437. const LLDataPackerBinaryBuffer& LLDataPackerBinaryBuffer::operator=(const LLDataPackerBinaryBuffer &a)
  438. {
  439. if (a.getBufferSize() > getBufferSize())
  440. {
  441. // We've got problems, ack!
  442. llerrs << "Trying to do an assignment with not enough room in the target." << llendl;
  443. }
  444. memcpy(mBufferp, a.mBufferp, a.getBufferSize()); /*Flawfinder: ignore*/
  445. return *this;
  446. }
  447. void LLDataPackerBinaryBuffer::dumpBufferToLog()
  448. {
  449. llwarns << "Binary Buffer Dump, size: " << mBufferSize << llendl;
  450. char line_buffer[256]; /*Flawfinder: ignore*/
  451. S32 i;
  452. S32 cur_line_pos = 0;
  453. S32 cur_line = 0;
  454. for (i = 0; i < mBufferSize; i++)
  455. {
  456. snprintf(line_buffer + cur_line_pos*3, sizeof(line_buffer) - cur_line_pos*3, "%02x ", mBufferp[i]);  /* Flawfinder: ignore */
  457. cur_line_pos++;
  458. if (cur_line_pos >= 16)
  459. {
  460. cur_line_pos = 0;
  461. llwarns << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << llendl;
  462. cur_line++;
  463. }
  464. }
  465. if (cur_line_pos)
  466. {
  467. llwarns << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << llendl;
  468. }
  469. }
  470. //---------------------------------------------------------------------------
  471. // LLDataPackerAsciiBuffer implementation
  472. //---------------------------------------------------------------------------
  473. BOOL LLDataPackerAsciiBuffer::packString(const std::string& value, const char *name)
  474. {
  475. BOOL success = TRUE;
  476. writeIndentedName(name);
  477. int numCopied = 0;
  478. if (mWriteEnabled) 
  479. {
  480. numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%sn", value.c_str()); /* Flawfinder: ignore */
  481. }
  482. else
  483. {
  484. numCopied = value.length() + 1; /*Flawfinder: ignore*/
  485. }
  486. // snprintf returns number of bytes that would have been written
  487. // had the output not being truncated. In that case, it will
  488. // return either -1 or value >= passed in size value . So a check needs to be added
  489. // to detect truncation, and if there is any, only account for the
  490. // actual number of bytes written..and not what could have been
  491. // written.
  492. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  493. {
  494. // *NOTE: I believe we need to mark a failure bit at this point.
  495.     numCopied = getBufferSize()-getCurrentSize();
  496. llwarns << "LLDataPackerAsciiBuffer::packString: string truncated: " << value << llendl;
  497. }
  498. mCurBufferp += numCopied;
  499. return success;
  500. }
  501. BOOL LLDataPackerAsciiBuffer::unpackString(std::string& value, const char *name)
  502. {
  503. BOOL success = TRUE;
  504. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/
  505. BOOL res = getValueStr(name, valuestr, DP_BUFSIZE); // NULL terminated
  506. if (!res) // 
  507. {
  508. return FALSE;
  509. }
  510. value = valuestr;
  511. return success;
  512. }
  513. BOOL LLDataPackerAsciiBuffer::packBinaryData(const U8 *value, S32 size, const char *name)
  514. {
  515. BOOL success = TRUE;
  516. writeIndentedName(name);
  517. int numCopied = 0;
  518. if (mWriteEnabled)
  519. {
  520. numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%010d ", size); /* Flawfinder: ignore */
  521. // snprintf returns number of bytes that would have been
  522. // written had the output not being truncated. In that case,
  523. // it will retuen >= passed in size value.  so a check needs
  524. // to be added to detect truncation, and if there is any, only
  525. // account for the actual number of bytes written..and not
  526. // what could have been written.
  527. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  528. {
  529. numCopied = getBufferSize()-getCurrentSize();
  530. llwarns << "LLDataPackerAsciiBuffer::packBinaryData: number truncated: " << size << llendl;
  531. }
  532. mCurBufferp += numCopied;
  533. S32 i;
  534. BOOL bBufferFull = FALSE;
  535. for (i = 0; i < size && !bBufferFull; i++)
  536. {
  537. numCopied = snprintf(mCurBufferp, getBufferSize()-getCurrentSize(), "%02x ", value[i]); /* Flawfinder: ignore */
  538. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  539. {
  540. numCopied = getBufferSize()-getCurrentSize();
  541. llwarns << "LLDataPackerAsciiBuffer::packBinaryData: data truncated: " << llendl;
  542. bBufferFull = TRUE;
  543. }
  544. mCurBufferp += numCopied;
  545. }
  546. if (!bBufferFull)
  547. {
  548. numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "n"); /* Flawfinder: ignore */
  549. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  550.      {
  551. numCopied = getBufferSize()-getCurrentSize();
  552. llwarns << "LLDataPackerAsciiBuffer::packBinaryData: newline truncated: " << llendl;
  553.      }
  554.      mCurBufferp += numCopied;
  555. }
  556. }
  557. else
  558. {
  559. // why +10 ?? XXXCHECK
  560. numCopied = 10 + 1; // size plus newline
  561. numCopied += size;
  562. if (numCopied > getBufferSize()-getCurrentSize())
  563. {
  564. numCopied = getBufferSize()-getCurrentSize();
  565. }   
  566. mCurBufferp += numCopied;
  567. }
  568. return success;
  569. }
  570. BOOL LLDataPackerAsciiBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name)
  571. {
  572. BOOL success = TRUE;
  573. char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */
  574. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  575. {
  576. return FALSE;
  577. }
  578. char *cur_pos = &valuestr[0];
  579. sscanf(valuestr,"%010d", &size);
  580. cur_pos += 11;
  581. S32 i;
  582. for (i = 0; i < size; i++)
  583. {
  584. S32 val;
  585. sscanf(cur_pos,"%02x", &val);
  586. value[i] = val;
  587. cur_pos += 3;
  588. }
  589. return success;
  590. }
  591. BOOL LLDataPackerAsciiBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name)
  592. {
  593. BOOL success = TRUE;
  594. writeIndentedName(name);
  595. if (mWriteEnabled)
  596. {
  597. S32 i;
  598. int numCopied = 0;
  599. BOOL bBufferFull = FALSE;
  600. for (i = 0; i < size && !bBufferFull; i++)
  601. {
  602. numCopied = snprintf(mCurBufferp, getBufferSize()-getCurrentSize(), "%02x ", value[i]); /* Flawfinder: ignore */
  603. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  604. {
  605.     numCopied = getBufferSize()-getCurrentSize();
  606. llwarns << "LLDataPackerAsciiBuffer::packBinaryDataFixed: data truncated: " << llendl;
  607.     bBufferFull = TRUE;
  608. }
  609. mCurBufferp += numCopied;
  610. }
  611. if (!bBufferFull)
  612. {
  613. numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "n"); /* Flawfinder: ignore */
  614. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  615. {
  616. numCopied = getBufferSize()-getCurrentSize();
  617. llwarns << "LLDataPackerAsciiBuffer::packBinaryDataFixed: newline truncated: " << llendl;
  618. }
  619. mCurBufferp += numCopied;
  620. }
  621. }
  622. else
  623. {
  624. int numCopied = 2 * size + 1; //hex bytes plus newline 
  625. if (numCopied > getBufferSize()-getCurrentSize())
  626. {
  627. numCopied = getBufferSize()-getCurrentSize();
  628. }   
  629. mCurBufferp += numCopied;
  630. }
  631. return success;
  632. }
  633. BOOL LLDataPackerAsciiBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name)
  634. {
  635. BOOL success = TRUE;
  636. char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */
  637. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  638. {
  639. return FALSE;
  640. }
  641. char *cur_pos = &valuestr[0];
  642. S32 i;
  643. for (i = 0; i < size; i++)
  644. {
  645. S32 val;
  646. sscanf(cur_pos,"%02x", &val);
  647. value[i] = val;
  648. cur_pos += 3;
  649. }
  650. return success;
  651. }
  652. BOOL LLDataPackerAsciiBuffer::packU8(const U8 value, const char *name)
  653. {
  654. BOOL success = TRUE;
  655. writeIndentedName(name);
  656. int numCopied = 0;
  657. if (mWriteEnabled)
  658. {
  659.      numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%dn", value); /* Flawfinder: ignore */
  660. }
  661. else
  662. {
  663. // just do the write to a temp buffer to get the length
  664. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%dn", value); /* Flawfinder: ignore */
  665. }
  666. // snprintf returns number of bytes that would have been written
  667. // had the output not being truncated. In that case, it will
  668. // return either -1 or value >= passed in size value . So a check needs to be added
  669. // to detect truncation, and if there is any, only account for the
  670. // actual number of bytes written..and not what could have been
  671. // written.
  672. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  673. {
  674. numCopied = getBufferSize()-getCurrentSize();
  675. llwarns << "LLDataPackerAsciiBuffer::packU8: val truncated: " << llendl;
  676. }
  677. mCurBufferp += numCopied;
  678. return success;
  679. }
  680. BOOL LLDataPackerAsciiBuffer::unpackU8(U8 &value, const char *name)
  681. {
  682. BOOL success = TRUE;
  683. char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */
  684. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  685. {
  686. return FALSE;
  687. }
  688. S32 in_val;
  689. sscanf(valuestr,"%d", &in_val);
  690. value = in_val;
  691. return success;
  692. }
  693. BOOL LLDataPackerAsciiBuffer::packU16(const U16 value, const char *name)
  694. {
  695. BOOL success = TRUE;
  696. writeIndentedName(name);
  697. int numCopied = 0;
  698. if (mWriteEnabled)
  699. {
  700.      numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%dn", value); /* Flawfinder: ignore */
  701. }
  702. else
  703. {
  704. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%dn", value); /* Flawfinder: ignore */
  705. }
  706. // snprintf returns number of bytes that would have been written
  707. // had the output not being truncated. In that case, it will
  708. // return either -1 or value >= passed in size value . So a check needs to be added
  709. // to detect truncation, and if there is any, only account for the
  710. // actual number of bytes written..and not what could have been
  711. // written.
  712. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  713. {
  714. numCopied = getBufferSize()-getCurrentSize();
  715. llwarns << "LLDataPackerAsciiBuffer::packU16: val truncated: " << llendl;
  716. }
  717. mCurBufferp += numCopied;
  718. return success;
  719. }
  720. BOOL LLDataPackerAsciiBuffer::unpackU16(U16 &value, const char *name)
  721. {
  722. BOOL success = TRUE;
  723. char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */
  724. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  725. {
  726. return FALSE;
  727. }
  728. S32 in_val;
  729. sscanf(valuestr,"%d", &in_val);
  730. value = in_val;
  731. return success;
  732. }
  733. BOOL LLDataPackerAsciiBuffer::packU32(const U32 value, const char *name)
  734. {
  735. BOOL success = TRUE;
  736. writeIndentedName(name);
  737. int numCopied = 0;
  738. if (mWriteEnabled)
  739. {
  740.      numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%un", value); /* Flawfinder: ignore */
  741. }
  742. else
  743. {
  744. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%un", value); /* Flawfinder: ignore */
  745. }
  746. // snprintf returns number of bytes that would have been written
  747. // had the output not being truncated. In that case, it will
  748. // return either -1 or value >= passed in size value . So a check needs to be added
  749. // to detect truncation, and if there is any, only account for the
  750. // actual number of bytes written..and not what could have been
  751. // written.
  752. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  753. {
  754. numCopied = getBufferSize()-getCurrentSize();
  755. llwarns << "LLDataPackerAsciiBuffer::packU32: val truncated: " << llendl;
  756. }
  757. mCurBufferp += numCopied;
  758. return success;
  759. }
  760. BOOL LLDataPackerAsciiBuffer::unpackU32(U32 &value, const char *name)
  761. {
  762. BOOL success = TRUE;
  763. char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */
  764. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  765. {
  766. return FALSE;
  767. }
  768. sscanf(valuestr,"%u", &value);
  769. return success;
  770. }
  771. BOOL LLDataPackerAsciiBuffer::packS32(const S32 value, const char *name)
  772. {
  773. BOOL success = TRUE;
  774. writeIndentedName(name);
  775. int numCopied = 0;
  776. if (mWriteEnabled)
  777. {
  778.      numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%dn", value); /* Flawfinder: ignore */
  779. }
  780. else
  781. {
  782. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%dn", value); /* Flawfinder: ignore */
  783. }
  784. // snprintf returns number of bytes that would have been written
  785. // had the output not being truncated. In that case, it will
  786. // return either -1 or value >= passed in size value . So a check needs to be added
  787. // to detect truncation, and if there is any, only account for the
  788. // actual number of bytes written..and not what could have been
  789. // written.
  790. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  791. {
  792. numCopied = getBufferSize()-getCurrentSize();
  793. llwarns << "LLDataPackerAsciiBuffer::packS32: val truncated: " << llendl;
  794. }
  795. mCurBufferp += numCopied;
  796. return success;
  797. }
  798. BOOL LLDataPackerAsciiBuffer::unpackS32(S32 &value, const char *name)
  799. {
  800. BOOL success = TRUE;
  801. char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */
  802. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  803. {
  804. return FALSE;
  805. }
  806. sscanf(valuestr,"%d", &value);
  807. return success;
  808. }
  809. BOOL LLDataPackerAsciiBuffer::packF32(const F32 value, const char *name)
  810. {
  811. BOOL success = TRUE;
  812. writeIndentedName(name);
  813. int numCopied = 0;
  814. if (mWriteEnabled)
  815. {
  816.      numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%fn", value); /* Flawfinder: ignore */
  817. }
  818. else
  819. {
  820. numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%fn", value); /* Flawfinder: ignore */
  821. }
  822. // snprintf returns number of bytes that would have been written
  823. // had the output not being truncated. In that case, it will
  824. // return either -1 or value >= passed in size value . So a check needs to be added
  825. // to detect truncation, and if there is any, only account for the
  826. // actual number of bytes written..and not what could have been
  827. // written.
  828. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  829. {
  830. numCopied = getBufferSize()-getCurrentSize();
  831. llwarns << "LLDataPackerAsciiBuffer::packF32: val truncated: " << llendl;
  832. }
  833. mCurBufferp += numCopied;
  834. return success;
  835. }
  836. BOOL LLDataPackerAsciiBuffer::unpackF32(F32 &value, const char *name)
  837. {
  838. BOOL success = TRUE;
  839. char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */
  840. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  841. {
  842. return FALSE;
  843. }
  844. sscanf(valuestr,"%f", &value);
  845. return success;
  846. }
  847. BOOL LLDataPackerAsciiBuffer::packColor4(const LLColor4 &value, const char *name)
  848. {
  849. BOOL success = TRUE;
  850. writeIndentedName(name);
  851. int numCopied = 0;
  852. if (mWriteEnabled)
  853. {
  854.      numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f %fn", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
  855. }
  856. else
  857. {
  858. numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f %fn", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
  859. }
  860. // snprintf returns number of bytes that would have been written
  861. // had the output not being truncated. In that case, it will
  862. // return either -1 or value >= passed in size value . So a check needs to be added
  863. // to detect truncation, and if there is any, only account for the
  864. // actual number of bytes written..and not what could have been
  865. // written.
  866. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  867. {
  868. numCopied = getBufferSize()-getCurrentSize();
  869. llwarns << "LLDataPackerAsciiBuffer::packColor4: truncated: " << llendl;
  870. }
  871. mCurBufferp += numCopied;
  872. return success;
  873. }
  874. BOOL LLDataPackerAsciiBuffer::unpackColor4(LLColor4 &value, const char *name)
  875. {
  876. BOOL success = TRUE;
  877. char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */
  878. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  879. {
  880. return FALSE;
  881. }
  882. sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]);
  883. return success;
  884. }
  885. BOOL LLDataPackerAsciiBuffer::packColor4U(const LLColor4U &value, const char *name)
  886. {
  887. BOOL success = TRUE;
  888. writeIndentedName(name);
  889. int numCopied = 0;
  890. if (mWriteEnabled)
  891. {
  892. numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d %d %d %dn", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
  893. }
  894. else
  895. {
  896. numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%d %d %d %dn", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
  897. }
  898. // snprintf returns number of bytes that would have been written
  899. // had the output not being truncated. In that case, it will
  900. // return either -1 or value >= passed in size value . So a check needs to be added
  901. // to detect truncation, and if there is any, only account for the
  902. // actual number of bytes written..and not what could have been
  903. // written.
  904. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  905. {
  906. numCopied = getBufferSize()-getCurrentSize();
  907. llwarns << "LLDataPackerAsciiBuffer::packColor4U: truncated: " << llendl;
  908. }
  909. mCurBufferp += numCopied;
  910. return success;
  911. }
  912. BOOL LLDataPackerAsciiBuffer::unpackColor4U(LLColor4U &value, const char *name)
  913. {
  914. BOOL success = TRUE;
  915. char valuestr[DP_BUFSIZE];  /* Flawfinder: ignore */ 
  916. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  917. {
  918. return FALSE;
  919. }
  920. S32 r, g, b, a;
  921. sscanf(valuestr,"%d %d %d %d", &r, &g, &b, &a);
  922. value.mV[0] = r;
  923. value.mV[1] = g;
  924. value.mV[2] = b;
  925. value.mV[3] = a;
  926. return success;
  927. }
  928. BOOL LLDataPackerAsciiBuffer::packVector2(const LLVector2 &value, const char *name)
  929. {
  930. BOOL success = TRUE;
  931. writeIndentedName(name);
  932. int numCopied = 0;
  933. if (mWriteEnabled)
  934. {
  935.      numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %fn", value.mV[0], value.mV[1]); /* Flawfinder: ignore */
  936. }
  937. else
  938. {
  939. numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %fn", value.mV[0], value.mV[1]); /* Flawfinder: ignore */
  940. }
  941. // snprintf returns number of bytes that would have been written
  942. // had the output not being truncated. In that case, it will
  943. // return either -1 or value >= passed in size value . So a check needs to be added
  944. // to detect truncation, and if there is any, only account for the
  945. // actual number of bytes written..and not what could have been
  946. // written.
  947. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  948. {
  949. numCopied = getBufferSize()-getCurrentSize();
  950. llwarns << "LLDataPackerAsciiBuffer::packVector2: truncated: " << llendl;
  951. }
  952. mCurBufferp += numCopied;
  953. return success;
  954. }
  955. BOOL LLDataPackerAsciiBuffer::unpackVector2(LLVector2 &value, const char *name)
  956. {
  957. BOOL success = TRUE;
  958. char valuestr[DP_BUFSIZE];  /* Flawfinder: ignore */ 
  959. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  960. {
  961. return FALSE;
  962. }
  963. sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]);
  964. return success;
  965. }
  966. BOOL LLDataPackerAsciiBuffer::packVector3(const LLVector3 &value, const char *name)
  967. {
  968. BOOL success = TRUE;
  969. writeIndentedName(name);
  970. int numCopied = 0;
  971. if (mWriteEnabled)
  972. {
  973.      numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %fn", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */
  974. }
  975. else
  976. {
  977. numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %fn", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */
  978. }
  979. // snprintf returns number of bytes that would have been written
  980. // had the output not being truncated. In that case, it will
  981. // return either -1 or value >= passed in size value . So a check needs to be added
  982. // to detect truncation, and if there is any, only account for the
  983. // actual number of bytes written..and not what could have been
  984. // written.
  985. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  986. {
  987.     numCopied = getBufferSize()-getCurrentSize();
  988. llwarns << "LLDataPackerAsciiBuffer::packVector3: truncated: " << llendl;
  989. }
  990. mCurBufferp += numCopied;
  991. return success;
  992. }
  993. BOOL LLDataPackerAsciiBuffer::unpackVector3(LLVector3 &value, const char *name)
  994. {
  995. BOOL success = TRUE;
  996. char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ 
  997. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  998. {
  999. return FALSE;
  1000. }
  1001. sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]);
  1002. return success;
  1003. }
  1004. BOOL LLDataPackerAsciiBuffer::packVector4(const LLVector4 &value, const char *name)
  1005. {
  1006. BOOL success = TRUE;
  1007. writeIndentedName(name);
  1008. int numCopied = 0;
  1009. if (mWriteEnabled)
  1010. {
  1011.      numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f %fn", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
  1012. }
  1013. else
  1014. {
  1015. numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f %fn", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
  1016. }
  1017. // snprintf returns number of bytes that would have been written
  1018. // had the output not being truncated. In that case, it will
  1019. // return either -1 or value >= passed in size value . So a check needs to be added
  1020. // to detect truncation, and if there is any, only account for the
  1021. // actual number of bytes written..and not what could have been
  1022. // written.
  1023. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  1024. {
  1025.     numCopied = getBufferSize()-getCurrentSize();
  1026. llwarns << "LLDataPackerAsciiBuffer::packVector4: truncated: " << llendl;
  1027. }
  1028. mCurBufferp += numCopied;
  1029. return success;
  1030. }
  1031. BOOL LLDataPackerAsciiBuffer::unpackVector4(LLVector4 &value, const char *name)
  1032. {
  1033. BOOL success = TRUE;
  1034. char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ 
  1035. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1036. {
  1037. return FALSE;
  1038. }
  1039. sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]);
  1040. return success;
  1041. }
  1042. BOOL LLDataPackerAsciiBuffer::packUUID(const LLUUID &value, const char *name)
  1043. {
  1044. BOOL success = TRUE;
  1045. writeIndentedName(name);
  1046. int numCopied = 0;
  1047. if (mWriteEnabled)
  1048. {
  1049. std::string tmp_str;
  1050. value.toString(tmp_str);
  1051. numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%sn", tmp_str.c_str()); /* Flawfinder: ignore */
  1052. }
  1053. else
  1054. {
  1055. numCopied = 64 + 1; // UUID + newline
  1056. }
  1057. // snprintf returns number of bytes that would have been written
  1058. // had the output not being truncated. In that case, it will
  1059. // return either -1 or value >= passed in size value . So a check needs to be added
  1060. // to detect truncation, and if there is any, only account for the
  1061. // actual number of bytes written..and not what could have been
  1062. // written.
  1063. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  1064. {
  1065.     numCopied = getBufferSize()-getCurrentSize();
  1066. llwarns << "LLDataPackerAsciiBuffer::packUUID: truncated: " << llendl;
  1067. success = FALSE;
  1068. }
  1069. mCurBufferp += numCopied;
  1070. return success;
  1071. }
  1072. BOOL LLDataPackerAsciiBuffer::unpackUUID(LLUUID &value, const char *name)
  1073. {
  1074. BOOL success = TRUE;
  1075. char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */
  1076. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1077. {
  1078. return FALSE;
  1079. }
  1080. char tmp_str[64]; /* Flawfinder: ignore */
  1081. sscanf(valuestr, "%63s", tmp_str); /* Flawfinder: ignore */
  1082. value.set(tmp_str);
  1083. return success;
  1084. }
  1085. void LLDataPackerAsciiBuffer::dump()
  1086. {
  1087. llinfos << "Buffer: " << mBufferp << llendl;
  1088. }
  1089. void LLDataPackerAsciiBuffer::writeIndentedName(const char *name)
  1090. {
  1091. if (mIncludeNames)
  1092. {
  1093. int numCopied = 0;
  1094. if (mWriteEnabled)
  1095. {
  1096. numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%st", name); /* Flawfinder: ignore */
  1097. }
  1098. else
  1099. {
  1100. numCopied = (S32)strlen(name) + 1;  /* Flawfinder: ignore */ //name + tab  
  1101. }
  1102. // snprintf returns number of bytes that would have been written
  1103. // had the output not being truncated. In that case, it will
  1104. // return either -1 or value >= passed in size value . So a check needs to be added
  1105. // to detect truncation, and if there is any, only account for the
  1106. // actual number of bytes written..and not what could have been
  1107. // written.
  1108. if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
  1109. {
  1110. numCopied = getBufferSize()-getCurrentSize();
  1111. llwarns << "LLDataPackerAsciiBuffer::writeIndentedName: truncated: " << llendl;
  1112. }
  1113. mCurBufferp += numCopied;
  1114. }
  1115. }
  1116. BOOL LLDataPackerAsciiBuffer::getValueStr(const char *name, char *out_value, S32 value_len)
  1117. {
  1118. BOOL success = TRUE;
  1119. char buffer[DP_BUFSIZE]; /* Flawfinder: ignore */
  1120. char keyword[DP_BUFSIZE]; /* Flawfinder: ignore */
  1121. char value[DP_BUFSIZE]; /* Flawfinder: ignore */
  1122. buffer[0] = '';
  1123. keyword[0] = '';
  1124. value[0] = '';
  1125. if (mIncludeNames)
  1126. {
  1127. // Read both the name and the value, and validate the name.
  1128. sscanf(mCurBufferp, "%511[^n]", buffer);
  1129. // Skip the n
  1130. mCurBufferp += (S32)strlen(buffer) + 1; /* Flawfinder: ignore */
  1131. sscanf(buffer, "%511s %511[^n]", keyword, value); /* Flawfinder: ignore */
  1132. if (strcmp(keyword, name))
  1133. {
  1134. llwarns << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << llendl;
  1135. return FALSE;
  1136. }
  1137. }
  1138. else
  1139. {
  1140. // Just the value exists
  1141. sscanf(mCurBufferp, "%511[^n]", value);
  1142. // Skip the n
  1143. mCurBufferp += (S32)strlen(value) + 1; /* Flawfinder: ignore */
  1144. }
  1145. S32 in_value_len = (S32)strlen(value)+1; /* Flawfinder: ignore */
  1146. S32 min_len = llmin(in_value_len, value_len);
  1147. memcpy(out_value, value, min_len); /* Flawfinder: ignore */
  1148. out_value[min_len-1] = 0;
  1149. return success;
  1150. }
  1151. // helper function used by LLDataPackerAsciiFile
  1152. // to convert F32 into a string. This is to avoid
  1153. // << operator writing F32 value into a stream 
  1154. // since it does not seem to preserve the float value
  1155. std::string convertF32ToString(F32 val)
  1156. {
  1157. std::string str;
  1158. char  buf[20];
  1159. snprintf(buf, 20, "%f", val);
  1160. str = buf;
  1161. return str;
  1162. }
  1163. //---------------------------------------------------------------------------
  1164. // LLDataPackerAsciiFile implementation
  1165. //---------------------------------------------------------------------------
  1166. BOOL LLDataPackerAsciiFile::packString(const std::string& value, const char *name)
  1167. {
  1168. BOOL success = TRUE;
  1169. writeIndentedName(name);
  1170. if (mFP)
  1171. {
  1172. fprintf(mFP,"%sn", value.c_str());
  1173. }
  1174. else if (mOutputStream)
  1175. {
  1176. *mOutputStream << value << "n";
  1177. }
  1178. return success;
  1179. }
  1180. BOOL LLDataPackerAsciiFile::unpackString(std::string& value, const char *name)
  1181. {
  1182. BOOL success = TRUE;
  1183. char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */
  1184. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1185. {
  1186. return FALSE;
  1187. }
  1188. value = valuestr;
  1189. return success;
  1190. }
  1191. BOOL LLDataPackerAsciiFile::packBinaryData(const U8 *value, S32 size, const char *name)
  1192. {
  1193. BOOL success = TRUE;
  1194. writeIndentedName(name);
  1195. if (mFP)
  1196. {
  1197. fprintf(mFP, "%010d ", size);
  1198. S32 i;
  1199. for (i = 0; i < size; i++)
  1200. {
  1201. fprintf(mFP, "%02x ", value[i]);
  1202. }
  1203. fprintf(mFP, "n");
  1204. }
  1205. else if (mOutputStream)
  1206. {
  1207. char buffer[32]; /* Flawfinder: ignore */
  1208. snprintf(buffer,sizeof(buffer), "%010d ", size); /* Flawfinder: ignore */
  1209. *mOutputStream << buffer;
  1210. S32 i;
  1211. for (i = 0; i < size; i++)
  1212. {
  1213. snprintf(buffer, sizeof(buffer), "%02x ", value[i]); /* Flawfinder: ignore */
  1214. *mOutputStream << buffer;
  1215. }
  1216. *mOutputStream << "n";
  1217. }
  1218. return success;
  1219. }
  1220. BOOL LLDataPackerAsciiFile::unpackBinaryData(U8 *value, S32 &size, const char *name)
  1221. {
  1222. BOOL success = TRUE;
  1223. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/
  1224. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1225. {
  1226. return FALSE;
  1227. }
  1228. char *cur_pos = &valuestr[0];
  1229. sscanf(valuestr,"%010d", &size);
  1230. cur_pos += 11;
  1231. S32 i;
  1232. for (i = 0; i < size; i++)
  1233. {
  1234. S32 val;
  1235. sscanf(cur_pos,"%02x", &val);
  1236. value[i] = val;
  1237. cur_pos += 3;
  1238. }
  1239. return success;
  1240. }
  1241. BOOL LLDataPackerAsciiFile::packBinaryDataFixed(const U8 *value, S32 size, const char *name)
  1242. {
  1243. BOOL success = TRUE;
  1244. writeIndentedName(name);
  1245. if (mFP)
  1246. {
  1247. S32 i;
  1248. for (i = 0; i < size; i++)
  1249. {
  1250. fprintf(mFP, "%02x ", value[i]);
  1251. }
  1252. fprintf(mFP, "n");
  1253. }
  1254. else if (mOutputStream)
  1255. {
  1256. char buffer[32]; /*Flawfinder: ignore*/
  1257. S32 i;
  1258. for (i = 0; i < size; i++)
  1259. {
  1260. snprintf(buffer, sizeof(buffer), "%02x ", value[i]); /* Flawfinder: ignore */
  1261. *mOutputStream << buffer;
  1262. }
  1263. *mOutputStream << "n";
  1264. }
  1265. return success;
  1266. }
  1267. BOOL LLDataPackerAsciiFile::unpackBinaryDataFixed(U8 *value, S32 size, const char *name)
  1268. {
  1269. BOOL success = TRUE;
  1270. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/
  1271. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1272. {
  1273. return FALSE;
  1274. }
  1275. char *cur_pos = &valuestr[0];
  1276. S32 i;
  1277. for (i = 0; i < size; i++)
  1278. {
  1279. S32 val;
  1280. sscanf(cur_pos,"%02x", &val);
  1281. value[i] = val;
  1282. cur_pos += 3;
  1283. }
  1284. return success;
  1285. }
  1286. BOOL LLDataPackerAsciiFile::packU8(const U8 value, const char *name)
  1287. {
  1288. BOOL success = TRUE;
  1289. writeIndentedName(name);
  1290. if (mFP)
  1291. {
  1292. fprintf(mFP,"%dn", value);
  1293. }
  1294. else if (mOutputStream)
  1295. {
  1296. // We have to cast this to an integer because streams serialize
  1297. // bytes as bytes - not as text.
  1298. *mOutputStream << (S32)value << "n";
  1299. }
  1300. return success;
  1301. }
  1302. BOOL LLDataPackerAsciiFile::unpackU8(U8 &value, const char *name)
  1303. {
  1304. BOOL success = TRUE;
  1305. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
  1306. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1307. {
  1308. return FALSE;
  1309. }
  1310. S32 in_val;
  1311. sscanf(valuestr,"%d", &in_val);
  1312. value = in_val;
  1313. return success;
  1314. }
  1315. BOOL LLDataPackerAsciiFile::packU16(const U16 value, const char *name)
  1316. {
  1317. BOOL success = TRUE;
  1318. writeIndentedName(name);
  1319. if (mFP)
  1320. {
  1321. fprintf(mFP,"%dn", value);
  1322. }
  1323. else if (mOutputStream)
  1324. {
  1325. *mOutputStream <<"" << value << "n";
  1326. }
  1327. return success;
  1328. }
  1329. BOOL LLDataPackerAsciiFile::unpackU16(U16 &value, const char *name)
  1330. {
  1331. BOOL success = TRUE;
  1332. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
  1333. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1334. {
  1335. return FALSE;
  1336. }
  1337. S32 in_val;
  1338. sscanf(valuestr,"%d", &in_val);
  1339. value = in_val;
  1340. return success;
  1341. }
  1342. BOOL LLDataPackerAsciiFile::packU32(const U32 value, const char *name)
  1343. {
  1344. BOOL success = TRUE;
  1345. writeIndentedName(name);
  1346. if (mFP)
  1347. {
  1348. fprintf(mFP,"%un", value);
  1349. }
  1350. else if (mOutputStream)
  1351. {
  1352. *mOutputStream <<"" << value << "n";
  1353. }
  1354. return success;
  1355. }
  1356. BOOL LLDataPackerAsciiFile::unpackU32(U32 &value, const char *name)
  1357. {
  1358. BOOL success = TRUE;
  1359. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
  1360. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1361. {
  1362. return FALSE;
  1363. }
  1364. sscanf(valuestr,"%u", &value);
  1365. return success;
  1366. }
  1367. BOOL LLDataPackerAsciiFile::packS32(const S32 value, const char *name)
  1368. {
  1369. BOOL success = TRUE;
  1370. writeIndentedName(name);
  1371. if (mFP)
  1372. {
  1373. fprintf(mFP,"%dn", value);
  1374. }
  1375. else if (mOutputStream)
  1376. {
  1377. *mOutputStream <<"" << value << "n";
  1378. }
  1379. return success;
  1380. }
  1381. BOOL LLDataPackerAsciiFile::unpackS32(S32 &value, const char *name)
  1382. {
  1383. BOOL success = TRUE;
  1384. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
  1385. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1386. {
  1387. return FALSE;
  1388. }
  1389. sscanf(valuestr,"%d", &value);
  1390. return success;
  1391. }
  1392. BOOL LLDataPackerAsciiFile::packF32(const F32 value, const char *name)
  1393. {
  1394. BOOL success = TRUE;
  1395. writeIndentedName(name);
  1396. if (mFP)
  1397. {
  1398. fprintf(mFP,"%fn", value);
  1399. }
  1400. else if (mOutputStream)
  1401. {
  1402. *mOutputStream <<"" << convertF32ToString(value) << "n";
  1403. }
  1404. return success;
  1405. }
  1406. BOOL LLDataPackerAsciiFile::unpackF32(F32 &value, const char *name)
  1407. {
  1408. BOOL success = TRUE;
  1409. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
  1410. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1411. {
  1412. return FALSE;
  1413. }
  1414. sscanf(valuestr,"%f", &value);
  1415. return success;
  1416. }
  1417. BOOL LLDataPackerAsciiFile::packColor4(const LLColor4 &value, const char *name)
  1418. {
  1419. BOOL success = TRUE;
  1420. writeIndentedName(name);
  1421. if (mFP)
  1422. {
  1423. fprintf(mFP,"%f %f %f %fn", value.mV[0], value.mV[1], value.mV[2], value.mV[3]);
  1424. }
  1425. else if (mOutputStream)
  1426. {
  1427. *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(value.mV[3]) << "n";
  1428. }
  1429. return success;
  1430. }
  1431. BOOL LLDataPackerAsciiFile::unpackColor4(LLColor4 &value, const char *name)
  1432. {
  1433. BOOL success = TRUE;
  1434. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
  1435. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1436. {
  1437. return FALSE;
  1438. }
  1439. sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]);
  1440. return success;
  1441. }
  1442. BOOL LLDataPackerAsciiFile::packColor4U(const LLColor4U &value, const char *name)
  1443. {
  1444. BOOL success = TRUE;
  1445. writeIndentedName(name);
  1446. if (mFP)
  1447. {
  1448. fprintf(mFP,"%d %d %d %dn", value.mV[0], value.mV[1], value.mV[2], value.mV[3]);
  1449. }
  1450. else if (mOutputStream)
  1451. {
  1452. *mOutputStream << (S32)(value.mV[0]) << " " << (S32)(value.mV[1]) << " " << (S32)(value.mV[2]) << " " << (S32)(value.mV[3]) << "n";
  1453. }
  1454. return success;
  1455. }
  1456. BOOL LLDataPackerAsciiFile::unpackColor4U(LLColor4U &value, const char *name)
  1457. {
  1458. BOOL success = TRUE;
  1459. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
  1460. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1461. {
  1462. return FALSE;
  1463. }
  1464. S32 r, g, b, a;
  1465. sscanf(valuestr,"%d %d %d %d", &r, &g, &b, &a);
  1466. value.mV[0] = r;
  1467. value.mV[1] = g;
  1468. value.mV[2] = b;
  1469. value.mV[3] = a;
  1470. return success;
  1471. }
  1472. BOOL LLDataPackerAsciiFile::packVector2(const LLVector2 &value, const char *name)
  1473. {
  1474. BOOL success = TRUE;
  1475. writeIndentedName(name);
  1476. if (mFP)
  1477. {
  1478. fprintf(mFP,"%f %fn", value.mV[0], value.mV[1]);
  1479. }
  1480. else if (mOutputStream)
  1481. {
  1482. *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << "n";
  1483. }
  1484. return success;
  1485. }
  1486. BOOL LLDataPackerAsciiFile::unpackVector2(LLVector2 &value, const char *name)
  1487. {
  1488. BOOL success = TRUE;
  1489. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
  1490. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1491. {
  1492. return FALSE;
  1493. }
  1494. sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]);
  1495. return success;
  1496. }
  1497. BOOL LLDataPackerAsciiFile::packVector3(const LLVector3 &value, const char *name)
  1498. {
  1499. BOOL success = TRUE;
  1500. writeIndentedName(name);
  1501. if (mFP)
  1502. {
  1503. fprintf(mFP,"%f %f %fn", value.mV[0], value.mV[1], value.mV[2]);
  1504. }
  1505. else if (mOutputStream)
  1506. {
  1507. *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << "n";
  1508. }
  1509. return success;
  1510. }
  1511. BOOL LLDataPackerAsciiFile::unpackVector3(LLVector3 &value, const char *name)
  1512. {
  1513. BOOL success = TRUE;
  1514. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
  1515. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1516. {
  1517. return FALSE;
  1518. }
  1519. sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]);
  1520. return success;
  1521. }
  1522. BOOL LLDataPackerAsciiFile::packVector4(const LLVector4 &value, const char *name)
  1523. {
  1524. BOOL success = TRUE;
  1525. writeIndentedName(name);
  1526. if (mFP)
  1527. {
  1528. fprintf(mFP,"%f %f %f %fn", value.mV[0], value.mV[1], value.mV[2], value.mV[3]);
  1529. }
  1530. else if (mOutputStream)
  1531. {
  1532. *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(value.mV[3]) << "n";
  1533. }
  1534. return success;
  1535. }
  1536. BOOL LLDataPackerAsciiFile::unpackVector4(LLVector4 &value, const char *name)
  1537. {
  1538. BOOL success = TRUE;
  1539. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
  1540. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1541. {
  1542. return FALSE;
  1543. }
  1544. sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]);
  1545. return success;
  1546. }
  1547. BOOL LLDataPackerAsciiFile::packUUID(const LLUUID &value, const char *name)
  1548. {
  1549. BOOL success = TRUE;
  1550. writeIndentedName(name);
  1551. std::string tmp_str;
  1552. value.toString(tmp_str);
  1553. if (mFP)
  1554. {
  1555. fprintf(mFP,"%sn", tmp_str.c_str());
  1556. }
  1557. else if (mOutputStream)
  1558. {
  1559. *mOutputStream <<"" << tmp_str << "n";
  1560. }
  1561. return success;
  1562. }
  1563. BOOL LLDataPackerAsciiFile::unpackUUID(LLUUID &value, const char *name)
  1564. {
  1565. BOOL success = TRUE;
  1566. char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
  1567. if (!getValueStr(name, valuestr, DP_BUFSIZE))
  1568. {
  1569. return FALSE;
  1570. }
  1571. char tmp_str[64]; /*Flawfinder: ignore */
  1572. sscanf(valuestr,"%63s",tmp_str); /* Flawfinder: ignore */
  1573. value.set(tmp_str);
  1574. return success;
  1575. }
  1576. void LLDataPackerAsciiFile::writeIndentedName(const char *name)
  1577. {
  1578. std::string indent_buf;
  1579. indent_buf.reserve(mIndent+1);
  1580. S32 i;
  1581. for(i = 0; i < mIndent; i++)
  1582. {
  1583. indent_buf[i] = 't';
  1584. }
  1585. indent_buf[i] = 0;
  1586. if (mFP)
  1587. {
  1588. fprintf(mFP,"%s%st",indent_buf.c_str(), name);
  1589. }
  1590. else if (mOutputStream)
  1591. {
  1592. *mOutputStream << indent_buf << name << "t";
  1593. }
  1594. }
  1595. BOOL LLDataPackerAsciiFile::getValueStr(const char *name, char *out_value, S32 value_len)
  1596. {
  1597. BOOL success = FALSE;
  1598. char buffer[DP_BUFSIZE]; /*Flawfinder: ignore*/
  1599. char keyword[DP_BUFSIZE]; /*Flawfinder: ignore*/
  1600. char value[DP_BUFSIZE]; /*Flawfinder: ignore*/
  1601. buffer[0] = '';
  1602. keyword[0] = '';
  1603. value[0] = '';
  1604. if (mFP)
  1605. {
  1606. fpos_t last_pos;
  1607. if (0 != fgetpos(mFP, &last_pos)) // 0==success for fgetpos
  1608. {
  1609. llwarns << "Data packer failed to fgetpos" << llendl;
  1610. return FALSE;
  1611. }
  1612. if (fgets(buffer, DP_BUFSIZE, mFP) == NULL)
  1613. {
  1614. buffer[0] = '';
  1615. }
  1616. sscanf(buffer, "%511s %511[^n]", keyword, value); /* Flawfinder: ignore */
  1617. if (!keyword[0])
  1618. {
  1619. llwarns << "Data packer could not get the keyword!" << llendl;
  1620. fsetpos(mFP, &last_pos);
  1621. return FALSE;
  1622. }
  1623. if (strcmp(keyword, name))
  1624. {
  1625. llwarns << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << llendl;
  1626. fsetpos(mFP, &last_pos);
  1627. return FALSE;
  1628. }
  1629. S32 in_value_len = (S32)strlen(value)+1; /*Flawfinder: ignore*/
  1630. S32 min_len = llmin(in_value_len, value_len);
  1631. memcpy(out_value, value, min_len); /*Flawfinder: ignore*/
  1632. out_value[min_len-1] = 0;
  1633. success = TRUE;
  1634. }
  1635. else if (mInputStream)
  1636. {
  1637. mInputStream->getline(buffer, DP_BUFSIZE);
  1638. sscanf(buffer, "%511s %511[^n]", keyword, value); /* Flawfinder: ignore */
  1639. if (!keyword[0])
  1640. {
  1641. llwarns << "Data packer could not get the keyword!" << llendl;
  1642. return FALSE;
  1643. }
  1644. if (strcmp(keyword, name))
  1645. {
  1646. llwarns << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << llendl;
  1647. return FALSE;
  1648. }
  1649. S32 in_value_len = (S32)strlen(value)+1; /*Flawfinder: ignore*/
  1650. S32 min_len = llmin(in_value_len, value_len);
  1651. memcpy(out_value, value, min_len); /*Flawfinder: ignore*/
  1652. out_value[min_len-1] = 0;
  1653. success = TRUE;
  1654. }
  1655. return success;
  1656. }