I need a BCD decoder and encoder

151 Views Asked by At

I am just starting to use Preon to decode configuration data from radios (channel number, frequency, mode, channel name, etc). Different radios have different radio formats, usually radically different. Preon seems to be the perfect solution. And its extensible.

One radio places the frequency data in BCD (8 digits of frequency are stored in 4 bytes). So I think I need to develop a BCD decoder and encoder in Preon. I believe I have read all the information I can find about Preon on the web but I am not sure how to go about this.

If you have developed a custom codec for Preon, please give me some tips on how to start.

1

There are 1 best solutions below

0
On

This question is very old, but since the docs for preon are pretty terrible, I'm going to try and answer some of these questions since I recently dug into this.

Preon works in two phases: Creating a Mega-Codec that can decode the class you asked it to decode Running the codec

The first phase is supported by CodecFactory classes which produce Codec classes for the second phase.

To register an extra CodecFactory you can invoke preon like so:

    DefaultCodecFactory fact = new DefaultCodecFactory();

    CodecFactory someFactory = new DefaultCodecFactory();

    CodecFactory[] additional = new CodecFactory[1];
    additional[0] = someFactory;

    Codec<MyClass> myCodec =  fact.create(null, MyClass.class, additional,
            new CodecDecorator[0], new BindingDecorator[0]);

    MyClass result = Codecs.decode(myCodec, buffer);

Just replace someFactory with your actual factory. Writing the actual factory is more of a pain, to do so you need to implement the create method:

public <T> Codec<T> create(AnnotatedElement metadata, Class<T> type,
                           ResolverContext context) {

Preon mostly goes through it's list of factories trying to find one that knows how to handle every element in the class you asked it to deserialize. So what you need to do is, based on the metadata and type parameters, figure out if the current class property to deserialize is one you want to support. Most likely, you want to add a @BoundBCD annotation, and then check something like

metadata.getAnnotation(BoundBCD.class)) != null

For those cases that you want to handle, you should return a Codec class that at least implements the decode method of the Codec interface (you might also need to implement getCodecDescriptor, the one I made has that copy and pasted from the list codec)

You will want to create this codec with all the parameters that are relevant, e.g. if your annotation has a size field (or you're infering it from the type size) you should initialize it in your codec before returning it, if it's a limbo expression, you should save that expression for evaluation in your codec. That way when you're in the decode function of your codec you will actually have all the data you need to run, and then all you will need to do is create the appropriately typed object from a BitBuffer.