PageRenderTime 79ms CodeModel.GetById 21ms app.highlight 52ms RepoModel.GetById 2ms 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
  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
 27#ifndef LL_LLDATAPACKER_H 
 28#define LL_LLDATAPACKER_H
 29
 30class LLColor4;
 31class LLColor4U;
 32class LLVector2;
 33class LLVector3;
 34class LLVector4;
 35class LLUUID;
 36
 37class LLDataPacker
 38{
 39public:
 40	virtual ~LLDataPacker() {}
 41	
 42	// Not required to override, but error to call?
 43	virtual void		reset();
 44	virtual void		dumpBufferToLog();
 45
 46	virtual BOOL		hasNext() const = 0;
 47
 48	virtual BOOL		packString(const std::string& value, const char *name) = 0;
 49	virtual BOOL		unpackString(std::string& value, const char *name) = 0;
 50
 51	virtual BOOL		packBinaryData(const U8 *value, S32 size, const char *name) = 0;
 52	virtual BOOL		unpackBinaryData(U8 *value, S32 &size, const char *name) = 0;
 53
 54	// Constant size binary data packing
 55	virtual BOOL		packBinaryDataFixed(const U8 *value, S32 size, const char *name) = 0;
 56	virtual BOOL		unpackBinaryDataFixed(U8 *value, S32 size, const char *name) = 0;
 57
 58	virtual BOOL		packU8(const U8 value, const char *name) = 0;
 59	virtual BOOL		unpackU8(U8 &value, const char *name) = 0;
 60
 61	virtual BOOL		packU16(const U16 value, const char *name) = 0;
 62	virtual BOOL		unpackU16(U16 &value, const char *name) = 0;
 63
 64	virtual BOOL		packU32(const U32 value, const char *name) = 0;
 65	virtual BOOL		unpackU32(U32 &value, const char *name) = 0;
 66
 67	virtual BOOL		packS32(const S32 value, const char *name) = 0;
 68	virtual BOOL		unpackS32(S32 &value, const char *name) = 0;
 69
 70	virtual BOOL		packF32(const F32 value, const char *name) = 0;
 71	virtual BOOL		unpackF32(F32 &value, const char *name) = 0;
 72
 73	// Packs a float into an integer, using the given size
 74	// and picks the right U* data type to pack into.
 75	BOOL				packFixed(const F32 value, const char *name,
 76								const BOOL is_signed, const U32 int_bits, const U32 frac_bits);
 77	BOOL				unpackFixed(F32 &value, const char *name,
 78								const BOOL is_signed, const U32 int_bits, const U32 frac_bits);
 79
 80	virtual BOOL		packColor4(const LLColor4 &value, const char *name) = 0;
 81	virtual BOOL		unpackColor4(LLColor4 &value, const char *name) = 0;
 82
 83	virtual BOOL		packColor4U(const LLColor4U &value, const char *name) = 0;
 84	virtual BOOL		unpackColor4U(LLColor4U &value, const char *name) = 0;
 85
 86	virtual BOOL		packVector2(const LLVector2 &value, const char *name) = 0;
 87	virtual BOOL		unpackVector2(LLVector2 &value, const char *name) = 0;
 88
 89	virtual BOOL		packVector3(const LLVector3 &value, const char *name) = 0;
 90	virtual BOOL		unpackVector3(LLVector3 &value, const char *name) = 0;
 91
 92	virtual BOOL		packVector4(const LLVector4 &value, const char *name) = 0;
 93	virtual BOOL		unpackVector4(LLVector4 &value, const char *name) = 0;
 94
 95	virtual BOOL		packUUID(const LLUUID &value, const char *name) = 0;
 96	virtual BOOL		unpackUUID(LLUUID &value, const char *name) = 0;
 97			U32			getPassFlags() const	{ return mPassFlags; }
 98			void		setPassFlags(U32 flags)	{ mPassFlags = flags; }
 99protected:
100	LLDataPacker();
101protected:
102	U32	mPassFlags;
103	BOOL mWriteEnabled; // disable this to do things like determine filesize without actually copying data
104};
105
106class LLDataPackerBinaryBuffer : public LLDataPacker
107{
108public:
109	LLDataPackerBinaryBuffer(U8 *bufferp, S32 size)
110	:	LLDataPacker(),
111		mBufferp(bufferp),
112		mCurBufferp(bufferp),
113		mBufferSize(size)
114	{
115		mWriteEnabled = TRUE;
116	}
117
118	LLDataPackerBinaryBuffer()
119	:	LLDataPacker(),
120		mBufferp(NULL),
121		mCurBufferp(NULL),
122		mBufferSize(0)
123	{
124	}
125
126	/*virtual*/ BOOL		packString(const std::string& value, const char *name);
127	/*virtual*/ BOOL		unpackString(std::string& value, const char *name);
128
129	/*virtual*/ BOOL		packBinaryData(const U8 *value, S32 size, const char *name);
130	/*virtual*/ BOOL		unpackBinaryData(U8 *value, S32 &size, const char *name);
131
132	// Constant size binary data packing
133	/*virtual*/ BOOL		packBinaryDataFixed(const U8 *value, S32 size, const char *name);
134	/*virtual*/ BOOL		unpackBinaryDataFixed(U8 *value, S32 size, const char *name);
135
136	/*virtual*/ BOOL		packU8(const U8 value, const char *name);
137	/*virtual*/ BOOL		unpackU8(U8 &value, const char *name);
138
139	/*virtual*/ BOOL		packU16(const U16 value, const char *name);
140	/*virtual*/ BOOL		unpackU16(U16 &value, const char *name);
141
142	/*virtual*/ BOOL		packU32(const U32 value, const char *name);
143	/*virtual*/ BOOL		unpackU32(U32 &value, const char *name);
144
145	/*virtual*/ BOOL		packS32(const S32 value, const char *name);
146	/*virtual*/ BOOL		unpackS32(S32 &value, const char *name);
147
148	/*virtual*/ BOOL		packF32(const F32 value, const char *name);
149	/*virtual*/ BOOL		unpackF32(F32 &value, const char *name);
150
151	/*virtual*/ BOOL		packColor4(const LLColor4 &value, const char *name);
152	/*virtual*/ BOOL		unpackColor4(LLColor4 &value, const char *name);
153
154	/*virtual*/ BOOL		packColor4U(const LLColor4U &value, const char *name);
155	/*virtual*/ BOOL		unpackColor4U(LLColor4U &value, const char *name);
156
157	/*virtual*/ BOOL		packVector2(const LLVector2 &value, const char *name);
158	/*virtual*/ BOOL		unpackVector2(LLVector2 &value, const char *name);
159
160	/*virtual*/ BOOL		packVector3(const LLVector3 &value, const char *name);
161	/*virtual*/ BOOL		unpackVector3(LLVector3 &value, const char *name);
162
163	/*virtual*/ BOOL		packVector4(const LLVector4 &value, const char *name);
164	/*virtual*/ BOOL		unpackVector4(LLVector4 &value, const char *name);
165
166	/*virtual*/ BOOL		packUUID(const LLUUID &value, const char *name);
167	/*virtual*/ BOOL		unpackUUID(LLUUID &value, const char *name);
168
169				S32			getCurrentSize() const	{ return (S32)(mCurBufferp - mBufferp); }
170				S32			getBufferSize() const	{ return mBufferSize; }
171				const U8*   getBuffer() const   { return mBufferp; }    
172				void		reset()				{ mCurBufferp = mBufferp; mWriteEnabled = (mCurBufferp != NULL); }
173				void		freeBuffer()		{ delete [] mBufferp; mBufferp = mCurBufferp = NULL; mBufferSize = 0; mWriteEnabled = FALSE; }
174				void		assignBuffer(U8 *bufferp, S32 size)
175				{
176					if(mBufferp && mBufferp != bufferp)
177					{
178						freeBuffer() ;
179					}
180					mBufferp = bufferp;
181					mCurBufferp = bufferp;
182					mBufferSize = size;
183					mWriteEnabled = TRUE;
184				}
185				const LLDataPackerBinaryBuffer&	operator=(const LLDataPackerBinaryBuffer &a);
186
187	/*virtual*/ BOOL		hasNext() const			{ return getCurrentSize() < getBufferSize(); }
188
189	/*virtual*/ void dumpBufferToLog();
190protected:
191	inline BOOL verifyLength(const S32 data_size, const char *name);
192
193	U8 *mBufferp;
194	U8 *mCurBufferp;
195	S32 mBufferSize;
196};
197
198inline BOOL LLDataPackerBinaryBuffer::verifyLength(const S32 data_size, const char *name)
199{
200	if (mWriteEnabled && (mCurBufferp - mBufferp) > mBufferSize - data_size)
201	{
202		llwarns << "Buffer overflow in BinaryBuffer length verify, field name " << name << "!" << llendl;
203		llwarns << "Current pos: " << (int)(mCurBufferp - mBufferp) << " Buffer size: " << mBufferSize << " Data size: " << data_size << llendl;
204		return FALSE;
205	}
206
207	return TRUE;
208}
209
210class LLDataPackerAsciiBuffer : public LLDataPacker
211{
212public:
213	LLDataPackerAsciiBuffer(char* bufferp, S32 size)
214	{
215		mBufferp = bufferp;
216		mCurBufferp = bufferp;
217		mBufferSize = size;
218		mPassFlags = 0;
219		mIncludeNames = FALSE;
220		mWriteEnabled = TRUE;
221	}
222
223	LLDataPackerAsciiBuffer()
224	{
225		mBufferp = NULL;
226		mCurBufferp = NULL;
227		mBufferSize = 0;
228		mPassFlags = 0;
229		mIncludeNames = FALSE;
230		mWriteEnabled = FALSE;
231	}
232
233	/*virtual*/ BOOL		packString(const std::string& value, const char *name);
234	/*virtual*/ BOOL		unpackString(std::string& value, const char *name);
235
236	/*virtual*/ BOOL		packBinaryData(const U8 *value, S32 size, const char *name);
237	/*virtual*/ BOOL		unpackBinaryData(U8 *value, S32 &size, const char *name);
238
239	// Constant size binary data packing
240	/*virtual*/ BOOL		packBinaryDataFixed(const U8 *value, S32 size, const char *name);
241	/*virtual*/ BOOL		unpackBinaryDataFixed(U8 *value, S32 size, const char *name);
242
243	/*virtual*/ BOOL		packU8(const U8 value, const char *name);
244	/*virtual*/ BOOL		unpackU8(U8 &value, const char *name);
245
246	/*virtual*/ BOOL		packU16(const U16 value, const char *name);
247	/*virtual*/ BOOL		unpackU16(U16 &value, const char *name);
248
249	/*virtual*/ BOOL		packU32(const U32 value, const char *name);
250	/*virtual*/ BOOL		unpackU32(U32 &value, const char *name);
251
252	/*virtual*/ BOOL		packS32(const S32 value, const char *name);
253	/*virtual*/ BOOL		unpackS32(S32 &value, const char *name);
254
255	/*virtual*/ BOOL		packF32(const F32 value, const char *name);
256	/*virtual*/ BOOL		unpackF32(F32 &value, const char *name);
257
258	/*virtual*/ BOOL		packColor4(const LLColor4 &value, const char *name);
259	/*virtual*/ BOOL		unpackColor4(LLColor4 &value, const char *name);
260
261	/*virtual*/ BOOL		packColor4U(const LLColor4U &value, const char *name);
262	/*virtual*/ BOOL		unpackColor4U(LLColor4U &value, const char *name);
263
264	/*virtual*/ BOOL		packVector2(const LLVector2 &value, const char *name);
265	/*virtual*/ BOOL		unpackVector2(LLVector2 &value, const char *name);
266
267	/*virtual*/ BOOL		packVector3(const LLVector3 &value, const char *name);
268	/*virtual*/ BOOL		unpackVector3(LLVector3 &value, const char *name);
269
270	/*virtual*/ BOOL		packVector4(const LLVector4 &value, const char *name);
271	/*virtual*/ BOOL		unpackVector4(LLVector4 &value, const char *name);
272
273	/*virtual*/ BOOL		packUUID(const LLUUID &value, const char *name);
274	/*virtual*/ BOOL		unpackUUID(LLUUID &value, const char *name);
275
276	void		setIncludeNames(BOOL b)	{ mIncludeNames = b; }
277
278	// Include the trailing NULL so it's always a valid string
279	S32			getCurrentSize() const	{ return (S32)(mCurBufferp - mBufferp) + 1; }
280
281	S32			getBufferSize() const	{ return mBufferSize; }
282	/*virtual*/ void		reset()					{ mCurBufferp = mBufferp; mWriteEnabled = (mCurBufferp != NULL); }
283
284	/*virtual*/ BOOL		hasNext() const			{ return getCurrentSize() < getBufferSize(); }
285
286	inline void	freeBuffer();
287	inline void	assignBuffer(char* bufferp, S32 size);
288	void		dump();
289
290protected:
291	void writeIndentedName(const char *name);
292	BOOL getValueStr(const char *name, char *out_value, const S32 value_len);
293	
294protected:
295	inline BOOL verifyLength(const S32 data_size, const char *name);
296
297	char *mBufferp;
298	char *mCurBufferp;
299	S32 mBufferSize;
300	BOOL mIncludeNames;	// useful for debugging, print the name of each field
301};
302
303inline void	LLDataPackerAsciiBuffer::freeBuffer()
304{
305	delete [] mBufferp; 
306	mBufferp = mCurBufferp = NULL; 
307	mBufferSize = 0;
308	mWriteEnabled = FALSE;
309}
310
311inline void	LLDataPackerAsciiBuffer::assignBuffer(char* bufferp, S32 size)
312{
313	mBufferp = bufferp;
314	mCurBufferp = bufferp;
315	mBufferSize = size;
316	mWriteEnabled = TRUE;
317}
318
319inline BOOL LLDataPackerAsciiBuffer::verifyLength(const S32 data_size, const char *name)
320{
321	if (mWriteEnabled && (mCurBufferp - mBufferp) > mBufferSize - data_size)
322	{
323		llwarns << "Buffer overflow in AsciiBuffer length verify, field name " << name << "!" << llendl;
324		llwarns << "Current pos: " << (int)(mCurBufferp - mBufferp) << " Buffer size: " << mBufferSize << " Data size: " << data_size << llendl;
325		return FALSE;
326	}
327
328	return TRUE;
329}
330
331class LLDataPackerAsciiFile : public LLDataPacker
332{
333public:
334	LLDataPackerAsciiFile(LLFILE *fp, const S32 indent = 2)
335	: 	LLDataPacker(),
336		mIndent(indent),
337		mFP(fp),
338		mOutputStream(NULL),
339		mInputStream(NULL)
340	{
341	}
342
343	LLDataPackerAsciiFile(std::ostream& output_stream, const S32 indent = 2)
344	: 	LLDataPacker(),
345		mIndent(indent),
346		mFP(NULL),
347		mOutputStream(&output_stream),
348		mInputStream(NULL)
349	{
350		mWriteEnabled = TRUE;
351	}
352
353	LLDataPackerAsciiFile(std::istream& input_stream, const S32 indent = 2)
354	: 	LLDataPacker(),
355		mIndent(indent),
356		mFP(NULL),
357		mOutputStream(NULL),
358		mInputStream(&input_stream)
359	{
360	}
361
362	/*virtual*/ BOOL		packString(const std::string& value, const char *name);
363	/*virtual*/ BOOL		unpackString(std::string& value, const char *name);
364
365	/*virtual*/ BOOL		packBinaryData(const U8 *value, S32 size, const char *name);
366	/*virtual*/ BOOL		unpackBinaryData(U8 *value, S32 &size, const char *name);
367
368	/*virtual*/ BOOL		packBinaryDataFixed(const U8 *value, S32 size, const char *name);
369	/*virtual*/ BOOL		unpackBinaryDataFixed(U8 *value, S32 size, const char *name);
370
371	/*virtual*/ BOOL		packU8(const U8 value, const char *name);
372	/*virtual*/ BOOL		unpackU8(U8 &value, const char *name);
373
374	/*virtual*/ BOOL		packU16(const U16 value, const char *name);
375	/*virtual*/ BOOL		unpackU16(U16 &value, const char *name);
376
377	/*virtual*/ BOOL		packU32(const U32 value, const char *name);
378	/*virtual*/ BOOL		unpackU32(U32 &value, const char *name);
379
380	/*virtual*/ BOOL		packS32(const S32 value, const char *name);
381	/*virtual*/ BOOL		unpackS32(S32 &value, const char *name);
382
383	/*virtual*/ BOOL		packF32(const F32 value, const char *name);
384	/*virtual*/ BOOL		unpackF32(F32 &value, const char *name);
385
386	/*virtual*/ BOOL		packColor4(const LLColor4 &value, const char *name);
387	/*virtual*/ BOOL		unpackColor4(LLColor4 &value, const char *name);
388
389	/*virtual*/ BOOL		packColor4U(const LLColor4U &value, const char *name);
390	/*virtual*/ BOOL		unpackColor4U(LLColor4U &value, const char *name);
391
392	/*virtual*/ BOOL		packVector2(const LLVector2 &value, const char *name);
393	/*virtual*/ BOOL		unpackVector2(LLVector2 &value, const char *name);
394
395	/*virtual*/ BOOL		packVector3(const LLVector3 &value, const char *name);
396	/*virtual*/ BOOL		unpackVector3(LLVector3 &value, const char *name);
397
398	/*virtual*/ BOOL		packVector4(const LLVector4 &value, const char *name);
399	/*virtual*/ BOOL		unpackVector4(LLVector4 &value, const char *name);
400
401	/*virtual*/ BOOL		packUUID(const LLUUID &value, const char *name);
402	/*virtual*/ BOOL		unpackUUID(LLUUID &value, const char *name);
403protected:
404	void writeIndentedName(const char *name);
405	BOOL getValueStr(const char *name, char *out_value, const S32 value_len);
406	
407	/*virtual*/ BOOL		hasNext() const			{ return true; }
408
409protected:
410	S32 mIndent;
411	LLFILE *mFP;
412	std::ostream* mOutputStream;
413	std::istream* mInputStream;
414};
415
416#endif // LL_LLDATAPACKER
417