00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "dcField.h"
00016 #include "dcFile.h"
00017 #include "dcPacker.h"
00018 #include "dcClass.h"
00019 #include "hashGenerator.h"
00020 #include "dcmsgtypes.h"
00021
00022 #ifdef WITHIN_PANDA
00023 #include "pStatTimer.h"
00024 #endif
00025
00026
00027
00028
00029
00030
00031 DCField::
00032 DCField() :
00033 _dclass(NULL)
00034 #ifdef WITHIN_PANDA
00035 ,
00036 _field_update_pcollector("DCField")
00037 #endif
00038 {
00039 _number = -1;
00040 _default_value_stale = true;
00041 _has_default_value = false;
00042
00043 _bogus_field = false;
00044
00045 _has_nested_fields = true;
00046 _num_nested_fields = 0;
00047 _pack_type = PT_field;
00048
00049 _has_fixed_byte_size = true;
00050 _fixed_byte_size = 0;
00051 _has_fixed_structure = true;
00052 }
00053
00054
00055
00056
00057
00058
00059 DCField::
00060 DCField(const string &name, DCClass *dclass) :
00061 DCPackerInterface(name),
00062 _dclass(dclass)
00063 #ifdef WITHIN_PANDA
00064 ,
00065 _field_update_pcollector(dclass->_class_update_pcollector, name)
00066 #endif
00067 {
00068 _number = -1;
00069 _has_default_value = false;
00070 _default_value_stale = true;
00071
00072 _bogus_field = false;
00073
00074 _has_nested_fields = true;
00075 _num_nested_fields = 0;
00076 _pack_type = PT_field;
00077
00078 _has_fixed_byte_size = true;
00079 _fixed_byte_size = 0;
00080 _has_fixed_structure = true;
00081 }
00082
00083
00084
00085
00086
00087
00088 DCField::
00089 ~DCField() {
00090 }
00091
00092
00093
00094
00095
00096
00097 DCField *DCField::
00098 as_field() {
00099 return this;
00100 }
00101
00102
00103
00104
00105
00106
00107 const DCField *DCField::
00108 as_field() const {
00109 return this;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119 DCAtomicField *DCField::
00120 as_atomic_field() {
00121 return (DCAtomicField *)NULL;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131 const DCAtomicField *DCField::
00132 as_atomic_field() const {
00133 return (DCAtomicField *)NULL;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143 DCMolecularField *DCField::
00144 as_molecular_field() {
00145 return (DCMolecularField *)NULL;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155 const DCMolecularField *DCField::
00156 as_molecular_field() const {
00157 return (DCMolecularField *)NULL;
00158 }
00159
00160
00161
00162
00163
00164
00165 DCParameter *DCField::
00166 as_parameter() {
00167 return (DCParameter *)NULL;
00168 }
00169
00170
00171
00172
00173
00174
00175 const DCParameter *DCField::
00176 as_parameter() const {
00177 return (DCParameter *)NULL;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187 string DCField::
00188 format_data(const string &packed_data, bool show_field_names) {
00189 DCPacker packer;
00190 packer.set_unpack_data(packed_data);
00191 packer.begin_unpack(this);
00192 string result = packer.unpack_and_format(show_field_names);
00193 if (!packer.end_unpack()) {
00194 return string();
00195 }
00196 return result;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 string DCField::
00209 parse_string(const string &formatted_string) {
00210 DCPacker packer;
00211 packer.begin_pack(this);
00212 if (!packer.parse_and_pack(formatted_string)) {
00213
00214 return string();
00215 }
00216 if (!packer.end_pack()) {
00217
00218 return string();
00219 }
00220
00221 return packer.get_string();
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 bool DCField::
00233 validate_ranges(const string &packed_data) const {
00234 DCPacker packer;
00235 packer.set_unpack_data(packed_data);
00236 packer.begin_unpack(this);
00237 packer.unpack_validate();
00238 if (!packer.end_unpack()) {
00239 return false;
00240 }
00241
00242 return (packer.get_num_unpacked_bytes() == packed_data.length());
00243 }
00244
00245 #ifdef HAVE_PYTHON
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 bool DCField::
00257 pack_args(DCPacker &packer, PyObject *sequence) const {
00258 nassertr(!packer.had_error(), false);
00259 nassertr(packer.get_current_field() == this, false);
00260
00261 packer.pack_object(sequence);
00262 if (!packer.had_error()) {
00263
00264
00265
00266
00267 return true;
00268 }
00269
00270 if (!Notify::ptr()->has_assert_failed()) {
00271 ostringstream strm;
00272 PyObject *exc_type = PyExc_StandardError;
00273
00274 if (as_parameter() != (DCParameter *)NULL) {
00275
00276
00277 if (packer.had_pack_error()) {
00278 strm << "Incorrect arguments to field: " << get_name()
00279 << " = " << get_pystr(sequence);
00280 exc_type = PyExc_TypeError;
00281 } else {
00282 strm << "Value out of range on field: " << get_name()
00283 << " = " << get_pystr(sequence);
00284 exc_type = PyExc_ValueError;
00285 }
00286
00287 } else {
00288
00289
00290 PyObject *tuple = PySequence_Tuple(sequence);
00291 if (tuple == (PyObject *)NULL) {
00292 strm << "Value for " << get_name() << " not a sequence: " \
00293 << get_pystr(sequence);
00294 exc_type = PyExc_TypeError;
00295
00296 } else {
00297 if (packer.had_pack_error()) {
00298 strm << "Incorrect arguments to field: " << get_name()
00299 << get_pystr(sequence);
00300 exc_type = PyExc_TypeError;
00301 } else {
00302 strm << "Value out of range on field: " << get_name()
00303 << get_pystr(sequence);
00304 exc_type = PyExc_ValueError;
00305 }
00306
00307 Py_DECREF(tuple);
00308 }
00309 }
00310
00311 string message = strm.str();
00312 PyErr_SetString(exc_type, message.c_str());
00313 }
00314 return false;
00315 }
00316 #endif // HAVE_PYTHON
00317
00318 #ifdef HAVE_PYTHON
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 PyObject *DCField::
00330 unpack_args(DCPacker &packer) const {
00331 nassertr(!packer.had_error(), NULL);
00332 nassertr(packer.get_current_field() == this, NULL);
00333
00334 size_t start_byte = packer.get_num_unpacked_bytes();
00335 PyObject *object = packer.unpack_object();
00336
00337 if (!packer.had_error()) {
00338
00339
00340
00341
00342
00343 return object;
00344 }
00345
00346 if (!Notify::ptr()->has_assert_failed()) {
00347 ostringstream strm;
00348 PyObject *exc_type = PyExc_StandardError;
00349
00350 if (packer.had_pack_error()) {
00351 strm << "Data error unpacking field ";
00352 output(strm, true);
00353 size_t length = packer.get_unpack_length() - start_byte;
00354 strm << "\nGot data (" << (int)length << " bytes):\n";
00355 Datagram dg(packer.get_unpack_data() + start_byte, length);
00356 dg.dump_hex(strm);
00357 size_t error_byte = packer.get_num_unpacked_bytes() - start_byte;
00358 strm << "Error detected on byte " << error_byte
00359 << " (" << hex << error_byte << dec << " hex)";
00360
00361 exc_type = PyExc_RuntimeError;
00362 } else {
00363 strm << "Value outside specified range when unpacking field "
00364 << get_name() << ": " << get_pystr(object);
00365 exc_type = PyExc_ValueError;
00366 }
00367
00368 string message = strm.str();
00369 PyErr_SetString(exc_type, message.c_str());
00370 }
00371
00372 Py_XDECREF(object);
00373 return NULL;
00374 }
00375 #endif // HAVE_PYTHON
00376
00377 #ifdef HAVE_PYTHON
00378
00379
00380
00381
00382
00383
00384
00385 void DCField::
00386 receive_update(DCPacker &packer, PyObject *distobj) const {
00387 if (as_parameter() != (DCParameter *)NULL) {
00388
00389
00390 PyObject *value = unpack_args(packer);
00391 if (value != (PyObject *)NULL) {
00392 PyObject_SetAttrString(distobj, (char *)_name.c_str(), value);
00393 }
00394 Py_DECREF(value);
00395
00396 } else {
00397
00398
00399
00400 if (!PyObject_HasAttrString(distobj, (char *)_name.c_str())) {
00401
00402
00403
00404 packer.unpack_skip();
00405
00406 } else {
00407
00408
00409 PyObject *args = unpack_args(packer);
00410
00411 if (args != (PyObject *)NULL) {
00412 PyObject *func = PyObject_GetAttrString(distobj, (char *)_name.c_str());
00413 nassertv(func != (PyObject *)NULL);
00414
00415 PyObject *result;
00416 {
00417 #ifdef WITHIN_PANDA
00418 PStatTimer timer(((DCField *)this)->_field_update_pcollector);
00419 #endif
00420 result = PyObject_CallObject(func, args);
00421 }
00422 Py_XDECREF(result);
00423 Py_DECREF(func);
00424 Py_DECREF(args);
00425 }
00426 }
00427 }
00428 }
00429 #endif // HAVE_PYTHON
00430
00431 #ifdef HAVE_PYTHON
00432
00433
00434
00435
00436
00437
00438
00439 Datagram DCField::
00440 client_format_update(DOID_TYPE do_id, PyObject *args) const {
00441 DCPacker packer;
00442
00443 packer.raw_pack_uint16(CLIENT_OBJECT_UPDATE_FIELD);
00444 packer.raw_pack_uint32(do_id);
00445 packer.raw_pack_uint16(_number);
00446
00447 packer.begin_pack(this);
00448 pack_args(packer, args);
00449 if (!packer.end_pack()) {
00450 return Datagram();
00451 }
00452
00453 return Datagram(packer.get_data(), packer.get_length());
00454 }
00455 #endif // HAVE_PYTHON
00456
00457 #ifdef HAVE_PYTHON
00458
00459
00460
00461
00462
00463
00464
00465 Datagram DCField::
00466 ai_format_update(DOID_TYPE do_id, CHANNEL_TYPE to_id, CHANNEL_TYPE from_id, PyObject *args) const {
00467 DCPacker packer;
00468
00469 packer.raw_pack_uint8(1);
00470 packer.RAW_PACK_CHANNEL(to_id);
00471 packer.RAW_PACK_CHANNEL(from_id);
00472 packer.raw_pack_uint16(STATESERVER_OBJECT_UPDATE_FIELD);
00473 packer.raw_pack_uint32(do_id);
00474 packer.raw_pack_uint16(_number);
00475
00476 packer.begin_pack(this);
00477 pack_args(packer, args);
00478 if (!packer.end_pack()) {
00479 return Datagram();
00480 }
00481
00482 return Datagram(packer.get_data(), packer.get_length());
00483 }
00484 #endif // HAVE_PYTHON
00485
00486 #ifdef HAVE_PYTHON
00487
00488
00489
00490
00491
00492
00493
00494
00495 Datagram DCField::
00496 ai_format_update_msg_type(DOID_TYPE do_id, CHANNEL_TYPE to_id, CHANNEL_TYPE from_id, int msg_type, PyObject *args) const {
00497 DCPacker packer;
00498
00499 packer.raw_pack_uint8(1);
00500 packer.RAW_PACK_CHANNEL(to_id);
00501 packer.RAW_PACK_CHANNEL(from_id);
00502 packer.raw_pack_uint16(msg_type);
00503 packer.raw_pack_uint32(do_id);
00504 packer.raw_pack_uint16(_number);
00505
00506 packer.begin_pack(this);
00507 pack_args(packer, args);
00508 if (!packer.end_pack()) {
00509 return Datagram();
00510 }
00511
00512 return Datagram(packer.get_data(), packer.get_length());
00513 }
00514 #endif // HAVE_PYTHON
00515
00516
00517
00518
00519
00520
00521
00522
00523 void DCField::
00524 generate_hash(HashGenerator &hashgen) const {
00525
00526
00527
00528
00529 hashgen.add_string(_name);
00530
00531
00532
00533 if (dc_multiple_inheritance) {
00534 hashgen.add_int(_number);
00535 }
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 bool DCField::
00548 pack_default_value(DCPackData &pack_data, bool &) const {
00549
00550
00551
00552 if (!_default_value_stale) {
00553 pack_data.append_data(_default_value.data(), _default_value.length());
00554 return true;
00555 }
00556
00557 return false;
00558 }
00559
00560
00561
00562
00563
00564
00565 void DCField::
00566 set_name(const string &name) {
00567 DCPackerInterface::set_name(name);
00568 if (_dclass != (DCClass *)NULL) {
00569 _dclass->_dc_file->mark_inherited_fields_stale();
00570 }
00571 }
00572
00573 #ifdef HAVE_PYTHON
00574
00575
00576
00577
00578
00579
00580 string DCField::
00581 get_pystr(PyObject *value) {
00582 if (value == NULL) {
00583 return "(null)";
00584 }
00585
00586 PyObject *str = PyObject_Str(value);
00587 if (str != NULL) {
00588 string result = PyString_AsString(str);
00589 Py_DECREF(str);
00590 return result;
00591 }
00592
00593 PyObject *repr = PyObject_Repr(value);
00594 if (repr != NULL) {
00595 string result = PyString_AsString(repr);
00596 Py_DECREF(repr);
00597 return result;
00598 }
00599
00600 if (value->ob_type != NULL) {
00601 PyObject *typestr = PyObject_Str((PyObject *)(value->ob_type));
00602 if (typestr != NULL) {
00603 string result = PyString_AsString(typestr);
00604 Py_DECREF(typestr);
00605 return result;
00606 }
00607 }
00608
00609 return "(invalid object)";
00610 }
00611 #endif // HAVE_PYTHON
00612
00613
00614
00615
00616
00617
00618
00619 void DCField::
00620 refresh_default_value() {
00621 DCPacker packer;
00622 packer.begin_pack(this);
00623 packer.pack_default_value();
00624 if (!packer.end_pack()) {
00625 cerr << "Error while packing default value for " << get_name() << "\n";
00626 } else {
00627 _default_value.assign(packer.get_data(), packer.get_length());
00628 }
00629 _default_value_stale = false;
00630 }