PageRenderTime 38ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmessage/lldatapacker.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 417 lines | 294 code | 91 blank | 32 comment | 9 complexity | 725e539ac63cf89cae3806f807ce2fb5 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lldatapacker.h
  3. * @brief Data packer declaration for tightly storing binary data.
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_LLDATAPACKER_H
  27. #define LL_LLDATAPACKER_H
  28. class LLColor4;
  29. class LLColor4U;
  30. class LLVector2;
  31. class LLVector3;
  32. class LLVector4;
  33. class LLUUID;
  34. class LLDataPacker
  35. {
  36. public:
  37. virtual ~LLDataPacker() {}
  38. // Not required to override, but error to call?
  39. virtual void reset();
  40. virtual void dumpBufferToLog();
  41. virtual BOOL hasNext() const = 0;
  42. virtual BOOL packString(const std::string& value, const char *name) = 0;
  43. virtual BOOL unpackString(std::string& value, const char *name) = 0;
  44. virtual BOOL packBinaryData(const U8 *value, S32 size, const char *name) = 0;
  45. virtual BOOL unpackBinaryData(U8 *value, S32 &size, const char *name) = 0;
  46. // Constant size binary data packing
  47. virtual BOOL packBinaryDataFixed(const U8 *value, S32 size, const char *name) = 0;
  48. virtual BOOL unpackBinaryDataFixed(U8 *value, S32 size, const char *name) = 0;
  49. virtual BOOL packU8(const U8 value, const char *name) = 0;
  50. virtual BOOL unpackU8(U8 &value, const char *name) = 0;
  51. virtual BOOL packU16(const U16 value, const char *name) = 0;
  52. virtual BOOL unpackU16(U16 &value, const char *name) = 0;
  53. virtual BOOL packU32(const U32 value, const char *name) = 0;
  54. virtual BOOL unpackU32(U32 &value, const char *name) = 0;
  55. virtual BOOL packS32(const S32 value, const char *name) = 0;
  56. virtual BOOL unpackS32(S32 &value, const char *name) = 0;
  57. virtual BOOL packF32(const F32 value, const char *name) = 0;
  58. virtual BOOL unpackF32(F32 &value, const char *name) = 0;
  59. // Packs a float into an integer, using the given size
  60. // and picks the right U* data type to pack into.
  61. BOOL packFixed(const F32 value, const char *name,
  62. const BOOL is_signed, const U32 int_bits, const U32 frac_bits);
  63. BOOL unpackFixed(F32 &value, const char *name,
  64. const BOOL is_signed, const U32 int_bits, const U32 frac_bits);
  65. virtual BOOL packColor4(const LLColor4 &value, const char *name) = 0;
  66. virtual BOOL unpackColor4(LLColor4 &value, const char *name) = 0;
  67. virtual BOOL packColor4U(const LLColor4U &value, const char *name) = 0;
  68. virtual BOOL unpackColor4U(LLColor4U &value, const char *name) = 0;
  69. virtual BOOL packVector2(const LLVector2 &value, const char *name) = 0;
  70. virtual BOOL unpackVector2(LLVector2 &value, const char *name) = 0;
  71. virtual BOOL packVector3(const LLVector3 &value, const char *name) = 0;
  72. virtual BOOL unpackVector3(LLVector3 &value, const char *name) = 0;
  73. virtual BOOL packVector4(const LLVector4 &value, const char *name) = 0;
  74. virtual BOOL unpackVector4(LLVector4 &value, const char *name) = 0;
  75. virtual BOOL packUUID(const LLUUID &value, const char *name) = 0;
  76. virtual BOOL unpackUUID(LLUUID &value, const char *name) = 0;
  77. U32 getPassFlags() const { return mPassFlags; }
  78. void setPassFlags(U32 flags) { mPassFlags = flags; }
  79. protected:
  80. LLDataPacker();
  81. protected:
  82. U32 mPassFlags;
  83. BOOL mWriteEnabled; // disable this to do things like determine filesize without actually copying data
  84. };
  85. class LLDataPackerBinaryBuffer : public LLDataPacker
  86. {
  87. public:
  88. LLDataPackerBinaryBuffer(U8 *bufferp, S32 size)
  89. : LLDataPacker(),
  90. mBufferp(bufferp),
  91. mCurBufferp(bufferp),
  92. mBufferSize(size)
  93. {
  94. mWriteEnabled = TRUE;
  95. }
  96. LLDataPackerBinaryBuffer()
  97. : LLDataPacker(),
  98. mBufferp(NULL),
  99. mCurBufferp(NULL),
  100. mBufferSize(0)
  101. {
  102. }
  103. /*virtual*/ BOOL packString(const std::string& value, const char *name);
  104. /*virtual*/ BOOL unpackString(std::string& value, const char *name);
  105. /*virtual*/ BOOL packBinaryData(const U8 *value, S32 size, const char *name);
  106. /*virtual*/ BOOL unpackBinaryData(U8 *value, S32 &size, const char *name);
  107. // Constant size binary data packing
  108. /*virtual*/ BOOL packBinaryDataFixed(const U8 *value, S32 size, const char *name);
  109. /*virtual*/ BOOL unpackBinaryDataFixed(U8 *value, S32 size, const char *name);
  110. /*virtual*/ BOOL packU8(const U8 value, const char *name);
  111. /*virtual*/ BOOL unpackU8(U8 &value, const char *name);
  112. /*virtual*/ BOOL packU16(const U16 value, const char *name);
  113. /*virtual*/ BOOL unpackU16(U16 &value, const char *name);
  114. /*virtual*/ BOOL packU32(const U32 value, const char *name);
  115. /*virtual*/ BOOL unpackU32(U32 &value, const char *name);
  116. /*virtual*/ BOOL packS32(const S32 value, const char *name);
  117. /*virtual*/ BOOL unpackS32(S32 &value, const char *name);
  118. /*virtual*/ BOOL packF32(const F32 value, const char *name);
  119. /*virtual*/ BOOL unpackF32(F32 &value, const char *name);
  120. /*virtual*/ BOOL packColor4(const LLColor4 &value, const char *name);
  121. /*virtual*/ BOOL unpackColor4(LLColor4 &value, const char *name);
  122. /*virtual*/ BOOL packColor4U(const LLColor4U &value, const char *name);
  123. /*virtual*/ BOOL unpackColor4U(LLColor4U &value, const char *name);
  124. /*virtual*/ BOOL packVector2(const LLVector2 &value, const char *name);
  125. /*virtual*/ BOOL unpackVector2(LLVector2 &value, const char *name);
  126. /*virtual*/ BOOL packVector3(const LLVector3 &value, const char *name);
  127. /*virtual*/ BOOL unpackVector3(LLVector3 &value, const char *name);
  128. /*virtual*/ BOOL packVector4(const LLVector4 &value, const char *name);
  129. /*virtual*/ BOOL unpackVector4(LLVector4 &value, const char *name);
  130. /*virtual*/ BOOL packUUID(const LLUUID &value, const char *name);
  131. /*virtual*/ BOOL unpackUUID(LLUUID &value, const char *name);
  132. S32 getCurrentSize() const { return (S32)(mCurBufferp - mBufferp); }
  133. S32 getBufferSize() const { return mBufferSize; }
  134. const U8* getBuffer() const { return mBufferp; }
  135. void reset() { mCurBufferp = mBufferp; mWriteEnabled = (mCurBufferp != NULL); }
  136. void freeBuffer() { delete [] mBufferp; mBufferp = mCurBufferp = NULL; mBufferSize = 0; mWriteEnabled = FALSE; }
  137. void assignBuffer(U8 *bufferp, S32 size)
  138. {
  139. if(mBufferp && mBufferp != bufferp)
  140. {
  141. freeBuffer() ;
  142. }
  143. mBufferp = bufferp;
  144. mCurBufferp = bufferp;
  145. mBufferSize = size;
  146. mWriteEnabled = TRUE;
  147. }
  148. const LLDataPackerBinaryBuffer& operator=(const LLDataPackerBinaryBuffer &a);
  149. /*virtual*/ BOOL hasNext() const { return getCurrentSize() < getBufferSize(); }
  150. /*virtual*/ void dumpBufferToLog();
  151. protected:
  152. inline BOOL verifyLength(const S32 data_size, const char *name);
  153. U8 *mBufferp;
  154. U8 *mCurBufferp;
  155. S32 mBufferSize;
  156. };
  157. inline BOOL LLDataPackerBinaryBuffer::verifyLength(const S32 data_size, const char *name)
  158. {
  159. if (mWriteEnabled && (mCurBufferp - mBufferp) > mBufferSize - data_size)
  160. {
  161. llwarns << "Buffer overflow in BinaryBuffer length verify, field name " << name << "!" << llendl;
  162. llwarns << "Current pos: " << (int)(mCurBufferp - mBufferp) << " Buffer size: " << mBufferSize << " Data size: " << data_size << llendl;
  163. return FALSE;
  164. }
  165. return TRUE;
  166. }
  167. class LLDataPackerAsciiBuffer : public LLDataPacker
  168. {
  169. public:
  170. LLDataPackerAsciiBuffer(char* bufferp, S32 size)
  171. {
  172. mBufferp = bufferp;
  173. mCurBufferp = bufferp;
  174. mBufferSize = size;
  175. mPassFlags = 0;
  176. mIncludeNames = FALSE;
  177. mWriteEnabled = TRUE;
  178. }
  179. LLDataPackerAsciiBuffer()
  180. {
  181. mBufferp = NULL;
  182. mCurBufferp = NULL;
  183. mBufferSize = 0;
  184. mPassFlags = 0;
  185. mIncludeNames = FALSE;
  186. mWriteEnabled = FALSE;
  187. }
  188. /*virtual*/ BOOL packString(const std::string& value, const char *name);
  189. /*virtual*/ BOOL unpackString(std::string& value, const char *name);
  190. /*virtual*/ BOOL packBinaryData(const U8 *value, S32 size, const char *name);
  191. /*virtual*/ BOOL unpackBinaryData(U8 *value, S32 &size, const char *name);
  192. // Constant size binary data packing
  193. /*virtual*/ BOOL packBinaryDataFixed(const U8 *value, S32 size, const char *name);
  194. /*virtual*/ BOOL unpackBinaryDataFixed(U8 *value, S32 size, const char *name);
  195. /*virtual*/ BOOL packU8(const U8 value, const char *name);
  196. /*virtual*/ BOOL unpackU8(U8 &value, const char *name);
  197. /*virtual*/ BOOL packU16(const U16 value, const char *name);
  198. /*virtual*/ BOOL unpackU16(U16 &value, const char *name);
  199. /*virtual*/ BOOL packU32(const U32 value, const char *name);
  200. /*virtual*/ BOOL unpackU32(U32 &value, const char *name);
  201. /*virtual*/ BOOL packS32(const S32 value, const char *name);
  202. /*virtual*/ BOOL unpackS32(S32 &value, const char *name);
  203. /*virtual*/ BOOL packF32(const F32 value, const char *name);
  204. /*virtual*/ BOOL unpackF32(F32 &value, const char *name);
  205. /*virtual*/ BOOL packColor4(const LLColor4 &value, const char *name);
  206. /*virtual*/ BOOL unpackColor4(LLColor4 &value, const char *name);
  207. /*virtual*/ BOOL packColor4U(const LLColor4U &value, const char *name);
  208. /*virtual*/ BOOL unpackColor4U(LLColor4U &value, const char *name);
  209. /*virtual*/ BOOL packVector2(const LLVector2 &value, const char *name);
  210. /*virtual*/ BOOL unpackVector2(LLVector2 &value, const char *name);
  211. /*virtual*/ BOOL packVector3(const LLVector3 &value, const char *name);
  212. /*virtual*/ BOOL unpackVector3(LLVector3 &value, const char *name);
  213. /*virtual*/ BOOL packVector4(const LLVector4 &value, const char *name);
  214. /*virtual*/ BOOL unpackVector4(LLVector4 &value, const char *name);
  215. /*virtual*/ BOOL packUUID(const LLUUID &value, const char *name);
  216. /*virtual*/ BOOL unpackUUID(LLUUID &value, const char *name);
  217. void setIncludeNames(BOOL b) { mIncludeNames = b; }
  218. // Include the trailing NULL so it's always a valid string
  219. S32 getCurrentSize() const { return (S32)(mCurBufferp - mBufferp) + 1; }
  220. S32 getBufferSize() const { return mBufferSize; }
  221. /*virtual*/ void reset() { mCurBufferp = mBufferp; mWriteEnabled = (mCurBufferp != NULL); }
  222. /*virtual*/ BOOL hasNext() const { return getCurrentSize() < getBufferSize(); }
  223. inline void freeBuffer();
  224. inline void assignBuffer(char* bufferp, S32 size);
  225. void dump();
  226. protected:
  227. void writeIndentedName(const char *name);
  228. BOOL getValueStr(const char *name, char *out_value, const S32 value_len);
  229. protected:
  230. inline BOOL verifyLength(const S32 data_size, const char *name);
  231. char *mBufferp;
  232. char *mCurBufferp;
  233. S32 mBufferSize;
  234. BOOL mIncludeNames; // useful for debugging, print the name of each field
  235. };
  236. inline void LLDataPackerAsciiBuffer::freeBuffer()
  237. {
  238. delete [] mBufferp;
  239. mBufferp = mCurBufferp = NULL;
  240. mBufferSize = 0;
  241. mWriteEnabled = FALSE;
  242. }
  243. inline void LLDataPackerAsciiBuffer::assignBuffer(char* bufferp, S32 size)
  244. {
  245. mBufferp = bufferp;
  246. mCurBufferp = bufferp;
  247. mBufferSize = size;
  248. mWriteEnabled = TRUE;
  249. }
  250. inline BOOL LLDataPackerAsciiBuffer::verifyLength(const S32 data_size, const char *name)
  251. {
  252. if (mWriteEnabled && (mCurBufferp - mBufferp) > mBufferSize - data_size)
  253. {
  254. llwarns << "Buffer overflow in AsciiBuffer length verify, field name " << name << "!" << llendl;
  255. llwarns << "Current pos: " << (int)(mCurBufferp - mBufferp) << " Buffer size: " << mBufferSize << " Data size: " << data_size << llendl;
  256. return FALSE;
  257. }
  258. return TRUE;
  259. }
  260. class LLDataPackerAsciiFile : public LLDataPacker
  261. {
  262. public:
  263. LLDataPackerAsciiFile(LLFILE *fp, const S32 indent = 2)
  264. : LLDataPacker(),
  265. mIndent(indent),
  266. mFP(fp),
  267. mOutputStream(NULL),
  268. mInputStream(NULL)
  269. {
  270. }
  271. LLDataPackerAsciiFile(std::ostream& output_stream, const S32 indent = 2)
  272. : LLDataPacker(),
  273. mIndent(indent),
  274. mFP(NULL),
  275. mOutputStream(&output_stream),
  276. mInputStream(NULL)
  277. {
  278. mWriteEnabled = TRUE;
  279. }
  280. LLDataPackerAsciiFile(std::istream& input_stream, const S32 indent = 2)
  281. : LLDataPacker(),
  282. mIndent(indent),
  283. mFP(NULL),
  284. mOutputStream(NULL),
  285. mInputStream(&input_stream)
  286. {
  287. }
  288. /*virtual*/ BOOL packString(const std::string& value, const char *name);
  289. /*virtual*/ BOOL unpackString(std::string& value, const char *name);
  290. /*virtual*/ BOOL packBinaryData(const U8 *value, S32 size, const char *name);
  291. /*virtual*/ BOOL unpackBinaryData(U8 *value, S32 &size, const char *name);
  292. /*virtual*/ BOOL packBinaryDataFixed(const U8 *value, S32 size, const char *name);
  293. /*virtual*/ BOOL unpackBinaryDataFixed(U8 *value, S32 size, const char *name);
  294. /*virtual*/ BOOL packU8(const U8 value, const char *name);
  295. /*virtual*/ BOOL unpackU8(U8 &value, const char *name);
  296. /*virtual*/ BOOL packU16(const U16 value, const char *name);
  297. /*virtual*/ BOOL unpackU16(U16 &value, const char *name);
  298. /*virtual*/ BOOL packU32(const U32 value, const char *name);
  299. /*virtual*/ BOOL unpackU32(U32 &value, const char *name);
  300. /*virtual*/ BOOL packS32(const S32 value, const char *name);
  301. /*virtual*/ BOOL unpackS32(S32 &value, const char *name);
  302. /*virtual*/ BOOL packF32(const F32 value, const char *name);
  303. /*virtual*/ BOOL unpackF32(F32 &value, const char *name);
  304. /*virtual*/ BOOL packColor4(const LLColor4 &value, const char *name);
  305. /*virtual*/ BOOL unpackColor4(LLColor4 &value, const char *name);
  306. /*virtual*/ BOOL packColor4U(const LLColor4U &value, const char *name);
  307. /*virtual*/ BOOL unpackColor4U(LLColor4U &value, const char *name);
  308. /*virtual*/ BOOL packVector2(const LLVector2 &value, const char *name);
  309. /*virtual*/ BOOL unpackVector2(LLVector2 &value, const char *name);
  310. /*virtual*/ BOOL packVector3(const LLVector3 &value, const char *name);
  311. /*virtual*/ BOOL unpackVector3(LLVector3 &value, const char *name);
  312. /*virtual*/ BOOL packVector4(const LLVector4 &value, const char *name);
  313. /*virtual*/ BOOL unpackVector4(LLVector4 &value, const char *name);
  314. /*virtual*/ BOOL packUUID(const LLUUID &value, const char *name);
  315. /*virtual*/ BOOL unpackUUID(LLUUID &value, const char *name);
  316. protected:
  317. void writeIndentedName(const char *name);
  318. BOOL getValueStr(const char *name, char *out_value, const S32 value_len);
  319. /*virtual*/ BOOL hasNext() const { return true; }
  320. protected:
  321. S32 mIndent;
  322. LLFILE *mFP;
  323. std::ostream* mOutputStream;
  324. std::istream* mInputStream;
  325. };
  326. #endif // LL_LLDATAPACKER