Panda3D
Loading...
Searching...
No Matches
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
24class DCClass;
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 */
34class EXPCL_DIRECT_DCPARSER DCPacker {
35PUBLISHED:
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);
45public:
46 void set_unpack_data(const char *unpack_data, size_t unpack_length,
47 bool owns_unpack_data);
48
49PUBLISHED:
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
93public:
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
105PUBLISHED:
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;
128public:
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
138PUBLISHED:
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
175public:
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
188public:
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
192private:
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
207private:
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
Defines a particular DistributedClass as read from an input .dc file.
Definition dcClass.h:44
A single field of a Distributed Class, either atomic or molecular.
Definition dcField.h:37
This is a block of data that receives the results of DCPacker.
Definition dcPackData.h:22
This object contains the names of all of the nested fields available within a particular field.
This defines the internal interface for packing values into a DCField.
This class can be used for packing a series of numeric and string data into a binary stream,...
Definition dcPacker.h:34
This represents a switch object used as a parameter itself, which packs the appropriate fields of the...
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
ostream & enquote_string(ostream &out, const string &str, int indent_level, bool always_quote)
Writes the string to the indicated output stream.