package org.infinispan.marshall.core;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.OutputStream;
import org.infinispan.commons.io.ByteBuffer;
import org.infinispan.commons.marshall.BufferSizePredictor;
import org.infinispan.commons.marshall.MarshallableTypeHints;
import org.infinispan.commons.marshall.StreamingMarshaller;
import org.infinispan.commons.marshall.jboss.ExtendedRiverUnmarshaller;
import org.infinispan.configuration.global.GlobalConfiguration;
import org.jboss.marshalling.ByteInput;
import org.jboss.marshalling.ByteOutput;
final class ExternalJBossMarshaller implements StreamingMarshaller {
final MarshallableTypeHints marshallableTypeHints = new MarshallableTypeHints();
final JBossMarshaller marshaller;
ExternalJBossMarshaller(GlobalMarshaller marshaller, GlobalConfiguration globalCfg) {
this.marshaller = new JBossMarshaller(marshaller, globalCfg);
}
@Override
public void objectToObjectStream(Object obj, ObjectOutput out) throws IOException {
BufferSizePredictor sizePredictor = marshallableTypeHints
.getBufferSizePredictor(obj.getClass());
int estimatedSize = sizePredictor.nextSize(obj);
ObjectOutput jbossOut = marshaller.startObjectOutput(
new JBossByteOutput(out), false, estimatedSize);
try {
jbossOut.writeObject(obj);
} finally {
marshaller.finishObjectOutput(jbossOut);
}
}
@Override
public Object objectFromObjectStream(ObjectInput in) throws IOException, ClassNotFoundException {
ExtendedRiverUnmarshaller jbossIn = (ExtendedRiverUnmarshaller)
marshaller.startObjectInput(new JBossByteInput(in), false);
try {
return jbossIn.readObject();
} finally {
// Rewind by skipping backwards (negatively)
in.skipBytes(-jbossIn.getUnreadBufferedCount());
marshaller.finishObjectInput(jbossIn);
}
}
@Override
public void start() {
marshaller.start();
}
@Override
public void stop() {
marshaller.stop();
}
@Override
public boolean isMarshallable(Object o) throws Exception {
return marshaller.isMarshallable(o);
}
@Override
public ObjectOutput startObjectOutput(OutputStream os, boolean isReentrant, int estimatedSize) throws IOException {
throw new UnsupportedOperationException("No longer in use");
}
@Override
public void finishObjectOutput(ObjectOutput oo) {
throw new UnsupportedOperationException("No longer in use");
}
@Override
public ObjectInput startObjectInput(InputStream is, boolean isReentrant) throws IOException {
throw new UnsupportedOperationException("No longer in use");
}
@Override
public void finishObjectInput(ObjectInput oi) {
throw new UnsupportedOperationException("No longer in use");
}
@Override
public Object objectFromInputStream(InputStream is) throws IOException, ClassNotFoundException {
throw new UnsupportedOperationException("No longer in use");
}
@Override
public byte[] objectToByteBuffer(Object obj, int estimatedSize) throws IOException, InterruptedException {
throw new UnsupportedOperationException("No longer in use");
}
@Override
public byte[] objectToByteBuffer(Object obj) throws IOException, InterruptedException {
throw new UnsupportedOperationException("No longer in use");
}
@Override
public Object objectFromByteBuffer(byte[] buf) throws IOException, ClassNotFoundException {
throw new UnsupportedOperationException("No longer in use");
}
@Override
public Object objectFromByteBuffer(byte[] buf, int offset, int length) throws IOException, ClassNotFoundException {
throw new UnsupportedOperationException("No longer in use");
}
@Override
public ByteBuffer objectToBuffer(Object o) throws IOException, InterruptedException {
throw new UnsupportedOperationException("No longer in use");
}
@Override
public BufferSizePredictor getBufferSizePredictor(Object o) {
throw new UnsupportedOperationException("No longer in use");
}
static final class JBossByteOutput extends OutputStream implements ByteOutput {
final ObjectOutput out;
JBossByteOutput(ObjectOutput out) {
this.out = out;
}
@Override
public void write(int b) throws IOException {
out.write(b);
}
}
static final class JBossByteInput extends InputStream implements ByteInput {
final ObjectInput in;
JBossByteInput(ObjectInput in) {
this.in = in;
}
@Override
public int read() throws IOException {
return in.read();
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return in.read(b, off, len);
}
}
}