Package aterm.pure.binary

Source Code of aterm.pure.binary.BAFReader$SymEntry

/*
* Java version of the ATerm library
* Copyright (C) 2006-2008, UiB, CWI, LORIA-INRIA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA  02111-1307, USA.
*/
package aterm.pure.binary;

import java.io.BufferedInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;

import aterm.AFun;
import aterm.ATerm;
import aterm.ATermList;
import aterm.ParseError;
import aterm.pure.PureFactory;

/**
* Reader for the binary aterm format (BAF).
*
* @author Karl Trygve Kalleberg
*
*/
public class BAFReader {
    private static final int BAF_MAGIC = 0xBAF;
    private static final int BAF_VERSION = 0x300;
    private static final int HEADER_BITS = 32;
    private BitStream reader;
    private int nrUniqueSymbols = -1;
    private SymEntry[] symbols;
    private PureFactory factory;
    public static boolean isDebugging = false;

    private static class SymEntry {
        public AFun fun;
        public int arity;
        public int nrTerms;
        public int termWidth;
        public ATerm[] terms;
        public int[] nrTopSyms;
        public int[] symWidth;
        public int[][] topSyms;
    }

    public BAFReader(PureFactory factory, InputStream inputStream) {
        this.factory = factory;
        reader = new BitStream(inputStream);
    }

    public ATerm readFromBinaryFile(boolean headerAlreadyRead) throws ParseError, IOException {

        if(!headerAlreadyRead && !isBinaryATerm(reader))
            throw new ParseError("Input is not a BAF file");

        int val = reader.readInt();

        if (val != BAF_VERSION)
            throw new ParseError("Wrong BAF version (wanted " + BAF_VERSION + ", got " + val + "), giving up");

        nrUniqueSymbols = reader.readInt();
        int nrUniqueTerms = reader.readInt();

        if(isDebugging()) {
            debug("" + nrUniqueSymbols + " unique symbols");
            debug("" + nrUniqueTerms + " unique terms");
        }

        symbols = new SymEntry[nrUniqueSymbols];

        readAllSymbols();

        int i = reader.readInt();

        return readTerm(symbols[i]);
    }

    private boolean isDebugging() {
        return isDebugging;
    }

    public static boolean isBinaryATerm(BufferedInputStream in) throws IOException {
        if(isBinaryATerm(new BitStream(in)))
            return true;
        return false;
    }

    private static boolean isBinaryATerm(BitStream in) throws IOException {
        try {
            int w1 = in.readInt();

            return (w1 == BAF_MAGIC);
        } catch(EOFException e) {}

        return false;
    }


    private void debug(String s) {
        System.err.println(s);
    }

    int level = 0;
   
    private ATerm readTerm(SymEntry e) throws ParseError, IOException {
        final int arity = e.arity;
        final ATerm[] args = new ATerm[arity];

        level++;
       
        if(isDebugging())
            debug("readTerm()/" + level + " - " + e.fun.getName() + "[" + arity + "]");

        for (int i = 0; i < arity; i++) {
            int val = reader.readBits(e.symWidth[i]);
            if(isDebugging()) {
                debug(" [" + i + "] - " + val);
                debug(" [" + i + "] - " + e.topSyms[i].length);
            }
            SymEntry argSym = symbols[e.topSyms[i][val]];

            val = reader.readBits(argSym.termWidth);
            if (argSym.terms[val] == null) {
                if(isDebugging())
                    debug(" [" + i+  "] - recurse");
                argSym.terms[val] = readTerm(argSym);
            }

            if (argSym.terms[val] == null)
                throw new ParseError("Cannot be null");

            args[i] = argSym.terms[val];
        }

        final String name = e.fun.getName();
       
        if (name.equals("<int>")) {
            int val = reader.readBits(HEADER_BITS);
            level--;
            return factory.makeInt(val);
        }
        else if (name.equals("<real>")) {
            reader.flushBitsFromReader();
            String s = reader.readString();
            level--;
            return factory.makeReal(new Double(s).doubleValue());
        }
        else if (name.equals("[_,_]")) {
            if(isDebugging()) {
                debug("--");
                for (int i = 0; i < args.length; i++)
                    debug(" + " + args[i].getClass());
            }
            level--;
            return ((ATermList) args[1]).insert(args[0]);
        }
        else if (name.equals("[]")) {
            level--;
            return factory.makeList();
        }
        else if (name.equals("{_}")) {
          return args[0].setAnnotations((ATermList)args[1]);
        }
        else if (name.equals("<_>")) {
          return factory.makePlaceholder(args[0]);
        } else if(false) {
            // FIXME: Add blob case
            reader.flushBitsFromReader();
            String t = reader.readString();
            return factory.makeBlob(t.getBytes());
        }
       

        if(isDebugging()) {
            debug(e.fun + " / " + args);
            for (int i = 0; i < args.length; i++)
                debug("" + args[i]);
        }
        level--;
        return factory.makeAppl(e.fun, args);
    }

