Package anvil.core

Source Code of anvil.core.Unserializer

/*
* $Id: Unserializer.java,v 1.20 2002/09/16 08:05:02 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.core;

import anvil.script.Context;
import java.util.ArrayList;

/**
*
* Class for wrapping byte array and pointer to it.
*
* @author Jani Lehtim�ki
* @version $Revision: 1.20 $
*/
public final class Unserializer
{

  byte[] _data;
  int    _length;
  int    _pos;

  private Context _context;
  private ArrayList _registered = null;
  private boolean _unicode = true;
 

  protected Unserializer(Context context, byte[] data)
      throws UnserializationException
  {
    _context = context;
    _data = data;
    _length = data.length;
    _pos = 0;
    _unicode = consumeIf('!');
  }


  protected Unserializer(Context context, byte[] data, int begin, int end)
      throws UnserializationException
  {
    _context = context;
    _data = data;
    _length = end;
    _pos = begin;
    _unicode = consumeIf('!');
  }


  public Context getContext() throws UnserializationException
  {
    Context context = _context;
    if (context == null) {
      _context = context = Context.getInstance();
    }
    return context;
  }
 

  public void register(Object o)
  {
    if (_registered == null) {
      _registered = new ArrayList();
    }
    _registered.add(o);
  }
 

  public void close()
  {
    if (_registered != null) {
      _registered.clear();
      _registered = null;
    }
  }
 

  public int peek()
  {
    if (_pos < _length) {
      return _data[_pos];
    } else {
      return -1;
    }
  }
 
 
  public void back()
  {
    if (_pos > 0) {
      _pos--;
    }
  } 

 
  public String getView()
  {
    return new String(_data, _pos, _length - _pos);
  }
 
  public int get() throws UnserializationException
  {
    if (_pos < _length) {
      return _data[_pos++];
    } else {
      throw new UnserializationException();
    }
  } 


  public void consume(int ch) throws UnserializationException
  {
    if (_pos < _length) {
      if (_data[_pos++] == ch) {
        return;
      }
    }
    throw new UnserializationException();
  }
 

  public Object consumeRegisteredIf() throws UnserializationException
  {
    if (_pos < _length) {
      if (_data[_pos] == '#') {
        _pos++;
        return _registered.get((int)getLong());
      }
      return null;
    } else {
      throw new UnserializationException();
    }
  }
   

  public boolean consumeIf(int ch) throws UnserializationException
  {
    if (_pos < _length) {
      if (_data[_pos] == ch) {
        _pos++;
        return true;
      }
      return false;
    }
    throw new UnserializationException();
  }
 

  /**
   * Helper method which actually does the serialization.
   *
   * @return Unserialized value
   * @exception UnserializationException If data has been corrupted
   */
  public final Any unserialize()
      throws UnserializationException
  {
    byte[] data = _data;
    if (_pos >= _length) {
      throw new UnserializationException();
    }

    switch(data[_pos++]) {
    case (byte)'!'// unicode marker, first byte in stream
    case (byte)'['// stackframe, appears only with closure
      throw new UnserializationException("Invalid tag");
     
    case (byte)'#':
      return (Any)_registered.get((int)getLong());

    case (byte)'-':
      return Any.NEG_INF;
 
    case (byte)'+':
      return Any.INF;

    case (byte)'n':
      return Any.NULL;

    case (byte)'u':
      return Any.UNDEFINED;
   
    case (byte)'t':
      return Any.TRUE;

    case (byte)'f':
      return Any.FALSE;
     
    case (byte)'i':
      return ObjectPool.createLong(getLong());

    case (byte)'d':
      return new AnyDouble(getDouble());

    case (byte)'s':
      {
        AnyString str = new AnyString(getUTF16String());
        register(str);
        return str;
      }
     
    case (byte)'b':
      return AnyBinary.unserialize(this);

    case (byte)'B':
      {
        AnyBuffer buffer = new AnyBuffer(new StringBuffer(getUTF16String()));
        register(buffer);
        return buffer;
      }

    case (byte)'l':
      return AnyTuple.unserialize(this);

    case (byte)'L':
      return AnyList.unserialize(this);

    case (byte)'a':
      return Array.unserialize(this);

    case (byte)'o':
      return AnyClass.unserialize(this);
     
    case (byte)'x':
      return AnyAbstractClass.unserialize(this);

    case (byte)'p':
      return AnyPattern.unserialize(this);

    case (byte)'r':
      return AnyRange.unserialize(this);
     
    case (byte)'m':
      return AnyMap.unserialize(this);

    case (byte)'q':
      return AnyLocalRef.unserialize(this);
     
    case (byte)'Q':
      return AnyEscapedLocalRef.unserialize(this);

    case (byte)'R':
      return AnyClassRef.unserialize(this);

    case (byte)'F':
      return anvil.core.io.AnyFile.unserialize(this);

    case (byte)'U':
      return anvil.core.net.AnyURL.unserialize(this);

    case (byte)'I':
      return anvil.core.net.AnyInetAddress.unserialize(this);

    case (byte)'C':
      return anvil.core.time.AnyCalendar.unserialize(this);
     
    case (byte)'M':
      return anvil.core.runtime.AnyScope.unserialize(this);

    case (byte)'c':
      return anvil.core.runtime.AnyFunction.unserialize(this);

    case (byte)'D':
      return anvil.core.runtime.AnyFunction.unserializeDelegate(this);

    case (byte)'Z':
      return anvil.core.runtime.AnyFunction.unserializeClosure(this);

    case (byte)'N':
      return anvil.core.runtime.AnyNamespace.unserialize(this);

    case (byte)'T':
      return anvil.core.runtime.AnyType.unserialize(this);

    case (byte)'H':
      return anvil.core.runtime.AnyDoc.unserialize(this);

    case (byte)'P':
      return anvil.core.runtime.AnyPermission.unserialize(this);

    case (byte)'A':
      return anvil.core.arrays.AnyArray.unserialize(this);

    default:
      throw new UnserializationException("Invalid tag");
    }

  }   

