All Downloads are FREE. Search and download functionalities are using the official Maven repository.

at.spardat.xma.serializer.AsciiDeserializer Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     s IT Solutions AT Spardat GmbH - initial API and implementation
 *******************************************************************************/

//@(#) $Id: AsciiDeserializer.java 2089 2007-11-28 13:56:13Z s3460 $
package at.spardat.xma.serializer;

import java.io.IOException;

import at.spardat.enterprise.exc.SysException;
import at.spardat.xma.util.ByteArray;

/**
 * Reads byte sequences produced by class AsciiSerializer.
 * 
 * @author MS, Feb 11, 2005 7:48:04 PM
 */
public class AsciiDeserializer implements Deserializer {
    
    /**
     * The input byte array
     */
    private byte[]              fData;
    
    /**
     * input data
     */
    protected ByteArray         fArr;
    
    
    
    /**
     * Constructor
     * 
     * @param data    serialized array of data 
     * @param length  first length bytes in data are used.
     */
    public AsciiDeserializer (byte[] data, int length) {
        this (data, 0, length);
    }
    
    /**
     * Constructor 
     * 
     * @param data  serialized array of data
     */
    public AsciiDeserializer (byte [] data) {
        this (data, 0, data.length);
    }
    
    /**
     * Constructor
     * 
     * @param data   input array
     * @param offset offset where data starts
     * @param length num bytes from offset
     */
    public AsciiDeserializer (byte [] data, int offset, int length) {
        fData = data;
        fArr = new ByteArray (data, length+offset);
        fArr.setPosition(offset);
    }

    /**
     * @see at.spardat.xma.serializer.XmaInput#readString()
     */
    public String readString() throws IOException {
        return readStringEscaped();
    }
    
    /**
     * @see at.spardat.xma.serializer.XmaInput#readStringN()
     */
    public String readStringN() throws IOException {
        boolean     isNull = readBoolean();
        if (!isNull) return readString();
        else return null;
    }

    /**
     * @see at.spardat.xma.serializer.XmaInput#readInt()
     */
    public int readInt() throws IOException {
        return readNumeric();
    }

    /**
     * @see at.spardat.xma.serializer.XmaInput#readShort()
     */
    public short readShort() throws IOException {
        return (short)readNumeric();
    }
    
    /**
     * @see at.spardat.xma.serializer.XmaInput#readLong()
     */
    public long readLong() throws IOException {
        return (long) readNumericLong();
    }

    /**
     * @see at.spardat.xma.serializer.XmaInput#readBoolean()
     */
    public boolean readBoolean() throws IOException {
        return readStringEscaped().equals("1");
    }

    /**
     * @see at.spardat.xma.serializer.XmaInput#readByte()
     */
    public byte readByte() throws IOException {
        return (byte) readNumeric();
    }
    
    /**
     * @see at.spardat.xma.serializer.XmaInput#readSerializedBytes()
     */
    public byte[] readSerializedBytes() throws IOException {
        if (!fArr.hasRemaining()) throw new SysException ("{ expected");
        if (fArr.get() != '{') throw new SysException ("{ expected");
        int             startPosition = fArr.getPosition();
        int             nestingLevel = 1;
        while (fArr.hasRemaining()) {
            int         ch = fArr.get();
            int         chBefore = fArr.getRel(-2);
            if (ch == '{' && chBefore != '\\') nestingLevel++;
            if (ch == '}' && chBefore != '\\') {
                nestingLevel--;
                if (nestingLevel == 0) break;
            }
        }
        if (nestingLevel != 0) throw new SysException ("missing }");
        int             stopPosition = fArr.getPosition()-1;   // index of }
        byte[]      result = new byte[stopPosition-startPosition];
        System.arraycopy(fArr.getBuffer(), startPosition, result, 0, stopPosition-startPosition);
        // read trailing ','
        if (fArr.get() != ',') throw new SysException ("comma expected");
        return result;
    }
    
    /**
     * @see at.spardat.xma.serializer.XmaInput#readObject()
     */
    public Object readObject() throws ClassNotFoundException, IOException {
        String type = readString();
        if ("S".equals(type)) {
            return readString();
        } else if ("B".equals(type)) {
            return new Boolean (readBoolean());
        } else if ("H".equals(type)) {
            return new Short (readShort());
        } else if ("I".equals(type)) {
            return new Integer (readInt());
        } else if ("J".equals(type)) {
            byte [] bytes = readSerializedBytes();
            return Util.deserialize(Util.hexDecode(bytes));
        } else {
            // an XmaSerializable
            Object obj = null;
            try {
                obj = Class.forName(type).newInstance();
            } catch (Exception x) {
                throw new SysException (x, "cannot create instance of " + type);
            }
            ((XmaSerializable)obj).deserialize(this);
            return obj;
        }
    }
    
    
    private int readNumeric () {
        return Integer.parseInt(readStringEscaped());
    }
    
    private long readNumericLong () {
        return Long.parseLong (readStringEscaped());
    }
    
    /**
     * Reads a string written by AsciiSerializer.writeStringEscaped.
     * The string stops at either ',' or '=' (characters are not included in string).
     * Those termination characters are consumed in fArr (i.e., get has been called
     * on them). 
     */
    protected String readStringEscaped () {
        StringBuffer        result = new StringBuffer();
        while (fArr.hasRemaining()) {
            int             act = fArr.get();
            // escape
            if (act == '\\') {
                if (!fArr.hasRemaining()) throw new SysException ("premature end");
                int         act2 = fArr.getRel(0);
                if (act2 >= '0' && act2 <= '9' || act2 >= 'a' && act2 <= 'f') {
                    // hex character follows; we expect \xxxx unicode character
                    if (fArr.remaining() < 4) throw new SysException ("premature end");
                    String  hex = null;
                    try {
                        hex = new String (fData, fArr.getPosition(), 4, "US-ASCII");
                    } catch (Exception x) {
                        throw new SysException (x);
                    }
                    fArr.setPosition(fArr.getPosition()+4);
                    int     hexAsInt = Integer.parseInt (hex, 16);
                    result.append ((char)hexAsInt);
                } else {
                    // character after escape is taken literally
                    fArr.get();
                    result.append((char)act2);
                }
            } else {
                if (act == ',') {
                    if (fArr.hasRemaining() && fArr.getRel(0) == '\n') fArr.get();
                    break;
                } else if (act == '=') {
                    break;
                }
                else if (act == '\n') continue;
                else {
                    // plain character
                    result.append ((char)act);
                }
            }
        }
        return result.toString();
    }
    

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy