PageRenderTime 39ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmessage/lldatapacker.cpp

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