/** * Creates a new FSTObjectOutput stream to write data to the specified underlying output stream. * The counter <code>written</code> 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. */ public FSTObjectOutput(OutputStream out, FSTConfiguration conf) { this.conf = conf; codec = conf.createStreamEncoder(); codec.setOutstream(out); objects = (FSTObjectRegistry) conf.getCachedObject(FSTObjectRegistry.class); if (objects == null) { objects = new FSTObjectRegistry(conf); objects.disabled = !conf.isShareReferences(); } else { objects.clearForWrite(); } }
/** * if out == null => automatically create/reuse a bytebuffer * * @param out */ public void resetForReUse(OutputStream out) { if (closed) throw new RuntimeException("Can't reuse closed stream"); codec.reset(); if (out != null) { codec.setOutstream(out); } objects.clearForWrite(); }
public void resetForReUse(byte[] out) { if (closed) throw new RuntimeException("Can't reuse closed stream"); codec.reset(); codec.reset(out); objects.clearForWrite(); }
void resetAndClearRefs() { codec.reset(); objects.clearForWrite(); }
// splitting this slows down ... protected void writeObjectWithContext(FSTClazzInfo.FSTFieldInfo referencee, Object toWrite) throws IOException { int startPosition = codec.getWritten(); boolean dontShare = objects.disabled; objectWillBeWritten(toWrite, startPosition); try { if (toWrite == null) { codec.writeTag(NULL, null, 0, toWrite); return; } 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)) { codec.writeTag(ONE_OF, oneOf, i, toWrite); codec.writeFByte(i); return; } } } if (dontShare) { codec.writeTag(STRING, toWrite, 0, toWrite); codec.writeStringUTF((String) toWrite); return; } } else if (clazz == Integer.class) { codec.writeTag(BIG_INT, null, 0, toWrite); codec.writeFInt(((Integer) toWrite).intValue()); return; } else if (clazz == Long.class) { codec.writeTag(BIG_LONG, null, 0, toWrite); codec.writeFLong(((Long) toWrite).longValue()); return; } else if (clazz == Boolean.class) { codec.writeTag( ((Boolean) toWrite).booleanValue() ? BIG_BOOLEAN_TRUE : BIG_BOOLEAN_FALSE, null, 0, toWrite); return; } else if ((referencee.getType() != null && referencee.getType().isEnum()) || toWrite instanceof Enum) { if (!codec.writeTag(ENUM, toWrite, 0, toWrite)) { boolean isEnumClass = toWrite.getClass().isEnum(); if (!isEnumClass) { // weird stuff .. Class c = toWrite.getClass(); while (c != null && !c.isEnum()) { c = toWrite.getClass().getEnclosingClass(); } if (c == null) { throw new RuntimeException("Can't handle this enum: " + toWrite.getClass()); } codec.writeClass(c); } else { codec.writeClass(getFstClazzInfo(referencee, toWrite.getClass())); } codec.writeFInt(((Enum) toWrite).ordinal()); } return; } FSTClazzInfo serializationInfo = getFstClazzInfo(referencee, clazz); // check for identical / equal objects FSTObjectSerializer ser = serializationInfo.getSer(); if (!dontShare && !referencee.isFlat() && !serializationInfo.isFlat() && (ser == null || !ser.alwaysCopy())) { int handle = objects.registerObjectForWrite(toWrite, codec.getWritten(), serializationInfo, tmp); // determine class header if (handle >= 0) { final boolean isIdentical = tmp[0] == 0; // objects.getReadRegisteredObject(handle) == toWrite; if (isIdentical) { // System.out.println("POK writeHandle"+handle+" // "+toWrite.getClass().getName()); if (!codec.writeTag(HANDLE, null, handle, toWrite)) codec.writeFInt(handle); return; } } } if (clazz.isArray()) { if (codec.writeTag(ARRAY, toWrite, 0, toWrite)) return; // 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 (!dontShare) { if (serializationInfo.getWriteReplaceMethod() != null) { Object replaced = null; try { replaced = serializationInfo.getWriteReplaceMethod().invoke(toWrite); } catch (Exception e) { throw FSTUtil.rethrow(e); } if (replaced != toWrite) { toWrite = replaced; serializationInfo = getClassInfoRegistry().getCLInfo(toWrite.getClass()); // fixme: update object map ? } } // clazz uses some JDK special stuff (frequently slow) if (serializationInfo.useCompatibleMode() && !serializationInfo.isExternalizable()) { writeObjectCompatible(referencee, toWrite, serializationInfo); return; } } if (!writeObjectHeader( serializationInfo, referencee, toWrite)) { // skip in case codec can write object as primitive defaultWriteObject(toWrite, serializationInfo); if (serializationInfo.isExternalizable()) codec.externalEnd(serializationInfo); } } else { // object has custom serializer // Object header (nothing written till here) int pos = codec.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); codec.externalEnd(serializationInfo); } } } finally { objectHasBeenWritten(toWrite, startPosition, codec.getWritten()); } }