diff options
author | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
---|---|---|
committer | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
commit | 420b91db29485df39fd6e724e782c449158811cb (patch) | |
tree | b471a94563af914d3ed3edd3e856d21cb1b69945 /indra/llmessage/lldatapacker.cpp |
Print done when done.
Diffstat (limited to 'indra/llmessage/lldatapacker.cpp')
-rw-r--r-- | indra/llmessage/lldatapacker.cpp | 1866 |
1 files changed, 1866 insertions, 0 deletions
diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp new file mode 100644 index 0000000000..bc9f4f3486 --- /dev/null +++ b/indra/llmessage/lldatapacker.cpp @@ -0,0 +1,1866 @@ +/** + * @file lldatapacker.cpp + * @brief Data packer implementation. + * + * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include <string.h> + +#include "linden_common.h" + +#include "lldatapacker.h" +#include "llerror.h" + +#include "message.h" + +#include "v4color.h" +#include "v4coloru.h" +#include "v2math.h" +#include "v3math.h" +#include "v4math.h" +#include "lluuid.h" + +// *NOTE: there are functions below which use sscanf and rely on this +// particular value of DP_BUFSIZE. Search for '511' (DP_BUFSIZE - 1) +// to find them if you change this number. +const S32 DP_BUFSIZE = 512; + +static char DUMMY_BUFFER[128]; /*Flawfinder: ignore*/ + +LLDataPacker::LLDataPacker() : mPassFlags(0), mWriteEnabled(FALSE) +{ +} + +BOOL LLDataPacker::packFixed(const F32 value, const char *name, + const BOOL is_signed, const U32 int_bits, const U32 frac_bits) +{ + BOOL success = TRUE; + S32 unsigned_bits = int_bits + frac_bits; + S32 total_bits = unsigned_bits; + + if (is_signed) + { + total_bits++; + } + + S32 min_val; + U32 max_val; + if (is_signed) + { + min_val = 1 << int_bits; + min_val *= -1; + } + else + { + min_val = 0; + } + max_val = 1 << int_bits; + + // Clamp to be within range + F32 fixed_val = llclamp(value, (F32)min_val, (F32)max_val); + if (is_signed) + { + fixed_val += max_val; + } + fixed_val *= 1 << frac_bits; + + if (total_bits <= 8) + { + packU8((U8)fixed_val, name); + } + else if (total_bits <= 16) + { + packU16((U16)fixed_val, name); + } + else if (total_bits <= 31) + { + packU32((U32)fixed_val, name); + } + else + { + llerrs << "Using fixed-point packing of " << total_bits << " bits, why?!" << llendl; + } + return success; +} + +BOOL LLDataPacker::unpackFixed(F32 &value, const char *name, + const BOOL is_signed, const U32 int_bits, const U32 frac_bits) +{ + //BOOL success = TRUE; + //llinfos << "unpackFixed:" << name << " int:" << int_bits << " frac:" << frac_bits << llendl; + BOOL ok = FALSE; + S32 unsigned_bits = int_bits + frac_bits; + S32 total_bits = unsigned_bits; + + if (is_signed) + { + total_bits++; + } + + S32 min_val; + U32 max_val; + if (is_signed) + { + min_val = 1 << int_bits; + min_val *= -1; + } + max_val = 1 << int_bits; + + F32 fixed_val; + if (total_bits <= 8) + { + U8 fixed_8; + ok = unpackU8(fixed_8, name); + fixed_val = (F32)fixed_8; + } + else if (total_bits <= 16) + { + U16 fixed_16; + ok = unpackU16(fixed_16, name); + fixed_val = (F32)fixed_16; + } + else if (total_bits <= 31) + { + U32 fixed_32; + ok = unpackU32(fixed_32, name); + fixed_val = (F32)fixed_32; + } + else + { + fixed_val = 0; + llerrs << "Bad bit count: " << total_bits << llendl; + } + + //llinfos << "Fixed_val:" << fixed_val << llendl; + + fixed_val /= (F32)(1 << frac_bits); + if (is_signed) + { + fixed_val -= max_val; + } + value = fixed_val; + //llinfos << "Value: " << value << llendl; + return ok; +} + +//--------------------------------------------------------------------------- +// LLDataPackerBinaryBuffer implementation +//--------------------------------------------------------------------------- + +BOOL LLDataPackerBinaryBuffer::packString(const char *value, const char *name) +{ + BOOL success = TRUE; + S32 length = (S32)strlen(value) + 1; /*Flawfinder: ignore*/ + + success &= verifyLength(length, name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, value, MVT_VARIABLE, length); + } + mCurBufferp += length; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackString(char *value, const char *name) +{ + BOOL success = TRUE; + S32 length = (S32)strlen((char *)mCurBufferp) + 1; /*Flawfinder: ignore*/ + + success &= verifyLength(length, name); + + htonmemcpy(value, mCurBufferp, MVT_VARIABLE, length); + mCurBufferp += length; + return success; +} + +BOOL LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(size + 4, name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, &size, MVT_S32, 4); + } + mCurBufferp += 4; + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, value, MVT_VARIABLE, size); + } + mCurBufferp += size; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(4, name); + htonmemcpy(&size, mCurBufferp, MVT_S32, 4); + mCurBufferp += 4; + success &= verifyLength(size, name); + if (success) + { + htonmemcpy(value, mCurBufferp, MVT_VARIABLE, size); + mCurBufferp += size; + } + else + { + llwarns << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << llendl; + success = FALSE; + } + return success; +} + + +BOOL LLDataPackerBinaryBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(size, name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, value, MVT_VARIABLE, size); + } + mCurBufferp += size; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(size, name); + htonmemcpy(value, mCurBufferp, MVT_VARIABLE, size); + mCurBufferp += size; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::packU8(const U8 value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(sizeof(U8), name); + + if (mWriteEnabled) + { + *mCurBufferp = value; + } + mCurBufferp++; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackU8(U8 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(sizeof(U8), name); + + value = *mCurBufferp; + mCurBufferp++; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::packU16(const U16 value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(sizeof(U16), name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, &value, MVT_U16, 2); + } + mCurBufferp += 2; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackU16(U16 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(sizeof(U16), name); + + htonmemcpy(&value, mCurBufferp, MVT_U16, 2); + mCurBufferp += 2; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::packU32(const U32 value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(sizeof(U32), name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, &value, MVT_U32, 4); + } + mCurBufferp += 4; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackU32(U32 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(sizeof(U32), name); + + htonmemcpy(&value, mCurBufferp, MVT_U32, 4); + mCurBufferp += 4; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::packS32(const S32 value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(sizeof(S32), name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, &value, MVT_S32, 4); + } + mCurBufferp += 4; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackS32(S32 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(sizeof(S32), name); + + htonmemcpy(&value, mCurBufferp, MVT_S32, 4); + mCurBufferp += 4; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::packF32(const F32 value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(sizeof(F32), name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, &value, MVT_F32, 4); + } + mCurBufferp += 4; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackF32(F32 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(sizeof(F32), name); + + htonmemcpy(&value, mCurBufferp, MVT_F32, 4); + mCurBufferp += 4; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::packColor4(const LLColor4 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(16, name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); + } + mCurBufferp += 16; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackColor4(LLColor4 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(16, name); + + htonmemcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); + mCurBufferp += 16; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::packColor4U(const LLColor4U &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(4, name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, value.mV, MVT_VARIABLE, 4); + } + mCurBufferp += 4; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackColor4U(LLColor4U &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(4, name); + + htonmemcpy(value.mV, mCurBufferp, MVT_VARIABLE, 4); + mCurBufferp += 4; + return success; +} + + + +BOOL LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(8, name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, &value.mV[0], MVT_F32, 4); + htonmemcpy(mCurBufferp+4, &value.mV[1], MVT_F32, 4); + } + mCurBufferp += 8; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackVector2(LLVector2 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(8, name); + + htonmemcpy(&value.mV[0], mCurBufferp, MVT_F32, 4); + htonmemcpy(&value.mV[1], mCurBufferp+4, MVT_F32, 4); + mCurBufferp += 8; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::packVector3(const LLVector3 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(12, name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, value.mV, MVT_LLVector3, 12); + } + mCurBufferp += 12; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackVector3(LLVector3 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(12, name); + + htonmemcpy(value.mV, mCurBufferp, MVT_LLVector3, 12); + mCurBufferp += 12; + return success; +} + +BOOL LLDataPackerBinaryBuffer::packVector4(const LLVector4 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(16, name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); + } + mCurBufferp += 16; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackVector4(LLVector4 &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(16, name); + + htonmemcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); + mCurBufferp += 16; + return success; +} + +BOOL LLDataPackerBinaryBuffer::packUUID(const LLUUID &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(16, name); + + if (mWriteEnabled) + { + htonmemcpy(mCurBufferp, value.mData, MVT_LLUUID, 16); + } + mCurBufferp += 16; + return success; +} + + +BOOL LLDataPackerBinaryBuffer::unpackUUID(LLUUID &value, const char *name) +{ + BOOL success = TRUE; + success &= verifyLength(16, name); + + htonmemcpy(value.mData, mCurBufferp, MVT_LLUUID, 16); + mCurBufferp += 16; + return success; +} + +const LLDataPackerBinaryBuffer& LLDataPackerBinaryBuffer::operator=(const LLDataPackerBinaryBuffer &a) +{ + if (a.getBufferSize() > getBufferSize()) + { + // We've got problems, ack! + llerrs << "Trying to do an assignment with not enough room in the target." << llendl; + } + memcpy(mBufferp, a.mBufferp, a.getBufferSize()); + return *this; +} + +void LLDataPackerBinaryBuffer::dumpBufferToLog() +{ + llwarns << "Binary Buffer Dump, size: " << mBufferSize << llendl; + char line_buffer[256]; /*Flawfinder: ignore*/ + S32 i; + S32 cur_line_pos = 0; + + S32 cur_line = 0; + for (i = 0; i < mBufferSize; i++) + { + snprintf(line_buffer + cur_line_pos*3, sizeof(line_buffer) - cur_line_pos*3, "%02x ", mBufferp[i]); /*Flawfinder: ignore*/ + cur_line_pos++; + if (cur_line_pos >= 16) + { + cur_line_pos = 0; + llwarns << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << llendl; + cur_line++; + } + } + if (cur_line_pos) + { + llwarns << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << llendl; + } +} + +//--------------------------------------------------------------------------- +// LLDataPackerAsciiBuffer implementation +//--------------------------------------------------------------------------- +BOOL LLDataPackerAsciiBuffer::packString(const char *value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\n", value); /*Flawfinder: ignore*/ + } + else + { + numCopied = (S32)strlen(value) + 1; /*Flawfinder: ignore*/ + } + + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return >= passed in size value. so a check needs to be added + // to detect truncation, and if there is any, only account for the + // actual number of bytes written..and not what could have been + // written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + // *NOTE: I believe we need to mark a failure bit at this point. + numCopied = getBufferSize()-getCurrentSize(); + } + mCurBufferp += numCopied; + return success; +} + +BOOL LLDataPackerAsciiBuffer::unpackString(char *value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + // XXXCHECK: Can result in buffer overrun. Need to pass in size for "value" + strcpy(value, valuestr); /*Flawfinder: ignore*/ + return success; +} + + +BOOL LLDataPackerAsciiBuffer::packBinaryData(const U8 *value, S32 size, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%010d ", size); /*Flawfinder: ignore*/ + + // snprintf returns number of bytes that would have been + // written had the output not being truncated. In that case, + // it will retuen >= passed in size value. so a check needs + // to be added to detect truncation, and if there is any, only + // account for the actual number of bytes written..and not + // what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + mCurBufferp += numCopied; + + + S32 i; + BOOL bBufferFull = FALSE; + for (i = 0; i < size && !bBufferFull; i++) + { + numCopied = snprintf(mCurBufferp, getBufferSize()-getCurrentSize(), "%02x ", value[i]); /* Flawfinder: ignore */ + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + bBufferFull = TRUE; + } + mCurBufferp += numCopied; + } + + if (!bBufferFull) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "\n"); /* Flawfinder: ignore */ + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + mCurBufferp += numCopied; + } + } + else + { + // why +10 ?? XXXCHECK + numCopied = 10 + 1; // size plus newline + numCopied += size; + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + mCurBufferp += numCopied; + } + + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + char *cur_pos = &valuestr[0]; + sscanf(valuestr,"%010d", &size); + cur_pos += 11; + + S32 i; + for (i = 0; i < size; i++) + { + S32 val; + sscanf(cur_pos,"%02x", &val); + value[i] = val; + cur_pos += 3; + } + return success; +} + + +BOOL LLDataPackerAsciiBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + + if (mWriteEnabled) + { + S32 i; + int numCopied = 0; + BOOL bBufferFull = FALSE; + for (i = 0; i < size && !bBufferFull; i++) + { + numCopied = snprintf(mCurBufferp, getBufferSize()-getCurrentSize(), "%02x ", value[i]); /* Flawfinder: ignore */ + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + bBufferFull = TRUE; + } + mCurBufferp += numCopied; + + } + if (!bBufferFull) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "\n"); /* Flawfinder: ignore */ + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + + mCurBufferp += numCopied; + } + } + else + { + int numCopied = 2 * size + 1; //hex bytes plus newline + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + mCurBufferp += numCopied; + } + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + char *cur_pos = &valuestr[0]; + + S32 i; + for (i = 0; i < size; i++) + { + S32 val; + sscanf(cur_pos,"%02x", &val); + value[i] = val; + cur_pos += 3; + } + return success; +} + + + +BOOL LLDataPackerAsciiBuffer::packU8(const U8 value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d\n", value); /*Flawfinder: ignore*/ + } + else + { + // just do the write to a temp buffer to get the length + numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value); /* Flawfinder: ignore */ + } + + // snprintf returns number of bytes that would have been written had the + // output not being truncated. In that case, it will retuen >= passed in size value. + // so a check needs to be added to detect truncation, and if there is any, + // only account for the actual number of bytes written..and not what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + + mCurBufferp += numCopied; + + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackU8(U8 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + S32 in_val; + sscanf(valuestr,"%d", &in_val); + value = in_val; + return success; +} + +BOOL LLDataPackerAsciiBuffer::packU16(const U16 value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d\n", value); /*Flawfinder: ignore*/ + } + else + { + numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value); /* Flawfinder: ignore */ + } + + // snprintf returns number of bytes that would have been written had the + // output not being truncated. In that case, it will retuen >= passed in size value. + // so a check needs to be added to detect truncation, and if there is any, + // only account for the actual number of bytes written..and not what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + + mCurBufferp += numCopied; + + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackU16(U16 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + S32 in_val; + sscanf(valuestr,"%d", &in_val); + value = in_val; + return success; +} + + +BOOL LLDataPackerAsciiBuffer::packU32(const U32 value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%u\n", value); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%u\n", value); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written had the + // output not being truncated. In that case, it will retuen >= passed in size value. + // so a check needs to be added to detect truncation, and if there is any, + // only account for the actual number of bytes written..and not what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + + mCurBufferp += numCopied; + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackU32(U32 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%u", &value); + return success; +} + + +BOOL LLDataPackerAsciiBuffer::packS32(const S32 value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d\n", value); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written had the + // output not being truncated. In that case, it will retuen >= passed in size value. + // so a check needs to be added to detect truncation, and if there is any, + // only account for the actual number of bytes written..and not what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + + mCurBufferp += numCopied; + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackS32(S32 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%d", &value); + return success; +} + + +BOOL LLDataPackerAsciiBuffer::packF32(const F32 value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g\n", value); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%g\n", value); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written had the + // output not being truncated. In that case, it will retuen >= passed in size value. + // so a check needs to be added to detect truncation, and if there is any, + // only account for the actual number of bytes written..and not what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + + mCurBufferp += numCopied; + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackF32(F32 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%g", &value); + return success; +} + + +BOOL LLDataPackerAsciiBuffer::packColor4(const LLColor4 &value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + } + else + { + 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 */ + } + // snprintf returns number of bytes that would have been written had the + // output not being truncated. In that case, it will retuen >= passed in size value. + // so a check needs to be added to detect truncation, and if there is any, + // only account for the actual number of bytes written..and not what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + + mCurBufferp += numCopied; + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackColor4(LLColor4 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%g %g %g %g", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); + return success; +} + +BOOL LLDataPackerAsciiBuffer::packColor4U(const LLColor4U &value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%d %d %d %d\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + } + else + { + 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 */ + } + // snprintf returns number of bytes that would have been written had the + // output not being truncated. In that case, it will retuen >= passed in size value. + // so a check needs to be added to detect truncation, and if there is any, + // only account for the actual number of bytes written..and not what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + + mCurBufferp += numCopied; + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackColor4U(LLColor4U &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + S32 r, g, b, a; + + sscanf(valuestr,"%d %d %d %d", &r, &g, &b, &a); + value.mV[0] = r; + value.mV[1] = g; + value.mV[2] = b; + value.mV[3] = a; + return success; +} + + +BOOL LLDataPackerAsciiBuffer::packVector2(const LLVector2 &value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g %g\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%g %g\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written had the + // output not being truncated. In that case, it will retuen >= passed in size value. + // so a check needs to be added to detect truncation, and if there is any, + // only account for the actual number of bytes written..and not what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + + mCurBufferp += numCopied; + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackVector2(LLVector2 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%g %g", &value.mV[0], &value.mV[1]); + return success; +} + + +BOOL LLDataPackerAsciiBuffer::packVector3(const LLVector3 &value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g %g %g\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%g %g %g\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ + } + // snprintf returns number of bytes that would have been written had the + // output not being truncated. In that case, it will retuen >= passed in size value. + // so a check needs to be added to detect truncation, and if there is any, + // only account for the actual number of bytes written..and not what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + + mCurBufferp += numCopied; + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackVector3(LLVector3 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%g %g %g", &value.mV[0], &value.mV[1], &value.mV[2]); + return success; +} + +BOOL LLDataPackerAsciiBuffer::packVector4(const LLVector4 &value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + } + else + { + 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 */ + } + // snprintf returns number of bytes that would have been written had the + // output not being truncated. In that case, it will retuen >= passed in size value. + // so a check needs to be added to detect truncation, and if there is any, + // only account for the actual number of bytes written..and not what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + + mCurBufferp += numCopied; + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackVector4(LLVector4 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%g %g %g %g", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); + return success; +} + + +BOOL LLDataPackerAsciiBuffer::packUUID(const LLUUID &value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + + int numCopied = 0; + if (mWriteEnabled) + { + char tmp_str[64]; /* Flawfinder: ignore */ + value.toString(tmp_str); + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\n", tmp_str); /* Flawfinder: ignore */ + } + else + { + numCopied = 64 + 1; // UUID + newline + } + // snprintf returns number of bytes that would have been written had the + // output not being truncated. In that case, it will retuen >= passed in size value. + // so a check needs to be added to detect truncation, and if there is any, + // only account for the actual number of bytes written..and not what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + success = FALSE; + } + mCurBufferp += numCopied; + return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackUUID(LLUUID &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + char tmp_str[64]; /* Flawfinder: ignore */ + sscanf(valuestr, "%63s", tmp_str); + value.set(tmp_str); + + return success; +} + +void LLDataPackerAsciiBuffer::dump() +{ + llinfos << "Buffer: " << mBufferp << llendl; +} + +void LLDataPackerAsciiBuffer::writeIndentedName(const char *name) +{ + if (mIncludeNames) + { + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\t", name); /* Flawfinder: ignore */ + } + else + { + numCopied = (S32)strlen(name) + 1; //name + tab /* Flawfinder: ignore */ + } + + // snprintf returns number of bytes that would have been written had the + // output not being truncated. In that case, it will retuen >= passed in size value. + // so a check needs to be added to detect truncation, and if there is any, + // only account for the actual number of bytes written..and not what could have been written. + if (numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + } + } +} + +BOOL LLDataPackerAsciiBuffer::getValueStr(const char *name, char *out_value, S32 value_len) +{ + BOOL success = TRUE; + char buffer[DP_BUFSIZE]; /* Flawfinder: ignore */ + char keyword[DP_BUFSIZE]; /* Flawfinder: ignore */ + char value[DP_BUFSIZE]; /* Flawfinder: ignore */ + + buffer[0] = '\0'; + keyword[0] = '\0'; + value[0] = '\0'; + + if (mIncludeNames) + { + // Read both the name and the value, and validate the name. + sscanf(mCurBufferp, "%511[^\n]", buffer); + // Skip the \n + mCurBufferp += (S32)strlen(buffer) + 1; + + sscanf(buffer, "%511s %511[^\n]", keyword, value); + + if (strcmp(keyword, name)) + { + llwarns << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << llendl; + return FALSE; + } + } + else + { + // Just the value exists + sscanf(mCurBufferp, "%511[^\n]", value); + // Skip the \n + mCurBufferp += (S32)strlen(value) + 1; /* Flawfinder: ignore */ + } + + S32 in_value_len = (S32)strlen(value)+1; /* Flawfinder: ignore */ + S32 min_len = llmin(in_value_len, value_len); + memcpy(out_value, value, min_len); /* Flawfinder: ignore */ + out_value[min_len-1] = 0; + + return success; +} + +//--------------------------------------------------------------------------- +// LLDataPackerAsciiFile implementation +//--------------------------------------------------------------------------- +BOOL LLDataPackerAsciiFile::packString(const char *value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%s\n", value); + } + else if (mOutputStream) + { + *mOutputStream << value << "\n"; + } + return success; +} + +BOOL LLDataPackerAsciiFile::unpackString(char *value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + strncpy(value, valuestr,DP_BUFSIZE); + return success; +} + + +BOOL LLDataPackerAsciiFile::packBinaryData(const U8 *value, S32 size, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + + if (mFP) + { + fprintf(mFP, "%010d ", size); + + S32 i; + for (i = 0; i < size; i++) + { + fprintf(mFP, "%02x ", value[i]); + } + fprintf(mFP, "\n"); + } + else if (mOutputStream) + { + char buffer[32]; /* Flawfinder: ignore */ + snprintf(buffer,sizeof(buffer), "%010d ", size); /* Flawfinder: ignore */ + *mOutputStream << buffer; + + S32 i; + for (i = 0; i < size; i++) + { + snprintf(buffer, sizeof(buffer), "%02x ", value[i]); /* Flawfinder: ignore */ + *mOutputStream << buffer; + } + *mOutputStream << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackBinaryData(U8 *value, S32 &size, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + char *cur_pos = &valuestr[0]; + sscanf(valuestr,"%010d", &size); + cur_pos += 11; + + S32 i; + for (i = 0; i < size; i++) + { + S32 val; + sscanf(cur_pos,"%02x", &val); + value[i] = val; + cur_pos += 3; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::packBinaryDataFixed(const U8 *value, S32 size, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + + if (mFP) + { + S32 i; + for (i = 0; i < size; i++) + { + fprintf(mFP, "%02x ", value[i]); + } + fprintf(mFP, "\n"); + } + else if (mOutputStream) + { + char buffer[32]; /*Flawfinder: ignore*/ + S32 i; + for (i = 0; i < size; i++) + { + snprintf(buffer, sizeof(buffer), "%02x ", value[i]); /*Flawfinder: ignore*/ + *mOutputStream << buffer; + } + *mOutputStream << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackBinaryDataFixed(U8 *value, S32 size, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + char *cur_pos = &valuestr[0]; + + S32 i; + for (i = 0; i < size; i++) + { + S32 val; + sscanf(cur_pos,"%02x", &val); + value[i] = val; + cur_pos += 3; + } + return success; +} + + + +BOOL LLDataPackerAsciiFile::packU8(const U8 value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%d\n", value); + } + else if (mOutputStream) + { + // We have to cast this to an integer because streams serialize + // bytes as bytes - not as text. + *mOutputStream << (S32)value << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackU8(U8 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + S32 in_val; + sscanf(valuestr,"%d", &in_val); + value = in_val; + return success; +} + +BOOL LLDataPackerAsciiFile::packU16(const U16 value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%d\n", value); + } + else if (mOutputStream) + { + *mOutputStream <<"" << value << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackU16(U16 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + S32 in_val; + sscanf(valuestr,"%d", &in_val); + value = in_val; + return success; +} + + +BOOL LLDataPackerAsciiFile::packU32(const U32 value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%u\n", value); + } + else if (mOutputStream) + { + *mOutputStream <<"" << value << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackU32(U32 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%u", &value); + return success; +} + + +BOOL LLDataPackerAsciiFile::packS32(const S32 value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%d\n", value); + } + else if (mOutputStream) + { + *mOutputStream <<"" << value << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackS32(S32 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%d", &value); + return success; +} + + +BOOL LLDataPackerAsciiFile::packF32(const F32 value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%g\n", value); + } + else if (mOutputStream) + { + *mOutputStream <<"" << value << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackF32(F32 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%g", &value); + return success; +} + + +BOOL LLDataPackerAsciiFile::packColor4(const LLColor4 &value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); + } + else if (mOutputStream) + { + *mOutputStream << value.mV[0] << " " << value.mV[1] << " " << value.mV[2] << " " << value.mV[3] << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackColor4(LLColor4 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%g %g %g %g", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); + return success; +} + +BOOL LLDataPackerAsciiFile::packColor4U(const LLColor4U &value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%d %d %d %d\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); + } + else if (mOutputStream) + { + *mOutputStream << (S32)(value.mV[0]) << " " << (S32)(value.mV[1]) << " " << (S32)(value.mV[2]) << " " << (S32)(value.mV[3]) << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackColor4U(LLColor4U &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + S32 r, g, b, a; + + sscanf(valuestr,"%d %d %d %d", &r, &g, &b, &a); + value.mV[0] = r; + value.mV[1] = g; + value.mV[2] = b; + value.mV[3] = a; + return success; +} + + +BOOL LLDataPackerAsciiFile::packVector2(const LLVector2 &value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%g %g\n", value.mV[0], value.mV[1]); + } + else if (mOutputStream) + { + *mOutputStream << value.mV[0] << " " << value.mV[1] << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackVector2(LLVector2 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%g %g", &value.mV[0], &value.mV[1]); + return success; +} + + +BOOL LLDataPackerAsciiFile::packVector3(const LLVector3 &value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%g %g %g\n", value.mV[0], value.mV[1], value.mV[2]); + } + else if (mOutputStream) + { + *mOutputStream << value.mV[0] << " " << value.mV[1] << " " << value.mV[2] << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackVector3(LLVector3 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%g %g %g", &value.mV[0], &value.mV[1], &value.mV[2]); + return success; +} + +BOOL LLDataPackerAsciiFile::packVector4(const LLVector4 &value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); + } + else if (mOutputStream) + { + *mOutputStream << value.mV[0] << " " << value.mV[1] << " " << value.mV[2] << " " << value.mV[3] << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackVector4(LLVector4 &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + sscanf(valuestr,"%g %g %g %g", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); + return success; +} + + +BOOL LLDataPackerAsciiFile::packUUID(const LLUUID &value, const char *name) +{ + BOOL success = TRUE; + writeIndentedName(name); + char tmp_str[64]; /*Flawfinder: ignore */ + value.toString(tmp_str); + if (mFP) + { + fprintf(mFP,"%s\n", tmp_str); + } + else if (mOutputStream) + { + *mOutputStream <<"" << tmp_str << "\n"; + } + return success; +} + + +BOOL LLDataPackerAsciiFile::unpackUUID(LLUUID &value, const char *name) +{ + BOOL success = TRUE; + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return FALSE; + } + + char tmp_str[64]; /*Flawfinder: ignore */ + sscanf(valuestr,"%63s",tmp_str); + value.set(tmp_str); + + return success; +} + + +void LLDataPackerAsciiFile::writeIndentedName(const char *name) +{ + char indent_buf[64]; /*Flawfinder: ignore*/ + + S32 i; + for(i = 0; i < mIndent; i++) + { + indent_buf[i] = '\t'; + } + indent_buf[i] = 0; + if (mFP) + { + fprintf(mFP,"%s%s\t",indent_buf, name); + } + else if (mOutputStream) + { + *mOutputStream << indent_buf << name << "\t"; + } +} + +BOOL LLDataPackerAsciiFile::getValueStr(const char *name, char *out_value, S32 value_len) +{ + BOOL success = FALSE; + char buffer[DP_BUFSIZE]; /*Flawfinder: ignore*/ + char keyword[DP_BUFSIZE]; /*Flawfinder: ignore*/ + char value[DP_BUFSIZE]; /*Flawfinder: ignore*/ + + buffer[0] = '\0'; + keyword[0] = '\0'; + value[0] = '\0'; + + if (mFP) + { + fpos_t last_pos; + fgetpos(mFP, &last_pos); + fgets(buffer, DP_BUFSIZE, mFP); + + sscanf(buffer, "%511s %511[^\n]", keyword, value); + + if (!keyword[0]) + { + llwarns << "Data packer could not get the keyword!" << llendl; + fsetpos(mFP, &last_pos); + return FALSE; + } + if (strcmp(keyword, name)) + { + llwarns << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << llendl; + fsetpos(mFP, &last_pos); + return FALSE; + } + + S32 in_value_len = (S32)strlen(value)+1; /*Flawfinder: ignore*/ + S32 min_len = llmin(in_value_len, value_len); + memcpy(out_value, value, min_len); /*Flawfinder: ignore*/ + out_value[min_len-1] = 0; + success = TRUE; + } + else if (mInputStream) + { + mInputStream->getline(buffer, DP_BUFSIZE); + + sscanf(buffer, "%511s %511[^\n]", keyword, value); + if (!keyword[0]) + { + llwarns << "Data packer could not get the keyword!" << llendl; + return FALSE; + } + if (strcmp(keyword, name)) + { + llwarns << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << llendl; + return FALSE; + } + + S32 in_value_len = (S32)strlen(value)+1; /*Flawfinder: ignore*/ + S32 min_len = llmin(in_value_len, value_len); + memcpy(out_value, value, min_len); /*Flawfinder: ignore*/ + out_value[min_len-1] = 0; + success = TRUE; + } + + return success; +} |