package org.infinispan.marshaller.protostuff;
import static io.protostuff.LinkedBuffer.MIN_BUFFER_SIZE;
import java.io.IOException;
import java.util.ServiceLoader;
import org.infinispan.commons.io.ByteBuffer;
import org.infinispan.commons.io.ByteBufferImpl;
import org.infinispan.commons.marshall.AbstractMarshaller;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
/**
* @author Ryan Emerson
* @since 9.0
*/
public class ProtostuffMarshaller extends AbstractMarshaller {
static {
ClassLoader loader = ProtostuffMarshaller.class.getClassLoader();
ServiceLoader.load(SchemaRegistryService.class, loader).forEach(SchemaRegistryService::register);
}
private static final Schema<Wrapper> WRAPPER_SCHEMA = RuntimeSchema.getSchema(Wrapper.class);
@Override
public Object objectFromByteBuffer(byte[] bytes, int offset, int length) throws IOException, ClassNotFoundException {
Wrapper wrapper = WRAPPER_SCHEMA.newMessage();
ProtostuffIOUtil.mergeFrom(bytes, offset, length, wrapper, WRAPPER_SCHEMA);
return wrapper.object;
}
@Override
protected ByteBuffer objectToBuffer(Object obj, int estimatedSize) throws IOException, InterruptedException {
LinkedBuffer buffer = estimatedSize < MIN_BUFFER_SIZE ? LinkedBuffer.allocate(MIN_BUFFER_SIZE) : LinkedBuffer.allocate(estimatedSize);
byte[] bytes = ProtostuffIOUtil.toByteArray(new Wrapper(obj), WRAPPER_SCHEMA, buffer);
return new ByteBufferImpl(bytes, 0, bytes.length);
}
@Override
public boolean isMarshallable(Object obj) throws Exception {
try {
objectToBuffer(obj);
return true;
} catch (Throwable t) {
return false;
}
}
}