15 #include "dcPackerCatalog.h"
16 #include "dcPackerInterface.h"
18 #include "dcSwitchParameter.h"
40 _entries(copy._entries),
41 _entries_by_name(copy._entries_by_name),
42 _entries_by_field(copy._entries_by_field)
55 if (_live_catalog != (LiveCatalog *)NULL) {
59 SwitchCatalogs::iterator si;
60 for (si = _switch_catalogs.begin(); si != _switch_catalogs.end(); ++si) {
75 EntriesByName::const_iterator ni;
76 ni = _entries_by_name.find(name);
77 if (ni != _entries_by_name.end()) {
93 EntriesByField::const_iterator ni;
94 ni = _entries_by_field.find(field);
95 if (ni != _entries_by_field.end()) {
118 return _live_catalog;
122 live_catalog->_catalog =
this;
123 live_catalog->_live_entries.reserve(_entries.size());
125 zero_entry._begin = 0;
127 for (
size_t i = 0; i < _entries.size(); i++) {
128 live_catalog->_live_entries.push_back(zero_entry);
135 r_fill_live_catalog(live_catalog, packer, last_switch);
167 if (live_catalog != _live_catalog) {
178 void DCPackerCatalog::
183 entry._field = field;
184 entry._parent = parent;
185 entry._field_index = field_index;
187 int entry_index = (int)_entries.size();
188 _entries.push_back(entry);
189 _entries_by_field.insert(EntriesByField::value_type(field, entry_index));
196 _entries_by_name[name] = entry_index;
202 string local_name = field->
get_name();
203 if (local_name != name) {
204 _entries_by_name.insert(EntriesByName::value_type(local_name, entry_index));
216 void DCPackerCatalog::
219 string next_name_prefix = name_prefix;
223 next_name_prefix += field->
get_name();
224 add_entry(next_name_prefix, field, parent, field_index);
226 next_name_prefix +=
".";
236 _switch_prefixes[switch_parameter] = next_name_prefix;
243 for (
int i = 0; i < num_nested; i++) {
246 r_fill_catalog(next_name_prefix, nested, field, i);
259 void DCPackerCatalog::
260 r_fill_live_catalog(LiveCatalog *live_catalog,
DCPacker &packer,
264 int field_index = live_catalog->find_entry_by_field(current_field);
265 if (field_index >= 0) {
266 nassertv(field_index < (
int)live_catalog->_live_entries.size());
274 r_fill_live_catalog(live_catalog, packer, last_switch);
282 if (field_index >= 0) {
294 live_catalog->_catalog->update_switch_fields(last_switch, switch_case);
296 live_catalog->_catalog = switch_catalog;
300 LiveCatalogEntry zero_entry;
301 zero_entry._begin = 0;
303 for (
size_t i = live_catalog->_live_entries.size();
304 i < switch_catalog->_entries.size();
306 live_catalog->_live_entries.push_back(zero_entry);
332 SwitchCatalogs::const_iterator si = _switch_catalogs.find(switch_case);
333 if (si != _switch_catalogs.end()) {
341 SwitchPrefixes::const_iterator pi = _switch_prefixes.find(switch_parameter);
342 if (pi == _switch_prefixes.end()) {
349 string name_prefix = (*pi).second;
360 for (
int i = 1; i < num_nested; i++) {
363 switch_catalog->r_fill_catalog(name_prefix, nested, switch_case, i);
369 ((
DCPackerCatalog *)
this)->_switch_catalogs[switch_case] = switch_catalog;
371 return switch_catalog;
const DCPackerInterface * get_current_field() const
Returns the field that will be referenced by the next call to pack_*() or unpack_*().
const string & get_name() const
Returns the name of this field, or empty string if the field is unnamed.
virtual DCPackerInterface * get_nested_field(int n) const
Returns the DCPackerInterface object that represents the nth nested field.
bool has_nested_fields() const
Returns true if the current field has any nested fields (and thus expects a push() ...
int find_entry_by_field(const DCPackerInterface *field) const
Returns the index number of the entry with the indicated field, or -1 if no entry has the indicated f...
int get_num_nested_fields() const
Returns the number of nested fields required by this field type.
This represents a switch object used as a parameter itself, which packs the appropriate fields of the...
void release_live_catalog(const LiveCatalog *live_catalog) const
Releases the LiveCatalog object that was returned by an earlier call to get_live_catalog().
const DCSwitchParameter * get_last_switch() const
Returns a pointer to the last DCSwitch instance that we have passed by and selected one case of durin...
void push()
Marks the beginning of a nested series of fields.
bool has_fixed_structure() const
Returns true if this field type always has the same structure regardless of the data in the stream...
const LiveCatalog * get_live_catalog(const char *data, size_t length) const
Returns a LiveCatalog object indicating the positions within the indicated data record of each field ...
DCPackType get_pack_type() const
Returns the type of value expected by the current field.
This class can be used for packing a series of numeric and string data into a binary stream...
int find_entry_by_name(const string &name) const
Returns the index number of the entry with the indicated name, or -1 if no entry has the indicated na...
void unpack_skip()
Skips the current field without unpacking it and advances to the next field.
bool more_nested_fields() const
Returns true if there are more nested fields to pack or unpack in the current push sequence...
This object contains the names of all of the nested fields available within a particular field...
size_t get_num_unpacked_bytes() const
Returns the number of bytes that have been unpacked so far, or after unpack_end(), the total number of bytes that were unpacked at all.
const DCPackerInterface * get_current_parent() const
Returns the field that we left in our last call to push(): the owner of the current level of fields...
void set_unpack_data(const string &data)
Sets up the unpack_data pointer.
void pop()
Marks the end of a nested series of fields.
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.
void begin_unpack(const DCPackerInterface *root)
Begins an unpacking session.
bool end_unpack()
Finishes the unpacking session.