Commits

Anonymous committed fa0b6ad

updated java code generator

Comments (0)

Files changed (4)

lib/msgpack/idl/ir.rb

 			else
 				@all_fields = new_fields
 			end
-			@max_id = @all_fields.map {|f| f.id }.max
+			@max_id = @all_fields.map {|f| f.id }.max || 0
+			@max_required_id = @all_fields.select {|f| f.required? }.map {|f| f.id }.max || 0
 		end
 
 		attr_reader :name, :super_class, :new_fields
-		attr_reader :all_fields, :max_id
+		attr_reader :all_fields, :max_id, :max_required_id
+
+		def [](id)
+			@all_fields.find {|f| f.id == id }
+		end
 	end
 
 	class Exception < Message
 			@name = name
 			@return_type = return_type
 			@args = args
-			@max_id = @args.map {|a| a.id }.max
+			@max_id = @args.map {|a| a.id }.max || 0
+			@max_id = @args.select {|a| a.required? }.map {|a| a.id }.max || 0
 		end
 		attr_reader :name, :return_type, :args
 		attr_reader :max_id

lib/msgpack/idl/lang/java.rb

 		'bool'   => 'boolean',
 		'raw'    => 'ByteBuffer',
 		'string' => 'String',
-		'list'   => 'ArrayList',
-		'map'    => 'HashMap',
+		'list'   => 'List',
+		'map'    => 'Map',
 	}
 
 	def format_type(t)
 			name
 		end
 	end
+
+	PRIMITIVE_UNPACK = {
+		'byte'   => 'unpackByte()',
+		'short'  => 'unpackShort()',
+		'int'    => 'unpackInt()',
+		'long'   => 'unpackLong()',
+		'ubyte'  => 'unpackShort()',
+		'ushort' => 'unpackInt()',
+		'uint'   => 'unpackLong()',
+		'ulong'  => 'unpackBigInteger()',
+		'float'  => 'unpackFloat()',
+		'double' => 'unpackDouble()',
+		'bool'   => 'unpackBoolean()',
+		'raw'    => 'ByteBuffer.wrap(unpackByteArray())',
+		'string' => 'unpackString()',
+		'list'   => 'unpackList()',
+		'map'    => 'unpackMap()',
+	}
+
+	def format_unpack(t)
+		# TODO type erasure
+		PRIMITIVE_UNPACK[t.name] || "unpack(#{t.name}.class)"
+	end
+
+	PRIMITIVE_CONVERT = {
+		'byte'   => 'asByte()',
+		'short'  => 'asShort()',
+		'int'    => 'asInt()',
+		'long'   => 'asLong()',
+		'ubyte'  => 'asShort()',
+		'ushort' => 'asInt()',
+		'uint'   => 'asLong()',
+		'ulong'  => 'asBigInteger()',
+		'float'  => 'asFloat()',
+		'double' => 'asDouble()',
+		'bool'   => 'asBoolean()',
+		'raw'    => 'ByteBuffer.wrap(asByteArray())',
+		'string' => 'asString()',
+		'list'   => 'asList()',
+		'map'    => 'asMap()',
+	}
+
+	def format_convert(t)
+		# TODO type erasure
+		PRIMITIVE_CONVERT[t.name] || "convert(#{t.name}.class)"
+	end
 end
 
 

lib/msgpack/idl/lang/java/message.java

 import java.io.IOException;
 import org.msgpack.MessageTypeException;
 
-public class #{@message.name} {
-	public static class Template extends org.msgpack.AbstractTemplate {
-	}
-
+public class #{@message.name} implements MessagePackable, MessageUnpackable, MessageConvertable {
 	<?rb @message.new_fields.each {|field| ?>
 	private #{format_type(field.type)} #{field.name};
 	<?rb } ?>
+
+	public void messagePack(Packer _Pk) throws IOException {
+		pk.packArray(#{@message.max_id});
+		<?rb 1.upto(@message.max_id) {|i| ?>
+		<?rb if f = @message[i]; ?>
+		_Pk.pack(this.#{f.name});
+		<?rb else ?>
+		_Pk.packNil();
+		<?rb end ?>
+		<?rb } ?>
+	}
+
+	public void messageUnpack(Unpacker pac) throws IOException, MessageTypeException {
+		int len = pac.unpackArray();
+
+		if(len < #{@message.max_required_id}) {
+			throw new MessagePackObject("#{@message.name} requires at least #{@message.max_required_id} elements.");
+		}
+
+		<?rb 1.upto(@message.max_id) {|i| ?>
+		<?rb f = @message[i] ?>
+		<?rb if !f ?>
+		pac.unpackObject();
+		<?rb elsif f.required? ?>
+		this.#{f.name} = pac.#{format_unpack(f.type)};
+		<?rb elsif i <= @message.max_required_id ?>
+		if(!pac.tryUnpackNull()) {
+			this.#{f.name} = pac.#{format_unpack(f.type)};
+		}
+		<?rb else ?>
+		if(len > #{i-1}) {
+			this.#{f.name} = pac.#{format_unpack(f.type)};
+		}
+		<?rb end ?>
+		<?rb } ?>
+	}
+
+	public void messageConvert(MessagePackObject obj) throws IOException, MessageTypeException {
+		if(!obj.isArrayType()) {
+			throw new MessageTypeException("target is not array");
+		}
+		MessagePackObject[] arr = obj.asArray();
+		int len = arr.length;
+
+		if(len < #{@message.max_required_id}) {
+			throw new MessagePackObject("#{@message.name} requires at least #{@message.max_required_id} elements.");
+		}
+
+		<?rb 1.upto(@message.max_id) {|i| ?>
+		<?rb if f = @message[i] ?>
+
+		<?rb if f.required? ?>
+		this.#{f.name} = arr[#{i}].#{format_convert(f.type)};  // TODO
+		<?rb else ?>
+		<?rb if i > @message.max_required_id  # optional ?>
+		if(len < #{i-1}) { return; }
+		<?rb end ?>
+		if(!arr[#{i}].isNil()) {
+			this.#{f.name} = arr[#{i}].#{format_convert(f.type)};
+		}
+		<?rb end ?>
+
+		<?rb end ?>
+		<?rb } ?>
+	}
 }
 

lib/msgpack/idl/parser/transform.rb

 			 :field_modifier => simple(:m),
 			 :field_type => simple(:t),
 			 :field_name => simple(:n)) {
-		m ||= AST::FIELD_REQUIRED
+		m = m() ? m() : AST::FIELD_REQUIRED
 		AST::Field.new(i, t, m, n)
 	}