/thirdparty/breakpad/third_party/protobuf/protobuf/python/google/protobuf/pyext/python-proto2.cc
C++ | 1660 lines | 1413 code | 184 blank | 63 comment | 208 complexity | b734479db7d2be23014ee74a35e84d98 MD5 | raw file
1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// http://code.google.com/p/protobuf/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31// Author: petar@google.com (Petar Petrov) 32 33#include <Python.h> 34#include <map> 35#include <string> 36#include <vector> 37 38#include <google/protobuf/stubs/common.h> 39#include <google/protobuf/pyext/python_descriptor.h> 40#include <google/protobuf/io/coded_stream.h> 41#include <google/protobuf/descriptor.h> 42#include <google/protobuf/dynamic_message.h> 43#include <google/protobuf/message.h> 44#include <google/protobuf/unknown_field_set.h> 45#include <google/protobuf/pyext/python_protobuf.h> 46 47/* Is 64bit */ 48#define IS_64BIT (SIZEOF_LONG == 8) 49 50#define FIELD_BELONGS_TO_MESSAGE(field_descriptor, message) \ 51 ((message)->GetDescriptor() == (field_descriptor)->containing_type()) 52 53#define FIELD_IS_REPEATED(field_descriptor) \ 54 ((field_descriptor)->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) 55 56#define GOOGLE_CHECK_GET_INT32(arg, value) \ 57 int32 value; \ 58 if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \ 59 return NULL; \ 60 } 61 62#define GOOGLE_CHECK_GET_INT64(arg, value) \ 63 int64 value; \ 64 if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \ 65 return NULL; \ 66 } 67 68#define GOOGLE_CHECK_GET_UINT32(arg, value) \ 69 uint32 value; \ 70 if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \ 71 return NULL; \ 72 } 73 74#define GOOGLE_CHECK_GET_UINT64(arg, value) \ 75 uint64 value; \ 76 if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \ 77 return NULL; \ 78 } 79 80#define GOOGLE_CHECK_GET_FLOAT(arg, value) \ 81 float value; \ 82 if (!CheckAndGetFloat(arg, &value)) { \ 83 return NULL; \ 84 } \ 85 86#define GOOGLE_CHECK_GET_DOUBLE(arg, value) \ 87 double value; \ 88 if (!CheckAndGetDouble(arg, &value)) { \ 89 return NULL; \ 90 } 91 92#define GOOGLE_CHECK_GET_BOOL(arg, value) \ 93 bool value; \ 94 if (!CheckAndGetBool(arg, &value)) { \ 95 return NULL; \ 96 } 97 98#define C(str) const_cast<char*>(str) 99 100// --- Globals: 101 102// Constants used for integer type range checking. 103static PyObject* kPythonZero; 104static PyObject* kint32min_py; 105static PyObject* kint32max_py; 106static PyObject* kuint32max_py; 107static PyObject* kint64min_py; 108static PyObject* kint64max_py; 109static PyObject* kuint64max_py; 110 111namespace google { 112namespace protobuf { 113namespace python { 114 115// --- Support Routines: 116 117static void AddConstants(PyObject* module) { 118 struct NameValue { 119 char* name; 120 int32 value; 121 } constants[] = { 122 // Labels: 123 {"LABEL_OPTIONAL", google::protobuf::FieldDescriptor::LABEL_OPTIONAL}, 124 {"LABEL_REQUIRED", google::protobuf::FieldDescriptor::LABEL_REQUIRED}, 125 {"LABEL_REPEATED", google::protobuf::FieldDescriptor::LABEL_REPEATED}, 126 // CPP types: 127 {"CPPTYPE_MESSAGE", google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE}, 128 // Field Types: 129 {"TYPE_MESSAGE", google::protobuf::FieldDescriptor::TYPE_MESSAGE}, 130 // End. 131 {NULL, 0} 132 }; 133 134 for (NameValue* constant = constants; 135 constant->name != NULL; constant++) { 136 PyModule_AddIntConstant(module, constant->name, constant->value); 137 } 138} 139 140// --- CMessage Custom Type: 141 142// ------ Type Forward Declaration: 143 144struct CMessage; 145struct CMessage_Type; 146 147static void CMessageDealloc(CMessage* self); 148static int CMessageInit(CMessage* self, PyObject *args, PyObject *kwds); 149static PyObject* CMessageStr(CMessage* self); 150 151static PyObject* CMessage_AddMessage(CMessage* self, PyObject* args); 152static PyObject* CMessage_AddRepeatedScalar(CMessage* self, PyObject* args); 153static PyObject* CMessage_AssignRepeatedScalar(CMessage* self, PyObject* args); 154static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args); 155static PyObject* CMessage_Clear(CMessage* self, PyObject* args); 156static PyObject* CMessage_ClearField(CMessage* self, PyObject* args); 157static PyObject* CMessage_ClearFieldByDescriptor( 158 CMessage* self, PyObject* args); 159static PyObject* CMessage_CopyFrom(CMessage* self, PyObject* args); 160static PyObject* CMessage_DebugString(CMessage* self, PyObject* args); 161static PyObject* CMessage_DeleteRepeatedField(CMessage* self, PyObject* args); 162static PyObject* CMessage_Equals(CMessage* self, PyObject* args); 163static PyObject* CMessage_FieldLength(CMessage* self, PyObject* args); 164static PyObject* CMessage_FindInitializationErrors(CMessage* self); 165static PyObject* CMessage_GetRepeatedMessage(CMessage* self, PyObject* args); 166static PyObject* CMessage_GetRepeatedScalar(CMessage* self, PyObject* args); 167static PyObject* CMessage_GetScalar(CMessage* self, PyObject* args); 168static PyObject* CMessage_HasField(CMessage* self, PyObject* args); 169static PyObject* CMessage_HasFieldByDescriptor(CMessage* self, PyObject* args); 170static PyObject* CMessage_IsInitialized(CMessage* self, PyObject* args); 171static PyObject* CMessage_ListFields(CMessage* self, PyObject* args); 172static PyObject* CMessage_MergeFrom(CMessage* self, PyObject* args); 173static PyObject* CMessage_MergeFromString(CMessage* self, PyObject* args); 174static PyObject* CMessage_MutableMessage(CMessage* self, PyObject* args); 175static PyObject* CMessage_NewSubMessage(CMessage* self, PyObject* args); 176static PyObject* CMessage_SetScalar(CMessage* self, PyObject* args); 177static PyObject* CMessage_SerializePartialToString( 178 CMessage* self, PyObject* args); 179static PyObject* CMessage_SerializeToString(CMessage* self, PyObject* args); 180static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args); 181static PyObject* CMessage_SwapRepeatedFieldElements( 182 CMessage* self, PyObject* args); 183 184// ------ Object Definition: 185 186typedef struct CMessage { 187 PyObject_HEAD 188 189 struct CMessage* parent; // NULL if wasn't created from another message. 190 CFieldDescriptor* parent_field; 191 const char* full_name; 192 google::protobuf::Message* message; 193 bool free_message; 194 bool read_only; 195} CMessage; 196 197// ------ Method Table: 198 199#define CMETHOD(name, args, doc) \ 200 { C(#name), (PyCFunction)CMessage_##name, args, C(doc) } 201static PyMethodDef CMessageMethods[] = { 202 CMETHOD(AddMessage, METH_O, 203 "Adds a new message to a repeated composite field."), 204 CMETHOD(AddRepeatedScalar, METH_VARARGS, 205 "Adds a scalar to a repeated scalar field."), 206 CMETHOD(AssignRepeatedScalar, METH_VARARGS, 207 "Clears and sets the values of a repeated scalar field."), 208 CMETHOD(ByteSize, METH_NOARGS, 209 "Returns the size of the message in bytes."), 210 CMETHOD(Clear, METH_NOARGS, 211 "Clears a protocol message."), 212 CMETHOD(ClearField, METH_O, 213 "Clears a protocol message field by name."), 214 CMETHOD(ClearFieldByDescriptor, METH_O, 215 "Clears a protocol message field by descriptor."), 216 CMETHOD(CopyFrom, METH_O, 217 "Copies a protocol message into the current message."), 218 CMETHOD(DebugString, METH_NOARGS, 219 "Returns the debug string of a protocol message."), 220 CMETHOD(DeleteRepeatedField, METH_VARARGS, 221 "Deletes a slice of values from a repeated field."), 222 CMETHOD(Equals, METH_O, 223 "Checks if two protocol messages are equal (by identity)."), 224 CMETHOD(FieldLength, METH_O, 225 "Returns the number of elements in a repeated field."), 226 CMETHOD(FindInitializationErrors, METH_NOARGS, 227 "Returns the initialization errors of a message."), 228 CMETHOD(GetRepeatedMessage, METH_VARARGS, 229 "Returns a message from a repeated composite field."), 230 CMETHOD(GetRepeatedScalar, METH_VARARGS, 231 "Returns a scalar value from a repeated scalar field."), 232 CMETHOD(GetScalar, METH_O, 233 "Returns the scalar value of a field."), 234 CMETHOD(HasField, METH_O, 235 "Checks if a message field is set."), 236 CMETHOD(HasFieldByDescriptor, METH_O, 237 "Checks if a message field is set by given its descriptor"), 238 CMETHOD(IsInitialized, METH_NOARGS, 239 "Checks if all required fields of a protocol message are set."), 240 CMETHOD(ListFields, METH_NOARGS, 241 "Lists all set fields of a message."), 242 CMETHOD(MergeFrom, METH_O, 243 "Merges a protocol message into the current message."), 244 CMETHOD(MergeFromString, METH_O, 245 "Merges a serialized message into the current message."), 246 CMETHOD(MutableMessage, METH_O, 247 "Returns a new instance of a nested protocol message."), 248 CMETHOD(NewSubMessage, METH_O, 249 "Creates and returns a python message given the descriptor of a " 250 "composite field of the current message."), 251 CMETHOD(SetScalar, METH_VARARGS, 252 "Sets the value of a singular scalar field."), 253 CMETHOD(SerializePartialToString, METH_VARARGS, 254 "Serializes the message to a string, even if it isn't initialized."), 255 CMETHOD(SerializeToString, METH_NOARGS, 256 "Serializes the message to a string, only for initialized messages."), 257 CMETHOD(SetInParent, METH_NOARGS, 258 "Sets the has bit of the given field in its parent message."), 259 CMETHOD(SwapRepeatedFieldElements, METH_VARARGS, 260 "Swaps the elements in two positions in a repeated field."), 261 { NULL, NULL } 262}; 263#undef CMETHOD 264 265static PyMemberDef CMessageMembers[] = { 266 { C("full_name"), T_STRING, offsetof(CMessage, full_name), 0, "Full name" }, 267 { NULL } 268}; 269 270// ------ Type Definition: 271 272// The definition for the type object that captures the type of CMessage 273// in Python. 274PyTypeObject CMessage_Type = { 275 PyObject_HEAD_INIT(&PyType_Type) 276 0, 277 C("google3.net.google.protobuf.python.internal." 278 "_net_proto2___python." 279 "CMessage"), // tp_name 280 sizeof(CMessage), // tp_basicsize 281 0, // tp_itemsize 282 (destructor)CMessageDealloc, // tp_dealloc 283 0, // tp_print 284 0, // tp_getattr 285 0, // tp_setattr 286 0, // tp_compare 287 0, // tp_repr 288 0, // tp_as_number 289 0, // tp_as_sequence 290 0, // tp_as_mapping 291 0, // tp_hash 292 0, // tp_call 293 (reprfunc)CMessageStr, // tp_str 294 0, // tp_getattro 295 0, // tp_setattro 296 0, // tp_as_buffer 297 Py_TPFLAGS_DEFAULT, // tp_flags 298 C("A ProtocolMessage"), // tp_doc 299 0, // tp_traverse 300 0, // tp_clear 301 0, // tp_richcompare 302 0, // tp_weaklistoffset 303 0, // tp_iter 304 0, // tp_iternext 305 CMessageMethods, // tp_methods 306 CMessageMembers, // tp_members 307 0, // tp_getset 308 0, // tp_base 309 0, // tp_dict 310 0, // tp_descr_get 311 0, // tp_descr_set 312 0, // tp_dictoffset 313 (initproc)CMessageInit, // tp_init 314 PyType_GenericAlloc, // tp_alloc 315 PyType_GenericNew, // tp_new 316 PyObject_Del, // tp_free 317}; 318 319// ------ Helper Functions: 320 321static void FormatTypeError(PyObject* arg, char* expected_types) { 322 PyObject* s = PyObject_Str(PyObject_Type(arg)); 323 PyObject* repr = PyObject_Repr(PyObject_Type(arg)); 324 PyErr_Format(PyExc_TypeError, 325 "%.100s has type %.100s, but expected one of: %s", 326 PyString_AS_STRING(repr), 327 PyString_AS_STRING(s), 328 expected_types); 329 Py_DECREF(s); 330 Py_DECREF(repr); 331} 332 333template <class T> 334static bool CheckAndGetInteger( 335 PyObject* arg, T* value, PyObject* min, PyObject* max) { 336 bool is_long = PyLong_Check(arg); 337 if (!PyInt_Check(arg) && !is_long) { 338 FormatTypeError(arg, "int, long"); 339 return false; 340 } 341 342 if (PyObject_Compare(min, arg) > 0 || PyObject_Compare(max, arg) < 0) { 343 PyObject* s = PyObject_Str(arg); 344 PyErr_Format(PyExc_ValueError, 345 "Value out of range: %s", 346 PyString_AS_STRING(s)); 347 Py_DECREF(s); 348 return false; 349 } 350 if (is_long) { 351 if (min == kPythonZero) { 352 *value = static_cast<T>(PyLong_AsUnsignedLongLong(arg)); 353 } else { 354 *value = static_cast<T>(PyLong_AsLongLong(arg)); 355 } 356 } else { 357 *value = static_cast<T>(PyInt_AsLong(arg)); 358 } 359 return true; 360} 361 362static bool CheckAndGetDouble(PyObject* arg, double* value) { 363 if (!PyInt_Check(arg) && !PyLong_Check(arg) && 364 !PyFloat_Check(arg)) { 365 FormatTypeError(arg, "int, long, float"); 366 return false; 367 } 368 *value = PyFloat_AsDouble(arg); 369 return true; 370} 371 372static bool CheckAndGetFloat(PyObject* arg, float* value) { 373 double double_value; 374 if (!CheckAndGetDouble(arg, &double_value)) { 375 return false; 376 } 377 *value = static_cast<float>(double_value); 378 return true; 379} 380 381static bool CheckAndGetBool(PyObject* arg, bool* value) { 382 if (!PyInt_Check(arg) && !PyBool_Check(arg) && !PyLong_Check(arg)) { 383 FormatTypeError(arg, "int, long, bool"); 384 return false; 385 } 386 *value = static_cast<bool>(PyInt_AsLong(arg)); 387 return true; 388} 389 390google::protobuf::DynamicMessageFactory* global_message_factory = NULL; 391static const google::protobuf::Message* CreateMessage(const char* message_type) { 392 string message_name(message_type); 393 const google::protobuf::Descriptor* descriptor = 394 GetDescriptorPool()->FindMessageTypeByName(message_name); 395 if (descriptor == NULL) { 396 return NULL; 397 } 398 return global_message_factory->GetPrototype(descriptor); 399} 400 401static bool CheckAndSetString( 402 PyObject* arg, google::protobuf::Message* message, 403 const google::protobuf::FieldDescriptor* descriptor, 404 const google::protobuf::Reflection* reflection, 405 bool append, 406 int index) { 407 GOOGLE_DCHECK(descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING || 408 descriptor->type() == google::protobuf::FieldDescriptor::TYPE_BYTES); 409 if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) { 410 if (!PyString_Check(arg) && !PyUnicode_Check(arg)) { 411 FormatTypeError(arg, "str, unicode"); 412 return false; 413 } 414 415 if (PyString_Check(arg)) { 416 PyObject* unicode = PyUnicode_FromEncodedObject(arg, "ascii", NULL); 417 if (unicode == NULL) { 418 PyObject* repr = PyObject_Repr(arg); 419 PyErr_Format(PyExc_ValueError, 420 "%s has type str, but isn't in 7-bit ASCII " 421 "encoding. Non-ASCII strings must be converted to " 422 "unicode objects before being added.", 423 PyString_AS_STRING(repr)); 424 Py_DECREF(repr); 425 return false; 426 } else { 427 Py_DECREF(unicode); 428 } 429 } 430 } else if (!PyString_Check(arg)) { 431 FormatTypeError(arg, "str"); 432 return false; 433 } 434 435 PyObject* encoded_string = NULL; 436 if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) { 437 if (PyString_Check(arg)) { 438 encoded_string = PyString_AsEncodedObject(arg, "utf-8", NULL); 439 } else { 440 encoded_string = PyUnicode_AsEncodedObject(arg, "utf-8", NULL); 441 } 442 } else { 443 // In this case field type is "bytes". 444 encoded_string = arg; 445 Py_INCREF(encoded_string); 446 } 447 448 if (encoded_string == NULL) { 449 return false; 450 } 451 452 char* value; 453 Py_ssize_t value_len; 454 if (PyString_AsStringAndSize(encoded_string, &value, &value_len) < 0) { 455 Py_DECREF(encoded_string); 456 return false; 457 } 458 459 string value_string(value, value_len); 460 if (append) { 461 reflection->AddString(message, descriptor, value_string); 462 } else if (index < 0) { 463 reflection->SetString(message, descriptor, value_string); 464 } else { 465 reflection->SetRepeatedString(message, descriptor, index, value_string); 466 } 467 Py_DECREF(encoded_string); 468 return true; 469} 470 471static PyObject* ToStringObject( 472 const google::protobuf::FieldDescriptor* descriptor, string value) { 473 if (descriptor->type() != google::protobuf::FieldDescriptor::TYPE_STRING) { 474 return PyString_FromStringAndSize(value.c_str(), value.length()); 475 } 476 477 PyObject* result = PyUnicode_DecodeUTF8(value.c_str(), value.length(), NULL); 478 // If the string can't be decoded in UTF-8, just return a string object that 479 // contains the raw bytes. This can't happen if the value was assigned using 480 // the members of the Python message object, but can happen if the values were 481 // parsed from the wire (binary). 482 if (result == NULL) { 483 PyErr_Clear(); 484 result = PyString_FromStringAndSize(value.c_str(), value.length()); 485 } 486 return result; 487} 488 489static void AssureWritable(CMessage* self) { 490 if (self == NULL || 491 self->parent == NULL || 492 self->parent_field == NULL) { 493 return; 494 } 495 496 if (!self->read_only) { 497 return; 498 } 499 500 AssureWritable(self->parent); 501 502 google::protobuf::Message* message = self->parent->message; 503 const google::protobuf::Reflection* reflection = message->GetReflection(); 504 self->message = reflection->MutableMessage( 505 message, self->parent_field->descriptor, global_message_factory); 506 self->read_only = false; 507 self->parent = NULL; 508 self->parent_field = NULL; 509} 510 511static PyObject* InternalGetScalar( 512 google::protobuf::Message* message, 513 const google::protobuf::FieldDescriptor* field_descriptor) { 514 const google::protobuf::Reflection* reflection = message->GetReflection(); 515 516 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { 517 PyErr_SetString( 518 PyExc_KeyError, "Field does not belong to message!"); 519 return NULL; 520 } 521 522 PyObject* result = NULL; 523 switch (field_descriptor->cpp_type()) { 524 case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { 525 int32 value = reflection->GetInt32(*message, field_descriptor); 526 result = PyInt_FromLong(value); 527 break; 528 } 529 case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { 530 int64 value = reflection->GetInt64(*message, field_descriptor); 531#if IS_64BIT 532 result = PyInt_FromLong(value); 533#else 534 result = PyLong_FromLongLong(value); 535#endif 536 break; 537 } 538 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { 539 uint32 value = reflection->GetUInt32(*message, field_descriptor); 540#if IS_64BIT 541 result = PyInt_FromLong(value); 542#else 543 result = PyLong_FromLongLong(value); 544#endif 545 break; 546 } 547 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { 548 uint64 value = reflection->GetUInt64(*message, field_descriptor); 549#if IS_64BIT 550 if (value <= static_cast<uint64>(kint64max)) { 551 result = PyInt_FromLong(static_cast<uint64>(value)); 552 } 553#else 554 if (value <= static_cast<uint32>(kint32max)) { 555 result = PyInt_FromLong(static_cast<uint32>(value)); 556 } 557#endif 558 else { // NOLINT 559 result = PyLong_FromUnsignedLongLong(value); 560 } 561 break; 562 } 563 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { 564 float value = reflection->GetFloat(*message, field_descriptor); 565 result = PyFloat_FromDouble(value); 566 break; 567 } 568 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { 569 double value = reflection->GetDouble(*message, field_descriptor); 570 result = PyFloat_FromDouble(value); 571 break; 572 } 573 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { 574 bool value = reflection->GetBool(*message, field_descriptor); 575 result = PyBool_FromLong(value); 576 break; 577 } 578 case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { 579 string value = reflection->GetString(*message, field_descriptor); 580 result = ToStringObject(field_descriptor, value); 581 break; 582 } 583 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { 584 if (!message->GetReflection()->HasField(*message, field_descriptor)) { 585 // Look for the value in the unknown fields. 586 google::protobuf::UnknownFieldSet* unknown_field_set = 587 message->GetReflection()->MutableUnknownFields(message); 588 for (int i = 0; i < unknown_field_set->field_count(); ++i) { 589 if (unknown_field_set->field(i).number() == 590 field_descriptor->number()) { 591 result = PyInt_FromLong(unknown_field_set->field(i).varint()); 592 break; 593 } 594 } 595 } 596 597 if (result == NULL) { 598 const google::protobuf::EnumValueDescriptor* enum_value = 599 message->GetReflection()->GetEnum(*message, field_descriptor); 600 result = PyInt_FromLong(enum_value->number()); 601 } 602 break; 603 } 604 default: 605 PyErr_Format( 606 PyExc_SystemError, "Getting a value from a field of unknown type %d", 607 field_descriptor->cpp_type()); 608 } 609 610 return result; 611} 612 613static PyObject* InternalSetScalar( 614 google::protobuf::Message* message, const google::protobuf::FieldDescriptor* field_descriptor, 615 PyObject* arg) { 616 const google::protobuf::Reflection* reflection = message->GetReflection(); 617 618 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { 619 PyErr_SetString( 620 PyExc_KeyError, "Field does not belong to message!"); 621 return NULL; 622 } 623 624 switch (field_descriptor->cpp_type()) { 625 case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { 626 GOOGLE_CHECK_GET_INT32(arg, value); 627 reflection->SetInt32(message, field_descriptor, value); 628 break; 629 } 630 case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { 631 GOOGLE_CHECK_GET_INT64(arg, value); 632 reflection->SetInt64(message, field_descriptor, value); 633 break; 634 } 635 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { 636 GOOGLE_CHECK_GET_UINT32(arg, value); 637 reflection->SetUInt32(message, field_descriptor, value); 638 break; 639 } 640 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { 641 GOOGLE_CHECK_GET_UINT64(arg, value); 642 reflection->SetUInt64(message, field_descriptor, value); 643 break; 644 } 645 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { 646 GOOGLE_CHECK_GET_FLOAT(arg, value); 647 reflection->SetFloat(message, field_descriptor, value); 648 break; 649 } 650 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { 651 GOOGLE_CHECK_GET_DOUBLE(arg, value); 652 reflection->SetDouble(message, field_descriptor, value); 653 break; 654 } 655 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { 656 GOOGLE_CHECK_GET_BOOL(arg, value); 657 reflection->SetBool(message, field_descriptor, value); 658 break; 659 } 660 case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { 661 if (!CheckAndSetString( 662 arg, message, field_descriptor, reflection, false, -1)) { 663 return NULL; 664 } 665 break; 666 } 667 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { 668 GOOGLE_CHECK_GET_INT32(arg, value); 669 const google::protobuf::EnumDescriptor* enum_descriptor = 670 field_descriptor->enum_type(); 671 const google::protobuf::EnumValueDescriptor* enum_value = 672 enum_descriptor->FindValueByNumber(value); 673 if (enum_value != NULL) { 674 reflection->SetEnum(message, field_descriptor, enum_value); 675 } else { 676 bool added = false; 677 // Add the value to the unknown fields. 678 google::protobuf::UnknownFieldSet* unknown_field_set = 679 message->GetReflection()->MutableUnknownFields(message); 680 for (int i = 0; i < unknown_field_set->field_count(); ++i) { 681 if (unknown_field_set->field(i).number() == 682 field_descriptor->number()) { 683 unknown_field_set->mutable_field(i)->set_varint(value); 684 added = true; 685 break; 686 } 687 } 688 689 if (!added) { 690 unknown_field_set->AddVarint(field_descriptor->number(), value); 691 } 692 reflection->ClearField(message, field_descriptor); 693 } 694 break; 695 } 696 default: 697 PyErr_Format( 698 PyExc_SystemError, "Setting value to a field of unknown type %d", 699 field_descriptor->cpp_type()); 700 } 701 702 Py_RETURN_NONE; 703} 704 705static PyObject* InternalAddRepeatedScalar( 706 google::protobuf::Message* message, const google::protobuf::FieldDescriptor* field_descriptor, 707 PyObject* arg) { 708 709 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { 710 PyErr_SetString( 711 PyExc_KeyError, "Field does not belong to message!"); 712 return NULL; 713 } 714 715 const google::protobuf::Reflection* reflection = message->GetReflection(); 716 switch (field_descriptor->cpp_type()) { 717 case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { 718 GOOGLE_CHECK_GET_INT32(arg, value); 719 reflection->AddInt32(message, field_descriptor, value); 720 break; 721 } 722 case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { 723 GOOGLE_CHECK_GET_INT64(arg, value); 724 reflection->AddInt64(message, field_descriptor, value); 725 break; 726 } 727 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { 728 GOOGLE_CHECK_GET_UINT32(arg, value); 729 reflection->AddUInt32(message, field_descriptor, value); 730 break; 731 } 732 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { 733 GOOGLE_CHECK_GET_UINT64(arg, value); 734 reflection->AddUInt64(message, field_descriptor, value); 735 break; 736 } 737 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { 738 GOOGLE_CHECK_GET_FLOAT(arg, value); 739 reflection->AddFloat(message, field_descriptor, value); 740 break; 741 } 742 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { 743 GOOGLE_CHECK_GET_DOUBLE(arg, value); 744 reflection->AddDouble(message, field_descriptor, value); 745 break; 746 } 747 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { 748 GOOGLE_CHECK_GET_BOOL(arg, value); 749 reflection->AddBool(message, field_descriptor, value); 750 break; 751 } 752 case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { 753 if (!CheckAndSetString( 754 arg, message, field_descriptor, reflection, true, -1)) { 755 return NULL; 756 } 757 break; 758 } 759 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { 760 GOOGLE_CHECK_GET_INT32(arg, value); 761 const google::protobuf::EnumDescriptor* enum_descriptor = 762 field_descriptor->enum_type(); 763 const google::protobuf::EnumValueDescriptor* enum_value = 764 enum_descriptor->FindValueByNumber(value); 765 if (enum_value != NULL) { 766 reflection->AddEnum(message, field_descriptor, enum_value); 767 } else { 768 PyObject* s = PyObject_Str(arg); 769 PyErr_Format(PyExc_ValueError, "Unknown enum value: %s", 770 PyString_AS_STRING(s)); 771 Py_DECREF(s); 772 return NULL; 773 } 774 break; 775 } 776 default: 777 PyErr_Format( 778 PyExc_SystemError, "Adding value to a field of unknown type %d", 779 field_descriptor->cpp_type()); 780 } 781 782 Py_RETURN_NONE; 783} 784 785static PyObject* InternalGetRepeatedScalar( 786 CMessage* cmessage, const google::protobuf::FieldDescriptor* field_descriptor, 787 int index) { 788 google::protobuf::Message* message = cmessage->message; 789 const google::protobuf::Reflection* reflection = message->GetReflection(); 790 791 int field_size = reflection->FieldSize(*message, field_descriptor); 792 if (index < 0) { 793 index = field_size + index; 794 } 795 if (index < 0 || index >= field_size) { 796 PyErr_Format(PyExc_IndexError, 797 "list assignment index (%d) out of range", index); 798 return NULL; 799 } 800 801 PyObject* result = NULL; 802 switch (field_descriptor->cpp_type()) { 803 case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { 804 int32 value = reflection->GetRepeatedInt32( 805 *message, field_descriptor, index); 806 result = PyInt_FromLong(value); 807 break; 808 } 809 case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { 810 int64 value = reflection->GetRepeatedInt64( 811 *message, field_descriptor, index); 812 result = PyLong_FromLongLong(value); 813 break; 814 } 815 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { 816 uint32 value = reflection->GetRepeatedUInt32( 817 *message, field_descriptor, index); 818 result = PyLong_FromLongLong(value); 819 break; 820 } 821 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { 822 uint64 value = reflection->GetRepeatedUInt64( 823 *message, field_descriptor, index); 824 result = PyLong_FromUnsignedLongLong(value); 825 break; 826 } 827 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { 828 float value = reflection->GetRepeatedFloat( 829 *message, field_descriptor, index); 830 result = PyFloat_FromDouble(value); 831 break; 832 } 833 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { 834 double value = reflection->GetRepeatedDouble( 835 *message, field_descriptor, index); 836 result = PyFloat_FromDouble(value); 837 break; 838 } 839 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { 840 bool value = reflection->GetRepeatedBool( 841 *message, field_descriptor, index); 842 result = PyBool_FromLong(value ? 1 : 0); 843 break; 844 } 845 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { 846 const google::protobuf::EnumValueDescriptor* enum_value = 847 message->GetReflection()->GetRepeatedEnum( 848 *message, field_descriptor, index); 849 result = PyInt_FromLong(enum_value->number()); 850 break; 851 } 852 case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { 853 string value = reflection->GetRepeatedString( 854 *message, field_descriptor, index); 855 result = ToStringObject(field_descriptor, value); 856 break; 857 } 858 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: { 859 CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); 860 if (py_cmsg == NULL) { 861 return NULL; 862 } 863 const google::protobuf::Message& msg = reflection->GetRepeatedMessage( 864 *message, field_descriptor, index); 865 py_cmsg->parent = cmessage; 866 py_cmsg->full_name = field_descriptor->full_name().c_str(); 867 py_cmsg->message = const_cast<google::protobuf::Message*>(&msg); 868 py_cmsg->free_message = false; 869 py_cmsg->read_only = false; 870 result = reinterpret_cast<PyObject*>(py_cmsg); 871 break; 872 } 873 default: 874 PyErr_Format( 875 PyExc_SystemError, 876 "Getting value from a repeated field of unknown type %d", 877 field_descriptor->cpp_type()); 878 } 879 880 return result; 881} 882 883static PyObject* InternalGetRepeatedScalarSlice( 884 CMessage* cmessage, const google::protobuf::FieldDescriptor* field_descriptor, 885 PyObject* slice) { 886 Py_ssize_t from; 887 Py_ssize_t to; 888 Py_ssize_t step; 889 Py_ssize_t length; 890 bool return_list = false; 891 google::protobuf::Message* message = cmessage->message; 892 893 if (PyInt_Check(slice)) { 894 from = to = PyInt_AsLong(slice); 895 } else if (PyLong_Check(slice)) { 896 from = to = PyLong_AsLong(slice); 897 } else if (PySlice_Check(slice)) { 898 const google::protobuf::Reflection* reflection = message->GetReflection(); 899 length = reflection->FieldSize(*message, field_descriptor); 900 PySlice_GetIndices( 901 reinterpret_cast<PySliceObject*>(slice), length, &from, &to, &step); 902 return_list = true; 903 } else { 904 PyErr_SetString(PyExc_TypeError, "list indices must be integers"); 905 return NULL; 906 } 907 908 if (!return_list) { 909 return InternalGetRepeatedScalar(cmessage, field_descriptor, from); 910 } 911 912 PyObject* list = PyList_New(0); 913 if (list == NULL) { 914 return NULL; 915 } 916 917 if (from <= to) { 918 if (step < 0) return list; 919 for (Py_ssize_t index = from; index < to; index += step) { 920 if (index < 0 || index >= length) break; 921 PyObject* s = InternalGetRepeatedScalar( 922 cmessage, field_descriptor, index); 923 PyList_Append(list, s); 924 Py_DECREF(s); 925 } 926 } else { 927 if (step > 0) return list; 928 for (Py_ssize_t index = from; index > to; index += step) { 929 if (index < 0 || index >= length) break; 930 PyObject* s = InternalGetRepeatedScalar( 931 cmessage, field_descriptor, index); 932 PyList_Append(list, s); 933 Py_DECREF(s); 934 } 935 } 936 return list; 937} 938 939// ------ C Constructor/Destructor: 940 941static int CMessageInit(CMessage* self, PyObject *args, PyObject *kwds) { 942 self->message = NULL; 943 return 0; 944} 945 946static void CMessageDealloc(CMessage* self) { 947 if (self->free_message) { 948 if (self->read_only) { 949 PyErr_WriteUnraisable(reinterpret_cast<PyObject*>(self)); 950 } 951 delete self->message; 952 } 953 self->ob_type->tp_free(reinterpret_cast<PyObject*>(self)); 954} 955 956// ------ Methods: 957 958static PyObject* CMessage_Clear(CMessage* self, PyObject* args) { 959 AssureWritable(self); 960 self->message->Clear(); 961 Py_RETURN_NONE; 962} 963 964static PyObject* CMessage_IsInitialized(CMessage* self, PyObject* args) { 965 return PyBool_FromLong(self->message->IsInitialized() ? 1 : 0); 966} 967 968static PyObject* CMessage_HasField(CMessage* self, PyObject* arg) { 969 char* field_name; 970 if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) { 971 return NULL; 972 } 973 974 google::protobuf::Message* message = self->message; 975 const google::protobuf::Descriptor* descriptor = message->GetDescriptor(); 976 const google::protobuf::FieldDescriptor* field_descriptor = 977 descriptor->FindFieldByName(field_name); 978 if (field_descriptor == NULL) { 979 PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name); 980 return NULL; 981 } 982 983 bool has_field = 984 message->GetReflection()->HasField(*message, field_descriptor); 985 return PyBool_FromLong(has_field ? 1 : 0); 986} 987 988static PyObject* CMessage_HasFieldByDescriptor(CMessage* self, PyObject* arg) { 989 CFieldDescriptor* cfield_descriptor = NULL; 990 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), 991 &CFieldDescriptor_Type)) { 992 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); 993 return NULL; 994 } 995 cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg); 996 997 google::protobuf::Message* message = self->message; 998 const google::protobuf::FieldDescriptor* field_descriptor = 999 cfield_descriptor->descriptor; 1000 1001 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { 1002 PyErr_SetString(PyExc_KeyError, 1003 "Field does not belong to message!"); 1004 return NULL; 1005 } 1006 1007 if (FIELD_IS_REPEATED(field_descriptor)) { 1008 PyErr_SetString(PyExc_KeyError, 1009 "Field is repeated. A singular method is required."); 1010 return NULL; 1011 } 1012 1013 bool has_field = 1014 message->GetReflection()->HasField(*message, field_descriptor); 1015 return PyBool_FromLong(has_field ? 1 : 0); 1016} 1017 1018static PyObject* CMessage_ClearFieldByDescriptor( 1019 CMessage* self, PyObject* arg) { 1020 CFieldDescriptor* cfield_descriptor = NULL; 1021 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), 1022 &CFieldDescriptor_Type)) { 1023 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); 1024 return NULL; 1025 } 1026 cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg); 1027 1028 google::protobuf::Message* message = self->message; 1029 const google::protobuf::FieldDescriptor* field_descriptor = 1030 cfield_descriptor->descriptor; 1031 1032 if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { 1033 PyErr_SetString(PyExc_KeyError, 1034 "Field does not belong to message!"); 1035 return NULL; 1036 } 1037 1038 message->GetReflection()->ClearField(message, field_descriptor); 1039 Py_RETURN_NONE; 1040} 1041 1042static PyObject* CMessage_ClearField(CMessage* self, PyObject* arg) { 1043 char* field_name; 1044 if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) { 1045 return NULL; 1046 } 1047 1048 google::protobuf::Message* message = self->message; 1049 const google::protobuf::Descriptor* descriptor = message->GetDescriptor(); 1050 const google::protobuf::FieldDescriptor* field_descriptor = 1051 descriptor->FindFieldByName(field_name); 1052 if (field_descriptor == NULL) { 1053 PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name); 1054 return NULL; 1055 } 1056 1057 message->GetReflection()->ClearField(message, field_descriptor); 1058 Py_RETURN_NONE; 1059} 1060 1061static PyObject* CMessage_GetScalar(CMessage* self, PyObject* arg) { 1062 CFieldDescriptor* cdescriptor = NULL; 1063 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), 1064 &CFieldDescriptor_Type)) { 1065 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); 1066 return NULL; 1067 } 1068 cdescriptor = reinterpret_cast<CFieldDescriptor*>(arg); 1069 1070 google::protobuf::Message* message = self->message; 1071 return InternalGetScalar(message, cdescriptor->descriptor); 1072} 1073 1074static PyObject* CMessage_GetRepeatedScalar(CMessage* self, PyObject* args) { 1075 CFieldDescriptor* cfield_descriptor; 1076 PyObject* slice; 1077 if (!PyArg_ParseTuple(args, C("O!O:GetRepeatedScalar"), 1078 &CFieldDescriptor_Type, &cfield_descriptor, &slice)) { 1079 return NULL; 1080 } 1081 1082 return InternalGetRepeatedScalarSlice( 1083 self, cfield_descriptor->descriptor, slice); 1084} 1085 1086static PyObject* CMessage_AssignRepeatedScalar(CMessage* self, PyObject* args) { 1087 CFieldDescriptor* cfield_descriptor; 1088 PyObject* slice; 1089 if (!PyArg_ParseTuple(args, C("O!O:AssignRepeatedScalar"), 1090 &CFieldDescriptor_Type, &cfield_descriptor, &slice)) { 1091 return NULL; 1092 } 1093 1094 AssureWritable(self); 1095 google::protobuf::Message* message = self->message; 1096 message->GetReflection()->ClearField(message, cfield_descriptor->descriptor); 1097 1098 PyObject* iter = PyObject_GetIter(slice); 1099 PyObject* next; 1100 while ((next = PyIter_Next(iter)) != NULL) { 1101 if (InternalAddRepeatedScalar( 1102 message, cfield_descriptor->descriptor, next) == NULL) { 1103 Py_DECREF(next); 1104 Py_DECREF(iter); 1105 return NULL; 1106 } 1107 Py_DECREF(next); 1108 } 1109 Py_DECREF(iter); 1110 Py_RETURN_NONE; 1111} 1112 1113static PyObject* CMessage_DeleteRepeatedField(CMessage* self, PyObject* args) { 1114 CFieldDescriptor* cfield_descriptor; 1115 PyObject* slice; 1116 if (!PyArg_ParseTuple(args, C("O!O:DeleteRepeatedField"), 1117 &CFieldDescriptor_Type, &cfield_descriptor, &slice)) { 1118 return NULL; 1119 } 1120 AssureWritable(self); 1121 1122 Py_ssize_t length, from, to, step, slice_length; 1123 google::protobuf::Message* message = self->message; 1124 const google::protobuf::FieldDescriptor* field_descriptor = 1125 cfield_descriptor->descriptor; 1126 const google::protobuf::Reflection* reflection = message->GetReflection(); 1127 int min, max; 1128 length = reflection->FieldSize(*message, field_descriptor); 1129 1130 if (PyInt_Check(slice) || PyLong_Check(slice)) { 1131 from = to = PyLong_AsLong(slice); 1132 if (from < 0) { 1133 from = to = length + from; 1134 } 1135 step = 1; 1136 min = max = from; 1137 1138 // Range check. 1139 if (from < 0 || from >= length) { 1140 PyErr_Format(PyExc_IndexError, "list assignment index out of range"); 1141 return NULL; 1142 } 1143 } else if (PySlice_Check(slice)) { 1144 from = to = step = slice_length = 0; 1145 PySlice_GetIndicesEx( 1146 reinterpret_cast<PySliceObject*>(slice), 1147 length, &from, &to, &step, &slice_length); 1148 if (from < to) { 1149 min = from; 1150 max = to - 1; 1151 } else { 1152 min = to + 1; 1153 max = from; 1154 } 1155 } else { 1156 PyErr_SetString(PyExc_TypeError, "list indices must be integers"); 1157 return NULL; 1158 } 1159 1160 Py_ssize_t i = from; 1161 std::vector<bool> to_delete(length, false); 1162 while (i >= min && i <= max) { 1163 to_delete[i] = true; 1164 i += step; 1165 } 1166 1167 to = 0; 1168 for (i = 0; i < length; ++i) { 1169 if (!to_delete[i]) { 1170 if (i != to) { 1171 reflection->SwapElements(message, field_descriptor, i, to); 1172 } 1173 ++to; 1174 } 1175 } 1176 1177 while (i > to) { 1178 reflection->RemoveLast(message, field_descriptor); 1179 --i; 1180 } 1181 1182 Py_RETURN_NONE; 1183} 1184 1185 1186static PyObject* CMessage_SetScalar(CMessage* self, PyObject* args) { 1187 CFieldDescriptor* cfield_descriptor; 1188 PyObject* arg; 1189 if (!PyArg_ParseTuple(args, C("O!O:SetScalar"), 1190 &CFieldDescriptor_Type, &cfield_descriptor, &arg)) { 1191 return NULL; 1192 } 1193 AssureWritable(self); 1194 1195 return InternalSetScalar(self->message, cfield_descriptor->descriptor, arg); 1196} 1197 1198static PyObject* CMessage_AddRepeatedScalar(CMessage* self, PyObject* args) { 1199 CFieldDescriptor* cfield_descriptor; 1200 PyObject* value; 1201 if (!PyArg_ParseTuple(args, C("O!O:AddRepeatedScalar"), 1202 &CFieldDescriptor_Type, &cfield_descriptor, &value)) { 1203 return NULL; 1204 } 1205 AssureWritable(self); 1206 1207 return InternalAddRepeatedScalar( 1208 self->message, cfield_descriptor->descriptor, value); 1209} 1210 1211static PyObject* CMessage_FieldLength(CMessage* self, PyObject* arg) { 1212 CFieldDescriptor* cfield_descriptor; 1213 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), 1214 &CFieldDescriptor_Type)) { 1215 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); 1216 return NULL; 1217 } 1218 cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg); 1219 1220 google::protobuf::Message* message = self->message; 1221 int length = message->GetReflection()->FieldSize( 1222 *message, cfield_descriptor->descriptor); 1223 return PyInt_FromLong(length); 1224} 1225 1226static PyObject* CMessage_DebugString(CMessage* self, PyObject* args) { 1227 return PyString_FromString(self->message->DebugString().c_str()); 1228} 1229 1230static PyObject* CMessage_SerializeToString(CMessage* self, PyObject* args) { 1231 int size = self->message->ByteSize(); 1232 if (size <= 0) { 1233 return PyString_FromString(""); 1234 } 1235 PyObject* result = PyString_FromStringAndSize(NULL, size); 1236 if (result == NULL) { 1237 return NULL; 1238 } 1239 char* buffer = PyString_AS_STRING(result); 1240 self->message->SerializeWithCachedSizesToArray( 1241 reinterpret_cast<uint8*>(buffer)); 1242 return result; 1243} 1244 1245static PyObject* CMessage_SerializePartialToString( 1246 CMessage* self, PyObject* args) { 1247 string contents; 1248 self->message->SerializePartialToString(&contents); 1249 return PyString_FromStringAndSize(contents.c_str(), contents.size()); 1250} 1251 1252static PyObject* CMessageStr(CMessage* self) { 1253 char str[1024]; 1254 str[sizeof(str) - 1] = 0; 1255 snprintf(str, sizeof(str) - 1, "CMessage: <%p>", self->message); 1256 return PyString_FromString(str); 1257} 1258 1259static PyObject* CMessage_MergeFrom(CMessage* self, PyObject* arg) { 1260 CMessage* other_message; 1261 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) { 1262 PyErr_SetString(PyExc_TypeError, "Must be a message"); 1263 return NULL; 1264 } 1265 1266 other_message = reinterpret_cast<CMessage*>(arg); 1267 if (other_message->message->GetDescriptor() != 1268 self->message->GetDescriptor()) { 1269 PyErr_Format(PyExc_TypeError, 1270 "Tried to merge from a message with a different type. " 1271 "to: %s, from: %s", 1272 self->message->GetDescriptor()->full_name().c_str(), 1273 other_message->message->GetDescriptor()->full_name().c_str()); 1274 return NULL; 1275 } 1276 AssureWritable(self); 1277 1278 self->message->MergeFrom(*other_message->message); 1279 Py_RETURN_NONE; 1280} 1281 1282static PyObject* CMessage_CopyFrom(CMessage* self, PyObject* arg) { 1283 CMessage* other_message; 1284 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) { 1285 PyErr_SetString(PyExc_TypeError, "Must be a message"); 1286 return NULL; 1287 } 1288 1289 other_message = reinterpret_cast<CMessage*>(arg); 1290 if (other_message->message->GetDescriptor() != 1291 self->message->GetDescriptor()) { 1292 PyErr_Format(PyExc_TypeError, 1293 "Tried to copy from a message with a different type. " 1294 "to: %s, from: %s", 1295 self->message->GetDescriptor()->full_name().c_str(), 1296 other_message->message->GetDescriptor()->full_name().c_str()); 1297 return NULL; 1298 } 1299 1300 AssureWritable(self); 1301 1302 self->message->CopyFrom(*other_message->message); 1303 Py_RETURN_NONE; 1304} 1305 1306static PyObject* CMessage_MergeFromString(CMessage* self, PyObject* arg) { 1307 const void* data; 1308 Py_ssize_t data_length; 1309 if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) { 1310 return NULL; 1311 } 1312 1313 AssureWritable(self); 1314 google::protobuf::io::CodedInputStream input( 1315 reinterpret_cast<const uint8*>(data), data_length); 1316 bool success = self->message->MergePartialFromCodedStream(&input); 1317 if (success) { 1318 return PyInt_FromLong(self->message->ByteSize()); 1319 } else { 1320 return PyInt_FromLong(-1); 1321 } 1322} 1323 1324static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args) { 1325 return PyLong_FromLong(self->message->ByteSize()); 1326} 1327 1328static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args) { 1329 AssureWritable(self); 1330 Py_RETURN_NONE; 1331} 1332 1333static PyObject* CMessage_SwapRepeatedFieldElements( 1334 CMessage* self, PyObject* args) { 1335 CFieldDescriptor* cfield_descriptor; 1336 int index1, index2; 1337 if (!PyArg_ParseTuple(args, C("O!ii:SwapRepeatedFieldElements"), 1338 &CFieldDescriptor_Type, &cfield_descriptor, 1339 &index1, &index2)) { 1340 return NULL; 1341 } 1342 1343 google::protobuf::Message* message = self->message; 1344 const google::protobuf::Reflection* reflection = message->GetReflection(); 1345 1346 reflection->SwapElements( 1347 message, cfield_descriptor->descriptor, index1, index2); 1348 Py_RETURN_NONE; 1349} 1350 1351static PyObject* CMessage_AddMessage(CMessage* self, PyObject* arg) { 1352 CFieldDescriptor* cfield_descriptor; 1353 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), 1354 &CFieldDescriptor_Type)) { 1355 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); 1356 return NULL; 1357 } 1358 cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg); 1359 AssureWritable(self); 1360 1361 CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); 1362 if (py_cmsg == NULL) { 1363 return NULL; 1364 } 1365 1366 google::protobuf::Message* message = self->message; 1367 const google::protobuf::Reflection* reflection = message->GetReflection(); 1368 google::protobuf::Message* sub_message = 1369 reflection->AddMessage(message, cfield_descriptor->descriptor); 1370 1371 py_cmsg->parent = NULL; 1372 py_cmsg->full_name = sub_message->GetDescriptor()->full_name().c_str(); 1373 py_cmsg->message = sub_message; 1374 py_cmsg->free_message = false; 1375 py_cmsg->read_only = false; 1376 return reinterpret_cast<PyObject*>(py_cmsg); 1377} 1378 1379static PyObject* CMessage_GetRepeatedMessage(CMessage* self, PyObject* args) { 1380 CFieldDescriptor* cfield_descriptor; 1381 PyObject* slice; 1382 if (!PyArg_ParseTuple(args, C("O!O:GetRepeatedMessage"), 1383 &CFieldDescriptor_Type, &cfield_descriptor, &slice)) { 1384 return NULL; 1385 } 1386 1387 return InternalGetRepeatedScalarSlice( 1388 self, cfield_descriptor->descriptor, slice); 1389} 1390 1391static PyObject* CMessage_NewSubMessage(CMessage* self, PyObject* arg) { 1392 CFieldDescriptor* cfield_descriptor; 1393 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), 1394 &CFieldDescriptor_Type)) { 1395 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); 1396 return NULL; 1397 } 1398 cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg); 1399 1400 CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); 1401 if (py_cmsg == NULL) { 1402 return NULL; 1403 } 1404 1405 google::protobuf::Message* message = self->message; 1406 const google::protobuf::Reflection* reflection = message->GetReflection(); 1407 const google::protobuf::Message& sub_message = 1408 reflection->GetMessage(*message, cfield_descriptor->descriptor, 1409 global_message_factory); 1410 1411 py_cmsg->full_name = sub_message.GetDescriptor()->full_name().c_str(); 1412 py_cmsg->parent = self; 1413 py_cmsg->parent_field = cfield_descriptor; 1414 py_cmsg->message = const_cast<google::protobuf::Message*>(&sub_message); 1415 py_cmsg->free_message = false; 1416 py_cmsg->read_only = true; 1417 return reinterpret_cast<PyObject*>(py_cmsg); 1418} 1419 1420static PyObject* CMessage_MutableMessage(CMessage* self, PyObject* arg) { 1421 CFieldDescriptor* cfield_descriptor; 1422 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), 1423 &CFieldDescriptor_Type)) { 1424 PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); 1425 return NULL; 1426 } 1427 cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg); 1428 AssureWritable(self); 1429 1430 CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); 1431 if (py_cmsg == NULL) { 1432 return NULL; 1433 } 1434 1435 google::protobuf::Message* message = self->message; 1436 const google::protobuf::Reflection* reflection = message->GetReflection(); 1437 google::protobuf::Message* mutable_message = 1438 reflection->MutableMessage(message, cfield_descriptor->descriptor, 1439 global_message_factory); 1440 1441 py_cmsg->full_name = mutable_message->GetDescriptor()->full_name().c_str(); 1442 py_cmsg->message = mutable_message; 1443 py_cmsg->free_message = false; 1444 py_cmsg->read_only = false; 1445 return reinterpret_cast<PyObject*>(py_cmsg); 1446} 1447 1448static PyObject* CMessage_Equals(CMessage* self, PyObject* arg) { 1449 CMessage* other_message; 1450 if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) { 1451 PyErr_SetString(PyExc_TypeError, "Must be a message"); 1452 return NULL; 1453 } 1454 other_message = reinterpret_cast<CMessage*>(arg); 1455 1456 if (other_message->message == self->message) { 1457 return PyBool_FromLong(1); 1458 } 1459 1460 if (other_message->message->GetDescriptor() != 1461 self->message->GetDescriptor()) { 1462 return PyBool_FromLong(0); 1463 } 1464 1465 return PyBool_FromLong(1); 1466} 1467 1468static PyObject* CMessage_ListFields(CMessage* self, PyObject* args) { 1469 google::protobuf::Message* message = self->message; 1470 const google::protobuf::Reflection* reflection = message->GetReflection(); 1471 vector<const google::protobuf::FieldDescriptor*> fields; 1472 reflection->ListFields(*message, &fields); 1473 1474 PyObject* list = PyList_New(fields.size()); 1475 if (list == NULL) { 1476 return NULL; 1477 } 1478 1479 for (unsigned int i = 0; i < fields.size(); ++i) { 1480 bool is_extension = fields[i]->is_extension(); 1481 PyObject* t = PyTuple_New(2); 1482 if (t == NULL) { 1483 Py_DECREF(list); 1484 return NULL; 1485 } 1486 1487 PyObject* is_extension_object = PyBool_FromLong(is_extension ? 1 : 0); 1488 1489 PyObject* field_name; 1490 const string* s; 1491 if (is_extension) { 1492 s = &fields[i]->full_name(); 1493 } else { 1494 s = &fields[i]->name(); 1495 } 1496 field_name = PyString_FromStringAndSize(s->c_str(), s->length()); 1497 if (field_name == NULL) { 1498 Py_DECREF(list); 1499 Py_DECREF(t); 1500 return NULL; 1501 } 1502 1503 PyTuple_SET_ITEM(t, 0, is_extension_object); 1504 PyTuple_SET_ITEM(t, 1, field_name); 1505 PyList_SET_ITEM(list, i, t); 1506 } 1507 1508 return list; 1509} 1510 1511static PyObject* CMessage_FindInitializationErrors(CMessage* self) { 1512 google::protobuf::Message* message = self->message; 1513 vector<string> errors; 1514 message->FindInitializationErrors(&errors); 1515 1516 PyObject* error_list = PyList_New(errors.size()); 1517 if (error_list == NULL) { 1518 return NULL; 1519 } 1520 for (unsigned int i = 0; i < errors.size(); ++i) { 1521 const string& error = errors[i]; 1522 PyObject* error_string = PyString_FromStringAndSize( 1523 error.c_str(), error.length()); 1524 if (error_string == NULL) { 1525 Py_DECREF(error_list); 1526 return NULL; 1527 } 1528 PyList_SET_ITEM(error_list, i, error_string); 1529 } 1530 return error_list; 1531} 1532 1533// ------ Python Constructor: 1534 1535PyObject* Python_NewCMessage(PyObject* ignored, PyObject* arg) { 1536 const char* message_type = PyString_AsString(arg); 1537 if (message_type == NULL) { 1538 return NULL; 1539 } 1540 1541 const google::protobuf::Message* message = CreateMessage(message_type); 1542 if (message == NULL) { 1543 PyErr_Format(PyExc_TypeError, "Couldn't create message of type %s!", 1544 message_type); 1545 return NULL; 1546 } 1547 1548 CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); 1549 if (py_cmsg == NULL) { 1550 return NULL; 1551 } 1552 py_cmsg->message = message->New(); 1553 py_cmsg->free_message = true; 1554 py_cmsg->full_name = message->GetDescriptor()->full_name().c_str(); 1555 py_cmsg->read_only = false; 1556 py_cmsg->parent = NULL; 1557 py_cmsg->parent_field = NULL; 1558 return reinterpret_cast<PyObject*>(py_cmsg); 1559} 1560 1561// --- Module Functions (exposed to Python): 1562 1563PyMethodDef methods[] = { 1564 { C("NewCMessage"), (PyCFunction)Python_NewCMessage, 1565 METH_O, 1566 C("Creates a new C++ protocol message, given its full name.") }, 1567 { C("NewCDescriptorPool"), (PyCFunction)Python_NewCDescriptorPool, 1568 METH_NOARGS, 1569 C("Creates a new C++ descriptor pool.") }, 1570 { C("BuildFile"), (PyCFunction)Python_BuildFile, 1571 METH_O, 1572 C("Registers a new protocol buffer file in the global C++ descriptor " 1573 "pool.") }, 1574 {NULL} 1575}; 1576 1577// --- Exposing the C proto living inside Python proto to C code: 1578 1579extern const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg); 1580extern Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg); 1581 1582static const google::protobuf::Message* GetCProtoInsidePyProtoImpl(PyObject* msg) { 1583 PyObject* c_msg_obj = PyObject_GetAttrString(msg, "_cmsg"); 1584 if (c_msg_obj == NULL) { 1585 PyErr_Clear(); 1586 return NULL; 1587 } 1588 Py_DECREF(c_msg_obj); 1589 if (!PyObject_TypeCheck(c_msg_obj, &CMessage_Type)) { 1590 return NULL; 1591 } 1592 CMessage* c_msg = reinterpret_cast<CMessage*>(c_msg_obj); 1593 return c_msg->message; 1594} 1595 1596static google::protobuf::Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) { 1597 PyObject* c_msg_obj = PyObject_GetAttrString(msg, "_cmsg"); 1598 if (c_msg_obj == NULL) { 1599 PyErr_Clear(); 1600 return NULL; 1601 } 1602 Py_DECREF(c_msg_obj); 1603 if (!PyObject_TypeCheck(c_msg_obj, &CMessage_Type)) { 1604 return NULL; 1605 } 1606 CMessage* c_msg = reinterpret_cast<CMessage*>(c_msg_obj); 1607 AssureWritable(c_msg); 1608 return c_msg->message; 1609} 1610 1611// --- Module Init Function: 1612 1613static const char module_docstring[] = 1614"python-proto2 is a module that can be used to enhance proto2 Python API\n" 1615"performance.\n" 1616"\n" 1617"It provides access to the protocol buffers C++ reflection API that\n" 1618"implements the basic protocol buffer functions."; 1619 1620extern "C" { 1621 void init_net_proto2___python() { 1622 // Initialize constants. 1623 kPythonZero = PyInt_FromLong(0); 1624 kint32min_py = PyInt_FromLong(kint32min); 1625 kint32max_py = PyInt_FromLong(kint32max); 1626 kuint32max_py = PyLong_FromLongLong(kuint32max); 1627 kint64min_py = PyLong_FromLongLong(kint64min); 1628 kint64max_py = PyLong_FromLongLong(kint64max); 1629 kuint64max_py = PyLong_FromUnsignedLongLong(kuint64max); 1630 1631 global_message_factory = new DynamicMessageFactory(GetDescriptorPool()); 1632 global_message_factory->SetDelegateToGeneratedFactory(true); 1633 1634 // Export our functions to Python. 1635 PyObject *m; 1636 m = Py_InitModule3(C("_net_proto2___python"), methods, C(module_docstring)); 1637 if (m == NULL) { 1638 return; 1639 } 1640 1641 AddConstants(m); 1642 1643 CMessage_Type.tp_new = PyType_GenericNew; 1644 if (PyType_Ready(&CMessage_Type) < 0) { 1645 return; 1646 } 1647 1648 if (!InitDescriptor()) { 1649 return; 1650 } 1651 1652 // Override {Get,Mutable}CProtoInsidePyProto. 1653 GetCProtoInsidePyProtoPtr = GetCProtoInsidePyProtoImpl; 1654 MutableCProtoInsidePyProtoPtr = MutableCProtoInsidePyProtoImpl; 1655 } 1656} 1657 1658} // namespace python 1659} // namespace protobuf 1660} // namespace google