Example #1
0
	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));
	}
Example #2
0
	Type(Protobuf* _protobuf, google::protobuf::Message *_message, Handle<Object> self, size_t _index) {
		protobuf = _protobuf;
		message = _message;
		descriptor = _message->GetDescriptor();
		index = _index;

		// Generate functions for bulk conversion between a JS object
		// and an array in descriptor order:
		//   from = function(arr) { this.f0 = arr[0]; this.f1 = arr[1]; ... }
		//   to   = function()    { return [ this.f0, this.f1, ... ] }
		// This is faster than repeatedly calling Get/Set on a v8::Object.
		std::ostringstream from, to;
		from << "(function(arr) { if(arr) {";
		to << "(function() { return [ ";
		for (int i = 0; i < descriptor->field_count(); i++) {
			std::string name = descriptor->field(i)->name();
			from << "var x = arr[" << i << "]; if (x !== undefined) this['" << name << "'] = x; ";
			if (i > 0) to << ", ";
			to << "this['" << name << "']";
		}
		from << " }})";
		to << " ]; })";

		// managed type->schema link
		self->SetInternalField(1, protobuf->handle_);
		self->SetInternalField(2, Script::Compile(String::New(from.str().c_str()))->Run());
		self->SetInternalField(3, Script::Compile(String::New(to.str().c_str()))->Run());

		Wrap(self);
	}
Example #3
0
	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);
			}
		}
	}