Package decoder.primitive

Source Code of decoder.primitive.HexStringDecoder

package decoder.primitive;

import api.Decoder;
import api.exceptions.DecodingException;
import org.apache.commons.codec.binary.Hex;

import java.io.IOException;
import java.io.InputStream;

/**
* If you see it, than I've forgotten javadoc
*
* @author Denis Golovachev
* @author $Author$ (current maintainer)
* @since 1.0
*/
public class HexStringDecoder implements Decoder<String> {


    private static final int constructor = ChecksumCalculator.calculate("string ? = String");

    private static final int longStringMarker = 0xFE;
    /**
     * Наконец, значения типа string выглядят по-разному в зависимости от длины передаваемой строки L.
     * Если L <= 253, то кодируется один байт L, затем L байтов строки, затем от 0 до 3 символов с кодом 0,
     * чтобы общая длина значения делилась на 4, после чего все это интерпретируется как последовательность
     * из int(L/4)+1 32-битных чисел. Если же L>=254, то кодируется байт 254, затем — 3 байта с длиной строки L,
     * затем — L байтов строки, затем - от 0 до 3 нулевых байтов выравнивания.
     */
    @Override
    public String decode(InputStream stream) throws DecodingException {
        try {
            int firstByte = stream.read();
            if(firstByte == longStringMarker) {
                return read(stream);
            }
            return read(stream, firstByte);
        } catch (IOException e) {
            throw new DecodingException("Do not like InputStream interface for ugly checked exception");
        }
    }

    /**
     * Long strings contains 'size' in three bytes, after 0xFE(first byte)
     * @param dataStream
     * @return
     * @throws IOException
     */
    private String read(InputStream dataStream) throws IOException {
        byte[] lengthBytes = new byte[3];
        dataStream.read(lengthBytes);
        int length = lengthBytes[0] + lengthBytes[1] * 256 + lengthBytes[2] * 65536;
        return read(dataStream, length);
    }

    private String read(InputStream stream, int size) throws IOException {
        byte[] stringBytes = new byte[size];
        stream.read(stringBytes);
        removePadding(stream, size + 1); // +1 byte = length byte.
        return Hex.encodeHexString(stringBytes);
    }

    private void removePadding(InputStream stream, int size) throws IOException {
        int difference = (size + 4) % 4;
        int padding = difference > 0 ? 4 - difference: 0; // 32 bit padding
        stream.read(new byte[padding]); // padding is useless
    }

    @Override
    public boolean isTypeConstructor(int otherConstructor) {
        return constructor == otherConstructor;
    }
}
TOP

Related Classes of decoder.primitive.HexStringDecoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.