diff options
author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 21:25:21 +0200 |
---|---|---|
committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-22 22:40:26 +0300 |
commit | e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 (patch) | |
tree | 1bb897489ce524986f6196201c10ac0d8861aa5f /indra/llmessage/lldatapacker.cpp | |
parent | 069ea06848f766466f1a281144c82a0f2bd79f3a (diff) |
Fix line endlings
Diffstat (limited to 'indra/llmessage/lldatapacker.cpp')
-rw-r--r-- | indra/llmessage/lldatapacker.cpp | 4360 |
1 files changed, 2180 insertions, 2180 deletions
diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp index e8cd11c0a0..134f34aafa 100644 --- a/indra/llmessage/lldatapacker.cpp +++ b/indra/llmessage/lldatapacker.cpp @@ -1,2180 +1,2180 @@ -/**
- * @file lldatapacker.cpp
- * @brief Data packer implementation.
- *
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#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)
-{
-}
-
-//virtual
-void LLDataPacker::reset()
-{
- LL_ERRS() << "Using unimplemented datapacker reset!" << LL_ENDL;
-}
-
-//virtual
-void LLDataPacker::dumpBufferToLog()
-{
- LL_ERRS() << "dumpBufferToLog not implemented for this type!" << LL_ENDL;
-}
-
-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
- {
- LL_ERRS() << "Using fixed-point packing of " << total_bits << " bits, why?!" << LL_ENDL;
- }
- 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;
- //LL_INFOS() << "unpackFixed:" << name << " int:" << int_bits << " frac:" << frac_bits << LL_ENDL;
- S32 unsigned_bits = int_bits + frac_bits;
- S32 total_bits = unsigned_bits;
-
- if (is_signed)
- {
- total_bits++;
- }
-
- U32 max_val;
- max_val = 1 << int_bits;
-
- F32 fixed_val;
- if (total_bits <= 8)
- {
- U8 fixed_8;
- success = unpackU8(fixed_8, name);
- fixed_val = (F32)fixed_8;
- }
- else if (total_bits <= 16)
- {
- U16 fixed_16;
- success = unpackU16(fixed_16, name);
- fixed_val = (F32)fixed_16;
- }
- else if (total_bits <= 31)
- {
- U32 fixed_32;
- success = unpackU32(fixed_32, name);
- fixed_val = (F32)fixed_32;
- }
- else
- {
- fixed_val = 0;
- LL_ERRS() << "Bad bit count: " << total_bits << LL_ENDL;
- }
-
- //LL_INFOS() << "Fixed_val:" << fixed_val << LL_ENDL;
-
- fixed_val /= (F32)(1 << frac_bits);
- if (is_signed)
- {
- fixed_val -= max_val;
- }
- value = fixed_val;
- //LL_INFOS() << "Value: " << value << LL_ENDL;
- return success;
-}
-
-bool LLDataPacker::unpackU16s(U16 *values, S32 count, const char *name)
-{
- for (S32 idx = 0; idx < count; ++idx)
- {
- if (!unpackU16(values[idx], name))
- {
- LL_WARNS("DATAPACKER") << "Buffer overflow reading Unsigned 16s \"" << name << "\" at index " << idx << "!" << LL_ENDL;
- return false;
- }
- }
- return true;
-}
-
-bool LLDataPacker::unpackS16s(S16 *values, S32 count, const char *name)
-{
- for (S32 idx = 0; idx < count; ++idx)
- {
- if (!unpackS16(values[idx], name))
- {
- LL_WARNS("DATAPACKER") << "Buffer overflow reading Signed 16s \"" << name << "\" at index " << idx << "!" << LL_ENDL;
- return false;
- }
- }
- return true;
-}
-
-bool LLDataPacker::unpackF32s(F32 *values, S32 count, const char *name)
-{
- for (S32 idx = 0; idx < count; ++idx)
- {
- if (!unpackF32(values[idx], name))
- {
- LL_WARNS("DATAPACKER") << "Buffer overflow reading Float 32s \"" << name << "\" at index " << idx << "!" << LL_ENDL;
- return false;
- }
- }
- return true;
-}
-
-bool LLDataPacker::unpackColor4Us(LLColor4U *values, S32 count, const char *name)
-{
- for (S32 idx = 0; idx < count; ++idx)
- {
- if (!unpackColor4U(values[idx], name))
- {
- LL_WARNS("DATAPACKER") << "Buffer overflow reading Float 32s \"" << name << "\" at index " << idx << "!" << LL_ENDL;
- return false;
- }
- }
- return true;
-}
-
-bool LLDataPacker::unpackUUIDs(LLUUID *values, S32 count, const char *name)
-{
- for (S32 idx = 0; idx < count; ++idx)
- {
- if (!unpackUUID(values[idx], name))
- {
- LL_WARNS("DATAPACKER") << "Buffer overflow reading UUIDs \"" << name << "\" at index " << idx << "!" << LL_ENDL;
- return false;
- }
- }
- return true;
-}
-
-//---------------------------------------------------------------------------
-// LLDataPackerBinaryBuffer implementation
-//---------------------------------------------------------------------------
-
-bool LLDataPackerBinaryBuffer::packString(const std::string& value, const char *name)
-{
- S32 length = value.length()+1;
-
- if (!verifyLength(length, name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, value.c_str(), MVT_VARIABLE, length);
- }
- mCurBufferp += length;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackString(std::string& value, const char *name)
-{
- S32 length = (S32)strlen((char *)mCurBufferp) + 1; /*Flawfinder: ignore*/
-
- if (!verifyLength(length, name))
- {
- return false;
- }
-
- value = std::string((char*)mCurBufferp); // We already assume NULL termination calling strlen()
-
- mCurBufferp += length;
- return true;
-}
-
-bool LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const char *name)
-{
- if (!verifyLength(size + 4, name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, &size, MVT_S32, 4);
- }
- mCurBufferp += 4;
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, value, MVT_VARIABLE, size);
- }
- mCurBufferp += size;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name)
-{
- if (!verifyLength(4, name))
- {
- LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL;
- return false;
- }
-
- htolememcpy(&size, mCurBufferp, MVT_S32, 4);
-
- if (size < 0)
- {
- LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData unpacked invalid size, aborting!" << LL_ENDL;
- return false;
- }
-
- mCurBufferp += 4;
-
- if (!verifyLength(size, name))
- {
- LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL;
- return false;
- }
-
- htolememcpy(value, mCurBufferp, MVT_VARIABLE, size);
- mCurBufferp += size;
-
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name)
-{
- if (!verifyLength(size, name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, value, MVT_VARIABLE, size);
- }
- mCurBufferp += size;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name)
-{
- if (!verifyLength(size, name))
- {
- return false;
- }
- htolememcpy(value, mCurBufferp, MVT_VARIABLE, size);
- mCurBufferp += size;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::packU8(const U8 value, const char *name)
-{
- if (!verifyLength(sizeof(U8), name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- *mCurBufferp = value;
- }
- mCurBufferp++;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackU8(U8 &value, const char *name)
-{
- if (!verifyLength(sizeof(U8), name))
- {
- return false;
- }
-
- value = *mCurBufferp;
- mCurBufferp++;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::packU16(const U16 value, const char *name)
-{
- if (!verifyLength(sizeof(U16), name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, &value, MVT_U16, 2);
- }
- mCurBufferp += 2;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackU16(U16 &value, const char *name)
-{
- if (!verifyLength(sizeof(U16), name))
- {
- return false;
- }
-
- htolememcpy(&value, mCurBufferp, MVT_U16, 2);
- mCurBufferp += 2;
- return true;
-}
-
-bool LLDataPackerBinaryBuffer::packS16(const S16 value, const char *name)
-{
- bool success = verifyLength(sizeof(S16), name);
-
- if (mWriteEnabled && success)
- {
- htolememcpy(mCurBufferp, &value, MVT_S16, 2);
- }
- mCurBufferp += 2;
- return success;
-}
-
-bool LLDataPackerBinaryBuffer::unpackS16(S16 &value, const char *name)
-{
- bool success = verifyLength(sizeof(S16), name);
-
- if (success)
- {
- htolememcpy(&value, mCurBufferp, MVT_S16, 2);
- }
- mCurBufferp += 2;
- return success;
-}
-
-bool LLDataPackerBinaryBuffer::packU32(const U32 value, const char *name)
-{
- if (!verifyLength(sizeof(U32), name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, &value, MVT_U32, 4);
- }
- mCurBufferp += 4;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackU32(U32 &value, const char *name)
-{
- if (!verifyLength(sizeof(U32), name))
- {
- return false;
- }
-
- htolememcpy(&value, mCurBufferp, MVT_U32, 4);
- mCurBufferp += 4;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::packS32(const S32 value, const char *name)
-{
- if (!verifyLength(sizeof(S32), name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, &value, MVT_S32, 4);
- }
- mCurBufferp += 4;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackS32(S32 &value, const char *name)
-{
- if(!verifyLength(sizeof(S32), name))
- {
- return false;
- }
-
- htolememcpy(&value, mCurBufferp, MVT_S32, 4);
- mCurBufferp += 4;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::packF32(const F32 value, const char *name)
-{
- if (!verifyLength(sizeof(F32), name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, &value, MVT_F32, 4);
- }
- mCurBufferp += 4;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackF32(F32 &value, const char *name)
-{
- if (!verifyLength(sizeof(F32), name))
- {
- return false;
- }
-
- htolememcpy(&value, mCurBufferp, MVT_F32, 4);
- mCurBufferp += 4;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::packColor4(const LLColor4 &value, const char *name)
-{
- if (!verifyLength(16, name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16);
- }
- mCurBufferp += 16;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackColor4(LLColor4 &value, const char *name)
-{
- if (!verifyLength(16, name))
- {
- return false;
- }
-
- htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16);
- mCurBufferp += 16;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::packColor4U(const LLColor4U &value, const char *name)
-{
- if (!verifyLength(4, name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, value.mV, MVT_VARIABLE, 4);
- }
- mCurBufferp += 4;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackColor4U(LLColor4U &value, const char *name)
-{
- if (!verifyLength(4, name))
- {
- return false;
- }
-
- htolememcpy(value.mV, mCurBufferp, MVT_VARIABLE, 4);
- mCurBufferp += 4;
- return true;
-}
-
-
-
-bool LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *name)
-{
- if (!verifyLength(8, name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, &value.mV[0], MVT_F32, 4);
- htolememcpy(mCurBufferp+4, &value.mV[1], MVT_F32, 4);
- }
- mCurBufferp += 8;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackVector2(LLVector2 &value, const char *name)
-{
- if (!verifyLength(8, name))
- {
- return false;
- }
-
- htolememcpy(&value.mV[0], mCurBufferp, MVT_F32, 4);
- htolememcpy(&value.mV[1], mCurBufferp+4, MVT_F32, 4);
- mCurBufferp += 8;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::packVector3(const LLVector3 &value, const char *name)
-{
- if (!verifyLength(12, name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, value.mV, MVT_LLVector3, 12);
- }
- mCurBufferp += 12;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackVector3(LLVector3 &value, const char *name)
-{
- if (!verifyLength(12, name))
- {
- return false;
- }
-
- htolememcpy(value.mV, mCurBufferp, MVT_LLVector3, 12);
- mCurBufferp += 12;
- return true;
-}
-
-bool LLDataPackerBinaryBuffer::packVector4(const LLVector4 &value, const char *name)
-{
- if (!verifyLength(16, name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16);
- }
- mCurBufferp += 16;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackVector4(LLVector4 &value, const char *name)
-{
- if (!verifyLength(16, name))
- {
- return false;
- }
-
- htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16);
- mCurBufferp += 16;
- return true;
-}
-
-bool LLDataPackerBinaryBuffer::packUUID(const LLUUID &value, const char *name)
-{
- if (!verifyLength(16, name))
- {
- return false;
- }
-
- if (mWriteEnabled)
- {
- htolememcpy(mCurBufferp, value.mData, MVT_LLUUID, 16);
- }
- mCurBufferp += 16;
- return true;
-}
-
-
-bool LLDataPackerBinaryBuffer::unpackUUID(LLUUID &value, const char *name)
-{
- if (!verifyLength(16, name))
- {
- return false;
- }
-
- htolememcpy(value.mData, mCurBufferp, MVT_LLUUID, 16);
- mCurBufferp += 16;
- return true;
-}
-
-const LLDataPackerBinaryBuffer& LLDataPackerBinaryBuffer::operator=(const LLDataPackerBinaryBuffer &a)
-{
- if (a.getBufferSize() > getBufferSize())
- {
- // We've got problems, ack!
- LL_ERRS() << "Trying to do an assignment with not enough room in the target." << LL_ENDL;
- }
- memcpy(mBufferp, a.mBufferp, a.getBufferSize()); /*Flawfinder: ignore*/
- return *this;
-}
-
-void LLDataPackerBinaryBuffer::dumpBufferToLog()
-{
- LL_WARNS() << "Binary Buffer Dump, size: " << mBufferSize << LL_ENDL;
- 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;
- LL_WARNS() << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << LL_ENDL;
- cur_line++;
- }
- }
- if (cur_line_pos)
- {
- LL_WARNS() << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << LL_ENDL;
- }
-}
-
-//---------------------------------------------------------------------------
-// LLDataPackerAsciiBuffer implementation
-//---------------------------------------------------------------------------
-bool LLDataPackerAsciiBuffer::packString(const std::string& value, const char *name)
-{
- bool success = true;
- writeIndentedName(name);
- int numCopied = 0;
- if (mWriteEnabled)
- {
- numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\n", value.c_str()); /* Flawfinder: ignore */
- }
- else
- {
- numCopied = value.length() + 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 either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- // *NOTE: I believe we need to mark a failure bit at this point.
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packString: string truncated: " << value << LL_ENDL;
- }
- mCurBufferp += numCopied;
- return success;
-}
-
-bool LLDataPackerAsciiBuffer::unpackString(std::string& value, const char *name)
-{
- char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/
- if (!getValueStr(name, valuestr, DP_BUFSIZE)) // NULL terminated
- {
- return false;
- }
- value = valuestr;
- return true;
-}
-
-
-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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryData: number truncated: " << size << LL_ENDL;
- }
- 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryData: data truncated: " << LL_ENDL;
- bBufferFull = true;
- }
- mCurBufferp += numCopied;
- }
-
- if (!bBufferFull)
- {
- numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "\n"); /* Flawfinder: ignore */
- if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryData: newline truncated: " << LL_ENDL;
- }
- 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryDataFixed: data truncated: " << LL_ENDL;
- bBufferFull = true;
- }
- mCurBufferp += numCopied;
-
- }
- if (!bBufferFull)
- {
- numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "\n"); /* Flawfinder: ignore */
- if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryDataFixed: newline truncated: " << LL_ENDL;
- }
-
- 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
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packU8: val truncated: " << LL_ENDL;
- }
-
- 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
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packU16: val truncated: " << LL_ENDL;
- }
-
- 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::packS16(const S16 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
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize() - getCurrentSize())
- {
- numCopied = getBufferSize() - getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packS16: val truncated: " << LL_ENDL;
- }
-
- mCurBufferp += numCopied;
-
- return success;
-}
-
-
-bool LLDataPackerAsciiBuffer::unpackS16(S16 &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
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packU32: val truncated: " << LL_ENDL;
- }
-
- 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
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packS32: val truncated: " << LL_ENDL;
- }
-
- 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(),"%f\n", value); /* Flawfinder: ignore */
- }
- else
- {
- numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%f\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
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packF32: val truncated: " << LL_ENDL;
- }
-
- 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,"%f", &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(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
- }
- else
- {
- 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 */
- }
- // snprintf returns number of bytes that would have been written
- // had the output not being truncated. In that case, it will
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packColor4: truncated: " << LL_ENDL;
- }
-
- 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,"%f %f %f %f", &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
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packColor4U: truncated: " << LL_ENDL;
- }
-
- 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(),"%f %f\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */
- }
- else
- {
- numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f\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
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packVector2: truncated: " << LL_ENDL;
- }
-
- 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,"%f %f", &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(),"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */
- }
- else
- {
- numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f\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
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packVector3: truncated: " << LL_ENDL;
- }
-
- 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,"%f %f %f", &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(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */
- }
- else
- {
- 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 */
- }
- // snprintf returns number of bytes that would have been written
- // had the output not being truncated. In that case, it will
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packVector4: truncated: " << LL_ENDL;
- }
-
- 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,"%f %f %f %f", &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)
- {
- std::string tmp_str;
- value.toString(tmp_str);
- numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\n", tmp_str.c_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
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::packUUID: truncated: " << LL_ENDL;
- 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); /* Flawfinder: ignore */
- value.set(tmp_str);
-
- return success;
-}
-
-void LLDataPackerAsciiBuffer::dump()
-{
- LL_INFOS() << "Buffer: " << mBufferp << LL_ENDL;
-}
-
-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; /* Flawfinder: ignore */ //name + tab
- }
-
- // snprintf returns number of bytes that would have been written
- // had the output not being truncated. In that case, it will
- // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize())
- {
- numCopied = getBufferSize()-getCurrentSize();
- LL_WARNS() << "LLDataPackerAsciiBuffer::writeIndentedName: truncated: " << LL_ENDL;
- }
-
- mCurBufferp += numCopied;
- }
-}
-
-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; /* Flawfinder: ignore */
-
- sscanf(buffer, "%511s %511[^\n]", keyword, value); /* Flawfinder: ignore */
-
- if (strcmp(keyword, name))
- {
- LL_WARNS() << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << LL_ENDL;
- 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;
-}
-
-// helper function used by LLDataPackerAsciiFile
-// to convert F32 into a string. This is to avoid
-// << operator writing F32 value into a stream
-// since it does not seem to preserve the float value
-std::string convertF32ToString(F32 val)
-{
- std::string str;
- char buf[20];
- snprintf(buf, 20, "%f", val);
- str = buf;
- return str;
-}
-
-//---------------------------------------------------------------------------
-// LLDataPackerAsciiFile implementation
-//---------------------------------------------------------------------------
-bool LLDataPackerAsciiFile::packString(const std::string& value, const char *name)
-{
- bool success = true;
- writeIndentedName(name);
- if (mFP)
- {
- fprintf(mFP,"%s\n", value.c_str());
- }
- else if (mOutputStream)
- {
- *mOutputStream << value << "\n";
- }
- return success;
-}
-
-bool LLDataPackerAsciiFile::unpackString(std::string& value, const char *name)
-{
- bool success = true;
- char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */
- if (!getValueStr(name, valuestr, DP_BUFSIZE))
- {
- return false;
- }
- value = valuestr;
- 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::packS16(const S16 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::unpackS16(S16 &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,"%f\n", value);
- }
- else if (mOutputStream)
- {
- *mOutputStream <<"" << convertF32ToString(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,"%f", &value);
- return success;
-}
-
-
-bool LLDataPackerAsciiFile::packColor4(const LLColor4 &value, const char *name)
-{
- bool success = true;
- writeIndentedName(name);
- if (mFP)
- {
- fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]);
- }
- else if (mOutputStream)
- {
- *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(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,"%f %f %f %f", &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,"%f %f\n", value.mV[0], value.mV[1]);
- }
- else if (mOutputStream)
- {
- *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(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,"%f %f", &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,"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]);
- }
- else if (mOutputStream)
- {
- *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(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,"%f %f %f", &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,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]);
- }
- else if (mOutputStream)
- {
- *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(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,"%f %f %f %f", &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);
- std::string tmp_str;
- value.toString(tmp_str);
- if (mFP)
- {
- fprintf(mFP,"%s\n", tmp_str.c_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); /* Flawfinder: ignore */
- value.set(tmp_str);
-
- return success;
-}
-
-
-void LLDataPackerAsciiFile::writeIndentedName(const char *name)
-{
- std::string indent_buf;
- indent_buf.reserve(mIndent+1);
-
- 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.c_str(), 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;
- if (0 != fgetpos(mFP, &last_pos)) // 0==success for fgetpos
- {
- LL_WARNS() << "Data packer failed to fgetpos" << LL_ENDL;
- return false;
- }
-
- if (fgets(buffer, DP_BUFSIZE, mFP) == NULL)
- {
- buffer[0] = '\0';
- }
-
- sscanf(buffer, "%511s %511[^\n]", keyword, value); /* Flawfinder: ignore */
-
- if (!keyword[0])
- {
- LL_WARNS() << "Data packer could not get the keyword!" << LL_ENDL;
- fsetpos(mFP, &last_pos);
- return false;
- }
- if (strcmp(keyword, name))
- {
- LL_WARNS() << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << LL_ENDL;
- 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); /* Flawfinder: ignore */
- if (!keyword[0])
- {
- LL_WARNS() << "Data packer could not get the keyword!" << LL_ENDL;
- return false;
- }
- if (strcmp(keyword, name))
- {
- LL_WARNS() << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << LL_ENDL;
- 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;
-}
+/** + * @file lldatapacker.cpp + * @brief Data packer implementation. + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#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) +{ +} + +//virtual +void LLDataPacker::reset() +{ + LL_ERRS() << "Using unimplemented datapacker reset!" << LL_ENDL; +} + +//virtual +void LLDataPacker::dumpBufferToLog() +{ + LL_ERRS() << "dumpBufferToLog not implemented for this type!" << LL_ENDL; +} + +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 + { + LL_ERRS() << "Using fixed-point packing of " << total_bits << " bits, why?!" << LL_ENDL; + } + 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; + //LL_INFOS() << "unpackFixed:" << name << " int:" << int_bits << " frac:" << frac_bits << LL_ENDL; + S32 unsigned_bits = int_bits + frac_bits; + S32 total_bits = unsigned_bits; + + if (is_signed) + { + total_bits++; + } + + U32 max_val; + max_val = 1 << int_bits; + + F32 fixed_val; + if (total_bits <= 8) + { + U8 fixed_8; + success = unpackU8(fixed_8, name); + fixed_val = (F32)fixed_8; + } + else if (total_bits <= 16) + { + U16 fixed_16; + success = unpackU16(fixed_16, name); + fixed_val = (F32)fixed_16; + } + else if (total_bits <= 31) + { + U32 fixed_32; + success = unpackU32(fixed_32, name); + fixed_val = (F32)fixed_32; + } + else + { + fixed_val = 0; + LL_ERRS() << "Bad bit count: " << total_bits << LL_ENDL; + } + + //LL_INFOS() << "Fixed_val:" << fixed_val << LL_ENDL; + + fixed_val /= (F32)(1 << frac_bits); + if (is_signed) + { + fixed_val -= max_val; + } + value = fixed_val; + //LL_INFOS() << "Value: " << value << LL_ENDL; + return success; +} + +bool LLDataPacker::unpackU16s(U16 *values, S32 count, const char *name) +{ + for (S32 idx = 0; idx < count; ++idx) + { + if (!unpackU16(values[idx], name)) + { + LL_WARNS("DATAPACKER") << "Buffer overflow reading Unsigned 16s \"" << name << "\" at index " << idx << "!" << LL_ENDL; + return false; + } + } + return true; +} + +bool LLDataPacker::unpackS16s(S16 *values, S32 count, const char *name) +{ + for (S32 idx = 0; idx < count; ++idx) + { + if (!unpackS16(values[idx], name)) + { + LL_WARNS("DATAPACKER") << "Buffer overflow reading Signed 16s \"" << name << "\" at index " << idx << "!" << LL_ENDL; + return false; + } + } + return true; +} + +bool LLDataPacker::unpackF32s(F32 *values, S32 count, const char *name) +{ + for (S32 idx = 0; idx < count; ++idx) + { + if (!unpackF32(values[idx], name)) + { + LL_WARNS("DATAPACKER") << "Buffer overflow reading Float 32s \"" << name << "\" at index " << idx << "!" << LL_ENDL; + return false; + } + } + return true; +} + +bool LLDataPacker::unpackColor4Us(LLColor4U *values, S32 count, const char *name) +{ + for (S32 idx = 0; idx < count; ++idx) + { + if (!unpackColor4U(values[idx], name)) + { + LL_WARNS("DATAPACKER") << "Buffer overflow reading Float 32s \"" << name << "\" at index " << idx << "!" << LL_ENDL; + return false; + } + } + return true; +} + +bool LLDataPacker::unpackUUIDs(LLUUID *values, S32 count, const char *name) +{ + for (S32 idx = 0; idx < count; ++idx) + { + if (!unpackUUID(values[idx], name)) + { + LL_WARNS("DATAPACKER") << "Buffer overflow reading UUIDs \"" << name << "\" at index " << idx << "!" << LL_ENDL; + return false; + } + } + return true; +} + +//--------------------------------------------------------------------------- +// LLDataPackerBinaryBuffer implementation +//--------------------------------------------------------------------------- + +bool LLDataPackerBinaryBuffer::packString(const std::string& value, const char *name) +{ + S32 length = value.length()+1; + + if (!verifyLength(length, name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value.c_str(), MVT_VARIABLE, length); + } + mCurBufferp += length; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackString(std::string& value, const char *name) +{ + S32 length = (S32)strlen((char *)mCurBufferp) + 1; /*Flawfinder: ignore*/ + + if (!verifyLength(length, name)) + { + return false; + } + + value = std::string((char*)mCurBufferp); // We already assume NULL termination calling strlen() + + mCurBufferp += length; + return true; +} + +bool LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const char *name) +{ + if (!verifyLength(size + 4, name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, &size, MVT_S32, 4); + } + mCurBufferp += 4; + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value, MVT_VARIABLE, size); + } + mCurBufferp += size; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name) +{ + if (!verifyLength(4, name)) + { + LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL; + return false; + } + + htolememcpy(&size, mCurBufferp, MVT_S32, 4); + + if (size < 0) + { + LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData unpacked invalid size, aborting!" << LL_ENDL; + return false; + } + + mCurBufferp += 4; + + if (!verifyLength(size, name)) + { + LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL; + return false; + } + + htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); + mCurBufferp += size; + + return true; +} + + +bool LLDataPackerBinaryBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name) +{ + if (!verifyLength(size, name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value, MVT_VARIABLE, size); + } + mCurBufferp += size; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name) +{ + if (!verifyLength(size, name)) + { + return false; + } + htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); + mCurBufferp += size; + return true; +} + + +bool LLDataPackerBinaryBuffer::packU8(const U8 value, const char *name) +{ + if (!verifyLength(sizeof(U8), name)) + { + return false; + } + + if (mWriteEnabled) + { + *mCurBufferp = value; + } + mCurBufferp++; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackU8(U8 &value, const char *name) +{ + if (!verifyLength(sizeof(U8), name)) + { + return false; + } + + value = *mCurBufferp; + mCurBufferp++; + return true; +} + + +bool LLDataPackerBinaryBuffer::packU16(const U16 value, const char *name) +{ + if (!verifyLength(sizeof(U16), name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, &value, MVT_U16, 2); + } + mCurBufferp += 2; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackU16(U16 &value, const char *name) +{ + if (!verifyLength(sizeof(U16), name)) + { + return false; + } + + htolememcpy(&value, mCurBufferp, MVT_U16, 2); + mCurBufferp += 2; + return true; +} + +bool LLDataPackerBinaryBuffer::packS16(const S16 value, const char *name) +{ + bool success = verifyLength(sizeof(S16), name); + + if (mWriteEnabled && success) + { + htolememcpy(mCurBufferp, &value, MVT_S16, 2); + } + mCurBufferp += 2; + return success; +} + +bool LLDataPackerBinaryBuffer::unpackS16(S16 &value, const char *name) +{ + bool success = verifyLength(sizeof(S16), name); + + if (success) + { + htolememcpy(&value, mCurBufferp, MVT_S16, 2); + } + mCurBufferp += 2; + return success; +} + +bool LLDataPackerBinaryBuffer::packU32(const U32 value, const char *name) +{ + if (!verifyLength(sizeof(U32), name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, &value, MVT_U32, 4); + } + mCurBufferp += 4; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackU32(U32 &value, const char *name) +{ + if (!verifyLength(sizeof(U32), name)) + { + return false; + } + + htolememcpy(&value, mCurBufferp, MVT_U32, 4); + mCurBufferp += 4; + return true; +} + + +bool LLDataPackerBinaryBuffer::packS32(const S32 value, const char *name) +{ + if (!verifyLength(sizeof(S32), name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, &value, MVT_S32, 4); + } + mCurBufferp += 4; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackS32(S32 &value, const char *name) +{ + if(!verifyLength(sizeof(S32), name)) + { + return false; + } + + htolememcpy(&value, mCurBufferp, MVT_S32, 4); + mCurBufferp += 4; + return true; +} + + +bool LLDataPackerBinaryBuffer::packF32(const F32 value, const char *name) +{ + if (!verifyLength(sizeof(F32), name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, &value, MVT_F32, 4); + } + mCurBufferp += 4; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackF32(F32 &value, const char *name) +{ + if (!verifyLength(sizeof(F32), name)) + { + return false; + } + + htolememcpy(&value, mCurBufferp, MVT_F32, 4); + mCurBufferp += 4; + return true; +} + + +bool LLDataPackerBinaryBuffer::packColor4(const LLColor4 &value, const char *name) +{ + if (!verifyLength(16, name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); + } + mCurBufferp += 16; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackColor4(LLColor4 &value, const char *name) +{ + if (!verifyLength(16, name)) + { + return false; + } + + htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); + mCurBufferp += 16; + return true; +} + + +bool LLDataPackerBinaryBuffer::packColor4U(const LLColor4U &value, const char *name) +{ + if (!verifyLength(4, name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value.mV, MVT_VARIABLE, 4); + } + mCurBufferp += 4; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackColor4U(LLColor4U &value, const char *name) +{ + if (!verifyLength(4, name)) + { + return false; + } + + htolememcpy(value.mV, mCurBufferp, MVT_VARIABLE, 4); + mCurBufferp += 4; + return true; +} + + + +bool LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *name) +{ + if (!verifyLength(8, name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, &value.mV[0], MVT_F32, 4); + htolememcpy(mCurBufferp+4, &value.mV[1], MVT_F32, 4); + } + mCurBufferp += 8; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackVector2(LLVector2 &value, const char *name) +{ + if (!verifyLength(8, name)) + { + return false; + } + + htolememcpy(&value.mV[0], mCurBufferp, MVT_F32, 4); + htolememcpy(&value.mV[1], mCurBufferp+4, MVT_F32, 4); + mCurBufferp += 8; + return true; +} + + +bool LLDataPackerBinaryBuffer::packVector3(const LLVector3 &value, const char *name) +{ + if (!verifyLength(12, name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value.mV, MVT_LLVector3, 12); + } + mCurBufferp += 12; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackVector3(LLVector3 &value, const char *name) +{ + if (!verifyLength(12, name)) + { + return false; + } + + htolememcpy(value.mV, mCurBufferp, MVT_LLVector3, 12); + mCurBufferp += 12; + return true; +} + +bool LLDataPackerBinaryBuffer::packVector4(const LLVector4 &value, const char *name) +{ + if (!verifyLength(16, name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); + } + mCurBufferp += 16; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackVector4(LLVector4 &value, const char *name) +{ + if (!verifyLength(16, name)) + { + return false; + } + + htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); + mCurBufferp += 16; + return true; +} + +bool LLDataPackerBinaryBuffer::packUUID(const LLUUID &value, const char *name) +{ + if (!verifyLength(16, name)) + { + return false; + } + + if (mWriteEnabled) + { + htolememcpy(mCurBufferp, value.mData, MVT_LLUUID, 16); + } + mCurBufferp += 16; + return true; +} + + +bool LLDataPackerBinaryBuffer::unpackUUID(LLUUID &value, const char *name) +{ + if (!verifyLength(16, name)) + { + return false; + } + + htolememcpy(value.mData, mCurBufferp, MVT_LLUUID, 16); + mCurBufferp += 16; + return true; +} + +const LLDataPackerBinaryBuffer& LLDataPackerBinaryBuffer::operator=(const LLDataPackerBinaryBuffer &a) +{ + if (a.getBufferSize() > getBufferSize()) + { + // We've got problems, ack! + LL_ERRS() << "Trying to do an assignment with not enough room in the target." << LL_ENDL; + } + memcpy(mBufferp, a.mBufferp, a.getBufferSize()); /*Flawfinder: ignore*/ + return *this; +} + +void LLDataPackerBinaryBuffer::dumpBufferToLog() +{ + LL_WARNS() << "Binary Buffer Dump, size: " << mBufferSize << LL_ENDL; + 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; + LL_WARNS() << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << LL_ENDL; + cur_line++; + } + } + if (cur_line_pos) + { + LL_WARNS() << "Offset:" << std::hex << cur_line*16 << std::dec << " Data:" << line_buffer << LL_ENDL; + } +} + +//--------------------------------------------------------------------------- +// LLDataPackerAsciiBuffer implementation +//--------------------------------------------------------------------------- +bool LLDataPackerAsciiBuffer::packString(const std::string& value, const char *name) +{ + bool success = true; + writeIndentedName(name); + int numCopied = 0; + if (mWriteEnabled) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\n", value.c_str()); /* Flawfinder: ignore */ + } + else + { + numCopied = value.length() + 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 either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + // *NOTE: I believe we need to mark a failure bit at this point. + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packString: string truncated: " << value << LL_ENDL; + } + mCurBufferp += numCopied; + return success; +} + +bool LLDataPackerAsciiBuffer::unpackString(std::string& value, const char *name) +{ + char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) // NULL terminated + { + return false; + } + value = valuestr; + return true; +} + + +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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryData: number truncated: " << size << LL_ENDL; + } + 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryData: data truncated: " << LL_ENDL; + bBufferFull = true; + } + mCurBufferp += numCopied; + } + + if (!bBufferFull) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "\n"); /* Flawfinder: ignore */ + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryData: newline truncated: " << LL_ENDL; + } + 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryDataFixed: data truncated: " << LL_ENDL; + bBufferFull = true; + } + mCurBufferp += numCopied; + + } + if (!bBufferFull) + { + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(), "\n"); /* Flawfinder: ignore */ + if (numCopied < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packBinaryDataFixed: newline truncated: " << LL_ENDL; + } + + 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 + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packU8: val truncated: " << LL_ENDL; + } + + 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 + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packU16: val truncated: " << LL_ENDL; + } + + 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::packS16(const S16 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 + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize() - getCurrentSize()) + { + numCopied = getBufferSize() - getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packS16: val truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + + return success; +} + + +bool LLDataPackerAsciiBuffer::unpackS16(S16 &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 + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packU32: val truncated: " << LL_ENDL; + } + + 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 + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packS32: val truncated: " << LL_ENDL; + } + + 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(),"%f\n", value); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%f\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 + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packF32: val truncated: " << LL_ENDL; + } + + 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,"%f", &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(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + } + else + { + 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 */ + } + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packColor4: truncated: " << LL_ENDL; + } + + 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,"%f %f %f %f", &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 + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packColor4U: truncated: " << LL_ENDL; + } + + 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(),"%f %f\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f\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 + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packVector2: truncated: " << LL_ENDL; + } + + 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,"%f %f", &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(),"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ + } + else + { + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f\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 + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packVector3: truncated: " << LL_ENDL; + } + + 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,"%f %f %f", &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(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + } + else + { + 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 */ + } + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packVector4: truncated: " << LL_ENDL; + } + + 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,"%f %f %f %f", &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) + { + std::string tmp_str; + value.toString(tmp_str); + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%s\n", tmp_str.c_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 + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::packUUID: truncated: " << LL_ENDL; + 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); /* Flawfinder: ignore */ + value.set(tmp_str); + + return success; +} + +void LLDataPackerAsciiBuffer::dump() +{ + LL_INFOS() << "Buffer: " << mBufferp << LL_ENDL; +} + +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; /* Flawfinder: ignore */ //name + tab + } + + // snprintf returns number of bytes that would have been written + // had the output not being truncated. In that case, it will + // return either -1 or value >= 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 < 0 || numCopied > getBufferSize()-getCurrentSize()) + { + numCopied = getBufferSize()-getCurrentSize(); + LL_WARNS() << "LLDataPackerAsciiBuffer::writeIndentedName: truncated: " << LL_ENDL; + } + + mCurBufferp += numCopied; + } +} + +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; /* Flawfinder: ignore */ + + sscanf(buffer, "%511s %511[^\n]", keyword, value); /* Flawfinder: ignore */ + + if (strcmp(keyword, name)) + { + LL_WARNS() << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << LL_ENDL; + 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; +} + +// helper function used by LLDataPackerAsciiFile +// to convert F32 into a string. This is to avoid +// << operator writing F32 value into a stream +// since it does not seem to preserve the float value +std::string convertF32ToString(F32 val) +{ + std::string str; + char buf[20]; + snprintf(buf, 20, "%f", val); + str = buf; + return str; +} + +//--------------------------------------------------------------------------- +// LLDataPackerAsciiFile implementation +//--------------------------------------------------------------------------- +bool LLDataPackerAsciiFile::packString(const std::string& value, const char *name) +{ + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%s\n", value.c_str()); + } + else if (mOutputStream) + { + *mOutputStream << value << "\n"; + } + return success; +} + +bool LLDataPackerAsciiFile::unpackString(std::string& value, const char *name) +{ + bool success = true; + char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ + if (!getValueStr(name, valuestr, DP_BUFSIZE)) + { + return false; + } + value = valuestr; + 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::packS16(const S16 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::unpackS16(S16 &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,"%f\n", value); + } + else if (mOutputStream) + { + *mOutputStream <<"" << convertF32ToString(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,"%f", &value); + return success; +} + + +bool LLDataPackerAsciiFile::packColor4(const LLColor4 &value, const char *name) +{ + bool success = true; + writeIndentedName(name); + if (mFP) + { + fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); + } + else if (mOutputStream) + { + *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(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,"%f %f %f %f", &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,"%f %f\n", value.mV[0], value.mV[1]); + } + else if (mOutputStream) + { + *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(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,"%f %f", &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,"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); + } + else if (mOutputStream) + { + *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(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,"%f %f %f", &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,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); + } + else if (mOutputStream) + { + *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(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,"%f %f %f %f", &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); + std::string tmp_str; + value.toString(tmp_str); + if (mFP) + { + fprintf(mFP,"%s\n", tmp_str.c_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); /* Flawfinder: ignore */ + value.set(tmp_str); + + return success; +} + + +void LLDataPackerAsciiFile::writeIndentedName(const char *name) +{ + std::string indent_buf; + indent_buf.reserve(mIndent+1); + + 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.c_str(), 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; + if (0 != fgetpos(mFP, &last_pos)) // 0==success for fgetpos + { + LL_WARNS() << "Data packer failed to fgetpos" << LL_ENDL; + return false; + } + + if (fgets(buffer, DP_BUFSIZE, mFP) == NULL) + { + buffer[0] = '\0'; + } + + sscanf(buffer, "%511s %511[^\n]", keyword, value); /* Flawfinder: ignore */ + + if (!keyword[0]) + { + LL_WARNS() << "Data packer could not get the keyword!" << LL_ENDL; + fsetpos(mFP, &last_pos); + return false; + } + if (strcmp(keyword, name)) + { + LL_WARNS() << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << LL_ENDL; + 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); /* Flawfinder: ignore */ + if (!keyword[0]) + { + LL_WARNS() << "Data packer could not get the keyword!" << LL_ENDL; + return false; + } + if (strcmp(keyword, name)) + { + LL_WARNS() << "Data packer expecting keyword of type " << name << ", got " << keyword << " instead!" << LL_ENDL; + 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; +} |