/*
* Created on Feb 22, 2007 Copyright (C) 2001-6, Anthony Harrison anh23@pitt.edu
* (jactr.org) This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have
* received a copy of the GNU Lesser 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 org.jactr.tools.async.message.ast;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.antlr.runtime.tree.CommonTree;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jactr.io.antlr3.serialization.Serializer;
import org.jactr.tools.async.message.BaseMessage;
/**
* @author developer
*/
public class BaseASTMessage extends BaseMessage implements Serializable,
IASTMessage
{
/**
*
*/
private static final long serialVersionUID = -7905429360085152901L;
/**
* logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(BaseASTMessage.class);
private transient CommonTree _ast;
private transient boolean _compress;
static private transient ThreadLocal<ByteArrayOutputStream> _localBAOS = new ThreadLocal<ByteArrayOutputStream>();
static private transient ThreadLocal<byte[]> _localInput = new ThreadLocal<byte[]>();
public BaseASTMessage(CommonTree ast)
{
_ast = ast;
}
public void compressAST()
{
_compress = true;
}
public CommonTree getAST()
{
return _ast;
}
protected void setAST(CommonTree ast)
{
_ast = ast;
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException
{
out.defaultWriteObject();
if (_ast != null)
{
out.writeBoolean(true);
out.writeBoolean(_compress);
if (_compress)
{
/*
* go to a GZIPOutputStream
*/
ByteArrayOutputStream baos = _localBAOS.get();
if (baos == null)
{
baos = new ByteArrayOutputStream();
_localBAOS.set(baos);
}
baos.reset();
DataOutputStream zip = new DataOutputStream(new GZIPOutputStream(baos));
Serializer.write(_ast, zip);
zip.flush();
zip.close();
// byte[] bytes = baos.toByteArray();
if (LOGGER.isDebugEnabled())
LOGGER.debug(String
.format("Writing %d compressed bytes", baos.size()));
out.writeInt(baos.size());
baos.writeTo(out);
// if (LOGGER.isDebugEnabled())
// LOGGER.debug("Compressed AST to "+bytes.length);
// out.writeInt(bytes.length);
// out.write(bytes);
}
else
Serializer.write(_ast, out);
}
else
out.writeBoolean(false);
}
private void readObject(java.io.ObjectInputStream in) throws IOException,
ClassNotFoundException
{
in.defaultReadObject();
boolean astIsNotNull = in.readBoolean();
if (astIsNotNull)
{
boolean wasCompressed = in.readBoolean();
if (wasCompressed)
{
/*
* pull through GZIPInputStream. this can be done more effeciently..
*/
int len = in.readInt();
byte[] bytes = _localInput.get();
if (bytes == null || bytes.length < len)
{
bytes = new byte[len];
_localInput.set(bytes);
}
if (LOGGER.isDebugEnabled()) LOGGER.debug("Reading "+len+" bytes to decompress");
in.read(bytes, 0, len);
// in.readFully(bytes);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes, 0, len);
DataInputStream zip = new DataInputStream(new GZIPInputStream(bais));
_ast = Serializer.read(zip);
}
else
_ast = Serializer.read(in);
}
}
}