00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef DCPACKER_H
00016 #define DCPACKER_H
00017
00018 #include "dcbase.h"
00019 #include "dcPackerInterface.h"
00020 #include "dcSubatomicType.h"
00021 #include "dcPackData.h"
00022 #include "dcPackerCatalog.h"
00023 #include "dcPython.h"
00024
00025 class DCClass;
00026 class DCSwitchParameter;
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 class EXPCL_DIRECT DCPacker {
00039 PUBLISHED:
00040 DCPacker();
00041 ~DCPacker();
00042
00043 INLINE void clear_data();
00044
00045 void begin_pack(const DCPackerInterface *root);
00046 bool end_pack();
00047
00048 void set_unpack_data(const string &data);
00049 public:
00050 void set_unpack_data(const char *unpack_data, size_t unpack_length,
00051 bool owns_unpack_data);
00052
00053 PUBLISHED:
00054 void begin_unpack(const DCPackerInterface *root);
00055 bool end_unpack();
00056
00057 void begin_repack(const DCPackerInterface *root);
00058 bool end_repack();
00059
00060 bool seek(const string &field_name);
00061 bool seek(int seek_index);
00062
00063 INLINE bool has_nested_fields() const;
00064 INLINE int get_num_nested_fields() const;
00065 INLINE bool more_nested_fields() const;
00066
00067 INLINE const DCPackerInterface *get_current_parent() const;
00068 INLINE const DCPackerInterface *get_current_field() const;
00069 INLINE const DCSwitchParameter *get_last_switch() const;
00070 INLINE DCPackType get_pack_type() const;
00071 INLINE string get_current_field_name() const;
00072
00073 void push();
00074 void pop();
00075
00076 INLINE void pack_double(double value);
00077 INLINE void pack_int(int value);
00078 INLINE void pack_uint(unsigned int value);
00079 INLINE void pack_int64(PN_int64 value);
00080 INLINE void pack_uint64(PN_uint64 value);
00081 INLINE void pack_string(const string &value);
00082 INLINE void pack_literal_value(const string &value);
00083 void pack_default_value();
00084
00085 INLINE double unpack_double();
00086 INLINE int unpack_int();
00087 INLINE unsigned int unpack_uint();
00088 INLINE PN_int64 unpack_int64();
00089 INLINE PN_uint64 unpack_uint64();
00090 INLINE string unpack_string();
00091 INLINE string unpack_literal_value();
00092 void unpack_validate();
00093 void unpack_skip();
00094
00095 public:
00096
00097
00098 INLINE void unpack_double(double &value);
00099 INLINE void unpack_int(int &value);
00100 INLINE void unpack_uint(unsigned int &value);
00101 INLINE void unpack_int64(PN_int64 &value);
00102 INLINE void unpack_uint64(PN_uint64 &value);
00103 INLINE void unpack_string(string &value);
00104 INLINE void unpack_literal_value(string &value);
00105
00106 PUBLISHED:
00107
00108 #ifdef HAVE_PYTHON
00109 void pack_object(PyObject *object);
00110 PyObject *unpack_object();
00111 #endif
00112
00113 bool parse_and_pack(const string &formatted_object);
00114 bool parse_and_pack(istream &in);
00115 string unpack_and_format(bool show_field_names = true);
00116 void unpack_and_format(ostream &out, bool show_field_names = true);
00117
00118 INLINE bool had_parse_error() const;
00119 INLINE bool had_pack_error() const;
00120 INLINE bool had_range_error() const;
00121 INLINE bool had_error() const;
00122 INLINE size_t get_num_unpacked_bytes() const;
00123
00124 INLINE size_t get_length() const;
00125 INLINE string get_string() const;
00126 INLINE size_t get_unpack_length() const;
00127 INLINE string get_unpack_string() const;
00128 public:
00129 INLINE void get_string(string &data) const;
00130 INLINE const char *get_data() const;
00131 INLINE char *take_data();
00132
00133 INLINE void append_data(const char *buffer, size_t size);
00134 INLINE char *get_write_pointer(size_t size);
00135
00136 INLINE const char *get_unpack_data() const;
00137
00138 PUBLISHED:
00139 INLINE static int get_num_stack_elements_ever_allocated();
00140
00141
00142
00143
00144
00145 INLINE void raw_pack_int8(int value);
00146 INLINE void raw_pack_int16(int value);
00147 INLINE void raw_pack_int32(int value);
00148 INLINE void raw_pack_int64(PN_int64 value);
00149 INLINE void raw_pack_uint8(unsigned int value);
00150 INLINE void raw_pack_uint16(unsigned int value);
00151 INLINE void raw_pack_uint32(unsigned int value);
00152 INLINE void raw_pack_uint64(PN_uint64 value);
00153 INLINE void raw_pack_float64(double value);
00154 INLINE void raw_pack_string(const string &value);
00155
00156
00157
00158 #define RAW_PACK_CHANNEL(in) raw_pack_uint64(in)
00159 #define RAW_UNPACK_CHANNEL() raw_unpack_uint64()
00160
00161
00162 INLINE int raw_unpack_int8();
00163 INLINE int raw_unpack_int16();
00164 INLINE int raw_unpack_int32();
00165 INLINE PN_int64 raw_unpack_int64();
00166 INLINE unsigned int raw_unpack_uint8();
00167 INLINE unsigned int raw_unpack_uint16();
00168 INLINE unsigned int raw_unpack_uint32();
00169 INLINE PN_uint64 raw_unpack_uint64();
00170 INLINE double raw_unpack_float64();
00171 INLINE string raw_unpack_string();
00172
00173 public:
00174 INLINE void raw_unpack_int8(int &value);
00175 INLINE void raw_unpack_int16(int &value);
00176 INLINE void raw_unpack_int32(int &value);
00177 INLINE void raw_unpack_int64(PN_int64 &value);
00178 INLINE void raw_unpack_uint8(unsigned int &value);
00179 INLINE void raw_unpack_uint16(unsigned int &value);
00180 INLINE void raw_unpack_uint32(unsigned int &value);
00181 INLINE void raw_unpack_uint64(PN_uint64 &value);
00182 INLINE void raw_unpack_float64(double &value);
00183 INLINE void raw_unpack_string(string &value);
00184
00185 public:
00186 static void enquote_string(ostream &out, char quote_mark, const string &str);
00187 static void output_hex_string(ostream &out, const string &str);
00188
00189 private:
00190 INLINE void advance();
00191 void handle_switch(const DCSwitchParameter *switch_parameter);
00192 void clear();
00193 void clear_stack();
00194
00195 #ifdef HAVE_PYTHON
00196 void pack_class_object(const DCClass *dclass, PyObject *object);
00197 PyObject *unpack_class_object(const DCClass *dclass);
00198 void set_class_element(PyObject *class_def, PyObject *&object,
00199 const DCField *field);
00200 void get_class_element(const DCClass *dclass, PyObject *object,
00201 const DCField *field);
00202 #endif
00203
00204 private:
00205 enum Mode {
00206 M_idle,
00207 M_pack,
00208 M_unpack,
00209 M_repack,
00210 };
00211 Mode _mode;
00212
00213 DCPackData _pack_data;
00214 const char *_unpack_data;
00215 size_t _unpack_length;
00216 bool _owns_unpack_data;
00217 size_t _unpack_p;
00218
00219 const DCPackerInterface *_root;
00220 const DCPackerCatalog *_catalog;
00221 const DCPackerCatalog::LiveCatalog *_live_catalog;
00222
00223 class StackElement {
00224 public:
00225
00226
00227 INLINE void *operator new(size_t size);
00228 INLINE void operator delete(void *ptr);
00229
00230 const DCPackerInterface *_current_parent;
00231 int _current_field_index;
00232 size_t _push_marker;
00233 size_t _pop_marker;
00234 StackElement *_next;
00235
00236 static StackElement *_deleted_chain;
00237 static int _num_ever_allocated;
00238 };
00239 StackElement *_stack;
00240
00241 const DCPackerInterface *_current_field;
00242 const DCPackerInterface *_current_parent;
00243 int _current_field_index;
00244
00245
00246
00247
00248 size_t _push_marker;
00249
00250
00251
00252
00253 size_t _pop_marker;
00254 int _num_nested_fields;
00255 const DCSwitchParameter *_last_switch;
00256
00257 bool _parse_error;
00258 bool _pack_error;
00259 bool _range_error;
00260 };
00261
00262 #include "dcPacker.I"
00263
00264 #endif