Code generation tool (II) Java Library Implementation of-miniproto

Source: Internet
Author: User

/////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////


This project is tentatively named miniproto1.0.

Limited compatible PROTOBUF syntax rules and coding rules. Includes coding rules for protobuf2.0 and 3.0.

Implement serialization and deserialization of proto structure.

Code generation tools, need boost library support (mainly using the Spirit library to do text parsing), I use the boost.1.64.0.

The generated code only needs to Miniproto the lib (corresponding C + +), DLL (corresponding to C #), Jar (corresponding Java) provided by itself, and no other third-party libraries are required.

Full project download address (VS Project compilation Please select Release/win32)

GitHub Project Address


/////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////


The previous article introduces Miniproto, which introduces the implementation of its Java library


1. Container

First spit the Java container.

Java in the mind of all objects, the container can not put the basic data types, can only put the basic data types of encapsulated class objects.

That is to say list<int> is illegal,list<integer> is legal.

Therefore, in Miniproto for Array/set/map this type of field, there will inevitably be unboxing operation, compared to egg pain.


2. Generic type

Then spit out the generics in Java.

For generics in Java, personal understanding is the invention of a device that is used to validate parameter types at compile time.

It says, in Java everything is object, the container can only put objects.

So I put an integer, and a string, into a list, which is fine before it has a generic type. Compilation does not complain.

Cause when you are dealing with elements in a container, if you accidentally turn an integer strong to string processing, it will classcastexception.

So with generics, you put a string object into the list<integer> and the compiler complains.

But that's just it ...

After compiling, there is no generics ...

class file, there is no information for the generic parameter ...

All become object, WTF ...

It is not like C + + template mechanism, compile-time, different generic parameters, directly generate different code and compile.

There is no such thing as C #, where Mr. Compile-time is intermediate code, and a generic parameter is a placeholder in the middle code. When an instance is created, a different local code is generated based on the argument type of the generic parameter.

Therefore, in Miniproto, it is impossible to realize the intention of overloading the encoding and decoding functions of different data types directly through generics.

Of course, I can't be exhaustive. All parameter types, given overloads.

is mainly a map, it has key and value two generic parameters, exhaustive words, the type of key xvalue is too much, lazy to write.

Therefore, you can only pass in a different type parameter (Miniproto is a custom enumeration).

Based on this parameter, the T (run time t has become object) is strongly turned, and then the overload of the codec function of different data types is invoked.


3, enumeration

Java slots are really a little bit more.

We can only define a series of constants with public static final before jdk1.5. 1.5 added an enumeration.

But an enumeration is a class.

The public enum XXX you wrote was eventually replaced with public class XXX extends Java.lang.Enum.

The constant YYY in the enumeration you write is eventually replaced by the static object of XXX, the public static final XXX YYY in this class.

So when I have a number int, I'm going to go to the corresponding enumeration entry, I can only switch...case return the corresponding yyy through a static method in this class XXX.

The static method, however, means that it cannot be polymorphic. That is, I can't do a numeric-enumeration by calling the base class interface and getting the subclass implementation. A specific enumeration type must be obtained in order to complete the transformation.

Therefore, in the underlying implementation of the decoding function, the enumeration type can only be treated as an integer.

An enumeration member in a proto message, or a container of an enumeration type, can only be implemented as an Integer or a list<integer>.

In the getter/setter of the message, the specific enumeration type is invoked to make the corresponding transformation.


4, Prototool

Basically the same as C + + prototool (get rid of some of the above spit slot). According to different data types, a series of coding and decoding functions are realized.

The Prototool code is given below, and a comment is made on the code. Concrete implementation will not be posted, you can download the full project.

Package Common.miniproto;
Import java.io.IOException;
Import Java.io.InputStream;
Import Java.io.OutputStream;
Import java.util.Collection;
Import java.util.List;
Import Java.util.Map;
Import Java.util.Set;

Import Java.util.Iterator;
	public class Prototool {//Zigzag codec/decode public static int zigzag (int value);
	public static long zigzag (Long value);
	public static int Dezigzag (int value);

	public static long Dezigzag (Long value);
	Number codec/decoding public static int numberbytesize (int value);
	public static int numberbytesize (Long value);
	public static int numberbytesize (float value);
	public static int numberbytesize (double value);
	public static void Numbercode (int value, OutputStream buf) throws IOException;
	public static void Numbercode (Long value, OutputStream buf) throws IOException;
	public static void Numbercode (float value, OutputStream buf) throws IOException;
	public static void Numbercode (double value, OutputStream buf) throws IOException; public static int Numberdecode (int value, InputStream buf) throws IOException;
	public static long Numberdecode (Long value, InputStream buf) throws IOException;
	public static float Numberdecode (float value, InputStream buf) throws IOException;

	public static double Numberdecode (double value, InputStream buf) throws IOException;
	Proto Key codec/decode public static int keybytesize (int num, protodefine.protowiretype type);
	public static void keycode (int num, protodefine.protowiretype type, OutputStream buf) throws IOException;

	public static int Keydecode (InputStream buf) throws IOException;

	Unknown field decodes public static void Unknowndecode (Protodefine.protowiretype type, InputStream buf) throws IOException;
	Single field codec/decode public static int boolbytesize (Boolean value);
	public static void Boolcode (Boolean value, OutputStream buf) throws IOException;

	public static Boolean Booldecode (InputStream buf) throws IOException;
	public static int int32bytesize (Integer value); public static void Int32code (Integer value, OutputstreAm buf) throws IOException;

	public static Integer Int32decode (InputStream buf) throws IOException;
	public static int sint32bytesize (Integer value);
	public static void Sint32code (Integer value, OutputStream buf) throws IOException;

	public static Integer Sint32decode (InputStream buf) throws IOException;
	public static int uint32bytesize (Integer value);
	public static void Uint32code (Integer value, OutputStream buf) throws IOException;

	public static Integer Uint32decode (InputStream buf) throws IOException;
	public static int int64bytesize (Long value);
	public static void Int64code (Long value, OutputStream buf) throws IOException;

	public static Long Int64decode (InputStream buf) throws IOException;
	public static int sint64bytesize (Long value);
	public static void Sint64code (Long value, OutputStream buf) throws IOException;

	public static Long Sint64decode (InputStream buf) throws IOException;
	public static int uint64bytesize (Long value); public static void Uint64code (Long value, OutputStream buf) throws IOException;

	public static Long Uint64decode (InputStream buf) throws IOException;
	public static int enumbytesize (Integer value);
	public static void Enumcode (Integer value, OutputStream buf) throws IOException;

	public static Integer Enumdecode (InputStream buf) throws IOException;
	public static int floatbytesize (Float value);
	public static void Floatcode (Float value, OutputStream buf) throws IOException;

	public static Float Floatdecode (InputStream buf) throws IOException;
	public static int doublebytesize (Double value);
	public static void Doublecode (Double value, OutputStream buf) throws IOException;

	public static Double Doubledecode (InputStream buf) throws IOException;
	public static int stringbytesize (String value) throws IOException;
	public static void Stringcode (String value, OutputStream buf) throws IOException;

	public static String Stringdecode (InputStream buf) throws IOException; public static <m extends protobase> int messagebytesIze (M value) throws IOException;
	public static <m extends protobase> void Messagecode (M value, OutputStream buf) throws IOException;

	public static <m extends protobase> M messagedecode (InputStream buf, class<m> cls) throws IOException; Array,set container, encoding/decoding of each element private static <T> int entrybytesize (T value, Protodefine.protofieldtype type) throws IO
	Exception;
	private static <T> void Entrycode (T value, OutputStream buf, Protodefine.protofieldtype type) throws IOException; private static <T> void Entrydecode (collection<t> values, InputStream buf, Protodefine.protofieldtype type)
	Throws IOException; private static <t extends protobase> void Entrydecode (collection<t> values, InputStream buf,

	Protodefine.protofieldtype type, class<t> cls) throws IOException; The array container's codec///internal call Entrybytesize/code/decode private static <T> int Arraybytesizewithoutlength (list<t&gt ; Values, Protodefine.protofieldtype type) tHrows IOException;
	public static <T> int arraybytesize (list<t> values, Protodefine.protofieldtype type) throws IOException; public static <T> void Arraycode (list<t> values, OutputStream buf, Protodefine.protofieldtype type) throws IO
	Exception; public static <T> void Arraydecode (list<t> values, InputStream buf, Protodefine.protofieldtype type) throws I
	Oexception; public static <t extends protobase> void Arraydecode (list<t> values, InputStream buf,

	Protodefine.protofieldtype type, class<t> cls) throws IOException; The Set container's codec///decode/Internal call Entrybytesize/code/decode private static <T> int setbytesizewithoutlength (set<t> va
	Lues, Protodefine.protofieldtype type) throws IOException;
	public static <T> int setbytesize (set<t> values, Protodefine.protofieldtype type) throws IOException; public static <T> void Setcode (set<t> values, OutputStream buf, Protodefine.protofieldtype type) throws Ioexc EptiOn public static <T> void Setdecode (set<t> values, InputStream buf, Protodefine.protofieldtype type) throws Ioex

	ception; In the map container, the encoding/decoding of each element is private static <k, v> int entrybytesizewithoutlength (K key, V value, Protodefine.protofieldtyp
	E KeyType, Protodefine.protofieldtype valuetype) throws IOException; public static <k, v> int entrybytesize (K key, V value, Protodefine.protofieldtype keyType, Protodefine.protofieldty
	PE valuetype) throws IOException; public static <k, v> void Entrycode (K key, V value, OutputStream buf, Protodefine.protofieldtype KeyType, Protodefin
	E.protofieldtype valuetype) throws IOException; public static <k, v> void Entrydecode (map<k, v> values, InputStream buf, Protodefine.protofieldtype KeyType, P
	Rotodefine.protofieldtype valuetype) throws IOException; public static <k, V extends protobase> void Entrydecode (map<k, v> values, InputStream buf, Protodefine.protofi Eldtype KeyType, Protodefine.protofieldtypE valuetype, Class<v> cls) throws IOException; The MAP container's encoding/decoding//Internal call Entrybytesize/code/decode private static <k, v> int mapbytesizewithoutlength (map<k, V&G T
	Values, Protodefine.protofieldtype KeyType, Protodefine.protofieldtype valuetype) throws IOException; public static <k, v> int mapbytesize (map<k, v> values, Protodefine.protofieldtype keyType,
	Protodefine.protofieldtype valuetype) throws IOException; public static <k, v> void Mapcode (map<k, v> values, OutputStream buf, Protodefine.protofieldtype keyType, prot
	Odefine.protofieldtype valuetype) throws IOException; public static <k, v> void Mapdecode (map<k, v> values, InputStream buf, Protodefine.protofieldtype KeyType, Pro
	Todefine.protofieldtype valuetype) throws IOException; public static <k, V extends protobase> void Mapdecode (map<k, v> values, InputStream buf, Protodefine.protofiel Dtype KeyType, Protodefine.protofieldtype valuetype, class<v> cls) throws IOException; }

5, Protobase

Basically identical C + + protobase, more than one ToString interface, convenient mode display message content information

Package Common.miniproto;

Import java.io.IOException;
Import Java.io.InputStream;
Import Java.io.OutputStream;
Import Java.lang.reflect.Field;

Public abstract class Protobase {public

	protobase ();

	public abstract int ByteSize () throws IOException;
	public abstract void Code (OutputStream buf, int size) throws IOException;
	public abstract void Decode (InputStream buf, int size) throws IOException;

	public abstract void Clear ();
	public abstract void Release ();

	public boolean Serializetostream (outputstream buf, int size);
	public boolean Parsefromstream (InputStream buf, int size);

	Public String toString ();
}

6, Protobitmap

Basically identical to C + + 's Protobitmap, bitmap length as a constructor parameter, more than one ToString interface.

Package Common.miniproto;

public class Protobitmap {public

	protobitmap (int count);

	public void setbit (int index);
	public void clearbit (int index);
	public boolean hasbit (int index);

	public void Clear ();

	Private byte[] m_bits = null;

	Public String toString ();
}


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.