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