  /**
   * Helper method for unserializing String.
   * This method uses deprecated API when instantiating new Strings
   * for the purposes of efficiency.
   *
   * @return Unserialized String
   * @exception UnserializationException If data has been corrupted
   */
  public final String getUTF16String() 
      throws UnserializationException
  {
    if (_unicode) {
      int length = (int)getLong();
      if (length < 0) {
        throw new UnserializationException();
      }
      byte[] data = _data;
      int pos = _pos;
      if ((pos + length*2) > _length) {
        throw new UnserializationException();
      }
      char[] array = new char[length];
      for(int i=0; i<length; i++) {
        array[i] = (char)((data[pos++]<<8) | (data[pos++] & 0xff));
      }
      _pos = pos;
      return new String(array);
     
    } else {
      return getBinaryString();
    }
  }


  public final String getBinaryString() 
      throws UnserializationException
  {
    int length = (int)getLong();
    if (length < 0) {
      throw new UnserializationException();
    }
    byte[] data = _data;
    int pos = _pos;
    if ((pos + length) > _length) {
      throw new UnserializationException();
    }
    _pos = pos + length;
    return new String(data, 0, pos, length);     
  }



  /**
   * Helper method for unserializing integer.
   *
   * @return Unserialized integer
   * @exception UnserializationException If data has been corrupted
   */
  public final long getLong() throws UnserializationException
  {
    byte[] data = _data;
    int length = _length;
    int pos = _pos;

    long number = 0;
    long multiply = 1;
    boolean negative = false;
    int begin;
    int ch;
   
    if ((pos+1) >= length) {
      throw new UnserializationException();
    }
   
    if (data[pos] == '-') {
      negative = true;
      pos++;
    }
     
    begin = pos;
    while(pos < length) {
      ch = data[pos++];
      if (ch<'0' || ch>'9') {
        break;
      }
    }

    if (pos - begin <= 1) {
      throw new UnserializationException();
    }
   
    for(int p=pos-2; p>=begin; p--) {
      number += ((((long)data[p])-'0') * multiply);
      multiply *= 10;
    }
    _pos = pos;
    return negative ? -number : number;
  }



  /**
   * Helper method for unserializing Double.
   *
   * @return Unserialized Double
   * @exception UnserializationException If data has been corrupted
   */
  public final double getDouble() throws UnserializationException
  {
    byte[] data   = _data;
    int    length = _length;
    int    pos    = _pos;
   
    if ((pos+2) >= length) {
      throw new UnserializationException();
    }
   
    int begin = pos;
    while(pos < length) {
      if (data[pos++]==';') {
        break;
      }
    }
    _pos = pos;
   
    try {
      return Double.parseDouble(new String(data, 0, begin, pos - 1 - begin));
    } catch (NumberFormatException e) {
      throw new UnserializationException();
    }
   
  }
 

  /**
   * Helper method for unserializing float.
   *
   * @return Unserialized float
   * @exception UnserializationException If data has been corrupted
   */
  public final float getFloat() throws UnserializationException
  {
    byte[] data   = _data;
    int    length = _length;
    int    pos    = _pos;
   
    if ((pos+2) >= length) {
      throw new UnserializationException();
    }
   
    int begin = pos;
    while(pos < length) {
      if (data[pos++]==';') {
        break;
      }
    }
    _pos = pos;
   
    try {
      return Float.parseFloat(new String(data, 0, begin, pos - 1 - begin));
    } catch (NumberFormatException e) {
      throw new UnserializationException();
    }
   
  }
 


  public char getCharUTF16() throws UnserializationException
  {
    if ((_pos+2) >= _length) {
      throw new UnserializationException();
    }
    byte[] data = _data;
    return (char)((data[_pos++]<<8) | (data[_pos++] & 0xff));
  }


}
TOP

Related Classes of anvil.core.Unserializer

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.