org.nustaq.serialization.FSTObjectOutputNoShared Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fst Show documentation
Show all versions of fst Show documentation
A fast java serialization drop in-replacement and some serialization based utils such as Structs and OffHeap Memory.
/*
* Copyright 2014 Ruediger Moeller.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nustaq.serialization;
import java.io.IOException;
import java.io.OutputStream;
/**
* Subclass optimized for "unshared mode". Cycles and Objects referenced more than once will not be detected.
* Additionally JDK compatibility is not supported (read/writeObject and stuff). Use case is highperformance
* serialization of plain cycle free data (e.g. messaging). Can perform significantly faster (20-40%).
*/
// FIXME: needs adaption to 2.0
public class FSTObjectOutputNoShared extends FSTObjectOutput {
/**
* Creates a new FSTObjectOutput stream to write data to the specified
* underlying output stream.
* uses Default Configuration singleton
*
* @param out
*/
public FSTObjectOutputNoShared(OutputStream out) {
super(out);
objects.disabled = true;
}
/**
* Creates a new FSTObjectOutputNoShared stream to write data to the specified
* underlying output stream. The counter written
is
* set to zero.
* Don't create a FSTConfiguration with each stream, just create one global static configuration and reuse it.
* FSTConfiguration is threadsafe.
*
* @param out the underlying output stream, to be saved for later
* use.
* @param conf
*/
public FSTObjectOutputNoShared(OutputStream out, FSTConfiguration conf) {
super(out, conf);
conf.setShareReferences(false);
objects.disabled = true;
}
/**
* serialize without an underlying stream, the resulting byte array of writing to
* this FSTObjectOutput can be accessed using getBuffer(), the size using getWritten().
*
* Don't create a FSTConfiguration with each stream, just create one global static configuration and reuseit.
* FSTConfiguration is threadsafe.
*
* @param conf
*/
public FSTObjectOutputNoShared(FSTConfiguration conf) {
super(conf);
conf.setShareReferences(false);
objects.disabled = true;
}
/**
* serialize without an underlying stream, the resulting byte array of writing to
* this FSTObjectOutput can be accessed using getBuffer(), the size using getWritten().
*
* uses default configuration singleton
*
*/
public FSTObjectOutputNoShared() {
super();
}
@Override
protected FSTClazzInfo writeObjectWithContext(FSTClazzInfo.FSTFieldInfo referencee, Object toWrite) throws IOException {
int startPosition = getCodec().getWritten();
boolean dontShare = true;
objectWillBeWritten(toWrite,startPosition);
try {
if ( toWrite == null ) {
getCodec().writeTag(NULL, null, 0, toWrite, this);
return null;
}
final Class clazz = toWrite.getClass();
if ( clazz == String.class ) {
String[] oneOf = referencee.getOneOf();
if ( oneOf != null ) {
for (int i = 0; i < oneOf.length; i++) {
String s = oneOf[i];
if ( s.equals(toWrite) ) {
getCodec().writeTag(ONE_OF, oneOf, i, toWrite, this);
getCodec().writeFByte(i);
return null;
}
}
}
if (dontShare) {
getCodec().writeTag(STRING, toWrite, 0, toWrite, this);
getCodec().writeStringUTF((String) toWrite);
return null;
}
} else if ( clazz == Integer.class ) {
getCodec().writeTag(BIG_INT, null, 0, toWrite, this);
getCodec().writeFInt(((Integer) toWrite).intValue()); return null;
} else if ( clazz == Long.class ) {
getCodec().writeTag(BIG_LONG, null, 0, toWrite, this);
getCodec().writeFLong(((Long) toWrite).longValue()); return null;
} else if ( clazz == Boolean.class ) {
getCodec().writeTag(((Boolean) toWrite).booleanValue() ? BIG_BOOLEAN_TRUE : BIG_BOOLEAN_FALSE, null, 0, toWrite, this); return null;
} else if ( (referencee.getType() != null && referencee.getType().isEnum()) || toWrite instanceof Enum ) {
if ( ! getCodec().writeTag(ENUM, toWrite, 0, toWrite, this) ) {
boolean isEnumClass = toWrite.getClass().isEnum();
if (!isEnumClass) {
// weird stuff ..
Class c = toWrite.getClass();
while (c != null && !c.isEnum()) {
c = toWrite.getClass().getSuperclass();
}
if (c == null) {
throw new RuntimeException("Can't handle this enum: " + toWrite.getClass());
}
getCodec().writeClass(c);
} else {
getCodec().writeClass(getFstClazzInfo(referencee, toWrite.getClass()));
}
getCodec().writeFInt(((Enum) toWrite).ordinal());
}
return null;
}
FSTClazzInfo serializationInfo = getFstClazzInfo(referencee, clazz);
// check for identical / equal objects
FSTObjectSerializer ser = serializationInfo.getSer();
if (clazz.isArray()) {
if (getCodec().writeTag(ARRAY, toWrite, 0, toWrite, this))
return null; // some codecs handle primitive arrays like an primitive type
writeArray(referencee, toWrite);
} else if ( ser == null ) {
// default write object wihtout custom serializer
// handle write replace
if (! writeObjectHeader(serializationInfo, referencee, toWrite) ) { // skip in case codec can write object as primitive
defaultWriteObject(toWrite, serializationInfo);
if ( serializationInfo.isExternalizable() )
getCodec().externalEnd(serializationInfo);
}
} else { // object has custom serializer
// Object header (nothing written till here)
int pos = getCodec().getWritten();
if (! writeObjectHeader(serializationInfo, referencee, toWrite) ) { // skip in case code can write object as primitive
// write object depending on type (custom, externalizable, serializable/java, default)
ser.writeObject(this, toWrite, serializationInfo, referencee, pos);
getCodec().externalEnd(serializationInfo);
}
}
return serializationInfo;
} finally {
objectHasBeenWritten(toWrite,startPosition, getCodec().getWritten());
}
}
public void resetForReUse( OutputStream out ) {
if ( closed )
throw new RuntimeException("Can't reuse closed stream");
getCodec().reset(null);
if ( out != null ) {
getCodec().setOutstream(out);
}
}
public void resetForReUse( byte[] out ) {
if ( closed )
throw new RuntimeException("Can't reuse closed stream");
getCodec().reset(out);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy