lldatapacker.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. /**
  2. * @file lldatapacker.h
  3. * @brief Data packer declaration for tightly storing binary data.
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewergpl$
  6. *
  7. * Copyright (c) 2002-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_LLDATAPACKER_H
  33. #define LL_LLDATAPACKER_H
  34. #include "llpreprocessor.h"
  35. class LLColor4;
  36. class LLColor4U;
  37. class LLVector2;
  38. class LLVector3;
  39. class LLVector4;
  40. class LLUUID;
  41. class LLDataPacker
  42. {
  43. protected:
  44. LOG_CLASS(LLDataPacker);
  45. public:
  46. ~LLDataPacker() = default;
  47. // Not required to override, but error to call ?
  48. virtual void reset();
  49. virtual void dumpBufferToLog();
  50. virtual bool hasNext() const = 0;
  51. virtual bool packString(const std::string& value, const char* name) = 0;
  52. virtual bool unpackString(std::string& value, const char* name) = 0;
  53. virtual bool packBinaryData(const U8* value, S32 size,
  54. const char* name) = 0;
  55. virtual bool unpackBinaryData(U8* value, S32& size,
  56. const char* name) = 0;
  57. // Constant size binary data packing
  58. virtual bool packBinaryDataFixed(const U8* value, S32 size,
  59. const char* name) = 0;
  60. virtual bool unpackBinaryDataFixed(U8* value, S32 size,
  61. const char* name) = 0;
  62. virtual bool packU8(U8 value, const char* name) = 0;
  63. virtual bool unpackU8(U8 &value, const char* name) = 0;
  64. virtual bool packU16(U16 value, const char* name) = 0;
  65. virtual bool unpackU16(U16& value, const char* name) = 0;
  66. virtual bool packU32(U32 value, const char* name) = 0;
  67. virtual bool unpackU32(U32& value, const char* name) = 0;
  68. virtual bool packS32(S32 value, const char* name) = 0;
  69. virtual bool unpackS32(S32& value, const char* name) = 0;
  70. virtual bool packF32(F32 value, const char* name) = 0;
  71. virtual bool unpackF32(F32& value, const char* name) = 0;
  72. // Packs a float into an integer, using the given size and picks the right
  73. // U* data type to pack into.
  74. bool packFixed(F32 value, const char* name, bool is_signed, U32 int_bits,
  75. U32 frac_bits);
  76. bool unpackFixed(F32& value, const char* name, bool is_signed,
  77. U32 int_bits, U32 frac_bits);
  78. virtual bool packColor4(const LLColor4& value, const char* name) = 0;
  79. virtual bool unpackColor4(LLColor4& value, const char* name) = 0;
  80. virtual bool packColor4U(const LLColor4U& value, const char* name) = 0;
  81. virtual bool unpackColor4U(LLColor4U& value, const char* name) = 0;
  82. virtual bool packVector2(const LLVector2& value, const char* name) = 0;
  83. virtual bool unpackVector2(LLVector2& value, const char* name) = 0;
  84. virtual bool packVector3(const LLVector3& value, const char* name) = 0;
  85. virtual bool unpackVector3(LLVector3& value, const char* name) = 0;
  86. virtual bool packVector4(const LLVector4& value, const char* name) = 0;
  87. virtual bool unpackVector4(LLVector4& value, const char* name) = 0;
  88. virtual bool packUUID(const LLUUID& value, const char* name) = 0;
  89. virtual bool unpackUUID(LLUUID& value, const char* name) = 0;
  90. LL_INLINE U32 getPassFlags() const { return mPassFlags; }
  91. LL_INLINE void setPassFlags(U32 flags) { mPassFlags = flags; }
  92. protected:
  93. LLDataPacker();
  94. protected:
  95. U32 mPassFlags;
  96. // Disable this to do things like determine filesize without actually
  97. // copying data
  98. bool mWriteEnabled;
  99. };
  100. class LLDataPackerBinaryBuffer final : public LLDataPacker
  101. {
  102. protected:
  103. LOG_CLASS(LLDataPackerBinaryBuffer);
  104. public:
  105. LLDataPackerBinaryBuffer(U8* bufferp, S32 size)
  106. : LLDataPacker(),
  107. mBufferp(bufferp),
  108. mCurBufferp(bufferp),
  109. mBufferSize(size)
  110. {
  111. mWriteEnabled = true;
  112. }
  113. LLDataPackerBinaryBuffer()
  114. : LLDataPacker(),
  115. mBufferp(NULL),
  116. mCurBufferp(NULL),
  117. mBufferSize(0)
  118. {
  119. }
  120. bool packString(const std::string& value, const char* name) override;
  121. bool unpackString(std::string& value, const char* name) override;
  122. bool packBinaryData(const U8* value, S32 size, const char* name) override;
  123. bool unpackBinaryData(U8* value, S32& size, const char* name) override;
  124. // Constant size binary data packing
  125. bool packBinaryDataFixed(const U8* value, S32 size,
  126. const char* name) override;
  127. bool unpackBinaryDataFixed(U8* value, S32 size, const char* name) override;
  128. bool packU8(U8 value, const char* name) override;
  129. bool unpackU8(U8 &value, const char* name) override;
  130. bool packU16(U16 value, const char* name) override;
  131. bool unpackU16(U16& value, const char* name) override;
  132. bool packU32(U32 value, const char* name) override;
  133. bool unpackU32(U32& value, const char* name) override;
  134. bool packS32(S32 value, const char* name) override;
  135. bool unpackS32(S32& value, const char* name) override;
  136. bool packF32(F32 value, const char* name) override;
  137. bool unpackF32(F32& value, const char* name) override;
  138. bool packColor4(const LLColor4& value, const char* name) override;
  139. bool unpackColor4(LLColor4& value, const char* name) override;
  140. bool packColor4U(const LLColor4U& value, const char* name) override;
  141. bool unpackColor4U(LLColor4U& value, const char* name) override;
  142. bool packVector2(const LLVector2& value, const char* name) override;
  143. bool unpackVector2(LLVector2& value, const char* name) override;
  144. bool packVector3(const LLVector3& value, const char* name) override;
  145. bool unpackVector3(LLVector3& value, const char* name) override;
  146. bool packVector4(const LLVector4& value, const char* name) override;
  147. bool unpackVector4(LLVector4& value, const char* name) override;
  148. bool packUUID(const LLUUID& value, const char* name) override;
  149. bool unpackUUID(LLUUID& value, const char* name) override;
  150. LL_INLINE S32 getCurrentSize() const { return (S32)(mCurBufferp - mBufferp); }
  151. LL_INLINE S32 getBufferSize() const { return mBufferSize; }
  152. LL_INLINE const U8* getBuffer() const { return mBufferp; }
  153. LL_INLINE void reset() override
  154. {
  155. mCurBufferp = mBufferp;
  156. mWriteEnabled = mCurBufferp != NULL;
  157. }
  158. LL_INLINE void shift(S32 offset) { reset(); mCurBufferp += offset; }
  159. LL_INLINE void freeBuffer()
  160. {
  161. if (mBufferp)
  162. {
  163. delete[] mBufferp;
  164. }
  165. mBufferp = mCurBufferp = NULL;
  166. mBufferSize = 0;
  167. mWriteEnabled = false;
  168. }
  169. LL_INLINE void assignBuffer(U8* bufferp, S32 size)
  170. {
  171. if (mBufferp && mBufferp != bufferp)
  172. {
  173. freeBuffer();
  174. }
  175. mBufferp = bufferp;
  176. mCurBufferp = bufferp;
  177. mBufferSize = size;
  178. mWriteEnabled = true;
  179. }
  180. const LLDataPackerBinaryBuffer& operator=(const LLDataPackerBinaryBuffer &a);
  181. LL_INLINE bool hasNext() const override
  182. {
  183. return getCurrentSize() < getBufferSize();
  184. }
  185. void dumpBufferToLog() override;
  186. protected:
  187. LL_INLINE bool verifyLength(S32 data_size, const char* name)
  188. {
  189. if (mWriteEnabled && mCurBufferp - mBufferp > mBufferSize - data_size)
  190. {
  191. warnBadLength(data_size, name);
  192. return false;
  193. }
  194. return true;
  195. }
  196. // Avoids inlining a llwarns while keeping verifyLength() inlined. HB
  197. LL_NO_INLINE void warnBadLength(S32 data_size, const char* name);
  198. protected:
  199. U8* mBufferp;
  200. U8* mCurBufferp;
  201. S32 mBufferSize;
  202. };
  203. class LLDataPackerAsciiBuffer final : public LLDataPacker
  204. {
  205. protected:
  206. LOG_CLASS(LLDataPackerAsciiBuffer);
  207. public:
  208. LLDataPackerAsciiBuffer(char* bufferp, S32 size)
  209. {
  210. mBufferp = bufferp;
  211. mCurBufferp = bufferp;
  212. mBufferSize = size;
  213. mPassFlags = 0;
  214. mIncludeNames = false;
  215. mWriteEnabled = true;
  216. }
  217. LLDataPackerAsciiBuffer()
  218. {
  219. mBufferp = NULL;
  220. mCurBufferp = NULL;
  221. mBufferSize = 0;
  222. mPassFlags = 0;
  223. mIncludeNames = false;
  224. mWriteEnabled = false;
  225. }
  226. bool packString(const std::string& value, const char* name) override;
  227. bool unpackString(std::string& value, const char* name) override;
  228. bool packBinaryData(const U8* value, S32 size, const char* name) override;
  229. bool unpackBinaryData(U8* value, S32& size, const char* name) override;
  230. // Constant size binary data packing
  231. bool packBinaryDataFixed(const U8* value, S32 size,
  232. const char* name) override;
  233. bool unpackBinaryDataFixed(U8* value, S32 size, const char* name) override;
  234. bool packU8(U8 value, const char* name) override;
  235. bool unpackU8(U8 &value, const char* name) override;
  236. bool packU16(U16 value, const char* name) override;
  237. bool unpackU16(U16& value, const char* name) override;
  238. bool packU32(U32 value, const char* name) override;
  239. bool unpackU32(U32& value, const char* name) override;
  240. bool packS32(S32 value, const char* name) override;
  241. bool unpackS32(S32& value, const char* name) override;
  242. bool packF32(F32 value, const char* name) override;
  243. bool unpackF32(F32& value, const char* name) override;
  244. bool packColor4(const LLColor4& value, const char* name) override;
  245. bool unpackColor4(LLColor4& value, const char* name) override;
  246. bool packColor4U(const LLColor4U& value, const char* name) override;
  247. bool unpackColor4U(LLColor4U& value, const char* name) override;
  248. bool packVector2(const LLVector2& value, const char* name) override;
  249. bool unpackVector2(LLVector2& value, const char* name) override;
  250. bool packVector3(const LLVector3& value, const char* name) override;
  251. bool unpackVector3(LLVector3& value, const char* name) override;
  252. bool packVector4(const LLVector4& value, const char* name) override;
  253. bool unpackVector4(LLVector4& value, const char* name) override;
  254. bool packUUID(const LLUUID& value, const char* name) override;
  255. bool unpackUUID(LLUUID& value, const char* name) override;
  256. LL_INLINE void setIncludeNames(bool b) { mIncludeNames = b; }
  257. // Include the trailing NULL so it's always a valid string
  258. LL_INLINE S32 getCurrentSize() const { return (S32)(mCurBufferp - mBufferp) + 1; }
  259. LL_INLINE S32 getBufferSize() const { return mBufferSize; }
  260. LL_INLINE void reset() override
  261. {
  262. mCurBufferp = mBufferp;
  263. mWriteEnabled = mCurBufferp != NULL;
  264. }
  265. LL_INLINE bool hasNext() const override { return getCurrentSize() < getBufferSize(); }
  266. LL_INLINE void freeBuffer();
  267. LL_INLINE void assignBuffer(char* bufferp, S32 size);
  268. void dump();
  269. protected:
  270. void writeIndentedName(const char* name);
  271. bool getValueStr(const char* name, char* out_value, S32 value_len);
  272. protected:
  273. LL_INLINE bool verifyLength(S32 data_size, const char* name);
  274. char* mBufferp;
  275. char* mCurBufferp;
  276. S32 mBufferSize;
  277. bool mIncludeNames; // useful for debugging, print the name of each field
  278. };
  279. LL_INLINE void LLDataPackerAsciiBuffer::freeBuffer()
  280. {
  281. if (mBufferp)
  282. {
  283. delete[] mBufferp;
  284. }
  285. mBufferp = mCurBufferp = NULL;
  286. mBufferSize = 0;
  287. mWriteEnabled = false;
  288. }
  289. LL_INLINE void LLDataPackerAsciiBuffer::assignBuffer(char* bufferp, S32 size)
  290. {
  291. mBufferp = bufferp;
  292. mCurBufferp = bufferp;
  293. mBufferSize = size;
  294. mWriteEnabled = true;
  295. }
  296. LL_INLINE bool LLDataPackerAsciiBuffer::verifyLength(S32 data_size,
  297. const char* name)
  298. {
  299. if (mWriteEnabled && mCurBufferp - mBufferp > mBufferSize - data_size)
  300. {
  301. llwarns << "Buffer overflow in AsciiBuffer length verify, field name '"
  302. << name << "' ! Current pos: "
  303. << (S32)(mCurBufferp - mBufferp)
  304. << " - Buffer size: " << mBufferSize << " - Data size: "
  305. << data_size << llendl;
  306. return false;
  307. }
  308. return true;
  309. }
  310. class LLDataPackerAsciiFile final : public LLDataPacker
  311. {
  312. protected:
  313. LOG_CLASS(LLDataPackerAsciiFile);
  314. public:
  315. LLDataPackerAsciiFile(LLFILE* fp, S32 indent = 2)
  316. : LLDataPacker(),
  317. mIndent(indent),
  318. mFP(fp),
  319. mOutputStream(NULL),
  320. mInputStream(NULL)
  321. {
  322. }
  323. LLDataPackerAsciiFile(std::ostream& output_stream, S32 indent = 2)
  324. : LLDataPacker(),
  325. mIndent(indent),
  326. mFP(NULL),
  327. mOutputStream(&output_stream),
  328. mInputStream(NULL)
  329. {
  330. mWriteEnabled = true;
  331. }
  332. LLDataPackerAsciiFile(std::istream& input_stream, S32 indent = 2)
  333. : LLDataPacker(),
  334. mIndent(indent),
  335. mFP(NULL),
  336. mOutputStream(NULL),
  337. mInputStream(&input_stream)
  338. {
  339. }
  340. bool packString(const std::string& value, const char* name) override;
  341. bool unpackString(std::string& value, const char* name) override;
  342. bool packBinaryData(const U8* value, S32 size, const char* name) override;
  343. bool unpackBinaryData(U8* value, S32& size, const char* name) override;
  344. bool packBinaryDataFixed(const U8* value, S32 size,
  345. const char* name) override;
  346. bool unpackBinaryDataFixed(U8* value, S32 size, const char* name) override;
  347. bool packU8(U8 value, const char* name) override;
  348. bool unpackU8(U8 &value, const char* name) override;
  349. bool packU16(U16 value, const char* name) override;
  350. bool unpackU16(U16& value, const char* name) override;
  351. bool packU32(U32 value, const char* name) override;
  352. bool unpackU32(U32& value, const char* name) override;
  353. bool packS32(S32 value, const char* name) override;
  354. bool unpackS32(S32& value, const char* name) override;
  355. bool packF32(F32 value, const char* name) override;
  356. bool unpackF32(F32& value, const char* name) override;
  357. bool packColor4(const LLColor4& value, const char* name) override;
  358. bool unpackColor4(LLColor4& value, const char* name) override;
  359. bool packColor4U(const LLColor4U& value, const char* name) override;
  360. bool unpackColor4U(LLColor4U& value, const char* name) override;
  361. bool packVector2(const LLVector2& value, const char* name) override;
  362. bool unpackVector2(LLVector2& value, const char* name) override;
  363. bool packVector3(const LLVector3& value, const char* name) override;
  364. bool unpackVector3(LLVector3& value, const char* name) override;
  365. bool packVector4(const LLVector4& value, const char* name) override;
  366. bool unpackVector4(LLVector4& value, const char* name) override;
  367. bool packUUID(const LLUUID& value, const char* name) override;
  368. bool unpackUUID(LLUUID& value, const char* name) override;
  369. protected:
  370. void writeIndentedName(const char* name);
  371. bool getValueStr(const char* name, char* out_value, S32 value_len);
  372. LL_INLINE bool hasNext() const override { return true; }
  373. protected:
  374. S32 mIndent;
  375. LLFILE* mFP;
  376. std::ostream* mOutputStream;
  377. std::istream* mInputStream;
  378. };
  379. #endif // LL_LLDATAPACKER