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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a block of data that receives the results of DCPacker.
Definition: dcPackData.h:22
ostream & enquote_string(ostream &out, const string &str, int indent_level, bool always_quote)
Writes the string to the indicated output stream.
A single field of a Distributed Class, either atomic or molecular.
Definition: dcField.h:37
This represents a switch object used as a parameter itself, which packs the appropriate fields of the...
Defines a particular DistributedClass as read from an input .dc file.
Definition: dcClass.h:44
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class can be used for packing a series of numeric and string data into a binary stream,...
Definition: dcPacker.h:34
This object contains the names of all of the nested fields available within a particular field.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This defines the internal interface for packing values into a DCField.