Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

30 Commits

Repository files navigation

jPack

Writing network code in Java isn't nice. It lacks unsigned types and POJO can't be simple packed & unpacked. Fear not! This handy (hopefully) set of classes let's you annotate POJOs to make it simple to read & write network protocols.

Adding the dependency

We use Maven for building & distributing jPack. You're welcome to use our Maven repositories, or build your own .jar.

To use our Maven repos just add:

<repositories>
<repository>
<id>monits-snapshots</id>
<url>http://nexus.monits.com/content/repositories/oss-snapshots/</url>
<name>Monits Snapshots</name>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.monits</groupId>
<artifactId>jpack</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>

To build a .jar from source:

mvn clean install

Using jPack

The usage is simple, annotate your POJOs and then use Packer.pack or Packer.unpack.

@Encode

jPack will only pay attention to fields annotated with @Encode, any other fields will be ignored. The important part is that this annotation lets jPack know the order of the fields in the byte stream, via a non-optional integer parameter. jPack expects that a getter and a setter (following the Java Bean convention) exist for a field with @Encode.

publicclassFirstExample {
@Encode(0)
privatebytefirst;
@Encode(1)
privatebytesecond;
publicbytegetFirst() {
returnfirst;
}
publicvoidsetFirst(bytefirst) {
this.first = first;
}
publicbytegetSecond() {
returnsecond;
}
publicvoidsetSecond(bytesecond) {
this.second = second;
}
}

Unsigned integers

Java has no unsigned types. That sucks. So of course jPack gives you a way to use unsigned integers. @Unsigned indicates an integer type field is unsigned. This applies to arrays of integer types too. A standard conversion is applied to fit unsigned types in Java's signed types:

  • A short represents an unsigned byte
  • An int represents an unsigned short
  • A long represents an unsigned int
@Encode(0)
@UnsignedprivatelonganUnsignedInt;

Nested types

When jPack finds a type it doesn't know of in a field annotated with @Encode it tries to treat that type as another annotated POJO. That means the following will work as expected:

publicclassNestedObject {
@Encode(0)
@Unsignedprivateintfield;
publicintgetField() {
returnfield;
}
publicvoidsetField(intfield) {
this.field = field;
}
}
publicclassBigObject {
@Encode(0)
privateNestedObjectobj;
publicvoidsetObj(NestedObjectobj) {
this.obj = obj;
}
publicNestedObjectgetObj() {
returnobj;
}
}

And when I say "as expected" I mean, NestedObject and BigObject will pack & unpack in the same way.

Arrays

You can have arrays of any type, as long as jPack knows how to treat that type. You only have to indicate the length of the array in some way.

Fixed length arrays

With @FixedLength you can indicate that an array will always have the same length. Say you have an array of four unsigned integers, you just write:

@Encode(0)
@FixedLength(4)
privateint[] myInts;
publicint[] getMyInts() {
returnmyInts;
}
publicvoidsetMyInts() {
this.myInts = myInts;
}

Variable length arrays

Sadly, jPack can't do magic and guess the length of your array. If you have an array of variable length, there must be a another field that indicates it's length. To tell jPack which field it is, just use @DependsOn (More on this annotation on the Custom Codec section).

Here we define an array of bytes, that will have it's length determined by a field called totalBytes (getters and setters skipped for brevity):

@Encode(0)
@UnsignedprivatelongtotalBytes;
@Encode(1)
@DependsOn({ "totalBytes" })
privatebyte[] lotsaBytes;

Custom Codec

Sometimes you need a little extra, thus Custom Codecs. Any class that implements the interface Codec can be used to pack & unpack fields. By annotating a field with @UseCodec you can force jPack to use that codec.

@DependsOn

If your codec needs to know the values of other fields before doing it's magic, you can add @DependsOn on the field. jPack will just get those values for you and make them readibly available at coding/decoding time.

Contributing

We encourage you to contribute to this project!

We are also looking forward to your bug reports, feature requests and questions.

Copyright and License

Copyright 2012 Monits.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License at:

http://www.apache.org/licenses/LICENSE-2.0

About

A set of classes to treat POJOs as network-friendly structs

Resources

Stars

1 star

Watchers

22 watching

Forks

Releases

Packages

Contributors

Languages