/** This function gets the (assumed to be set) integer field's value from the message and casts it to a int64_t value. @param inputMessage: The message to retrieve the integer from @param inputField: The specific field to retrieve it from @throw: This function can throw exceptions */ int64_t pylongps::getIntegerFieldValue(const google::protobuf::Message &inputMessage, const google::protobuf::FieldDescriptor *inputField) { const google::protobuf::Reflection *messageReflection = inputMessage.GetReflection(); int64_t value = 0; switch(inputField->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_INT32: value = messageReflection->GetInt32(inputMessage, inputField); break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: value = messageReflection->GetInt64(inputMessage, inputField); break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: value = messageReflection->GetUInt32(inputMessage, inputField); break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: value = messageReflection->GetUInt64(inputMessage, inputField); break; case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: value = messageReflection->GetEnum(inputMessage, inputField)->number(); break; default: throw SOMException("Non-integer data type\n", INVALID_FUNCTION_INPUT, __FILE__, __LINE__); break; } return value; }
/// merges /// crutch for repeated fields void clear_repeated( gpb::Message &to, gpb::Message const &from ) { gpb::Reflection const *refl( to.GetReflection() ); typedef std::vector<gpb::FieldDescriptor const *> flds_vector; flds_vector fields; refl->ListFields( from, &fields ); flds_vector::const_iterator b(fields.begin( )); flds_vector::const_iterator e(fields.end( )); for(; b!=e; ++b) { const gpb::FieldDescriptor *next(*b); if ( next->is_repeated( ) ) { refl->ClearField( &to, next ); } else if( field_is_message( next ) ) { if( message_has_repeated( next ) ) { refl->MutableMessage( &to, next )->Clear( ); } else if( refl->HasField( to, next ) ) { clear_repeated( *refl->MutableMessage( &to, next ), refl->GetMessage( from, next )); } } } }
Handle<Object> ParsePart(const google::protobuf::Message &message) { HandleScope scope; const Reflection* r = message.GetReflection(); const Descriptor* descriptor = message.GetDescriptor(); Local<Array> properties = Array::New(descriptor->field_count()); for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); bool repeated = field->is_repeated(); if (repeated && !r->FieldSize(message, field)) continue; if (!repeated && !r->HasField(message, field)) continue; Handle<Value> value; if (field->is_repeated()) { int size = r->FieldSize(message, field); Handle<Array> array = Array::New(size); for (int j = 0; j < size; j++) array->Set(j, ParseField(message, r, field, j)); value = array; } else { value = ParseField(message, r, field, -1); } if (value->IsNull()) continue; properties->Set(i, value); } Local<Function> from_array = handle_->GetInternalField(2).As<Function>(); Handle<Value> args = properties; return scope.Close(from_array->NewInstance(1, &args)); }
/** This function binds the value of a protobuf field to a SQLite statement according to the type of the field (can only be a primative type). @param inputStatement: The statement to bind the field value to @param inputSQLStatementIndex: The index of the statement field to bind @param inputMessage: The message to get the value from @param inputField: The field (from the message) to get the value from @throw: This function can throw exceptions */ void pylongps::bindFieldValueToStatement(sqlite3_stmt &inputStatement, uint32_t inputSQLStatementIndex, const google::protobuf::Message &inputMessage, const google::protobuf::FieldDescriptor *inputField) { const google::protobuf::Reflection *messageReflection = inputMessage.GetReflection(); int returnValue = 0; if(messageReflection->HasField(inputMessage, inputField) == true) { switch(inputField->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_INT32: returnValue = sqlite3_bind_int64(&inputStatement, inputSQLStatementIndex, messageReflection->GetInt32(inputMessage, inputField)); break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: returnValue = sqlite3_bind_int64(&inputStatement, inputSQLStatementIndex, messageReflection->GetInt64(inputMessage, inputField)); break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: returnValue = sqlite3_bind_int64(&inputStatement, inputSQLStatementIndex, messageReflection->GetUInt32(inputMessage, inputField)); break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: returnValue = sqlite3_bind_int64(&inputStatement, inputSQLStatementIndex, messageReflection->GetUInt64(inputMessage, inputField)); break; case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: returnValue = sqlite3_bind_double(&inputStatement, inputSQLStatementIndex, messageReflection->GetDouble(inputMessage, inputField)); break; case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: returnValue = sqlite3_bind_double(&inputStatement, inputSQLStatementIndex, messageReflection->GetDouble(inputMessage, inputField)); break; case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: returnValue = sqlite3_bind_int64(&inputStatement, inputSQLStatementIndex, messageReflection->GetBool(inputMessage, inputField)); break; case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: returnValue = sqlite3_bind_int64(&inputStatement, inputSQLStatementIndex, messageReflection->GetEnum(inputMessage, inputField)->number()); break; case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { std::string buffer; buffer = messageReflection->GetStringReference(inputMessage, inputField, &buffer); returnValue = sqlite3_bind_blob64(&inputStatement, inputSQLStatementIndex, (const void*) buffer.c_str(), buffer.size(), SQLITE_TRANSIENT); } break; default: throw SOMException("Unrecognized data type\n", AN_ASSUMPTION_WAS_VIOLATED_ERROR, __FILE__, __LINE__); break; } } else { //Its a optional field that is not set, so store a NULL value returnValue = sqlite3_bind_null(&inputStatement, inputSQLStatementIndex); } if(returnValue != SQLITE_OK) { throw SOMException("Database error occurred (" + std::to_string(returnValue)+ ")\n", SQLITE3_ERROR, __FILE__, __LINE__); } }
/// true if equal bool messages_diff ( gpb::Message const &templ, gpb::Message &src, gpb::FieldDescriptor const *fld ) { gpb::Reflection const *treflect( templ.GetReflection( ) ); gpb::Reflection const *sreflect( src.GetReflection( ) ); if( message_has_repeated( fld ) ) { gpb::Message const &tmpl_next( treflect->GetMessage( templ, fld ) ); gpb::Message *src_next( sreflect->MutableMessage( &src, fld ) ); std::string tmpls(tmpl_next.SerializeAsString()); std::string srss(src_next->SerializeAsString()); return tmpls == srss; } if( !fld->is_repeated( ) ) { gpb::Message const &tmpl_next( treflect->GetMessage( templ, fld ) ); gpb::Message *src_next( sreflect->MutableMessage( &src, fld ) ); bool equal = false; if( make_message_diff( tmpl_next, *src_next, *src_next ) ) { sreflect->ClearField( &src, fld ); equal = true; } return equal; } int tsize( templ.GetReflection( )->FieldSize( templ, fld ) ); int ssize( src.GetReflection( )->FieldSize( src, fld ) ); if( tsize != ssize ) return false; for( int i(0); i<tsize; ++i ) { std::string tmess( treflect->GetRepeatedMessage( templ, fld, i ) .SerializeAsString( ) ); std::string smess( sreflect->GetRepeatedMessage( src, fld, i ) .SerializeAsString( ) ); if( tmess.compare(smess) != 0 ) return false; } sreflect->ClearField( &src, fld ); return true; }
void ProtobufBsonFormatter::formatMessage(const google::protobuf::Message& message, BSONObjBuilder& builder) { const google::protobuf::Reflection* reflection = message.GetReflection(); const google::protobuf::Descriptor* descriptor = message.GetDescriptor(); int fieldCnt = descriptor->field_count(); for (int i = 0; i < fieldCnt; ++i) { bool serialized = formatField(message, descriptor->field(i), builder); } }
void Serializer::WriteRepeatedMessageField(google::protobuf::Message const& value, google::protobuf::FieldDescriptor const* field) { google::protobuf::Reflection const* reflection = value.GetReflection(); for (int32 i = 0; i < reflection->FieldSize(value, field); ++i) { switch (field->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_INT32: WriteInt32(reflection->GetRepeatedInt32(value, field, i)); break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: WriteInt64(reflection->GetRepeatedInt64(value, field, i)); break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: WriteUInt32(reflection->GetRepeatedUInt32(value, field, i)); break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: WriteUInt64(reflection->GetRepeatedUInt64(value, field, i)); break; case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: WriteDouble(reflection->GetRepeatedDouble(value, field, i)); break; case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: WriteFloat(reflection->GetRepeatedFloat(value, field, i)); break; case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: WriteBool(reflection->GetRepeatedBool(value, field, i)); break; case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: WriteEnum(reflection->GetRepeatedEnum(value, field, i)); break; case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { std::string strValue = reflection->GetRepeatedString(value, field, i); if (field->type() == google::protobuf::FieldDescriptor::TYPE_STRING) WriteString(strValue); else { _writer.StartArray(); for (std::size_t j = 0; j < strValue.length(); ++j) WriteUInt32(uint32(strValue[j])); _writer.EndArray(); } break; } case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: WriteMessage(reflection->GetRepeatedMessage(value, field, i)); break; default: break; } } }
void Serializer::WriteMessage(google::protobuf::Message const& value) { google::protobuf::Reflection const* reflection = value.GetReflection(); std::vector<google::protobuf::FieldDescriptor const*> fields; reflection->ListFields(value, &fields); _writer.StartObject(); for (std::size_t i = 0; i < fields.size(); ++i) WriteMessageField(value, fields[i]); _writer.EndObject(); }
/** This function retrieves the the value of a protobuf field from a SQLite statement according to the type of the field (can only be a primative type). @param inputStatement: The statement to retrieve the field value from (should already be stepped) @param inputSQLStatementIndex: The index of the statement field to retrieve from @param inputMessage: The message to store the value to @param inputField: The field (from the message) to store the value in @throw: This function can throw exceptions */ void pylongps::retrieveFieldValueFromStatement(sqlite3_stmt &inputStatement, uint32_t inputSQLStatementIndex, google::protobuf::Message &inputMessage, const google::protobuf::FieldDescriptor *inputField) { const google::protobuf::Reflection *messageReflection = inputMessage.GetReflection(); if(sqlite3_column_type(&inputStatement, inputSQLStatementIndex) != SQLITE_NULL) { switch(inputField->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_INT32: messageReflection->SetInt32(&inputMessage, inputField, sqlite3_column_int64(&inputStatement, inputSQLStatementIndex)); break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: messageReflection->SetInt64(&inputMessage, inputField, sqlite3_column_int64(&inputStatement, inputSQLStatementIndex)); break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: messageReflection->SetUInt32(&inputMessage, inputField, sqlite3_column_int64(&inputStatement, inputSQLStatementIndex)); break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: messageReflection->SetUInt64(&inputMessage, inputField, sqlite3_column_int64(&inputStatement, inputSQLStatementIndex)); break; case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: messageReflection->SetDouble(&inputMessage, inputField, sqlite3_column_double(&inputStatement, inputSQLStatementIndex)); break; case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: messageReflection->SetFloat(&inputMessage, inputField, sqlite3_column_double(&inputStatement, inputSQLStatementIndex)); break; case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: messageReflection->SetBool(&inputMessage, inputField, sqlite3_column_int64(&inputStatement, inputSQLStatementIndex)); break; case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: messageReflection->SetEnum(&inputMessage, inputField, inputField->enum_type()->FindValueByNumber(sqlite3_column_int64(&inputStatement, inputSQLStatementIndex))); break; case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { int stringSize = sqlite3_column_bytes16(&inputStatement, inputSQLStatementIndex); const void *stringData = sqlite3_column_blob(&inputStatement, inputSQLStatementIndex); messageReflection->SetString(&inputMessage, inputField, std::string((const char *)stringData, stringSize)); } break; default: throw SOMException("Unrecognized data type " + std::to_string(inputField->cpp_type()) + "\n", AN_ASSUMPTION_WAS_VIOLATED_ERROR, __FILE__, __LINE__); break; } } else { //It was NULL in the database, so clear it messageReflection->ClearField(&inputMessage, inputField); } }
bool ProtobufBsonFormatter::formatField(const google::protobuf::Message& message, const google::protobuf::FieldDescriptor* field, BSONObjBuilder& builder) { const google::protobuf::Reflection* reflection = message.GetReflection(); //FIXME if (field->is_repeated() || reflection->HasField(message, field)) { formatSingleField(message, field, builder); return true; } return false; }
void MachinetalkService::updateComplexRepeatedField(QObject *object, const google::protobuf::Message &message, const google::protobuf::FieldDescriptor *field, const QString &tempDir) { const auto &name = QByteArray::fromStdString(field->camelcase_name()); const gpb::Reflection *reflection = message.GetReflection(); auto list = qvariant_cast<QVariant>(object->property(name)).toList(); QList<int> removeList; // store index of items to remove bool lengthChanged = false; for (int i = 0; i < reflection->FieldSize(message, field); ++i) { const gpb::Message &subMessage = reflection->GetRepeatedMessage(message, field, i); const gpb::Descriptor *subDescriptor = subMessage.GetDescriptor(); const gpb::FieldDescriptor *subField = subDescriptor->FindFieldByName("index"); const gpb::Reflection *subReflection = subMessage.GetReflection(); const int index = subReflection->GetInt32(subMessage, subField); while (list.size() < (index + 1)) { QObject *newObject = recurseDescriptor(subDescriptor, object); list.append(QVariant::fromValue(newObject)); lengthChanged = true; } QObject *item = qvariant_cast<QObject*>(list.at(index)); Q_ASSERT(item != nullptr); if (recurseMessage(subMessage, item, tempDir) <= 1) // only index -> remove object { removeList.append(index); } } // remove marked items if (removeList.length() > 0) { std::sort(removeList.begin(), removeList.end()); for (int k = (removeList.length() - 1); k >= 0; k--) { QObject *item = qvariant_cast<QObject*>(list.takeAt(removeList[k])); Q_ASSERT(item != nullptr); item->deleteLater(); } lengthChanged = true; } if (lengthChanged) // we need to notify property bindings about changes in length { object->setProperty(name, QVariant::fromValue(list)); } }
void MachinetalkService::updateSimpleRepeatedField(QObject *object, const gpb::Message &message, const gpb::FieldDescriptor *field) { const auto &name = QByteArray::fromStdString(field->camelcase_name()); const gpb::Reflection *reflection = message.GetReflection(); auto list = qvariant_cast<QVariant>(object->property(name)).toList(); QList<int> removeList; // store index of items to remove for (int i = 0; i < reflection->FieldSize(message, field); ++i) { const gpb::Message &subMessage = reflection->GetRepeatedMessage(message, field, i); const gpb::Descriptor *subDescriptor = subMessage.GetDescriptor(); const gpb::FieldDescriptor *subField = subDescriptor->FindFieldByName("index"); const gpb::Reflection *subReflection = subMessage.GetReflection(); const int index = subReflection->GetInt32(subMessage, subField); while (list.size() < (index + 1)) { list.append(QVariant()); } gpb::vector< const gpb::FieldDescriptor * > output; subReflection->ListFields(subMessage, &output); if (output.size() > 1) // index and value field { for (const auto subField: output) { if (subField->name() == "index") { continue; } list[index] = simpleFieldValueToVariant(subMessage, subField); } } else // only index -> remove object { removeList.append(index); } } // remove marked items if (removeList.length() > 0) { std::sort(removeList.begin(), removeList.end()); for (int k = (removeList.length() - 1); k >= 0; k--) { list.removeAt(removeList[k]); } } object->setProperty(name, QVariant::fromValue(list)); }
/// true if messages are equal bool make_message_diff( gpb::Message const &templ, gpb::Message const &src, gpb::Message &result ) { boost::scoped_ptr<gpb::Message> new_result(src.New()); new_result->CopyFrom( src ); typedef gpb::FieldDescriptor field_desc; typedef std::vector<const field_desc *> field_list; field_list fields; new_result->GetReflection( )->ListFields(*new_result, &fields); size_t changes(0); for( field_list::const_iterator b(fields.begin()), e(fields.end()); b!=e; ++b ) { field_desc const *next(*b); if( !next->is_repeated() && !templ.GetReflection( )->HasField( templ, next ) ) { ++changes; continue; } if( next->cpp_type( ) == field_desc::CPPTYPE_MESSAGE ) { changes += (!messages_diff( templ, *new_result, next )); } else { changes += (!field_diff( templ, *new_result, next )); } } result.GetReflection()->Swap( new_result.get(), &result ); return changes == 0; }
QVariant MachinetalkService::simpleFieldValueToVariant(const gpb::Message &message, const gpb::FieldDescriptor *field) { const gpb::Reflection *reflection = message.GetReflection(); QVariant value; switch (field->cpp_type()) { case gpb::FieldDescriptor::CPPTYPE_BOOL: value = reflection->GetBool(message, field); break; case gpb::FieldDescriptor::CPPTYPE_DOUBLE: value = reflection->GetDouble(message, field); break; case gpb::FieldDescriptor::CPPTYPE_FLOAT: value = static_cast<double>(reflection->GetFloat(message, field)); break; case gpb::FieldDescriptor::CPPTYPE_INT32: value = static_cast<int>(reflection->GetInt32(message, field)); break; case gpb::FieldDescriptor::CPPTYPE_INT64: value = static_cast<int>(reflection->GetInt64(message, field)); break; case gpb::FieldDescriptor::CPPTYPE_UINT32: value = static_cast<int>(reflection->GetUInt32(message, field)); break; case gpb::FieldDescriptor::CPPTYPE_UINT64: value = static_cast<int>(reflection->GetUInt64(message, field)); break; case gpb::FieldDescriptor::CPPTYPE_STRING: value = QString::fromStdString(reflection->GetString(message, field)); break; case gpb::FieldDescriptor::CPPTYPE_ENUM: value = reflection->GetEnum(message, field)->number(); break; case gpb::FieldDescriptor::CPPTYPE_MESSAGE: qCritical() << "called simple convert function with complex type"; break; } return value; }
void SerializePart(google::protobuf::Message *message, Handle<Object> src) { Handle<Function> to_array = handle_->GetInternalField(3).As<Function>(); Handle<Array> properties = to_array->Call(src, 0, NULL).As<Array>(); const Reflection *r = message->GetReflection(); for (int i = 0; i < descriptor->field_count(); i++) { Local<Value> value = properties->Get(i); if (value->IsUndefined() || value->IsNull()) continue; const FieldDescriptor* field = descriptor->field(i); if (field->is_repeated()) { if (value->IsArray()) { Handle<Array> array = value.As<Array>(); int length = array->Length(); for (int j = 0; j < length; j++) SerializeField(message, r, field, array->Get(j)); } else if (value->IsObject() && field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && field->message_type()->name().compare(0, 20, "KeyValuePair_String_") == 0) { Local<Object> object = value.As<Object>(); Local<Array> subProperties = object->GetOwnPropertyNames(); int len = subProperties->Length(); for (int keyIdx = 0; keyIdx < len; keyIdx++) { Local<Object> keyValuePair = Object::New(); Local<Value> key = subProperties->Get(keyIdx); keyValuePair->Set(KeySymbol, key); keyValuePair->Set(ValueSymbol, object->Get(key)); SerializeField(message, r, field, keyValuePair); } } } else { SerializeField(message, r, field, value); } } }
bool ProtobufTree::addTreeData(QTreeWidgetItem* parent, const google::protobuf::Message& msg) { const Reflection* ref = msg.GetReflection(); // Get fields in the message vector<const FieldDescriptor*> fields; ref->ListFields(msg, &fields); // Get map of field numbers to child items FieldMap fieldMap = parent->data(Column_Tag, FieldMapRole).value<FieldMap>(); bool newFields = false; // Clear data for missing fields const Descriptor* desc = msg.GetDescriptor(); for (FieldMap::const_iterator i = fieldMap.begin(); i != fieldMap.end(); ++i) { const FieldDescriptor* field = desc->FindFieldByNumber(i.key()); if (!field) { // Field has left the descriptor - should never happen printf("Lost field %s.%d\n", desc->name().c_str(), i.key()); continue; } QTreeWidgetItem* item = i.value(); bool hasData; if (field->is_repeated()) { hasData = ref->FieldSize(msg, field); if (!hasData && item->childCount()) { // Remove and delete children for (QTreeWidgetItem* child : item->takeChildren()) { delete child; } } } else { hasData = ref->HasField(msg, field); } if (!hasData) { item->setText(Column_Value, QString()); item->setData(Column_Value, Qt::CheckStateRole, QVariant()); } } for (const FieldDescriptor* field : fields) { // Get the item for this field if the field has been seen before QTreeWidgetItem* item; FieldMap::iterator fieldIter = fieldMap.find(field->number()); if (fieldIter != fieldMap.end()) { // Field is already in parent item = *fieldIter; } else { // New field item = new QTreeWidgetItem(parent); fieldMap.insert(field->number(), item); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); parent->setData(Column_Tag, FieldMapRole, QVariant::fromValue<FieldMap>(fieldMap)); item->setData(Column_Tag, Qt::DisplayRole, field->number()); item->setData(Column_Tag, FieldDescriptorRole, QVariant::fromValue(field)); item->setText(Column_Field, QString::fromStdString(field->name())); if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_repeated()) { // Singular messages are expanded by default expandItem(item); } newFields = true; } if (field->is_repeated()) { // Repeated field int n = ref->FieldSize(msg, field); // Show the number of elements as the value for the field itself item->setData(Column_Value, Qt::DisplayRole, n); // Make sure we have enough children int children = item->childCount(); if (children < n) { // Add children for (int i = children; i < n; ++i) { QTreeWidgetItem* child = new QTreeWidgetItem(item); child->setText(Column_Field, QString("[%1]").arg(i)); child->setData(Column_Tag, FieldDescriptorRole, field); // For repeated items, the tag column holds the index in the // field child->setData(Column_Tag, Qt::DisplayRole, i); // A FieldMap is not used here because the items don't // actually have tags. The item's position in its parent is // its position in the repeated field. } newFields = true; } else if (children > n) { // Remove excess children // Internally, QTreeWidgetItem stores a QList of children. // Hopefully this is efficient. QList<QTreeWidgetItem*> kids = item->takeChildren(); for (int i = 0; i < (children - n); ++i) { delete kids.back(); kids.pop_back(); } item->addChildren(kids); } // Set data for children for (int i = 0; i < n; ++i) { QTreeWidgetItem* child = item->child(i); switch (field->type()) { case FieldDescriptor::TYPE_INT32: case FieldDescriptor::TYPE_SINT32: case FieldDescriptor::TYPE_FIXED32: case FieldDescriptor::TYPE_SFIXED32: child->setData(Column_Value, Qt::DisplayRole, ref->GetRepeatedInt32(msg, field, i)); break; case FieldDescriptor::TYPE_INT64: case FieldDescriptor::TYPE_SINT64: case FieldDescriptor::TYPE_FIXED64: case FieldDescriptor::TYPE_SFIXED64: child->setData( Column_Value, Qt::DisplayRole, (qlonglong)ref->GetRepeatedInt64(msg, field, i)); break; case FieldDescriptor::TYPE_UINT32: child->setData(Column_Value, Qt::DisplayRole, ref->GetRepeatedUInt32(msg, field, i)); break; case FieldDescriptor::TYPE_UINT64: child->setData( Column_Value, Qt::DisplayRole, (qulonglong)ref->GetRepeatedUInt64(msg, field, i)); break; case FieldDescriptor::TYPE_FLOAT: child->setData(Column_Value, Qt::DisplayRole, ref->GetRepeatedFloat(msg, field, i)); break; case FieldDescriptor::TYPE_DOUBLE: child->setData(Column_Value, Qt::DisplayRole, ref->GetRepeatedDouble(msg, field, i)); break; case FieldDescriptor::TYPE_BOOL: child->setCheckState(Column_Value, ref->GetRepeatedBool(msg, field, i) ? Qt::Checked : Qt::Unchecked); break; case FieldDescriptor::TYPE_ENUM: { const EnumValueDescriptor* ev = ref->GetRepeatedEnum(msg, field, i); child->setText(Column_Value, QString::fromStdString(ev->name())); break; } case FieldDescriptor::TYPE_STRING: child->setText(Column_Value, QString::fromStdString( ref->GetRepeatedString( msg, field, i))); break; case FieldDescriptor::TYPE_MESSAGE: child->setData(Column_Tag, IsMessageRole, true); newFields |= addTreeData( child, ref->GetRepeatedMessage(msg, field, i)); break; case FieldDescriptor::TYPE_BYTES: addBytes(child, ref->GetRepeatedString(msg, field, i)); break; default: child->setText(Column_Value, QString("??? %1").arg(field->type())); break; } } } else switch (field->type()) { case FieldDescriptor::TYPE_INT32: case FieldDescriptor::TYPE_SINT32: case FieldDescriptor::TYPE_FIXED32: case FieldDescriptor::TYPE_SFIXED32: item->setData(Column_Value, Qt::DisplayRole, ref->GetInt32(msg, field)); break; case FieldDescriptor::TYPE_INT64: case FieldDescriptor::TYPE_SINT64: case FieldDescriptor::TYPE_FIXED64: case FieldDescriptor::TYPE_SFIXED64: item->setData(Column_Value, Qt::DisplayRole, (qlonglong)ref->GetInt64(msg, field)); break; case FieldDescriptor::TYPE_UINT32: item->setData(Column_Value, Qt::DisplayRole, ref->GetUInt32(msg, field)); break; case FieldDescriptor::TYPE_UINT64: item->setData(Column_Value, Qt::DisplayRole, (qulonglong)ref->GetUInt64(msg, field)); break; case FieldDescriptor::TYPE_FLOAT: item->setData(Column_Value, Qt::DisplayRole, ref->GetFloat(msg, field)); break; case FieldDescriptor::TYPE_DOUBLE: item->setData(Column_Value, Qt::DisplayRole, ref->GetDouble(msg, field)); break; case FieldDescriptor::TYPE_BOOL: item->setCheckState(Column_Value, ref->GetBool(msg, field) ? Qt::Checked : Qt::Unchecked); break; case FieldDescriptor::TYPE_ENUM: { const EnumValueDescriptor* ev = ref->GetEnum(msg, field); item->setText(Column_Value, QString::fromStdString(ev->name())); break; } case FieldDescriptor::TYPE_STRING: item->setText( Column_Value, QString::fromStdString(ref->GetString(msg, field))); break; case FieldDescriptor::TYPE_MESSAGE: item->setData(Column_Tag, IsMessageRole, true); newFields |= addTreeData(item, ref->GetMessage(msg, field)); break; case FieldDescriptor::TYPE_BYTES: addBytes(item, ref->GetString(msg, field)); break; default: item->setText(Column_Value, QString("??? %1").arg(field->type())); break; } } return newFields; }
bool field_diff( gpb::Message const &templ, gpb::Message &src, gpb::FieldDescriptor const *fld ) { typedef gpb::FieldDescriptor fld_type; gpb::Reflection const *treflect( templ.GetReflection( ) ); gpb::Reflection const *sreflect( src.GetReflection( ) ); #define VTRC_CAS_NOT_REP_EQUAL( Type, Getter ) \ case fld_type::Type: \ if( treflect->Getter( templ, fld ) != \ sreflect->Getter (src, fld ) ) \ return false; \ break #define VTRC_CAS_REP_EQUAL( Type, Getter, index ) \ case fld_type::Type: \ equal = treflect->Getter( templ, fld, index ) == \ sreflect->Getter( src, fld, index ); \ break if( !fld->is_repeated( ) ) { switch( fld->cpp_type( ) ) { VTRC_CAS_NOT_REP_EQUAL( CPPTYPE_BOOL, GetBool ); VTRC_CAS_NOT_REP_EQUAL( CPPTYPE_UINT64, GetUInt64); VTRC_CAS_NOT_REP_EQUAL( CPPTYPE_UINT32, GetUInt32); VTRC_CAS_NOT_REP_EQUAL( CPPTYPE_INT64, GetInt64 ); VTRC_CAS_NOT_REP_EQUAL( CPPTYPE_INT32, GetInt32 ); VTRC_CAS_NOT_REP_EQUAL( CPPTYPE_FLOAT, GetFloat ); VTRC_CAS_NOT_REP_EQUAL( CPPTYPE_DOUBLE, GetDouble); VTRC_CAS_NOT_REP_EQUAL( CPPTYPE_STRING, GetString); default: break; } sreflect->ClearField( &src, fld ); return true; } else { int tsize( templ.GetReflection( )->FieldSize( templ, fld ) ); int ssize( src.GetReflection( )->FieldSize( src, fld ) ); if( tsize != ssize ) return false; for( int i(0); i<tsize; ++i ) { bool equal(false); switch( fld->cpp_type() ) { VTRC_CAS_REP_EQUAL( CPPTYPE_BOOL, GetRepeatedBool, i ); VTRC_CAS_REP_EQUAL( CPPTYPE_UINT64, GetRepeatedUInt64, i ); VTRC_CAS_REP_EQUAL( CPPTYPE_UINT32, GetRepeatedUInt32, i ); VTRC_CAS_REP_EQUAL( CPPTYPE_INT64 , GetRepeatedInt64, i ); VTRC_CAS_REP_EQUAL( CPPTYPE_INT32 , GetRepeatedInt32, i ); VTRC_CAS_REP_EQUAL( CPPTYPE_FLOAT , GetRepeatedFloat, i ); VTRC_CAS_REP_EQUAL( CPPTYPE_DOUBLE, GetRepeatedDouble, i ); VTRC_CAS_REP_EQUAL( CPPTYPE_STRING, GetRepeatedString, i ); VTRC_CAS_REP_EQUAL( CPPTYPE_ENUM, GetRepeatedEnum, i ); default: break; } if( !equal ) return false; } } #undef VTRC_CAS_REP_EQUAL #undef VTRC_CAS_NOT_REP_EQUAL sreflect->ClearField( &src, fld ); return true; }
void DynamicParse::ReadDesAndInsert(const google::protobuf::Message& message, Map_Message*& map_content) { map_content = new Map_Message; const google::protobuf::Descriptor* des = message.GetDescriptor(); const google::protobuf::Reflection* refl = message.GetReflection(); int count = des->field_count(); for (int i=0; i<count; ++i) { const google::protobuf::FieldDescriptor* field_des = des->field(i); string str_name = field_des->name(); StructValue* str_value = new StructValue; str_value->type1 = field_des->label(); str_value->type2 = field_des->type(); str_value->key_name = str_name; map_content->insert(make_pair(str_name, str_value)); //repeated if (field_des->is_repeated()) { // HTREEITEM hSubItem = m_tree.InsertItem(str_name.c_str(),hItem); int field_size = refl->FieldSize(message, field_des); for (int j=0; j<field_size; ++j) { // CString str_show; if (field_des->type() == FieldDescriptor::TYPE_STRING || field_des->type() == FieldDescriptor::TYPE_BYTES) { //str_show.Format("[%d]%s", j, (refl->GetRepeatedString(message, field_des, j)).c_str()); //hSubItem = m_tree.InsertItem((LPCSTR)str_show, hSubItem); str_value->vec_value.push_back(refl->GetRepeatedString(message, field_des, j)); } else if (field_des->type() == FieldDescriptor::TYPE_MESSAGE) { //str_show.Format("[%d]", j); //HTREEITEM hItem_temp = m_tree.InsertItem((LPCSTR)str_show, hSubItem); const google::protobuf::Message& msg_sub = refl->GetRepeatedMessage(message, field_des, j); //ReadDesAndInsert(msg_sub, hItem_temp); Map_Message* map_msg; ReadDesAndInsert(msg_sub, map_msg); str_value->vec_message.push_back(map_msg); } else { char value[128] = {0}; // uint64 temp_value = 0; switch (field_des->type()) { case FieldDescriptor::TYPE_INT32: //itoa(refl->GetRepeatedInt32(message, field_des, j), value, 10); sprintf(value, "%d", refl->GetRepeatedInt32(message, field_des, j)); break; case FieldDescriptor::TYPE_UINT32: //itoa(refl->GetRepeatedUInt32(message, field_des, j), value, 10); sprintf(value, "%u", refl->GetRepeatedUInt32(message, field_des, j)); break; case FieldDescriptor::TYPE_INT64: //_i64toa(refl->GetRepeatedInt64(message, field_des, j), value, 10); sprintf(value, "%lld", refl->GetRepeatedInt64(message, field_des, j)); break; case FieldDescriptor::TYPE_UINT64: //_ui64toa(refl->GetRepeatedUInt64(message, field_des, j), value, 10); sprintf(value, "%llu", refl->GetRepeatedUInt64(message, field_des, j)); break; default: break; } //str_show.Format("[%d]%I64u", j, temp_value); //m_tree.InsertItem((LPCSTR)str_show, hSubItem); // str_show.Format("%I64u", temp_value); // string val_temp = str_show; str_value->vec_value.push_back(string(value)); } } } else { // CString str_show; if (field_des->type() == FieldDescriptor::TYPE_STRING || field_des->type() == FieldDescriptor::TYPE_BYTES) { //str_show.Format("[%s]%s", str_name.c_str(), (refl->GetString(message, field_des)).c_str()); //m_tree.InsertItem((LPCSTR)str_show, hItem); str_value->vec_value.push_back(refl->GetString(message, field_des)); } else if (field_des->type() == FieldDescriptor::TYPE_MESSAGE) { //str_show.Format("%s", str_name.c_str()); //HTREEITEM hSubItem = m_tree.InsertItem((LPCSTR)str_show, hItem); const google::protobuf::Message& msg_sub = refl->GetMessage(message, field_des); //ReadDesAndInsert(msg_sub, hSubItem); Map_Message* map_msg; ReadDesAndInsert(msg_sub, map_msg); str_value->vec_message.push_back(map_msg); } else { char value[128] = {0}; // string val_temp; // ULONGLONG temp_value = 0; switch (field_des->type()) { case FieldDescriptor::TYPE_INT32: //_itoa(refl->GetInt32(message, field_des), value, 10); sprintf(value, "%d", refl->GetInt32(message, field_des)); break; case FieldDescriptor::TYPE_UINT32: //_itoa(refl->GetUInt32(message, field_des), value, 10); sprintf(value, "%u", refl->GetUInt32(message, field_des)); break; case FieldDescriptor::TYPE_INT64: //_i64toa(refl->GetInt64(message, field_des), value, 10); sprintf(value, "%llu", refl->GetInt64(message, field_des)); break; case FieldDescriptor::TYPE_UINT64: //_ui64toa(refl->GetUInt64(message, field_des), value, 10); sprintf(value, "%llu", refl->GetUInt64(message, field_des)); break; default: break; } //str_show.Format("[%s]%I64u", str_name.c_str(), temp_value); //m_tree.InsertItem((LPCSTR)str_show, hItem); // str_show.Format("%I64u", temp_value); // string val_temp = str_show; str_value->vec_value.push_back(string(value)); } } } }
void CMetadata::toProtobuf(google::protobuf::Message &message) { //protobuf const google::protobuf::Reflection *pReflection = message.GetReflection(); const google::protobuf::Descriptor *pDescriptor = message.GetDescriptor(); google::protobuf::FieldDescriptor *pFieldDescriptor = NULL; std::string tmpStr; std::string NameStr; for(int i = 0; i < pDescriptor->field_count(); i++) { pFieldDescriptor = (google::protobuf::FieldDescriptor *)pDescriptor->field(i); NameStr = pFieldDescriptor->name(); if (!m_members.HasMember(NameStr.data())) continue; if (pFieldDescriptor->is_repeated()) { if (this->isFieldVec(m_members[NameStr.data()])) { switch(pFieldDescriptor->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_INT32: for(int idx = 0; idx < this->_getVecCount(m_members[NameStr.data()]); ++idx) { pReflection->AddInt32(&message, pFieldDescriptor, this->getFieldInt(m_members[NameStr.data()][idx])); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: for(int idx = 0; idx < this->_getVecCount(m_members[NameStr.data()]); ++idx) { pReflection->AddInt64(&message, pFieldDescriptor, this->getFieldI64(m_members[NameStr.data()][idx])); } break; case google::protobuf::FieldDescriptor::CPPTYPE_STRING: for(int idx = 0; idx < this->_getVecCount(m_members[NameStr.data()]); ++idx) { pReflection->AddString(&message, pFieldDescriptor,this->getFieldStr(m_members[NameStr.data()][idx])); } break; default: return; } } } else { switch(pFieldDescriptor->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_INT32: if (this->isFieldInt(m_members[NameStr.data()])) { pReflection->SetInt32(&message, pFieldDescriptor, this->getFieldInt(m_members[NameStr.data()])); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: if (this->isFieldI64(m_members[NameStr.data()])) { pReflection->SetInt64(&message, pFieldDescriptor, this->getFieldI64(m_members[NameStr.data()])); } break; case google::protobuf::FieldDescriptor::CPPTYPE_STRING: if (this->isFieldStr(m_members[NameStr.data()])) { tmpStr.assign(this->getFieldStr(m_members[NameStr.data()])); pReflection->SetString(&message, pFieldDescriptor, tmpStr); } break; default: return; } } } }
int MachinetalkService::recurseMessage(const google::protobuf::Message &message, QObject *object, const QString &tempDir, const QString &fieldFilter) { Q_ASSERT(object != nullptr); const bool filterEnabled = !fieldFilter.isEmpty(); bool isPosition = false; const gpb::Reflection *reflection = message.GetReflection(); gpb::vector< const gpb::FieldDescriptor * > output; reflection->ListFields(message, &output); if (message.GetDescriptor() == machinetalk::File::descriptor()) // handle files with binary data { machinetalk::File file; file.MergeFrom(message); fileToObject(file, object, tempDir); return static_cast<int>(output.size()); } else if (message.GetDescriptor() == machinetalk::Position::descriptor()) // handle position vectors { isPosition = true; } for (const gpb::FieldDescriptor *field: output) { const auto &name = QByteArray::fromStdString(field->camelcase_name()); if ((name == "index") || (filterEnabled && (name != fieldFilter))) { continue; } if (!field->is_repeated()) { if (field->cpp_type() != gpb::FieldDescriptor::CPPTYPE_MESSAGE) { const auto &value = simpleFieldValueToVariant(message, field); object->setProperty(name, value); if (isPosition) { object->setProperty(QString::number(field->index()).toLocal8Bit(), value); } } else { QObject *memberObject = qvariant_cast<QObject *>(object->property(name)); Q_ASSERT(memberObject != nullptr); recurseMessage(reflection->GetMessage(message, field), memberObject, tempDir); } } else if (field->cpp_type() == gpb::FieldDescriptor::CPPTYPE_MESSAGE) { if (field->message_type()->field_count() != 2) // not only index and value field { updateComplexRepeatedField(object, message, field, tempDir); } else { updateSimpleRepeatedField(object, message, field); } } } return static_cast<int>(output.size()); }
void parseMessageToFILE(const google::protobuf::Message& message, FILE* output, int tabcount = 0) { using google::protobuf::FieldDescriptor; using google::protobuf::UnknownField; using google::protobuf::UnknownFieldSet; using google::protobuf::EnumValueDescriptor; auto* reflection = message.GetReflection(); auto* descriptor = message.GetDescriptor(); size_t expected_size = descriptor->field_count(); std::vector< const FieldDescriptor* > ref_fields; // array of known fields in the message UnknownFieldSet unknown_fields; ref_fields.reserve(expected_size); for (int i=0, n=descriptor->field_count(); i<n; ++i) { auto* field_desc = descriptor->field(i); ref_fields.push_back(field_desc); } fprintf(output, "%s\n", /*std::string(tabcount,' ').c_str(),*/ message.GetTypeName().c_str()); ++tabcount; for(const auto& ref : ref_fields) { switch(ref->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32 : { if (ref->is_repeated()) { printRepeatedType(reflection->GetRepeatedField<google::protobuf::int32>(message, ref), ref->camelcase_name(), output, tabcount); }else { printType(reflection->GetInt32(message, ref), ref->camelcase_name(), output, tabcount); } } break; case FieldDescriptor::CPPTYPE_INT64 : { if (ref->is_repeated()) { printRepeatedType(reflection->GetRepeatedField<google::protobuf::int64>(message, ref), ref->camelcase_name(), output, tabcount); }else { printType(reflection->GetInt64(message, ref), ref->camelcase_name(), output, tabcount); } } break; case FieldDescriptor::CPPTYPE_UINT32 : { if (ref->is_repeated()) { printRepeatedType(reflection->GetRepeatedField<google::protobuf::uint32>(message, ref), ref->camelcase_name(), output, tabcount); }else { printType(reflection->GetUInt32(message, ref), ref->camelcase_name(), output, tabcount); } } break; case FieldDescriptor::CPPTYPE_UINT64 : { if (ref->is_repeated()) { printRepeatedType(reflection->GetRepeatedField<google::protobuf::uint64>(message, ref), ref->camelcase_name(), output, tabcount); }else { printType(reflection->GetUInt64(message, ref), ref->camelcase_name(), output, tabcount); } } break; case FieldDescriptor::CPPTYPE_DOUBLE : { if (ref->is_repeated()) { printRepeatedType(reflection->GetRepeatedField<double>(message, ref), ref->camelcase_name(), output, tabcount); }else { printType(reflection->GetDouble(message, ref), ref->camelcase_name(), output, tabcount); } } break; case FieldDescriptor::CPPTYPE_FLOAT : { if (ref->is_repeated()) { printRepeatedType(reflection->GetRepeatedField<float>(message, ref), ref->camelcase_name(), output, tabcount); }else { printType(reflection->GetFloat(message, ref), ref->camelcase_name(), output, tabcount); } } break; case FieldDescriptor::CPPTYPE_BOOL : { if (ref->is_repeated()) { printRepeatedType(reflection->GetRepeatedField<bool>(message, ref), ref->camelcase_name(), output, tabcount); }else { printType(reflection->GetBool(message, ref), ref->camelcase_name(), output, tabcount); } } break; case FieldDescriptor::CPPTYPE_ENUM : { // Enums are a little akward... if (ref->is_repeated()) { for (int i=0, n=reflection->FieldSize(message, ref); i<n; ++i) { printTypeArray(*reflection->GetEnum(message, ref), ref->camelcase_name(), output, tabcount, i); } }else { printType(*reflection->GetEnum(message, ref), ref->camelcase_name(), output, tabcount); } } break; case FieldDescriptor::CPPTYPE_STRING : { //TODO: Output binary as HEX numbers. // can't print bytes if (ref->type() == FieldDescriptor::TYPE_BYTES) { fprintf(output, "%s%s=<BINARY DATA>\n", std::string(tabcount,' ').c_str(), ref->camelcase_name().c_str()); break; } if (ref->is_repeated()) { printRepeatedType(reflection->GetRepeatedPtrField<std::string>(message, ref), ref->camelcase_name(), output, tabcount); }else { printType(reflection->GetString(message, ref), ref->camelcase_name(), output, tabcount); } } break; case FieldDescriptor::CPPTYPE_MESSAGE: { if (ref->is_repeated()) { printRepeatedType(reflection->GetRepeatedPtrField<google::protobuf::Message>(message, ref), ref->camelcase_name(), output, tabcount); }else { printType(reflection->GetMessage(message, ref), ref->camelcase_name(), output, tabcount); } } break; } } }
void ProtobufBsonFormatter::formatSingleField(const google::protobuf::Message& message, const google::protobuf::FieldDescriptor* field, BSONObjBuilder& builder) { std::string fieldName(""); if (field->is_extension()) { //TODO } else if (field->type() == google::protobuf::FieldDescriptor::TYPE_GROUP) { // Groups must be serialized with their original capitalization. fieldName = field->message_type()->name().c_str(); //...append values } else { fieldName = field->camelcase_name(); const google::protobuf::Reflection* reflection = message.GetReflection(); if (field->is_repeated()) { int fieldsize = reflection->FieldSize(message, field); switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { //= 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 std::vector<int32> values; values.reserve(fieldsize); for (int i = 0; i < fieldsize; ++i) { values.push_back(reflection->GetRepeatedInt32(message,field,i)); } builder.append(fieldName,values); break; } case FieldDescriptor::CPPTYPE_INT64: { //= 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 std::vector<long long> values; values.reserve(fieldsize); for (int i = 0; i < fieldsize; ++i) { values.push_back(reflection->GetRepeatedInt64(message,field,i)); } builder.append(fieldName, values); break; } case FieldDescriptor::CPPTYPE_UINT32: { //= 3, // TYPE_UINT32, TYPE_FIXED32 std::vector<uint32> values; values.reserve(fieldsize); for (int i = 0; i < fieldsize; ++i) { values.push_back(reflection->GetRepeatedUInt32(message,field,i)); } builder.append(fieldName,values); break; } case FieldDescriptor::CPPTYPE_UINT64: { //= 4, // TYPE_UINT64, TYPE_FIXED64 std::vector<long long> values; values.reserve(fieldsize); for (int i = 0; i < fieldsize; ++i) { values.push_back((long long)reflection->GetRepeatedUInt64(message,field,i)); } builder.append(fieldName,values); break; } case FieldDescriptor::CPPTYPE_DOUBLE: { //= 5, // TYPE_DOUBLE std::vector<double> values; values.reserve(fieldsize); for (int i = 0; i < fieldsize; ++i) { values.push_back(reflection->GetRepeatedDouble(message,field,i)); } builder.append(fieldName,values); break; } case FieldDescriptor::CPPTYPE_FLOAT: { //= 6, // TYPE_FLOAT std::vector<float> values; values.reserve(fieldsize); for (int i = 0; i < fieldsize; ++i) { values.push_back(reflection->GetRepeatedFloat(message,field,i)); } builder.append(fieldName,values); break; } case FieldDescriptor::CPPTYPE_BOOL: { //= 7, // TYPE_BOOL std::vector<bool> values; values.reserve(fieldsize); for (int i = 0; i < fieldsize; ++i) { values.push_back(reflection->GetRepeatedBool(message,field,i)); } builder.append(fieldName,values); break; } case FieldDescriptor::CPPTYPE_STRING: { //= 9, // TYPE_STRING, TYPE_BYTES std::vector<std::string> values; values.reserve(fieldsize); for (int i = 0; i < fieldsize; ++i) { values.push_back(reflection->GetRepeatedString(message,field,i)); } builder.append(fieldName,values); break; } case FieldDescriptor::CPPTYPE_ENUM: { //= 8, // TYPE_ENUM std::vector<std::string> values; values.reserve(fieldsize); for (int i = 0; i < fieldsize; ++i) { values.push_back(reflection->GetRepeatedEnum(message,field,i)->name()); } builder.append(fieldName,values); break; } case FieldDescriptor::CPPTYPE_MESSAGE: { //= 10, // TYPE_MESSAGE, TYPE_GROUP BSONObjBuilder sub(builder.subarrayStart(fieldName)); for (int i = 0; i < fieldsize; ++i) { char number[16] = {0}; sprintf(number, "%d", i); BSONObjBuilder obj(sub.subobjStart(number)); formatMessage(reflection->GetRepeatedMessage(message, field, i), obj); obj.done(); } sub.done(); break; } default: { break; } }// end switch } else { //not repeated switch (/*cppType*/field->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { //= 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 builder.append(fieldName, reflection->GetInt32(message,field)); break; } case FieldDescriptor::CPPTYPE_INT64: { //= 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 builder.append(fieldName, static_cast<long long>(reflection->GetInt64(message,field))); break; } case FieldDescriptor::CPPTYPE_UINT32: { //= 3, // TYPE_UINT32, TYPE_FIXED32 builder.append(fieldName,reflection->GetUInt32(message,field)); break; } case FieldDescriptor::CPPTYPE_UINT64: { //= 4, // TYPE_UINT64, TYPE_FIXED64 builder.append(fieldName, static_cast<long long>(reflection->GetUInt64(message,field))); break; } case FieldDescriptor::CPPTYPE_DOUBLE: { //= 5, // TYPE_DOUBLE builder.append(fieldName,reflection->GetDouble(message,field)); break; } case FieldDescriptor::CPPTYPE_FLOAT: { //= 6, // TYPE_FLOAT builder.append(fieldName,reflection->GetFloat(message,field)); break; } case FieldDescriptor::CPPTYPE_BOOL: { //= 7, // TYPE_BOOL builder.append(fieldName,reflection->GetBool(message,field)); break; } case FieldDescriptor::CPPTYPE_STRING: { //= 9, // TYPE_STRING, TYPE_BYTES builder.append(fieldName,reflection->GetString(message,field)); break; } case FieldDescriptor::CPPTYPE_ENUM: { //= 8, // TYPE_ENUM builder.append(fieldName,reflection->GetEnum(message,field)->name()); break; } case FieldDescriptor::CPPTYPE_MESSAGE: { //= 10, // TYPE_MESSAGE, TYPE_GROUP BSONObjBuilder sub(builder.subobjStart(fieldName)); formatMessage(reflection->GetMessage(message, field), sub); sub.done(); break; } default: { break; } }// end switch } } //end else }
void CMetadata::fromProtobuf(google::protobuf::Message& message) { //protobuf const google::protobuf::Reflection *pReflection = message.GetReflection(); const google::protobuf::Descriptor *pDescriptor = message.GetDescriptor(); google::protobuf::FieldDescriptor *pFieldDescriptor = NULL; std::string NameStr; int32 FieldNum; for(int i = 0; i < pDescriptor->field_count(); i++){ pFieldDescriptor = (google::protobuf::FieldDescriptor *)pDescriptor->field(i); NameStr = pFieldDescriptor->name(); if (!m_members.HasMember(NameStr.data())) continue; if (pFieldDescriptor->is_repeated()) { if (this->isFieldVec(m_members[NameStr.data()])) { switch(pFieldDescriptor->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_INT32: for(FieldNum = 0; FieldNum < pReflection->FieldSize(message, pFieldDescriptor); FieldNum++){ this->setFieldVec(NameStr, FieldNum, (int)pReflection->GetRepeatedInt32(message, pFieldDescriptor, FieldNum)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: for(FieldNum = 0; FieldNum < pReflection->FieldSize(message, pFieldDescriptor); FieldNum++){ this->setFieldVec(NameStr, FieldNum, (int64)pReflection->GetRepeatedInt64(message, pFieldDescriptor, FieldNum)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_STRING: for(FieldNum = 0; FieldNum < pReflection->FieldSize(message, pFieldDescriptor); FieldNum++){ this->setFieldVec(NameStr, FieldNum, pReflection->GetRepeatedString(message, pFieldDescriptor, FieldNum).c_str()); } break; default: return; } } } else { switch(pFieldDescriptor->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_INT32: if (this->isFieldInt(m_members[NameStr.data()])) { this->setFieldInt(NameStr, pReflection->GetInt32(message, pFieldDescriptor)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: if (this->isFieldI64(m_members[NameStr.data()])) { this->setFieldI64(NameStr, pReflection->GetInt64(message, pFieldDescriptor)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_STRING: if (this->isFieldStr(m_members[NameStr.data()])) { this->setFieldString(NameStr, pReflection->GetString(message, pFieldDescriptor)); } break; default: return; } } } }
bool ProtoMessageToXmlWithoutRoot( const google::protobuf::Message& message, std::string* xml_string, std::string* error) { using namespace std; using namespace google::protobuf; const Reflection* reflection = message.GetReflection(); const Descriptor* descriptor = message.GetDescriptor(); vector<const FieldDescriptor*> fields; for (int i = 0; i < descriptor->extension_range_count(); i++) { const Descriptor::ExtensionRange* ext_range = descriptor->extension_range(i); for (int tag_number = ext_range->start; tag_number < ext_range->end; tag_number++) { const FieldDescriptor* field = reflection->FindKnownExtensionByNumber(tag_number); if (field) { fields.push_back(field); } } } for (int i = 0; i < descriptor->field_count(); i++) { fields.push_back(descriptor->field(i)); } for (size_t i = 0; i < fields.size(); i++) { const FieldDescriptor* field = fields[i]; if (!field->is_repeated() && !reflection->HasField(message, field)) { if (field->is_required()) { if (error) error->assign("missed required field " + field->full_name() + "."); return false; } continue; } switch (field->cpp_type()) { #define CASE_FIELD_TYPE(cpptype, method, ToString, as_binary) \ case FieldDescriptor::CPPTYPE_##cpptype: { \ if (field->is_repeated()) { \ int field_size = reflection->FieldSize(message, field); \ for (int index = 0; index < field_size; ++index) { \ AppendAsXml( \ field->name(), ToString( \ reflection->GetRepeated##method(message, field, index)), \ xml_string, as_binary); \ } \ } else { \ AppendAsXml( \ field->name(), ToString( \ reflection->Get##method(message, field)), \ xml_string, as_binary); \ } \ break; \ } CASE_FIELD_TYPE(INT32, Int32, SimpleItoa, false); CASE_FIELD_TYPE(INT64, Int64, SimpleItoa, false); CASE_FIELD_TYPE(UINT32, UInt32, SimpleItoa, false); CASE_FIELD_TYPE(UINT64, UInt64, SimpleItoa, false); CASE_FIELD_TYPE(FLOAT, Float, SimpleFtoa, false); CASE_FIELD_TYPE(DOUBLE, Double, SimpleDtoa, false); CASE_FIELD_TYPE(STRING, String, SimpleStoa, true); #undef CASE_FIELD_TYPE case FieldDescriptor::CPPTYPE_ENUM: { if (field->is_repeated()) { int field_size = reflection->FieldSize(message, field); for (int index = 0; index < field_size; index++) { AppendAsXml( field->name(), SimpleItoa(reflection->GetRepeatedEnum(message, field, index)->number()), xml_string); } } else { AppendAsXml( field->name(), SimpleItoa(reflection->GetEnum(message, field)->number()), xml_string); } break; } case FieldDescriptor::CPPTYPE_BOOL: { if (field->is_repeated()) { int field_size = reflection->FieldSize(message, field); for (int index = 0; index < field_size; index++) { AppendAsXml( field->name(), reflection->GetRepeatedBool(message, field, index) ? "true" : "false", xml_string); } } else { AppendAsXml( field->name(), reflection->GetBool(message, field) ? "true" : "false", xml_string); } break; } case FieldDescriptor::CPPTYPE_MESSAGE: { if (field->is_repeated()) { int field_size = reflection->FieldSize(message, field); for (int index = 0; index < field_size; index++) { StringAppend(xml_string, '<', field->name(), '>'); if (!ProtoMessageToXmlWithoutRoot( reflection->GetRepeatedMessage(message, field, index), xml_string, error)) { return false; } StringAppend(xml_string, "</", field->name(), '>'); } } else { StringAppend(xml_string, '<', field->name(), '>'); if (!ProtoMessageToXmlWithoutRoot( reflection->GetMessage(message, field), xml_string, error)) { return false; } StringAppend(xml_string, "</", field->name(), '>'); } break; } } ///< switch } ///< for return true; }