Panda3D
dcPacker.h
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file dcPacker.h
10  * @author drose
11  * @date 2004-06-15
12  */
13 
14 #ifndef DCPACKER_H
15 #define DCPACKER_H
16 
17 #include "dcbase.h"
18 #include "dcPackerInterface.h"
19 #include "dcSubatomicType.h"
20 #include "dcPackData.h"
21 #include "dcPackerCatalog.h"
22 #include "dcPython.h"
23 
24 class DCClass;
25 class DCSwitchParameter;
26 
27 /**
28  * This class can be used for packing a series of numeric and string data into
29  * a binary stream, according to the DC specification.
30  *
31  * See also direct/src/doc/dcPacker.txt for a more complete description and
32  * examples of using this class.
33  */
34 class EXPCL_DIRECT_DCPARSER DCPacker {
35 PUBLISHED:
36  DCPacker();
37  ~DCPacker();
38 
39  INLINE void clear_data();
40 
41  void begin_pack(const DCPackerInterface *root);
42  bool end_pack();
43 
44  void set_unpack_data(const vector_uchar &data);
45 public:
46  void set_unpack_data(const char *unpack_data, size_t unpack_length,
47  bool owns_unpack_data);
48 
49 PUBLISHED:
50  void begin_unpack(const DCPackerInterface *root);
51  bool end_unpack();
52 
53  void begin_repack(const DCPackerInterface *root);
54  bool end_repack();
55 
56  bool seek(const std::string &field_name);
57  bool seek(int seek_index);
58 
59  INLINE bool has_nested_fields() const;
60  INLINE int get_num_nested_fields() const;
61  INLINE bool more_nested_fields() const;
62 
63  INLINE const DCPackerInterface *get_current_parent() const;
64  INLINE const DCPackerInterface *get_current_field() const;
65  INLINE const DCSwitchParameter *get_last_switch() const;
66  INLINE DCPackType get_pack_type() const;
67  INLINE std::string get_current_field_name() const;
68 
69  void push();
70  void pop();
71 
72  INLINE void pack_double(double value);
73  INLINE void pack_int(int value);
74  INLINE void pack_uint(unsigned int value);
75  INLINE void pack_int64(int64_t value);
76  INLINE void pack_uint64(uint64_t value);
77  INLINE void pack_string(const std::string &value);
78  INLINE void pack_blob(const vector_uchar &value);
79  INLINE void pack_literal_value(const vector_uchar &value);
80  void pack_default_value();
81 
82  INLINE double unpack_double();
83  INLINE int unpack_int();
84  INLINE unsigned int unpack_uint();
85  INLINE int64_t unpack_int64();
86  INLINE uint64_t unpack_uint64();
87  INLINE std::string unpack_string();
88  INLINE vector_uchar unpack_blob();
89  INLINE vector_uchar unpack_literal_value();
90  void unpack_validate();
91  void unpack_skip();
92 
93 public:
94  // The following are variants on the above unpack() calls that pass the
95  // result back by reference instead of as a return value.
96  INLINE void unpack_double(double &value);
97  INLINE void unpack_int(int &value);
98  INLINE void unpack_uint(unsigned int &value);
99  INLINE void unpack_int64(int64_t &value);
100  INLINE void unpack_uint64(uint64_t &value);
101  INLINE void unpack_string(std::string &value);
102  INLINE void unpack_blob(vector_uchar &value);
103  INLINE void unpack_literal_value(vector_uchar &value);
104 
105 PUBLISHED:
106 
107 #ifdef HAVE_PYTHON
108  void pack_object(PyObject *object);
109  PyObject *unpack_object();
110 #endif
111 
112  bool parse_and_pack(const std::string &formatted_object);
113  bool parse_and_pack(std::istream &in);
114  std::string unpack_and_format(bool show_field_names = true);
115  void unpack_and_format(std::ostream &out, bool show_field_names = true);
116 
117  INLINE bool had_parse_error() const;
118  INLINE bool had_pack_error() const;
119  INLINE bool had_range_error() const;
120  INLINE bool had_error() const;
121  INLINE size_t get_num_unpacked_bytes() const;
122 
123  INLINE size_t get_length() const;
124  INLINE std::string get_string() const;
125  INLINE vector_uchar get_bytes() const;
126  INLINE size_t get_unpack_length() const;
127  INLINE std::string get_unpack_string() const;
128 public:
129  INLINE void get_string(std::string &data) const;
130  INLINE const char *get_data() const;
131  INLINE char *take_data();
132 
133  INLINE void append_data(const unsigned char *buffer, size_t size);
134  INLINE char *get_write_pointer(size_t size);
135 
136  INLINE const char *get_unpack_data() const;
137 
138 PUBLISHED:
139  INLINE static int get_num_stack_elements_ever_allocated();
140 
141  // The following methods are used only for packing (or unpacking) raw data
142  // into the buffer between packing sessions (e.g. between calls to
143  // end_pack() and the next begin_pack()).
144 
145  INLINE void raw_pack_int8(int value);
146  INLINE void raw_pack_int16(int value);
147  INLINE void raw_pack_int32(int value);
148  INLINE void raw_pack_int64(int64_t value);
149  INLINE void raw_pack_uint8(unsigned int value);
150  INLINE void raw_pack_uint16(unsigned int value);
151  INLINE void raw_pack_uint32(unsigned int value);
152  INLINE void raw_pack_uint64(uint64_t value);
153  INLINE void raw_pack_float64(double value);
154  INLINE void raw_pack_string(const std::string &value);
155  INLINE void raw_pack_blob(const vector_uchar &value);
156 
157 // this is a hack to allw me to get in and out of 32bit Mode Faster need to
158 // agree with channel_type in dcbase.h
159 #define RAW_PACK_CHANNEL(in) raw_pack_uint64(in)
160 #define RAW_UNPACK_CHANNEL() raw_unpack_uint64()
161 
162 
163  INLINE int raw_unpack_int8();
164  INLINE int raw_unpack_int16();
165  INLINE int raw_unpack_int32();
166  INLINE int64_t raw_unpack_int64();
167  INLINE unsigned int raw_unpack_uint8();
168  INLINE unsigned int raw_unpack_uint16();
169  INLINE unsigned int raw_unpack_uint32();
170  INLINE uint64_t raw_unpack_uint64();
171  INLINE double raw_unpack_float64();
172  INLINE std::string raw_unpack_string();
173  INLINE vector_uchar raw_unpack_blob();
174 
175 public:
176  INLINE void raw_unpack_int8(int &value);
177  INLINE void raw_unpack_int16(int &value);
178  INLINE void raw_unpack_int32(int &value);
179  INLINE void raw_unpack_int64(int64_t &value);
180  INLINE void raw_unpack_uint8(unsigned int &value);
181  INLINE void raw_unpack_uint16(unsigned int &value);
182  INLINE void raw_unpack_uint32(unsigned int &value);
183  INLINE void raw_unpack_uint64(uint64_t &value);
184  INLINE void raw_unpack_float64(double &value);
185  INLINE void raw_unpack_string(std::string &value);
186  INLINE void raw_unpack_blob(vector_uchar &value);
187 
188 public:
189  static void enquote_string(std::ostream &out, char quote_mark, const std::string &str);
190  static void output_hex_string(std::ostream &out, const vector_uchar &str);
191 
192 private:
193  INLINE void advance();
194  void handle_switch(const DCSwitchParameter *switch_parameter);
195  void clear();
196  void clear_stack();
197 
198 #ifdef HAVE_PYTHON
199  void pack_class_object(const DCClass *dclass, PyObject *object);
200  PyObject *unpack_class_object(const DCClass *dclass);
201  void set_class_element(PyObject *class_def, PyObject *&object,
202  const DCField *field);
203  void get_class_element(const DCClass *dclass, PyObject *object,
204  const DCField *field);
205 #endif
206 
207 private:
208  enum Mode {
209  M_idle,
210  M_pack,
211  M_unpack,
212  M_repack,
213  };
214  Mode _mode;
215 
216  DCPackData _pack_data;
217  const char *_unpack_data;
218  size_t _unpack_length;
219  bool _owns_unpack_data;
220  size_t _unpack_p;
221 
222  const DCPackerInterface *_root;
223  const DCPackerCatalog *_catalog;
224  const DCPackerCatalog::LiveCatalog *_live_catalog;
225 
226  class StackElement {
227  public:
228  // As an optimization, we implement operator new and delete here to
229  // minimize allocation overhead during push() and pop().
230  INLINE void *operator new(size_t size);
231  INLINE void operator delete(void *ptr);
232 
233  const DCPackerInterface *_current_parent;
234  int _current_field_index;
235  size_t _push_marker;
236  size_t _pop_marker;
237  StackElement *_next;
238 
239  static StackElement *_deleted_chain;
240  static int _num_ever_allocated;
241  };
242  StackElement *_stack;
243 
244  const DCPackerInterface *_current_field;
245  const DCPackerInterface *_current_parent;
246  int _current_field_index;
247 
248  // _push_marker marks the beginning of the push record (so we can go back
249  // and write in the length later, or figure out the switch parameter).
250  size_t _push_marker;
251  // _pop_marker is used in unpack mode with certain data structures (like
252  // dynamic arrays) to mark the end of the push record (so we know when we've
253  // reached the end). It is zero when it is not in use.
254  size_t _pop_marker;
255  int _num_nested_fields;
256  const DCSwitchParameter *_last_switch;
257 
258  bool _parse_error;
259  bool _pack_error;
260  bool _range_error;
261 };
262 
263 #include "dcPacker.I"
264 
265 #endif
dcPacker.I
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
DCPackerInterface
This defines the internal interface for packing values into a DCField.
Definition: dcPackerInterface.h:67
enquote_string
ostream & enquote_string(ostream &out, const string &str, int indent_level, bool always_quote)
Writes the string to the indicated output stream.
Definition: eggMiscFuncs.cxx:30
dcPython.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
DCPacker
This class can be used for packing a series of numeric and string data into a binary stream,...
Definition: dcPacker.h:34
DCField
A single field of a Distributed Class, either atomic or molecular.
Definition: dcField.h:37
dcPackData.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
DCSwitchParameter
This represents a switch object used as a parameter itself, which packs the appropriate fields of the...
Definition: dcSwitchParameter.h:26
DCPackData
This is a block of data that receives the results of DCPacker.
Definition: dcPackData.h:22
DCPackerCatalog
This object contains the names of all of the nested fields available within a particular field.
Definition: dcPackerCatalog.h:29
dcPackerCatalog.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
dcPackerInterface.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
DCPackerCatalog::LiveCatalog
Definition: dcPackerCatalog.h:54
dcbase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
dcSubatomicType.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
DCClass
Defines a particular DistributedClass as read from an input .dc file.
Definition: dcClass.h:44