    private void readAllSymbols() throws IOException {

        for (int i = 0; i < nrUniqueSymbols; i++) {
            SymEntry e = new SymEntry();
            symbols[i] = e;

            AFun fun = readSymbol();
            e.fun = fun;
            int arity = e.arity = fun.getArity();

            int v = reader.readInt();
            e.nrTerms = v;
            e.termWidth = bitWidth(v);
            // FIXME: original code is inconsistent at this point!
            e.terms = (v == 0) ? null : new ATerm[v];

            if (arity == 0) {
                e.nrTopSyms = null;
                e.symWidth = null;
                e.topSyms = null;
            } else {

                e.nrTopSyms = new int[arity];
                e.symWidth = new int[arity];
                e.topSyms = new int[arity][];
            }
            for (int j = 0; j < arity; j++) {
                v = reader.readInt();
                e.nrTopSyms[j] = v;
                e.symWidth[j] = bitWidth(v);
                e.topSyms[j] = new int[v];

                for (int k = 0; k < e.nrTopSyms[j]; k++) {
                    v = reader.readInt();
                    e.topSyms[j][k] = v;
                }
            }
        }
    }

    private int bitWidth(int v) {
        int nrBits = 0;

        if (v <= 1)
            return 0;

        while (v != 0) {
            v >>= 1;
            nrBits++;
        }

        return nrBits;
    }

    private AFun readSymbol() throws IOException {
        String s = reader.readString();
        int arity = reader.readInt();
        int quoted = reader.readInt();

        if(isDebugging())
            debug(s + " / " + arity + " / " + quoted);

        return factory.makeAFun(s, arity, quoted != 0);
    }

    public static class BitStream {

        InputStream stream;
        private int bitsInBuffer;
        private int bitBuffer;

        public BitStream(InputStream inputStream) {
            stream = inputStream;
        }

        public int readInt() throws IOException {
            int[] buf = new int[5];

            buf[0] = readByte();
           
            // Check if 1st character is enough
            if((buf[0] & 0x80) == 0)
                return buf[0];

            buf[1= readByte();
           
            // Check if 2nd character is enough
            if((buf[0] & 0x40) == 0)
                return buf[1] + ((buf[0] & ~0xc0) << 8);

            buf[2] = readByte();

            // Check if 3rd character is enough
            if((buf[0] & 0x20) == 0 )
                return buf[2] + (buf[1] << 8) + ((buf[0] & ~0xe0) << 16);

            buf[3] = readByte();
           
            // Check if 4th character is enough
            if((buf[0] & 0x10) == 0 )
                return buf[3] + (buf[2] << 8) + (buf[1] << 16) +
                  ((buf[0] & ~0xf0) << 24);
           
            buf[4] = readByte();

            return buf[4] + (buf[3] << 8) + (buf[2] << 16) + (buf[1] << 24);
        }

        private int readByte() throws IOException {
            int c = stream.read();
            if(c == -1)
                throw new EOFException();
            return c;
        }

        public String readString() throws IOException {
            int l = readInt();
            byte[] b = new byte[l];
            int v = 0;
            while(v < b.length) {
                v += stream.read(b, v, b.length - v);
            }
            return new String(b);
        }

        public int readBits(int nrBits) throws IOException {
            int mask = 1;
            int val = 0;
           
            for (int i=0; i<nrBits; i++) {
              if (bitsInBuffer == 0) {
                int v = readByte();
                if (v == -1)
                  return -1;
                bitBuffer = v;
                bitsInBuffer = 8;
              }
              val |= (((bitBuffer & 0x80) != 0) ? mask : 0);
              mask <<= 1;
              bitBuffer <<= 1;
              bitsInBuffer--;
            }
           
            return val;
        }

        public void flushBitsFromReader() {
            bitsInBuffer = 0;
        }
    }
}
TOP

Related Classes of aterm.pure.binary.BAFReader$SymEntry

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.
y>