lldatapacker.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "lldatapacker.h"
00035 #include "llerror.h"
00036 
00037 #include "message.h"
00038 
00039 #include "v4color.h"
00040 #include "v4coloru.h"
00041 #include "v2math.h"
00042 #include "v3math.h"
00043 #include "v4math.h"
00044 #include "lluuid.h"
00045 
00046 // *NOTE: there are functions below which use sscanf and rely on this
00047 // particular value of DP_BUFSIZE. Search for '511' (DP_BUFSIZE - 1)
00048 // to find them if you change this number.
00049 const S32 DP_BUFSIZE = 512;
00050 
00051 static char DUMMY_BUFFER[128]; /*Flawfinder: ignore*/
00052 
00053 LLDataPacker::LLDataPacker() : mPassFlags(0), mWriteEnabled(FALSE)
00054 {
00055 }
00056 
00057 BOOL LLDataPacker::packFixed(const F32 value, const char *name,
00058                                                          const BOOL is_signed, const U32 int_bits, const U32 frac_bits)
00059 {
00060         BOOL success = TRUE;
00061         S32 unsigned_bits = int_bits + frac_bits;
00062         S32 total_bits = unsigned_bits;
00063 
00064         if (is_signed)
00065         {
00066                 total_bits++;
00067         }
00068 
00069         S32 min_val;
00070         U32 max_val;
00071         if (is_signed)
00072         {
00073                 min_val = 1 << int_bits;
00074                 min_val *= -1;
00075         }
00076         else
00077         {
00078                 min_val = 0;
00079         }
00080         max_val = 1 << int_bits;
00081 
00082         // Clamp to be within range
00083         F32 fixed_val = llclamp(value, (F32)min_val, (F32)max_val);
00084         if (is_signed)
00085         {
00086                 fixed_val += max_val;
00087         }
00088         fixed_val *= 1 << frac_bits;
00089 
00090         if (total_bits <= 8)
00091         {
00092                 packU8((U8)fixed_val, name);
00093         }
00094         else if (total_bits <= 16)
00095         {
00096                 packU16((U16)fixed_val, name);
00097         }
00098         else if (total_bits <= 31)
00099         {
00100                 packU32((U32)fixed_val, name);
00101         }
00102         else
00103         {
00104                 llerrs << "Using fixed-point packing of " << total_bits << " bits, why?!" << llendl;
00105         }
00106         return success;
00107 }
00108 
00109 BOOL LLDataPacker::unpackFixed(F32 &value, const char *name,
00110                                                            const BOOL is_signed, const U32 int_bits, const U32 frac_bits)
00111 {
00112         //BOOL success = TRUE;
00113         //llinfos << "unpackFixed:" << name << " int:" << int_bits << " frac:" << frac_bits << llendl;
00114         BOOL ok = FALSE;
00115         S32 unsigned_bits = int_bits + frac_bits;
00116         S32 total_bits = unsigned_bits;
00117 
00118         if (is_signed)
00119         {
00120                 total_bits++;
00121         }
00122 
00123         S32 min_val;
00124         U32 max_val;
00125         if (is_signed)
00126         {
00127                 min_val = 1 << int_bits;
00128                 min_val *= -1;
00129         }
00130         max_val = 1 << int_bits;
00131 
00132         F32 fixed_val;
00133         if (total_bits <= 8)
00134         {
00135                 U8 fixed_8;
00136                 ok = unpackU8(fixed_8, name);
00137                 fixed_val = (F32)fixed_8;
00138         }
00139         else if (total_bits <= 16)
00140         {
00141                 U16 fixed_16;
00142                 ok = unpackU16(fixed_16, name);
00143                 fixed_val = (F32)fixed_16;
00144         }
00145         else if (total_bits <= 31)
00146         {
00147                 U32 fixed_32;
00148                 ok = unpackU32(fixed_32, name);
00149                 fixed_val = (F32)fixed_32;
00150         }
00151         else
00152         {
00153                 fixed_val = 0;
00154                 llerrs << "Bad bit count: " << total_bits << llendl;
00155         }
00156 
00157         //llinfos << "Fixed_val:" << fixed_val << llendl;
00158 
00159         fixed_val /= (F32)(1 << frac_bits);
00160         if (is_signed)
00161         {
00162                 fixed_val -= max_val;
00163         }
00164         value = fixed_val;
00165         //llinfos << "Value: " << value << llendl;
00166         return ok;
00167 }
00168 
00169 //---------------------------------------------------------------------------
00170 // LLDataPackerBinaryBuffer implementation
00171 //---------------------------------------------------------------------------
00172 
00173 BOOL LLDataPackerBinaryBuffer::packString(const char *value, const char *name)
00174 {
00175         BOOL success = TRUE;
00176         S32 length = (S32)strlen(value) + 1; /*Flawfinder: ignore*/
00177 
00178         success &= verifyLength(length, name);
00179 
00180         if (mWriteEnabled) 
00181         {
00182                 htonmemcpy(mCurBufferp, value, MVT_VARIABLE, length);  
00183         }
00184         mCurBufferp += length;
00185         return success;
00186 }
00187 
00188 
00189 BOOL LLDataPackerBinaryBuffer::unpackString(std::string& value, const char *name)
00190 {
00191         BOOL success = TRUE;
00192         S32 length = (S32)strlen((char *)mCurBufferp) + 1; /*Flawfinder: ignore*/
00193 
00194         success &= verifyLength(length, name);
00195 
00196         value = std::string((char*)mCurBufferp); // We already assume NULL termination calling strlen()
00197         
00198         mCurBufferp += length;
00199         return success;
00200 }
00201 
00202 BOOL LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const char *name)
00203 {
00204         BOOL success = TRUE;
00205         success &= verifyLength(size + 4, name);
00206 
00207         if (mWriteEnabled) 
00208         { 
00209                 htonmemcpy(mCurBufferp, &size, MVT_S32, 4);  
00210         }
00211         mCurBufferp += 4;
00212         if (mWriteEnabled) 
00213         { 
00214                 htonmemcpy(mCurBufferp, value, MVT_VARIABLE, size);  
00215         }
00216         mCurBufferp += size;
00217         return success;
00218 }
00219 
00220 
00221 BOOL LLDataPackerBinaryBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name)
00222 {
00223         BOOL success = TRUE;
00224         success &= verifyLength(4, name);
00225         htonmemcpy(&size, mCurBufferp, MVT_S32, 4);
00226         mCurBufferp += 4;
00227         success &= verifyLength(size, name);
00228         if (success)
00229         {
00230                 htonmemcpy(value, mCurBufferp, MVT_VARIABLE, size);
00231                 mCurBufferp += size;
00232         }
00233         else
00234         {
00235                 llwarns << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << llendl;
00236                 success = FALSE;
00237         }
00238         return success;
00239 }
00240 
00241 
00242 BOOL LLDataPackerBinaryBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name)
00243 {
00244         BOOL success = TRUE;
00245         success &= verifyLength(size, name);
00246 
00247         if (mWriteEnabled) 
00248         { 
00249                 htonmemcpy(mCurBufferp, value, MVT_VARIABLE, size);  
00250         }
00251         mCurBufferp += size;
00252         return success;
00253 }
00254 
00255 
00256 BOOL LLDataPackerBinaryBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name)
00257 {
00258         BOOL success = TRUE;
00259         success &= verifyLength(size, name);
00260         htonmemcpy(value, mCurBufferp, MVT_VARIABLE, size);
00261         mCurBufferp += size;
00262         return success;
00263 }
00264 
00265 
00266 BOOL LLDataPackerBinaryBuffer::packU8(const U8 value, const char *name)
00267 {
00268         BOOL success = TRUE;
00269         success &= verifyLength(sizeof(U8), name);
00270 
00271         if (mWriteEnabled) 
00272         {
00273                 *mCurBufferp = value;
00274         }
00275         mCurBufferp++;
00276         return success;
00277 }
00278 
00279 
00280 BOOL LLDataPackerBinaryBuffer::unpackU8(U8 &value, const char *name)
00281 {
00282         BOOL success = TRUE;
00283         success &= verifyLength(sizeof(U8), name);
00284 
00285         value = *mCurBufferp;
00286         mCurBufferp++;
00287         return success;
00288 }
00289 
00290 
00291 BOOL LLDataPackerBinaryBuffer::packU16(const U16 value, const char *name)
00292 {
00293         BOOL success = TRUE;
00294         success &= verifyLength(sizeof(U16), name);
00295 
00296         if (mWriteEnabled) 
00297         { 
00298                 htonmemcpy(mCurBufferp, &value, MVT_U16, 2);  
00299         }
00300         mCurBufferp += 2;
00301         return success;
00302 }
00303 
00304 
00305 BOOL LLDataPackerBinaryBuffer::unpackU16(U16 &value, const char *name)
00306 {
00307         BOOL success = TRUE;
00308         success &= verifyLength(sizeof(U16), name);
00309 
00310         htonmemcpy(&value, mCurBufferp, MVT_U16, 2);
00311         mCurBufferp += 2;
00312         return success;
00313 }
00314 
00315 
00316 BOOL LLDataPackerBinaryBuffer::packU32(const U32 value, const char *name)
00317 {
00318         BOOL success = TRUE;
00319         success &= verifyLength(sizeof(U32), name);
00320 
00321         if (mWriteEnabled) 
00322         { 
00323                 htonmemcpy(mCurBufferp, &value, MVT_U32, 4);  
00324         }
00325         mCurBufferp += 4;
00326         return success;
00327 }
00328 
00329 
00330 BOOL LLDataPackerBinaryBuffer::unpackU32(U32 &value, const char *name)
00331 {
00332         BOOL success = TRUE;
00333         success &= verifyLength(sizeof(U32), name);
00334 
00335         htonmemcpy(&value, mCurBufferp, MVT_U32, 4);
00336         mCurBufferp += 4;
00337         return success;
00338 }
00339 
00340 
00341 BOOL LLDataPackerBinaryBuffer::packS32(const S32 value, const char *name)
00342 {
00343         BOOL success = TRUE;
00344         success &= verifyLength(sizeof(S32), name);
00345 
00346         if (mWriteEnabled) 
00347         { 
00348                 htonmemcpy(mCurBufferp, &value, MVT_S32, 4); 
00349         }
00350         mCurBufferp += 4;
00351         return success;
00352 }
00353 
00354 
00355 BOOL LLDataPackerBinaryBuffer::unpackS32(S32 &value, const char *name)
00356 {
00357         BOOL success = TRUE;
00358         success &= verifyLength(sizeof(S32), name);
00359 
00360         htonmemcpy(&value, mCurBufferp, MVT_S32, 4);
00361         mCurBufferp += 4;
00362         return success;
00363 }
00364 
00365 
00366 BOOL LLDataPackerBinaryBuffer::packF32(const F32 value, const char *name)
00367 {
00368         BOOL success = TRUE;
00369         success &= verifyLength(sizeof(F32), name);
00370 
00371         if (mWriteEnabled) 
00372         { 
00373                 htonmemcpy(mCurBufferp, &value, MVT_F32, 4); 
00374         }
00375         mCurBufferp += 4;
00376         return success;
00377 }
00378 
00379 
00380 BOOL LLDataPackerBinaryBuffer::unpackF32(F32 &value, const char *name)
00381 {
00382         BOOL success = TRUE;
00383         success &= verifyLength(sizeof(F32), name);
00384 
00385         htonmemcpy(&value, mCurBufferp, MVT_F32, 4);
00386         mCurBufferp += 4;
00387         return success;
00388 }
00389 
00390 
00391 BOOL LLDataPackerBinaryBuffer::packColor4(const LLColor4 &value, const char *name)
00392 {
00393         BOOL success = TRUE;
00394         success &= verifyLength(16, name);
00395 
00396         if (mWriteEnabled) 
00397         { 
00398                 htonmemcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); 
00399         }
00400         mCurBufferp += 16;
00401         return success;
00402 }
00403 
00404 
00405 BOOL LLDataPackerBinaryBuffer::unpackColor4(LLColor4 &value, const char *name)
00406 {
00407         BOOL success = TRUE;
00408         success &= verifyLength(16, name);
00409 
00410         htonmemcpy(value.mV, mCurBufferp, MVT_LLVector4, 16);
00411         mCurBufferp += 16;
00412         return success;
00413 }
00414 
00415 
00416 BOOL LLDataPackerBinaryBuffer::packColor4U(const LLColor4U &value, const char *name)
00417 {
00418         BOOL success = TRUE;
00419         success &= verifyLength(4, name);
00420 
00421         if (mWriteEnabled) 
00422         { 
00423                 htonmemcpy(mCurBufferp, value.mV, MVT_VARIABLE, 4);  
00424         }
00425         mCurBufferp += 4;
00426         return success;
00427 }
00428 
00429 
00430 BOOL LLDataPackerBinaryBuffer::unpackColor4U(LLColor4U &value, const char *name)
00431 {
00432         BOOL success = TRUE;
00433         success &= verifyLength(4, name);
00434 
00435         htonmemcpy(value.mV, mCurBufferp, MVT_VARIABLE, 4);
00436         mCurBufferp += 4;
00437         return success;
00438 }
00439 
00440 
00441 
00442 BOOL LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *name)
00443 {
00444         BOOL success = TRUE;
00445         success &= verifyLength(8, name);
00446 
00447         if (mWriteEnabled) 
00448         { 
00449                 htonmemcpy(mCurBufferp, &value.mV[0], MVT_F32, 4);  
00450                 htonmemcpy(mCurBufferp+4, &value.mV[1], MVT_F32, 4);  
00451         }
00452         mCurBufferp += 8;
00453         return success;
00454 }
00455 
00456 
00457 BOOL LLDataPackerBinaryBuffer::unpackVector2(LLVector2 &value, const char *name)
00458 {
00459         BOOL success = TRUE;
00460         success &= verifyLength(8, name);
00461 
00462         htonmemcpy(&value.mV[0], mCurBufferp, MVT_F32, 4);
00463         htonmemcpy(&value.mV[1], mCurBufferp+4, MVT_F32, 4);
00464         mCurBufferp += 8;
00465         return success;
00466 }
00467 
00468 
00469 BOOL LLDataPackerBinaryBuffer::packVector3(const LLVector3 &value, const char *name)
00470 {
00471         BOOL success = TRUE;
00472         success &= verifyLength(12, name);
00473 
00474         if (mWriteEnabled) 
00475         { 
00476                 htonmemcpy(mCurBufferp, value.mV, MVT_LLVector3, 12);  
00477         }
00478         mCurBufferp += 12;
00479         return success;
00480 }
00481 
00482 
00483 BOOL LLDataPackerBinaryBuffer::unpackVector3(LLVector3 &value, const char *name)
00484 {
00485         BOOL success = TRUE;
00486         success &= verifyLength(12, name);
00487 
00488         htonmemcpy(value.mV, mCurBufferp, MVT_LLVector3, 12);
00489         mCurBufferp += 12;
00490         return success;
00491 }
00492 
00493 BOOL LLDataPackerBinaryBuffer::packVector4(const LLVector4 &value, const char *name)
00494 {
00495         BOOL success = TRUE;
00496         success &= verifyLength(16, name);
00497 
00498         if (mWriteEnabled) 
00499         { 
00500                 htonmemcpy(mCurBufferp, value.mV, MVT_LLVector4, 16);  
00501         }
00502         mCurBufferp += 16;
00503         return success;
00504 }
00505 
00506 
00507 BOOL LLDataPackerBinaryBuffer::unpackVector4(LLVector4 &value, const char *name)
00508 {
00509         BOOL success = TRUE;
00510         success &= verifyLength(16, name);
00511 
00512         htonmemcpy(value.mV, mCurBufferp, MVT_LLVector4, 16);
00513         mCurBufferp += 16;
00514         return success;
00515 }
00516 
00517 BOOL LLDataPackerBinaryBuffer::packUUID(const LLUUID &value, const char *name)
00518 {
00519         BOOL success = TRUE;
00520         success &= verifyLength(16, name);
00521 
00522         if (mWriteEnabled) 
00523         { 
00524                 htonmemcpy(mCurBufferp, value.mData, MVT_LLUUID, 16);  
00525         }
00526         mCurBufferp += 16;
00527         return success;
00528 }
00529 
00530 
00531 BOOL LLDataPackerBinaryBuffer::unpackUUID(LLUUID &value, const char *name)
00532 {
00533         BOOL success = TRUE;
00534         success &= verifyLength(16, name);
00535 
00536         htonmemcpy(value.mData, mCurBufferp, MVT_LLUUID, 16);
00537         mCurBufferp += 16;
00538         return success;
00539 }
00540 
00541 const LLDataPackerBinaryBuffer& LLDataPackerBinaryBuffer::operator=(const LLDataPackerBinaryBuffer &a)
00542 {
00543         if (a.getBufferSize() > getBufferSize())
00544         {
00545                 // We've got problems, ack!
00546                 llerrs << "Trying to do an assignment with not enough room in the target." << llendl;
00547         }
00548         memcpy(mBufferp, a.mBufferp, a.getBufferSize());        /*Flawfinder: ignore*/
00549         return *this;
00550 }
00551 
00552 void LLDataPackerBinaryBuffer::dumpBufferToLog()
00553 {
00554         llwarns << "Binary Buffer Dump, size: " << mBufferSize << llendl;
00555         char line_buffer[256]; /*Flawfinder: ignore*/
00556         S32 i;
00557         S32 cur_line_pos = 0;
00558 
00559         S32 cur_line = 0;
00560         for (i = 0; i < mBufferSize; i++)
00561         {
00562                 snprintf(line_buffer + cur_line_pos*3, sizeof(line_buffer) - cur_line_pos*3, "%02x ", mBufferp[i]);     /* Flawfinder: ignore */
00563                 cur_line_pos++;
00564                 if (cur_line_pos >= 16)
00565                 {
00566                         cur_line_pos = 0;
00567                         llwarns << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << llendl;
00568                         cur_line++;
00569                 }
00570         }
00571         if (cur_line_pos)
00572         {
00573                 llwarns << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << llendl;
00574         }
00575 }
00576 
00577 //---------------------------------------------------------------------------
00578 // LLDataPackerAsciiBuffer implementation
00579 //---------------------------------------------------------------------------
00580 BOOL LLDataPackerAsciiBuffer::packString(const char *value, const char *name)
00581 {
00582         BOOL success = TRUE;
00583         writeIndentedName(name);
00584         int numCopied = 0;
00585         if (mWriteEnabled) 
00586         {
00587                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\n", value);               /* Flawfinder: ignore */
00588         }
00589         else
00590         {
00591                 numCopied = (S32)strlen(value) + 1; /*Flawfinder: ignore*/
00592         }
00593 
00594         // snprintf returns number of bytes that would have been written
00595         // had the output not being truncated. In that case, it will
00596         // return either -1 or value >= passed in size value . So a check needs to be added
00597         // to detect truncation, and if there is any, only account for the
00598         // actual number of bytes written..and not what could have been
00599         // written.
00600         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
00601         {
00602                 // *NOTE: I believe we need to mark a failure bit at this point.
00603             numCopied = getBufferSize()-getCurrentSize();
00604                 llwarns << "LLDataPackerAsciiBuffer::packString: string truncated: " << value << llendl;
00605         }
00606         mCurBufferp += numCopied;
00607         return success;
00608 }
00609 
00610 BOOL LLDataPackerAsciiBuffer::unpackString(std::string& value, const char *name)
00611 {
00612         BOOL success = TRUE;
00613         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/
00614         BOOL res = getValueStr(name, valuestr, DP_BUFSIZE); // NULL terminated
00615         if (!res) // 
00616         {
00617                 return FALSE;
00618         }
00619         value = valuestr;
00620         return success;
00621 }
00622 
00623 
00624 BOOL LLDataPackerAsciiBuffer::packBinaryData(const U8 *value, S32 size, const char *name)
00625 {
00626         BOOL success = TRUE;
00627         writeIndentedName(name);
00628         
00629         int numCopied = 0;
00630         if (mWriteEnabled)
00631         {
00632                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%010d ", size);      /* Flawfinder: ignore */
00633 
00634                 // snprintf returns number of bytes that would have been
00635                 // written had the output not being truncated. In that case,
00636                 // it will retuen >= passed in size value.  so a check needs
00637                 // to be added to detect truncation, and if there is any, only
00638                 // account for the actual number of bytes written..and not
00639                 // what could have been written.
00640                 if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
00641                 {
00642                         numCopied = getBufferSize()-getCurrentSize();
00643                         llwarns << "LLDataPackerAsciiBuffer::packBinaryData: number truncated: " << size << llendl;
00644                 }
00645                 mCurBufferp += numCopied;
00646 
00647 
00648                 S32 i;
00649                 BOOL bBufferFull = FALSE;
00650                 for (i = 0; i < size && !bBufferFull; i++)
00651                 {
00652                         numCopied = snprintf(mCurBufferp, getBufferSize()-getCurrentSize(), "%02x ", value[i]); /* Flawfinder: ignore */
00653                         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
00654                         {
00655                                 numCopied = getBufferSize()-getCurrentSize();
00656                                 llwarns << "LLDataPackerAsciiBuffer::packBinaryData: data truncated: " << llendl;
00657                                 bBufferFull = TRUE;
00658                         }
00659                         mCurBufferp += numCopied;
00660                 }
00661 
00662                 if (!bBufferFull)
00663                 {
00664                         numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "\n");       /* Flawfinder: ignore */
00665                         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
00666                         {
00667                                 numCopied = getBufferSize()-getCurrentSize();
00668                                 llwarns << "LLDataPackerAsciiBuffer::packBinaryData: newline truncated: " << llendl;
00669                         }
00670                         mCurBufferp += numCopied;
00671                 }
00672         }
00673         else
00674         {
00675                 // why +10 ?? XXXCHECK
00676                 numCopied = 10 + 1; // size plus newline
00677                 numCopied += size;
00678                 if (numCopied > getBufferSize()-getCurrentSize())
00679                 {
00680                         numCopied = getBufferSize()-getCurrentSize();
00681                 }   
00682                 mCurBufferp += numCopied;
00683         }
00684         
00685         return success;
00686 }
00687 
00688 
00689 BOOL LLDataPackerAsciiBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name)
00690 {
00691         BOOL success = TRUE;
00692         char valuestr[DP_BUFSIZE];              /* Flawfinder: ignore */
00693         if (!getValueStr(name, valuestr, DP_BUFSIZE))
00694         {
00695                 return FALSE;
00696         }
00697 
00698         char *cur_pos = &valuestr[0];
00699         sscanf(valuestr,"%010d", &size);
00700         cur_pos += 11;
00701 
00702         S32 i;
00703         for (i = 0; i < size; i++)
00704         {
00705                 S32 val;
00706                 sscanf(cur_pos,"%02x", &val);
00707                 value[i] = val;
00708                 cur_pos += 3;
00709         }
00710         return success;
00711 }
00712 
00713 
00714 BOOL LLDataPackerAsciiBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name)
00715 {
00716         BOOL success = TRUE;
00717         writeIndentedName(name);
00718         
00719         if (mWriteEnabled)
00720         {
00721                 S32 i;
00722                 int numCopied = 0;
00723                 BOOL bBufferFull = FALSE;
00724                 for (i = 0; i < size && !bBufferFull; i++)
00725                 {
00726                         numCopied = snprintf(mCurBufferp, getBufferSize()-getCurrentSize(), "%02x ", value[i]); /* Flawfinder: ignore */
00727                         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
00728                         {
00729                             numCopied = getBufferSize()-getCurrentSize();
00730                                 llwarns << "LLDataPackerAsciiBuffer::packBinaryDataFixed: data truncated: " << llendl;
00731                             bBufferFull = TRUE;
00732                         }
00733                         mCurBufferp += numCopied;
00734 
00735                 }
00736                 if (!bBufferFull)
00737                 {
00738                         numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "\n");       /* Flawfinder: ignore */
00739                         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
00740                         {
00741                                 numCopied = getBufferSize()-getCurrentSize();
00742                                 llwarns << "LLDataPackerAsciiBuffer::packBinaryDataFixed: newline truncated: " << llendl;
00743                         }
00744                         
00745                         mCurBufferp += numCopied;
00746                 }
00747         }
00748         else
00749         {
00750                 int numCopied = 2 * size + 1; //hex bytes plus newline 
00751                 if (numCopied > getBufferSize()-getCurrentSize())
00752                 {
00753                         numCopied = getBufferSize()-getCurrentSize();
00754                 }   
00755                 mCurBufferp += numCopied;
00756         }
00757         return success;
00758 }
00759 
00760 
00761 BOOL LLDataPackerAsciiBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name)
00762 {
00763         BOOL success = TRUE;
00764         char valuestr[DP_BUFSIZE];              /* Flawfinder: ignore */                
00765         if (!getValueStr(name, valuestr, DP_BUFSIZE))
00766         {
00767                 return FALSE;
00768         }
00769 
00770         char *cur_pos = &valuestr[0];
00771 
00772         S32 i;
00773         for (i = 0; i < size; i++)
00774         {
00775                 S32 val;
00776                 sscanf(cur_pos,"%02x", &val);
00777                 value[i] = val;
00778                 cur_pos += 3;
00779         }
00780         return success;
00781 }
00782 
00783 
00784 
00785 BOOL LLDataPackerAsciiBuffer::packU8(const U8 value, const char *name)
00786 {
00787         BOOL success = TRUE;
00788         writeIndentedName(name);
00789         int numCopied = 0;
00790         if (mWriteEnabled)
00791         {
00792                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d\n", value);       /* Flawfinder: ignore */
00793         }
00794         else
00795         {
00796                 // just do the write to a temp buffer to get the length
00797                 numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value);        /* Flawfinder: ignore */
00798         }
00799 
00800         // snprintf returns number of bytes that would have been written
00801         // had the output not being truncated. In that case, it will
00802         // return either -1 or value >= passed in size value . So a check needs to be added
00803         // to detect truncation, and if there is any, only account for the
00804         // actual number of bytes written..and not what could have been
00805         // written.
00806         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
00807         {
00808                 numCopied = getBufferSize()-getCurrentSize();
00809                 llwarns << "LLDataPackerAsciiBuffer::packU8: val truncated: " << llendl;
00810         }
00811 
00812         mCurBufferp += numCopied;
00813 
00814         return success;
00815 }
00816 
00817 
00818 BOOL LLDataPackerAsciiBuffer::unpackU8(U8 &value, const char *name)
00819 {
00820         BOOL success = TRUE;
00821         char valuestr[DP_BUFSIZE];              /* Flawfinder: ignore */
00822         if (!getValueStr(name, valuestr, DP_BUFSIZE))
00823         {
00824                 return FALSE;
00825         }
00826 
00827         S32 in_val;
00828         sscanf(valuestr,"%d", &in_val);
00829         value = in_val;
00830         return success;
00831 }
00832 
00833 BOOL LLDataPackerAsciiBuffer::packU16(const U16 value, const char *name)
00834 {
00835         BOOL success = TRUE;
00836         writeIndentedName(name);
00837         int numCopied = 0;
00838         if (mWriteEnabled)
00839         {
00840                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d\n", value);       /* Flawfinder: ignore */
00841         }
00842         else
00843         {
00844                 numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value);        /* Flawfinder: ignore */
00845         }
00846 
00847         // snprintf returns number of bytes that would have been written
00848         // had the output not being truncated. In that case, it will
00849         // return either -1 or value >= passed in size value . So a check needs to be added
00850         // to detect truncation, and if there is any, only account for the
00851         // actual number of bytes written..and not what could have been
00852         // written.
00853         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
00854         {
00855                 numCopied = getBufferSize()-getCurrentSize();
00856                 llwarns << "LLDataPackerAsciiBuffer::packU16: val truncated: " << llendl;
00857         }
00858 
00859         mCurBufferp += numCopied;
00860 
00861         return success;
00862 }
00863 
00864 
00865 BOOL LLDataPackerAsciiBuffer::unpackU16(U16 &value, const char *name)
00866 {
00867         BOOL success = TRUE;
00868         char valuestr[DP_BUFSIZE];              /* Flawfinder: ignore */
00869         if (!getValueStr(name, valuestr, DP_BUFSIZE))
00870         {
00871                 return FALSE;
00872         }
00873 
00874         S32 in_val;
00875         sscanf(valuestr,"%d", &in_val);
00876         value = in_val;
00877         return success;
00878 }
00879 
00880 
00881 BOOL LLDataPackerAsciiBuffer::packU32(const U32 value, const char *name)
00882 {
00883         BOOL success = TRUE;
00884         writeIndentedName(name);
00885         int numCopied = 0;
00886         if (mWriteEnabled)
00887         {
00888                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%u\n", value);       /* Flawfinder: ignore */
00889         }
00890         else
00891         {
00892                 numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%u\n", value);        /* Flawfinder: ignore */
00893         }
00894         // snprintf returns number of bytes that would have been written
00895         // had the output not being truncated. In that case, it will
00896         // return either -1 or value >= passed in size value . So a check needs to be added
00897         // to detect truncation, and if there is any, only account for the
00898         // actual number of bytes written..and not what could have been
00899         // written.
00900         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
00901         {
00902                 numCopied = getBufferSize()-getCurrentSize();
00903                 llwarns << "LLDataPackerAsciiBuffer::packU32: val truncated: " << llendl;
00904         }
00905 
00906         mCurBufferp += numCopied;
00907         return success;
00908 }
00909 
00910 
00911 BOOL LLDataPackerAsciiBuffer::unpackU32(U32 &value, const char *name)
00912 {
00913         BOOL success = TRUE;
00914         char valuestr[DP_BUFSIZE];              /* Flawfinder: ignore */
00915         if (!getValueStr(name, valuestr, DP_BUFSIZE))
00916         {
00917                 return FALSE;
00918         }
00919 
00920         sscanf(valuestr,"%u", &value);
00921         return success;
00922 }
00923 
00924 
00925 BOOL LLDataPackerAsciiBuffer::packS32(const S32 value, const char *name)
00926 {
00927         BOOL success = TRUE;
00928         writeIndentedName(name);
00929         int numCopied = 0;
00930         if (mWriteEnabled)
00931         {
00932                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d\n", value);       /* Flawfinder: ignore */
00933         }
00934         else
00935         {
00936                 numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value);                /* Flawfinder: ignore */        
00937         }
00938         // snprintf returns number of bytes that would have been written
00939         // had the output not being truncated. In that case, it will
00940         // return either -1 or value >= passed in size value . So a check needs to be added
00941         // to detect truncation, and if there is any, only account for the
00942         // actual number of bytes written..and not what could have been
00943         // written.
00944         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
00945         {
00946                 numCopied = getBufferSize()-getCurrentSize();
00947                 llwarns << "LLDataPackerAsciiBuffer::packS32: val truncated: " << llendl;
00948         }
00949 
00950         mCurBufferp += numCopied;
00951         return success;
00952 }
00953 
00954 
00955 BOOL LLDataPackerAsciiBuffer::unpackS32(S32 &value, const char *name)
00956 {
00957         BOOL success = TRUE;
00958         char valuestr[DP_BUFSIZE];              /* Flawfinder: ignore */
00959         if (!getValueStr(name, valuestr, DP_BUFSIZE))
00960         {
00961                 return FALSE;
00962         }
00963 
00964         sscanf(valuestr,"%d", &value);
00965         return success;
00966 }
00967 
00968 
00969 BOOL LLDataPackerAsciiBuffer::packF32(const F32 value, const char *name)
00970 {
00971         BOOL success = TRUE;
00972         writeIndentedName(name);
00973         int numCopied = 0;
00974         if (mWriteEnabled)
00975         {
00976                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f\n", value);               /* Flawfinder: ignore */
00977         }
00978         else
00979         {
00980                 numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%f\n", value);                /* Flawfinder: ignore */        
00981         }
00982         // snprintf returns number of bytes that would have been written
00983         // had the output not being truncated. In that case, it will
00984         // return either -1 or value >= passed in size value . So a check needs to be added
00985         // to detect truncation, and if there is any, only account for the
00986         // actual number of bytes written..and not what could have been
00987         // written.
00988         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
00989         {
00990                 numCopied = getBufferSize()-getCurrentSize();
00991                 llwarns << "LLDataPackerAsciiBuffer::packF32: val truncated: " << llendl;
00992         }
00993 
00994         mCurBufferp += numCopied;
00995         return success;
00996 }
00997 
00998 
00999 BOOL LLDataPackerAsciiBuffer::unpackF32(F32 &value, const char *name)
01000 {
01001         BOOL success = TRUE;
01002         char valuestr[DP_BUFSIZE];              /* Flawfinder: ignore */
01003         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01004         {
01005                 return FALSE;
01006         }
01007 
01008         sscanf(valuestr,"%f", &value);
01009         return success;
01010 }
01011 
01012 
01013 BOOL LLDataPackerAsciiBuffer::packColor4(const LLColor4 &value, const char *name)
01014 {
01015         BOOL success = TRUE;
01016         writeIndentedName(name);
01017         int numCopied = 0;
01018         if (mWriteEnabled)
01019         {
01020                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
01021         }
01022         else
01023         {
01024                 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 */
01025         }
01026         // snprintf returns number of bytes that would have been written
01027         // had the output not being truncated. In that case, it will
01028         // return either -1 or value >= passed in size value . So a check needs to be added
01029         // to detect truncation, and if there is any, only account for the
01030         // actual number of bytes written..and not what could have been
01031         // written.
01032         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
01033         {
01034                 numCopied = getBufferSize()-getCurrentSize();
01035                 llwarns << "LLDataPackerAsciiBuffer::packColor4: truncated: " << llendl;
01036         }
01037 
01038         mCurBufferp += numCopied;
01039         return success;
01040 }
01041 
01042 
01043 BOOL LLDataPackerAsciiBuffer::unpackColor4(LLColor4 &value, const char *name)
01044 {
01045         BOOL success = TRUE;
01046         char valuestr[DP_BUFSIZE];      /* Flawfinder: ignore */
01047         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01048         {
01049                 return FALSE;
01050         }
01051 
01052         sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]);
01053         return success;
01054 }
01055 
01056 BOOL LLDataPackerAsciiBuffer::packColor4U(const LLColor4U &value, const char *name)
01057 {
01058         BOOL success = TRUE;
01059         writeIndentedName(name);
01060         int numCopied = 0;
01061         if (mWriteEnabled)
01062         {
01063                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d %d %d %d\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
01064         }
01065         else
01066         {
01067                 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 */
01068         }
01069         // snprintf returns number of bytes that would have been written
01070         // had the output not being truncated. In that case, it will
01071         // return either -1 or value >= passed in size value . So a check needs to be added
01072         // to detect truncation, and if there is any, only account for the
01073         // actual number of bytes written..and not what could have been
01074         // written.
01075         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
01076         {
01077                 numCopied = getBufferSize()-getCurrentSize();
01078                 llwarns << "LLDataPackerAsciiBuffer::packColor4U: truncated: " << llendl;
01079         }
01080 
01081         mCurBufferp += numCopied;
01082         return success;
01083 }
01084 
01085 
01086 BOOL LLDataPackerAsciiBuffer::unpackColor4U(LLColor4U &value, const char *name)
01087 {
01088         BOOL success = TRUE;
01089         char valuestr[DP_BUFSIZE];       /* Flawfinder: ignore */ 
01090         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01091         {
01092                 return FALSE;
01093         }
01094 
01095         S32 r, g, b, a;
01096 
01097         sscanf(valuestr,"%d %d %d %d", &r, &g, &b, &a);
01098         value.mV[0] = r;
01099         value.mV[1] = g;
01100         value.mV[2] = b;
01101         value.mV[3] = a;
01102         return success;
01103 }
01104 
01105 
01106 BOOL LLDataPackerAsciiBuffer::packVector2(const LLVector2 &value, const char *name)
01107 {
01108         BOOL success = TRUE;
01109         writeIndentedName(name);
01110         int numCopied = 0;
01111         if (mWriteEnabled)
01112         {
01113                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */
01114         }
01115         else
01116         {
01117                 numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f\n", value.mV[0], value.mV[1]);            /* Flawfinder: ignore */
01118         }
01119         // snprintf returns number of bytes that would have been written
01120         // had the output not being truncated. In that case, it will
01121         // return either -1 or value >= passed in size value . So a check needs to be added
01122         // to detect truncation, and if there is any, only account for the
01123         // actual number of bytes written..and not what could have been
01124         // written.
01125         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
01126         {
01127                 numCopied = getBufferSize()-getCurrentSize();
01128                 llwarns << "LLDataPackerAsciiBuffer::packVector2: truncated: " << llendl;
01129         }
01130 
01131         mCurBufferp += numCopied;
01132         return success;
01133 }
01134 
01135 
01136 BOOL LLDataPackerAsciiBuffer::unpackVector2(LLVector2 &value, const char *name)
01137 {
01138         BOOL success = TRUE;
01139         char valuestr[DP_BUFSIZE];       /* Flawfinder: ignore */ 
01140         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01141         {
01142                 return FALSE;
01143         }
01144 
01145         sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]);
01146         return success;
01147 }
01148 
01149 
01150 BOOL LLDataPackerAsciiBuffer::packVector3(const LLVector3 &value, const char *name)
01151 {
01152         BOOL success = TRUE;
01153         writeIndentedName(name);
01154         int numCopied = 0;
01155         if (mWriteEnabled)
01156         {
01157                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */
01158         }
01159         else
01160         {
01161                 numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]);    /* Flawfinder: ignore */
01162         }
01163         // snprintf returns number of bytes that would have been written
01164         // had the output not being truncated. In that case, it will
01165         // return either -1 or value >= passed in size value . So a check needs to be added
01166         // to detect truncation, and if there is any, only account for the
01167         // actual number of bytes written..and not what could have been
01168         // written.
01169         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
01170         {
01171             numCopied = getBufferSize()-getCurrentSize();
01172                 llwarns << "LLDataPackerAsciiBuffer::packVector3: truncated: " << llendl;
01173         }
01174 
01175         mCurBufferp += numCopied;
01176         return success;
01177 }
01178 
01179 
01180 BOOL LLDataPackerAsciiBuffer::unpackVector3(LLVector3 &value, const char *name)
01181 {
01182         BOOL success = TRUE;
01183         char valuestr[DP_BUFSIZE];      /* Flawfinder: ignore */ 
01184         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01185         {
01186                 return FALSE;
01187         }
01188 
01189         sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]);
01190         return success;
01191 }
01192 
01193 BOOL LLDataPackerAsciiBuffer::packVector4(const LLVector4 &value, const char *name)
01194 {
01195         BOOL success = TRUE;
01196         writeIndentedName(name);
01197         int numCopied = 0;
01198         if (mWriteEnabled)
01199         {
01200                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
01201         }
01202         else
01203         {
01204                 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 */
01205         }
01206         // snprintf returns number of bytes that would have been written
01207         // had the output not being truncated. In that case, it will
01208         // return either -1 or value >= passed in size value . So a check needs to be added
01209         // to detect truncation, and if there is any, only account for the
01210         // actual number of bytes written..and not what could have been
01211         // written.
01212         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
01213         {
01214             numCopied = getBufferSize()-getCurrentSize();
01215                 llwarns << "LLDataPackerAsciiBuffer::packVector4: truncated: " << llendl;
01216         }
01217 
01218         mCurBufferp += numCopied;
01219         return success;
01220 }
01221 
01222 
01223 BOOL LLDataPackerAsciiBuffer::unpackVector4(LLVector4 &value, const char *name)
01224 {
01225         BOOL success = TRUE;
01226         char valuestr[DP_BUFSIZE];      /* Flawfinder: ignore */ 
01227         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01228         {
01229                 return FALSE;
01230         }
01231 
01232         sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]);
01233         return success;
01234 }
01235 
01236 
01237 BOOL LLDataPackerAsciiBuffer::packUUID(const LLUUID &value, const char *name)
01238 {
01239         BOOL success = TRUE;
01240         writeIndentedName(name);
01241 
01242         int numCopied = 0;
01243         if (mWriteEnabled)
01244         {
01245                 char tmp_str[64]; /* Flawfinder: ignore */ 
01246                 value.toString(tmp_str);
01247                 numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\n", tmp_str);     /* Flawfinder: ignore */
01248         }
01249         else
01250         {
01251                 numCopied = 64 + 1; // UUID + newline
01252         }
01253         // snprintf returns number of bytes that would have been written
01254         // had the output not being truncated. In that case, it will
01255         // return either -1 or value >= passed in size value . So a check needs to be added
01256         // to detect truncation, and if there is any, only account for the
01257         // actual number of bytes written..and not what could have been
01258         // written.
01259         if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
01260         {
01261             numCopied = getBufferSize()-getCurrentSize();
01262                 llwarns << "LLDataPackerAsciiBuffer::packUUID: truncated: " << llendl;
01263                 success = FALSE;
01264         }
01265         mCurBufferp += numCopied;
01266         return success;
01267 }
01268 
01269 
01270 BOOL LLDataPackerAsciiBuffer::unpackUUID(LLUUID &value, const char *name)
01271 {
01272         BOOL success = TRUE;
01273         char valuestr[DP_BUFSIZE];      /* Flawfinder: ignore */
01274         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01275         {
01276                 return FALSE;
01277         }
01278 
01279         char tmp_str[64];       /* Flawfinder: ignore */
01280         sscanf(valuestr, "%63s", tmp_str);      /* Flawfinder: ignore */
01281         value.set(tmp_str);
01282 
01283         return success;
01284 }
01285 
01286 void LLDataPackerAsciiBuffer::dump()
01287 {
01288         llinfos << "Buffer: " << mBufferp << llendl;
01289 }
01290 
01291 void LLDataPackerAsciiBuffer::writeIndentedName(const char *name)
01292 {
01293         if (mIncludeNames)
01294         {
01295                 int numCopied = 0;
01296                 if (mWriteEnabled)
01297                 {
01298                         numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\t", name);        /* Flawfinder: ignore */
01299                 }
01300                 else
01301                 {
01302                         numCopied = (S32)strlen(name) + 1;      /* Flawfinder: ignore */ //name + tab   
01303                 }
01304 
01305                 // snprintf returns number of bytes that would have been written
01306                 // had the output not being truncated. In that case, it will
01307                 // return either -1 or value >= passed in size value . So a check needs to be added
01308                 // to detect truncation, and if there is any, only account for the
01309                 // actual number of bytes written..and not what could have been
01310                 // written.
01311                 if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
01312                 {
01313                         numCopied = getBufferSize()-getCurrentSize();
01314                         llwarns << "LLDataPackerAsciiBuffer::writeIndentedName: truncated: " << llendl;
01315                 }
01316 
01317                 mCurBufferp += numCopied;
01318         }
01319 }
01320 
01321 BOOL LLDataPackerAsciiBuffer::getValueStr(const char *name, char *out_value, S32 value_len)
01322 {
01323         BOOL success = TRUE;
01324         char buffer[DP_BUFSIZE];        /* Flawfinder: ignore */
01325         char keyword[DP_BUFSIZE];       /* Flawfinder: ignore */
01326         char value[DP_BUFSIZE]; /* Flawfinder: ignore */
01327 
01328         buffer[0] = '\0';
01329         keyword[0] = '\0';
01330         value[0] = '\0';
01331 
01332         if (mIncludeNames)
01333         {
01334                 // Read both the name and the value, and validate the name.
01335                 sscanf(mCurBufferp, "%511[^\n]", buffer);
01336                 // Skip the \n
01337                 mCurBufferp += (S32)strlen(buffer) + 1; /* Flawfinder: ignore */
01338 
01339                 sscanf(buffer, "%511s %511[^\n]", keyword, value);      /* Flawfinder: ignore */
01340 
01341                 if (strcmp(keyword, name))
01342                 {
01343                         llwarns << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << llendl;
01344                         return FALSE;
01345                 }
01346         }
01347         else
01348         {
01349                 // Just the value exists
01350                 sscanf(mCurBufferp, "%511[^\n]", value);
01351                 // Skip the \n
01352                 mCurBufferp += (S32)strlen(value) + 1;  /* Flawfinder: ignore */
01353         }
01354 
01355         S32 in_value_len = (S32)strlen(value)+1;        /* Flawfinder: ignore */
01356         S32 min_len = llmin(in_value_len, value_len);
01357         memcpy(out_value, value, min_len);      /* Flawfinder: ignore */
01358         out_value[min_len-1] = 0;
01359 
01360         return success;
01361 }
01362 
01363 // helper function used by LLDataPackerAsciiFile
01364 // to convert F32 into a string. This is to avoid
01365 // << operator writing F32 value into a stream 
01366 // since it does not seem to preserve the float value
01367 std::string convertF32ToString(F32 val)
01368 {
01369         std::string str;
01370         char  buf[20];
01371         snprintf(buf, 20, "%f", val);
01372         str = buf;
01373         return str;
01374 }
01375 
01376 //---------------------------------------------------------------------------
01377 // LLDataPackerAsciiFile implementation
01378 //---------------------------------------------------------------------------
01379 BOOL LLDataPackerAsciiFile::packString(const char *value, const char *name)
01380 {
01381         BOOL success = TRUE;
01382         writeIndentedName(name);
01383         if (mFP)
01384         {
01385                 fprintf(mFP,"%s\n", value);     
01386         }
01387         else if (mOutputStream)
01388         {
01389                 *mOutputStream << value << "\n";
01390         }
01391         return success;
01392 }
01393 
01394 BOOL LLDataPackerAsciiFile::unpackString(std::string& value, const char *name)
01395 {
01396         BOOL success = TRUE;
01397         char valuestr[DP_BUFSIZE];      /* Flawfinder: ignore */
01398         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01399         {
01400                 return FALSE;
01401         }
01402         value = valuestr;
01403         return success;
01404 }
01405 
01406 
01407 BOOL LLDataPackerAsciiFile::packBinaryData(const U8 *value, S32 size, const char *name)
01408 {
01409         BOOL success = TRUE;
01410         writeIndentedName(name);
01411         
01412         if (mFP)
01413         {
01414                 fprintf(mFP, "%010d ", size);
01415 
01416                 S32 i;
01417                 for (i = 0; i < size; i++)
01418                 {
01419                         fprintf(mFP, "%02x ", value[i]);
01420                 }
01421                 fprintf(mFP, "\n");
01422         }
01423         else if (mOutputStream)
01424         {
01425                 char buffer[32];        /* Flawfinder: ignore */
01426                 snprintf(buffer,sizeof(buffer), "%010d ", size);        /* Flawfinder: ignore */
01427                 *mOutputStream << buffer;
01428 
01429                 S32 i;
01430                 for (i = 0; i < size; i++)
01431                 {
01432                         snprintf(buffer, sizeof(buffer), "%02x ", value[i]);    /* Flawfinder: ignore */
01433                         *mOutputStream << buffer;
01434                 }
01435                 *mOutputStream << "\n";
01436         }
01437         return success;
01438 }
01439 
01440 
01441 BOOL LLDataPackerAsciiFile::unpackBinaryData(U8 *value, S32 &size, const char *name)
01442 {
01443         BOOL success = TRUE;
01444         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/
01445         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01446         {
01447                 return FALSE;
01448         }
01449 
01450         char *cur_pos = &valuestr[0];
01451         sscanf(valuestr,"%010d", &size);
01452         cur_pos += 11;
01453 
01454         S32 i;
01455         for (i = 0; i < size; i++)
01456         {
01457                 S32 val;
01458                 sscanf(cur_pos,"%02x", &val);
01459                 value[i] = val;
01460                 cur_pos += 3;
01461         }
01462         return success;
01463 }
01464 
01465 
01466 BOOL LLDataPackerAsciiFile::packBinaryDataFixed(const U8 *value, S32 size, const char *name)
01467 {
01468         BOOL success = TRUE;
01469         writeIndentedName(name);
01470         
01471         if (mFP)
01472         {
01473                 S32 i;
01474                 for (i = 0; i < size; i++)
01475                 {
01476                         fprintf(mFP, "%02x ", value[i]);
01477                 }
01478                 fprintf(mFP, "\n");
01479         }
01480         else if (mOutputStream)
01481         {
01482                 char buffer[32]; /*Flawfinder: ignore*/
01483                 S32 i;
01484                 for (i = 0; i < size; i++)
01485                 {
01486                         snprintf(buffer, sizeof(buffer), "%02x ", value[i]);    /* Flawfinder: ignore */
01487                         *mOutputStream << buffer;
01488                 }
01489                 *mOutputStream << "\n";
01490         }
01491         return success;
01492 }
01493 
01494 
01495 BOOL LLDataPackerAsciiFile::unpackBinaryDataFixed(U8 *value, S32 size, const char *name)
01496 {
01497         BOOL success = TRUE;
01498         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/
01499         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01500         {
01501                 return FALSE;
01502         }
01503 
01504         char *cur_pos = &valuestr[0];
01505 
01506         S32 i;
01507         for (i = 0; i < size; i++)
01508         {
01509                 S32 val;
01510                 sscanf(cur_pos,"%02x", &val);
01511                 value[i] = val;
01512                 cur_pos += 3;
01513         }
01514         return success;
01515 }
01516 
01517 
01518 
01519 BOOL LLDataPackerAsciiFile::packU8(const U8 value, const char *name)
01520 {
01521         BOOL success = TRUE;
01522         writeIndentedName(name);
01523         if (mFP)
01524         {
01525                 fprintf(mFP,"%d\n", value);     
01526         }
01527         else if (mOutputStream)
01528         {
01529                 // We have to cast this to an integer because streams serialize
01530                 // bytes as bytes - not as text.
01531                 *mOutputStream << (S32)value << "\n";
01532         }
01533         return success;
01534 }
01535 
01536 
01537 BOOL LLDataPackerAsciiFile::unpackU8(U8 &value, const char *name)
01538 {
01539         BOOL success = TRUE;
01540         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
01541         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01542         {
01543                 return FALSE;
01544         }
01545 
01546         S32 in_val;
01547         sscanf(valuestr,"%d", &in_val);
01548         value = in_val;
01549         return success;
01550 }
01551 
01552 BOOL LLDataPackerAsciiFile::packU16(const U16 value, const char *name)
01553 {
01554         BOOL success = TRUE;
01555         writeIndentedName(name);
01556         if (mFP)
01557         {
01558                 fprintf(mFP,"%d\n", value);     
01559         }
01560         else if (mOutputStream)
01561         {
01562                 *mOutputStream <<"" << value << "\n";
01563         }
01564         return success;
01565 }
01566 
01567 
01568 BOOL LLDataPackerAsciiFile::unpackU16(U16 &value, const char *name)
01569 {
01570         BOOL success = TRUE;
01571         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
01572         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01573         {
01574                 return FALSE;
01575         }
01576 
01577         S32 in_val;
01578         sscanf(valuestr,"%d", &in_val);
01579         value = in_val;
01580         return success;
01581 }
01582 
01583 
01584 BOOL LLDataPackerAsciiFile::packU32(const U32 value, const char *name)
01585 {
01586         BOOL success = TRUE;
01587         writeIndentedName(name);
01588         if (mFP)
01589         {
01590                 fprintf(mFP,"%u\n", value);     
01591         }
01592         else if (mOutputStream)
01593         {
01594                 *mOutputStream <<"" << value << "\n";
01595         }
01596         return success;
01597 }
01598 
01599 
01600 BOOL LLDataPackerAsciiFile::unpackU32(U32 &value, const char *name)
01601 {
01602         BOOL success = TRUE;
01603         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
01604         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01605         {
01606                 return FALSE;
01607         }
01608 
01609         sscanf(valuestr,"%u", &value);
01610         return success;
01611 }
01612 
01613 
01614 BOOL LLDataPackerAsciiFile::packS32(const S32 value, const char *name)
01615 {
01616         BOOL success = TRUE;
01617         writeIndentedName(name);
01618         if (mFP)
01619         {
01620                 fprintf(mFP,"%d\n", value);     
01621         }
01622         else if (mOutputStream)
01623         {
01624                 *mOutputStream <<"" << value << "\n";
01625         }
01626         return success;
01627 }
01628 
01629 
01630 BOOL LLDataPackerAsciiFile::unpackS32(S32 &value, const char *name)
01631 {
01632         BOOL success = TRUE;
01633         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
01634         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01635         {
01636                 return FALSE;
01637         }
01638 
01639         sscanf(valuestr,"%d", &value);
01640         return success;
01641 }
01642 
01643 
01644 BOOL LLDataPackerAsciiFile::packF32(const F32 value, const char *name)
01645 {
01646         BOOL success = TRUE;
01647         writeIndentedName(name);
01648         if (mFP)
01649         {
01650                 fprintf(mFP,"%f\n", value);     
01651         }
01652         else if (mOutputStream)
01653         {
01654                 *mOutputStream <<"" << convertF32ToString(value) << "\n";
01655         }
01656         return success;
01657 }
01658 
01659 
01660 BOOL LLDataPackerAsciiFile::unpackF32(F32 &value, const char *name)
01661 {
01662         BOOL success = TRUE;
01663         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
01664         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01665         {
01666                 return FALSE;
01667         }
01668 
01669         sscanf(valuestr,"%f", &value);
01670         return success;
01671 }
01672 
01673 
01674 BOOL LLDataPackerAsciiFile::packColor4(const LLColor4 &value, const char *name)
01675 {
01676         BOOL success = TRUE;
01677         writeIndentedName(name);
01678         if (mFP)
01679         {
01680                 fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]);       
01681         }
01682         else if (mOutputStream)
01683         {
01684                 *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(value.mV[3]) << "\n";
01685         }
01686         return success;
01687 }
01688 
01689 
01690 BOOL LLDataPackerAsciiFile::unpackColor4(LLColor4 &value, const char *name)
01691 {
01692         BOOL success = TRUE;
01693         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
01694         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01695         {
01696                 return FALSE;
01697         }
01698 
01699         sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]);
01700         return success;
01701 }
01702 
01703 BOOL LLDataPackerAsciiFile::packColor4U(const LLColor4U &value, const char *name)
01704 {
01705         BOOL success = TRUE;
01706         writeIndentedName(name);
01707         if (mFP)
01708         {
01709                 fprintf(mFP,"%d %d %d %d\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]);       
01710         }
01711         else if (mOutputStream)
01712         {
01713                 *mOutputStream << (S32)(value.mV[0]) << " " << (S32)(value.mV[1]) << " " << (S32)(value.mV[2]) << " " << (S32)(value.mV[3]) << "\n";
01714         }
01715         return success;
01716 }
01717 
01718 
01719 BOOL LLDataPackerAsciiFile::unpackColor4U(LLColor4U &value, const char *name)
01720 {
01721         BOOL success = TRUE;
01722         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
01723         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01724         {
01725                 return FALSE;
01726         }
01727 
01728         S32 r, g, b, a;
01729 
01730         sscanf(valuestr,"%d %d %d %d", &r, &g, &b, &a);
01731         value.mV[0] = r;
01732         value.mV[1] = g;
01733         value.mV[2] = b;
01734         value.mV[3] = a;
01735         return success;
01736 }
01737 
01738 
01739 BOOL LLDataPackerAsciiFile::packVector2(const LLVector2 &value, const char *name)
01740 {
01741         BOOL success = TRUE;
01742         writeIndentedName(name);
01743         if (mFP)
01744         {
01745                 fprintf(mFP,"%f %f\n", value.mV[0], value.mV[1]);       
01746         }
01747         else if (mOutputStream)
01748         {
01749                 *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << "\n";
01750         }
01751         return success;
01752 }
01753 
01754 
01755 BOOL LLDataPackerAsciiFile::unpackVector2(LLVector2 &value, const char *name)
01756 {
01757         BOOL success = TRUE;
01758         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
01759         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01760         {
01761                 return FALSE;
01762         }
01763 
01764         sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]);
01765         return success;
01766 }
01767 
01768 
01769 BOOL LLDataPackerAsciiFile::packVector3(const LLVector3 &value, const char *name)
01770 {
01771         BOOL success = TRUE;
01772         writeIndentedName(name);
01773         if (mFP)
01774         {
01775                 fprintf(mFP,"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]);       
01776         }
01777         else if (mOutputStream)
01778         {
01779                 *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << "\n";
01780         }
01781         return success;
01782 }
01783 
01784 
01785 BOOL LLDataPackerAsciiFile::unpackVector3(LLVector3 &value, const char *name)
01786 {
01787         BOOL success = TRUE;
01788         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
01789         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01790         {
01791                 return FALSE;
01792         }
01793 
01794         sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]);
01795         return success;
01796 }
01797 
01798 BOOL LLDataPackerAsciiFile::packVector4(const LLVector4 &value, const char *name)
01799 {
01800         BOOL success = TRUE;
01801         writeIndentedName(name);
01802         if (mFP)
01803         {
01804                 fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]);       
01805         }
01806         else if (mOutputStream)
01807         {
01808                 *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(value.mV[3]) << "\n";
01809         }
01810         return success;
01811 }
01812 
01813 
01814 BOOL LLDataPackerAsciiFile::unpackVector4(LLVector4 &value, const char *name)
01815 {
01816         BOOL success = TRUE;
01817         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
01818         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01819         {
01820                 return FALSE;
01821         }
01822 
01823         sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]);
01824         return success;
01825 }
01826 
01827 
01828 BOOL LLDataPackerAsciiFile::packUUID(const LLUUID &value, const char *name)
01829 {
01830         BOOL success = TRUE;
01831         writeIndentedName(name);
01832         char tmp_str[64]; /*Flawfinder: ignore */
01833         value.toString(tmp_str);
01834         if (mFP)
01835         {
01836                 fprintf(mFP,"%s\n", tmp_str);
01837         }
01838         else if (mOutputStream)
01839         {
01840                 *mOutputStream <<"" << tmp_str << "\n";
01841         }
01842         return success;
01843 }
01844 
01845 
01846 BOOL LLDataPackerAsciiFile::unpackUUID(LLUUID &value, const char *name)
01847 {
01848         BOOL success = TRUE;
01849         char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */
01850         if (!getValueStr(name, valuestr, DP_BUFSIZE))
01851         {
01852                 return FALSE;
01853         }
01854 
01855         char tmp_str[64]; /*Flawfinder: ignore */
01856         sscanf(valuestr,"%63s",tmp_str);        /* Flawfinder: ignore */
01857         value.set(tmp_str);
01858 
01859         return success;
01860 }
01861 
01862 
01863 void LLDataPackerAsciiFile::writeIndentedName(const char *name)
01864 {
01865         std::string indent_buf;
01866         indent_buf.reserve(mIndent+1);
01867 
01868         S32 i;
01869         for(i = 0; i < mIndent; i++)
01870         {
01871                 indent_buf[i] = '\t';
01872         }
01873         indent_buf[i] = 0;
01874         if (mFP)
01875         {
01876                 fprintf(mFP,"%s%s\t",indent_buf.c_str(), name);         
01877         }
01878         else if (mOutputStream)
01879         {
01880                 *mOutputStream << indent_buf.c_str() << name << "\t";
01881         }
01882 }
01883 
01884 BOOL LLDataPackerAsciiFile::getValueStr(const char *name, char *out_value, S32 value_len)
01885 {
01886         BOOL success = FALSE;
01887         char buffer[DP_BUFSIZE]; /*Flawfinder: ignore*/
01888         char keyword[DP_BUFSIZE]; /*Flawfinder: ignore*/
01889         char value[DP_BUFSIZE]; /*Flawfinder: ignore*/
01890 
01891         buffer[0] = '\0';
01892         keyword[0] = '\0';
01893         value[0] = '\0';
01894 
01895         if (mFP)
01896         {
01897                 fpos_t last_pos;
01898                 fgetpos(mFP, &last_pos);
01899                 if (fgets(buffer, DP_BUFSIZE, mFP) == NULL)
01900                 {
01901                         buffer[0] = '\0';
01902                 }
01903         
01904                 sscanf(buffer, "%511s %511[^\n]", keyword, value);      /* Flawfinder: ignore */
01905         
01906                 if (!keyword[0])
01907                 {
01908                         llwarns << "Data packer could not get the keyword!" << llendl;
01909                         fsetpos(mFP, &last_pos);
01910                         return FALSE;
01911                 }
01912                 if (strcmp(keyword, name))
01913                 {
01914                         llwarns << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << llendl;
01915                         fsetpos(mFP, &last_pos);
01916                         return FALSE;
01917                 }
01918 
01919                 S32 in_value_len = (S32)strlen(value)+1; /*Flawfinder: ignore*/
01920                 S32 min_len = llmin(in_value_len, value_len);
01921                 memcpy(out_value, value, min_len); /*Flawfinder: ignore*/
01922                 out_value[min_len-1] = 0;
01923                 success = TRUE;
01924         }
01925         else if (mInputStream)
01926         {
01927                 mInputStream->getline(buffer, DP_BUFSIZE);
01928         
01929                 sscanf(buffer, "%511s %511[^\n]", keyword, value);      /* Flawfinder: ignore */
01930                 if (!keyword[0])
01931                 {
01932                         llwarns << "Data packer could not get the keyword!" << llendl;
01933                         return FALSE;
01934                 }
01935                 if (strcmp(keyword, name))
01936                 {
01937                         llwarns << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << llendl;
01938                         return FALSE;
01939                 }
01940 
01941                 S32 in_value_len = (S32)strlen(value)+1; /*Flawfinder: ignore*/
01942                 S32 min_len = llmin(in_value_len, value_len);
01943                 memcpy(out_value, value, min_len); /*Flawfinder: ignore*/
01944                 out_value[min_len-1] = 0;
01945                 success = TRUE;
01946         }
01947 
01948         return success;
01949 }

Generated on Thu Jul 1 06:08:23 2010 for Second Life Viewer by  doxygen 1.4.7