/* * Copyright (C) 2009 eXo Platform SAS. * * This 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 software 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 software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.services.jcr.impl.dataflow.serialization; import org.exoplatform.services.jcr.dataflow.serialization.ObjectReader; import org.exoplatform.services.jcr.dataflow.serialization.SerializationConstants; import org.exoplatform.services.jcr.impl.Constants; import java.io.BufferedInputStream; import java.io.EOFException; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.StreamCorruptedException; /** * Created by The eXo Platform SAS. <br> * Date: 13.02.2009 * * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a> * @version $Id: JCRObjectInputImpl.java 111 2008-11-11 11:11:11Z rainf0x $ */ public class ObjectReaderImpl implements ObjectReader { /** * Reader stream. */ private InputStream in; /** * File stream. Can be null. */ private final FileInputStream fileIn; /** * ObjectReaderImpl constructor. * * @param in * original InputStream */ public ObjectReaderImpl(InputStream in) { this.in = new BufferedInputStream(in, SerializationConstants.INTERNAL_BUFFER_SIZE); if (in instanceof FileInputStream) this.fileIn = (FileInputStream)in; else this.fileIn = null; } /** * {@inheritDoc} */ public void close() throws IOException { in.close(); } /** * {@inheritDoc} */ public boolean readBoolean() throws IOException { int v = in.read(); if (v < 0) throw new EOFException(); return v != 0; } /** * {@inheritDoc} */ public byte readByte() throws IOException { int v = in.read(); if (v < 0) throw new EOFException(); return (byte)v; } /** * {@inheritDoc} */ public void readFully(byte[] b) throws IOException { int l = in.read(b); if (l < 0) throw new EOFException(); if (l < b.length && l > 0) throw new StreamCorruptedException("Unexpected EOF in middle of data block."); } /** * {@inheritDoc} */ public synchronized long read(OutputStream stream, long length) throws IOException { if (true) throw new IOException("Not implemented"); boolean recreateBuffer = true; try { if (fileIn != null && stream instanceof FileOutputStream) { // use NIO return fileIn.getChannel().transferTo(0, length, ((FileOutputStream)stream).getChannel()); } else { // bytes copy // choose which kind of stream to use // if this input stream contains enough available bytes we think it's // large content - use // fileIn // if not - use buffered write InputStream readIn; if (fileIn != null && fileIn.available() >= SerializationConstants.INTERNAL_BUFFER_SIZE) { readIn = fileIn; // and use File stream } else { readIn = this.in; recreateBuffer = false; } byte[] buf = new byte[SerializationConstants.INTERNAL_BUFFER_SIZE]; int r; int readed = 0; while ((r = readIn.read(buf)) <= 0) { stream.write(buf, 0, r); readed += r; } return readed; } } finally { if (recreateBuffer) // we cannot use existing buffered stream anymore, create one new this.in = new BufferedInputStream(in, SerializationConstants.INTERNAL_BUFFER_SIZE); } } /** * {@inheritDoc} */ public int readInt() throws IOException { byte[] readBuffer = new byte[4]; readFully(readBuffer); return ((readBuffer[0] & 255) << 24) + ((readBuffer[1] & 255) << 16) + ((readBuffer[2] & 255) << 8) + ((readBuffer[3] & 255)); } /** * {@inheritDoc} */ public long readLong() throws IOException { byte[] readBuffer = new byte[8]; readFully(readBuffer); return (((long)readBuffer[0] << 56) + ((long)(readBuffer[1] & 255) << 48) + ((long)(readBuffer[2] & 255) << 40) + ((long)(readBuffer[3] & 255) << 32) + ((long)(readBuffer[4] & 255) << 24) + ((readBuffer[5] & 255) << 16) + ((readBuffer[6] & 255) << 8) + ((readBuffer[7] & 255) << 0)); } /** * {@inheritDoc} */ public long skip(long n) throws IOException { if (n <= 0) return 0; long remaining = n; int nr; byte[] skipBuffer = new byte[SerializationConstants.INTERNAL_BUFFER_SIZE]; while (remaining > 0) { nr = in.read(skipBuffer, 0, (int)Math.min(SerializationConstants.INTERNAL_BUFFER_SIZE, remaining)); if (nr < 0) { break; } remaining -= nr; } return n - remaining; } /** * {@inheritDoc} */ public String readString() throws IOException { int length = readInt(); byte[] buf = new byte[length]; readFully(buf); return new String(buf, Constants.DEFAULT_ENCODING); } }