Panda3D
 All Classes Functions Variables Enumerations
dcPackerInterface.I
1 // Filename: dcPackerInterface.I
2 // Created by: drose (18Jun04)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 ////////////////////////////////////////////////////////////////////
17 // Function: DCPackerInterface::get_name
18 // Access: Published
19 // Description: Returns the name of this field, or empty string
20 // if the field is unnamed.
21 ////////////////////////////////////////////////////////////////////
22 INLINE const string &DCPackerInterface::
23 get_name() const {
24  return _name;
25 }
26 
27 ////////////////////////////////////////////////////////////////////
28 // Function: DCPackerInterface::check_match
29 // Access: Published
30 // Description: Returns true if the other interface is bitwise the
31 // same as this one--that is, a uint32 only matches a
32 // uint32, etc. Names of components, and range limits,
33 // are not compared.
34 ////////////////////////////////////////////////////////////////////
35 INLINE bool DCPackerInterface::
36 check_match(const DCPackerInterface *other) const {
37  return do_check_match(other);
38 }
39 
40 ////////////////////////////////////////////////////////////////////
41 // Function: DCPackerInterface::has_fixed_byte_size
42 // Access: Public
43 // Description: Returns true if this field type always packs to the
44 // same number of bytes, false if it is variable.
45 ////////////////////////////////////////////////////////////////////
46 INLINE bool DCPackerInterface::
48  return _has_fixed_byte_size;
49 }
50 
51 ////////////////////////////////////////////////////////////////////
52 // Function: DCPackerInterface::get_fixed_byte_size
53 // Access: Public
54 // Description: If has_fixed_byte_size() returns true, this returns
55 // the number of bytes this field type will use.
56 ////////////////////////////////////////////////////////////////////
57 INLINE size_t DCPackerInterface::
59  return _fixed_byte_size;
60 }
61 
62 ////////////////////////////////////////////////////////////////////
63 // Function: DCPackerInterface::has_fixed_structure
64 // Access: Public
65 // Description: Returns true if this field type always has the same
66 // structure regardless of the data in the stream, or
67 // false if its structure may vary. This is almost, but
68 // not quite, the same thing as has_fixed_byte_size.
69 // The difference is that a DCSwitch may have multiple
70 // cases all with the same byte size, but they will
71 // still (presumably) have different structures, in the
72 // sense that the actual list of fields varies according
73 // to the live data.
74 ////////////////////////////////////////////////////////////////////
75 INLINE bool DCPackerInterface::
77  return _has_fixed_structure;
78 }
79 
80 ////////////////////////////////////////////////////////////////////
81 // Function: DCPackerInterface::has_range_limits
82 // Access: Public
83 // Description: Returns true if this field, or any sub-field of this
84 // field, has a limit imposed in the DC file on its
85 // legal values. If this is false, then
86 // unpack_validate() is trivial.
87 ////////////////////////////////////////////////////////////////////
88 INLINE bool DCPackerInterface::
90  return _has_range_limits;
91 }
92 
93 ////////////////////////////////////////////////////////////////////
94 // Function: DCPackerInterface::get_num_length_bytes
95 // Access: Public
96 // Description: Returns the number of bytes that should be written
97 // into the stream on a push() to record the number of
98 // bytes in the record up until the next pop(). This is
99 // only meaningful if _has_nested_fields is true.
100 ////////////////////////////////////////////////////////////////////
101 INLINE size_t DCPackerInterface::
103  return _num_length_bytes;
104 }
105 
106 
107 ////////////////////////////////////////////////////////////////////
108 // Function: DCPackerInterface::has_nested_fields
109 // Access: Public
110 // Description: Returns true if this field type has any nested fields
111 // (and thus expects a push() .. pop() interface to the
112 // DCPacker), or false otherwise. If this returns true,
113 // get_num_nested_fields() may be called to determine
114 // how many nested fields are expected.
115 ////////////////////////////////////////////////////////////////////
116 INLINE bool DCPackerInterface::
118  return _has_nested_fields;
119 }
120 
121 ////////////////////////////////////////////////////////////////////
122 // Function: DCPackerInterface::get_num_nested_fields
123 // Access: Public
124 // Description: Returns the number of nested fields required by this
125 // field type. These may be array elements or structure
126 // elements. The return value may be -1 to indicate the
127 // number of nested fields is variable.
128 ////////////////////////////////////////////////////////////////////
129 INLINE int DCPackerInterface::
131  return _num_nested_fields;
132 }
133 
134 ////////////////////////////////////////////////////////////////////
135 // Function: DCPackerInterface::get_pack_type
136 // Access: Public
137 // Description: Returns the type of value expected by this field.
138 ////////////////////////////////////////////////////////////////////
139 INLINE DCPackType DCPackerInterface::
140 get_pack_type() const {
141  return _pack_type;
142 }
143 
144 ////////////////////////////////////////////////////////////////////
145 // Function: DCPackerInterface::do_pack_int8
146 // Access: Public, Static
147 // Description:
148 ////////////////////////////////////////////////////////////////////
149 INLINE void DCPackerInterface::
150 do_pack_int8(char *buffer, int value) {
151  buffer[0] = (char)(value & 0xff);
152 }
153 
154 ////////////////////////////////////////////////////////////////////
155 // Function: DCPackerInterface::do_pack_int16
156 // Access: Public, Static
157 // Description:
158 ////////////////////////////////////////////////////////////////////
159 INLINE void DCPackerInterface::
160 do_pack_int16(char *buffer, int value) {
161  buffer[0] = (char)(value & 0xff);
162  buffer[1] = (char)((value >> 8) & 0xff);
163 }
164 
165 ////////////////////////////////////////////////////////////////////
166 // Function: DCPackerInterface::do_pack_int32
167 // Access: Public, Static
168 // Description:
169 ////////////////////////////////////////////////////////////////////
170 INLINE void DCPackerInterface::
171 do_pack_int32(char *buffer, int value) {
172  buffer[0] = (char)(value & 0xff);
173  buffer[1] = (char)((value >> 8) & 0xff);
174  buffer[2] = (char)((value >> 16) & 0xff);
175  buffer[3] = (char)((value >> 24) & 0xff);
176 }
177 
178 ////////////////////////////////////////////////////////////////////
179 // Function: DCPackerInterface::do_pack_int64
180 // Access: Public, Static
181 // Description:
182 ////////////////////////////////////////////////////////////////////
183 INLINE void DCPackerInterface::
184 do_pack_int64(char *buffer, PN_int64 value) {
185  buffer[0] = (char)(value & 0xff);
186  buffer[1] = (char)((value >> 8) & 0xff);
187  buffer[2] = (char)((value >> 16) & 0xff);
188  buffer[3] = (char)((value >> 24) & 0xff);
189  buffer[4] = (char)((value >> 32) & 0xff);
190  buffer[5] = (char)((value >> 40) & 0xff);
191  buffer[6] = (char)((value >> 48) & 0xff);
192  buffer[7] = (char)((value >> 56) & 0xff);
193 }
194 
195 ////////////////////////////////////////////////////////////////////
196 // Function: DCPackerInterface::do_pack_uint8
197 // Access: Public, Static
198 // Description:
199 ////////////////////////////////////////////////////////////////////
200 INLINE void DCPackerInterface::
201 do_pack_uint8(char *buffer, unsigned int value) {
202  buffer[0] = (char)(value & 0xff);
203 }
204 
205 ////////////////////////////////////////////////////////////////////
206 // Function: DCPackerInterface::do_pack_uint16
207 // Access: Public, Static
208 // Description:
209 ////////////////////////////////////////////////////////////////////
210 INLINE void DCPackerInterface::
211 do_pack_uint16(char *buffer, unsigned int value) {
212  buffer[0] = (char)(value & 0xff);
213  buffer[1] = (char)((value >> 8) & 0xff);
214 }
215 
216 ////////////////////////////////////////////////////////////////////
217 // Function: DCPackerInterface::do_pack_uint32
218 // Access: Public, Static
219 // Description:
220 ////////////////////////////////////////////////////////////////////
221 INLINE void DCPackerInterface::
222 do_pack_uint32(char *buffer, unsigned int value) {
223  buffer[0] = (char)(value & 0xff);
224  buffer[1] = (char)((value >> 8) & 0xff);
225  buffer[2] = (char)((value >> 16) & 0xff);
226  buffer[3] = (char)((value >> 24) & 0xff);
227 }
228 
229 ////////////////////////////////////////////////////////////////////
230 // Function: DCPackerInterface::do_pack_uint64
231 // Access: Public, Static
232 // Description:
233 ////////////////////////////////////////////////////////////////////
234 INLINE void DCPackerInterface::
235 do_pack_uint64(char *buffer, PN_uint64 value) {
236  buffer[0] = (char)(value & 0xff);
237  buffer[1] = (char)((value >> 8) & 0xff);
238  buffer[2] = (char)((value >> 16) & 0xff);
239  buffer[3] = (char)((value >> 24) & 0xff);
240  buffer[4] = (char)((value >> 32) & 0xff);
241  buffer[5] = (char)((value >> 40) & 0xff);
242  buffer[6] = (char)((value >> 48) & 0xff);
243  buffer[7] = (char)((value >> 56) & 0xff);
244 }
245 
246 ////////////////////////////////////////////////////////////////////
247 // Function: DCPackerInterface::do_pack_float64
248 // Access: Public, Static
249 // Description:
250 ////////////////////////////////////////////////////////////////////
251 INLINE void DCPackerInterface::
252 do_pack_float64(char *buffer, double value) {
253 #ifdef WORDS_BIGENDIAN
254  // Reverse the byte ordering for big-endian machines.
255  char *p = (char *)&value;
256  for (size_t i = 0; i < 8; i++) {
257  buffer[i] = p[7 - i];
258  }
259 #else
260  memcpy(buffer, &value, 8);
261 #endif
262 }
263 
264 
265 ////////////////////////////////////////////////////////////////////
266 // Function: DCPackerInterface::do_unpack_int8
267 // Access: Public, Static
268 // Description:
269 ////////////////////////////////////////////////////////////////////
270 INLINE int DCPackerInterface::
271 do_unpack_int8(const char *buffer) {
272  return (int)(signed char)buffer[0];
273 }
274 
275 ////////////////////////////////////////////////////////////////////
276 // Function: DCPackerInterface::do_unpack_int16
277 // Access: Public, Static
278 // Description:
279 ////////////////////////////////////////////////////////////////////
280 INLINE int DCPackerInterface::
281 do_unpack_int16(const char *buffer) {
282  return (int)((unsigned int)(unsigned char)buffer[0] |
283  ((int)(signed char)buffer[1] << 8));
284 }
285 
286 ////////////////////////////////////////////////////////////////////
287 // Function: DCPackerInterface::do_unpack_int32
288 // Access: Public, Static
289 // Description:
290 ////////////////////////////////////////////////////////////////////
291 INLINE int DCPackerInterface::
292 do_unpack_int32(const char *buffer) {
293  return (int)((unsigned int)(unsigned char)buffer[0] |
294  ((unsigned int)(unsigned char)buffer[1] << 8) |
295  ((unsigned int)(unsigned char)buffer[2] << 16) |
296  ((int)(signed char)buffer[3] << 24));
297 }
298 
299 ////////////////////////////////////////////////////////////////////
300 // Function: DCPackerInterface::do_unpack_int64
301 // Access: Public, Static
302 // Description:
303 ////////////////////////////////////////////////////////////////////
304 INLINE PN_int64 DCPackerInterface::
305 do_unpack_int64(const char *buffer) {
306  return (PN_int64)((PN_uint64)(unsigned char)buffer[0] |
307  ((PN_uint64)(unsigned char)buffer[1] << 8) |
308  ((PN_uint64)(unsigned char)buffer[2] << 16) |
309  ((PN_uint64)(unsigned char)buffer[3] << 24) |
310  ((PN_uint64)(unsigned char)buffer[4] << 32) |
311  ((PN_uint64)(unsigned char)buffer[5] << 40) |
312  ((PN_uint64)(unsigned char)buffer[6] << 48) |
313  ((PN_int64)(signed char)buffer[7] << 54));
314 }
315 ////////////////////////////////////////////////////////////////////
316 // Function: DCPackerInterface::do_unpack_uint8
317 // Access: Public, Static
318 // Description:
319 ////////////////////////////////////////////////////////////////////
320 INLINE unsigned int DCPackerInterface::
321 do_unpack_uint8(const char *buffer) {
322  return (unsigned int)(unsigned char)buffer[0];
323 }
324 
325 ////////////////////////////////////////////////////////////////////
326 // Function: DCPackerInterface::do_unpack_uint16
327 // Access: Public, Static
328 // Description:
329 ////////////////////////////////////////////////////////////////////
330 INLINE unsigned int DCPackerInterface::
331 do_unpack_uint16(const char *buffer) {
332  return ((unsigned int)(unsigned char)buffer[0] |
333  ((unsigned int)(unsigned char)buffer[1] << 8));
334 }
335 
336 ////////////////////////////////////////////////////////////////////
337 // Function: DCPackerInterface::do_unpack_uint32
338 // Access: Public, Static
339 // Description:
340 ////////////////////////////////////////////////////////////////////
341 INLINE unsigned int DCPackerInterface::
342 do_unpack_uint32(const char *buffer) {
343  return ((unsigned int)(unsigned char)buffer[0] |
344  ((unsigned int)(unsigned char)buffer[1] << 8) |
345  ((unsigned int)(unsigned char)buffer[2] << 16) |
346  ((unsigned int)(unsigned char)buffer[3] << 24));
347 }
348 
349 ////////////////////////////////////////////////////////////////////
350 // Function: DCPackerInterface::do_unpack_uint64
351 // Access: Public, Static
352 // Description:
353 ////////////////////////////////////////////////////////////////////
354 INLINE PN_uint64 DCPackerInterface::
355 do_unpack_uint64(const char *buffer) {
356  return ((PN_uint64)(unsigned char)buffer[0] |
357  ((PN_uint64)(unsigned char)buffer[1] << 8) |
358  ((PN_uint64)(unsigned char)buffer[2] << 16) |
359  ((PN_uint64)(unsigned char)buffer[3] << 24) |
360  ((PN_uint64)(unsigned char)buffer[4] << 32) |
361  ((PN_uint64)(unsigned char)buffer[5] << 40) |
362  ((PN_uint64)(unsigned char)buffer[6] << 48) |
363  ((PN_int64)(signed char)buffer[7] << 54));
364 }
365 
366 
367 ////////////////////////////////////////////////////////////////////
368 // Function: DCPackerInterface::do_unpack_float64
369 // Access: Public, Static
370 // Description:
371 ////////////////////////////////////////////////////////////////////
372 INLINE double DCPackerInterface::
373 do_unpack_float64(const char *buffer) {
374 #ifdef WORDS_BIGENDIAN
375  char reverse[8];
376 
377  // Reverse the byte ordering for big-endian machines.
378  for (size_t i = 0; i < 8; i++) {
379  reverse[i] = buffer[7 - i];
380  }
381  return *(double *)reverse;
382 #else
383  return *(double *)buffer;
384 #endif // WORDS_BIGENDIAN
385 }
386 
387 ////////////////////////////////////////////////////////////////////
388 // Function: DCPackerInterface::validate_int_limits
389 // Access: Public, Static
390 // Description: Confirms that the signed value fits within num_bits
391 // bits. Sets range_error true if it does not.
392 ////////////////////////////////////////////////////////////////////
393 INLINE void DCPackerInterface::
394 validate_int_limits(int value, int num_bits, bool &range_error) {
395  // What we're really checking is that all of the bits above the
396  // lower (num_bits - 1) bits are the same--either all 1 or all 0.
397 
398  // First, turn on the lower (num_bits - 1).
399  int mask = ((int)1 << (num_bits - 1)) - 1;
400  value |= mask;
401 
402  // The result should be either mask (all high bits are 0) or -1 (all
403  // high bits are 1). If it is anything else we have a range error.
404  if (value != mask && value != -1) {
405  range_error = true;
406  }
407 }
408 
409 ////////////////////////////////////////////////////////////////////
410 // Function: DCPackerInterface::validate_int64_limits
411 // Access: Public, Static
412 // Description: Confirms that the signed value fits within num_bits
413 // bits. Sets range_error true if it does not.
414 ////////////////////////////////////////////////////////////////////
415 INLINE void DCPackerInterface::
416 validate_int64_limits(PN_int64 value, int num_bits, bool &range_error) {
417  PN_int64 mask = ((PN_int64)1 << (num_bits - 1)) - 1;
418  value |= mask;
419 
420  if (value != mask && value != -1) {
421  range_error = true;
422  }
423 }
424 
425 ////////////////////////////////////////////////////////////////////
426 // Function: DCPackerInterface::validate_uint_limits
427 // Access: Public, Static
428 // Description: Confirms that the unsigned value fits within num_bits
429 // bits. Sets range_error true if it does not.
430 ////////////////////////////////////////////////////////////////////
431 INLINE void DCPackerInterface::
432 validate_uint_limits(unsigned int value, int num_bits, bool &range_error) {
433  // Here we're really checking that all of the bits above the lower
434  // num_bits bits are all 0.
435 
436  unsigned int mask = ((unsigned int)1 << num_bits) - 1;
437  value &= ~mask;
438 
439  if (value != 0) {
440  range_error = true;
441  }
442 }
443 
444 ////////////////////////////////////////////////////////////////////
445 // Function: DCPackerInterface::validate_uint64_limits
446 // Access: Public, Static
447 // Description: Confirms that the unsigned value fits within num_bits
448 // bits. Sets range_error true if it does not.
449 ////////////////////////////////////////////////////////////////////
450 INLINE void DCPackerInterface::
451 validate_uint64_limits(PN_uint64 value, int num_bits, bool &range_error) {
452  PN_uint64 mask = ((PN_uint64)1 << num_bits) - 1;
453  value &= ~mask;
454 
455  if (value != 0) {
456  range_error = true;
457  }
458 }
const string & get_name() const
Returns the name of this field, or empty string if the field is unnamed.
static void validate_int_limits(int value, int num_bits, bool &range_error)
Confirms that the signed value fits within num_bits bits.
int get_num_nested_fields() const
Returns the number of nested fields required by this field type.
size_t get_fixed_byte_size() const
If has_fixed_byte_size() returns true, this returns the number of bytes this field type will use...
bool has_range_limits() const
Returns true if this field, or any sub-field of this field, has a limit imposed in the DC file on its...
static void validate_uint64_limits(PN_uint64 value, int num_bits, bool &range_error)
Confirms that the unsigned value fits within num_bits bits.
size_t get_num_length_bytes() const
Returns the number of bytes that should be written into the stream on a push() to record the number o...
static void validate_int64_limits(PN_int64 value, int num_bits, bool &range_error)
Confirms that the signed value fits within num_bits bits.
bool has_fixed_structure() const
Returns true if this field type always has the same structure regardless of the data in the stream...
bool check_match(const DCPackerInterface *other) const
Returns true if the other interface is bitwise the same as this one–that is, a uint32 only matches a ...
DCPackType get_pack_type() const
Returns the type of value expected by this field.
bool has_nested_fields() const
Returns true if this field type has any nested fields (and thus expects a push() .
This defines the internal interface for packing values into a DCField.
static void validate_uint_limits(unsigned int value, int num_bits, bool &range_error)
Confirms that the unsigned value fits within num_bits bits.
bool has_fixed_byte_size() const
Returns true if this field type always packs to the same number of bytes, false if it is variable...