// write identical to other version, but take field values from hashmap (because of annoying // putField/getField feature) private void writeCompatibleObjectFields( Object toWrite, Map fields, FSTClazzInfo.FSTFieldInfo[] fieldInfo) throws IOException { int booleanMask = 0; int boolcount = 0; for (int i = 0; i < fieldInfo.length; i++) { try { FSTClazzInfo.FSTFieldInfo subInfo = fieldInfo[i]; boolean isarr = subInfo.isArray(); Class subInfType = subInfo.getType(); if (subInfType != boolean.class || isarr) { if (boolcount > 0) { codec.writeFByte(booleanMask << (8 - boolcount)); boolcount = 0; booleanMask = 0; } } if (subInfo.isIntegral() && !isarr) { if (subInfType == boolean.class) { if (boolcount == 8) { codec.writeFByte(booleanMask << (8 - boolcount)); boolcount = 0; booleanMask = 0; } boolean booleanValue = ((Boolean) fields.get(subInfo.getField().getName())).booleanValue(); booleanMask = booleanMask << 1; booleanMask = (booleanMask | (booleanValue ? 1 : 0)); boolcount++; } else if (subInfType == int.class) { codec.writeFInt(((Number) fields.get(subInfo.getField().getName())).intValue()); } else if (subInfType == long.class) { codec.writeFLong(((Number) fields.get(subInfo.getField().getName())).longValue()); } else if (subInfType == byte.class) { codec.writeFByte(((Number) fields.get(subInfo.getField().getName())).byteValue()); } else if (subInfType == char.class) { codec.writeFChar((char) ((Number) fields.get(subInfo.getField().getName())).intValue()); } else if (subInfType == short.class) { codec.writeFShort(((Number) fields.get(subInfo.getField().getName())).shortValue()); } else if (subInfType == float.class) { codec.writeFFloat(((Number) fields.get(subInfo.getField().getName())).floatValue()); } else if (subInfType == double.class) { codec.writeFDouble(((Number) fields.get(subInfo.getField().getName())).doubleValue()); } } else { // object Object subObject = fields.get(subInfo.getField().getName()); writeObjectWithContext(subInfo, subObject); } } catch (Exception ex) { throw FSTUtil.rethrow(ex); } } if (boolcount > 0) { codec.writeFByte(booleanMask << (8 - boolcount)); } }
private void writeObjectFields( Object toWrite, FSTClazzInfo serializationInfo, FSTClazzInfo.FSTFieldInfo[] fieldInfo, int startIndex, int version) throws IOException { try { int booleanMask = 0; int boolcount = 0; final int length = fieldInfo.length; int j = startIndex; if (!codec.isWritingAttributes()) { for (; ; j++) { if (j == length || fieldInfo[j].getVersion() != version) { if (boolcount > 0) { codec.writeFByte(booleanMask << (8 - boolcount)); } break; } final FSTClazzInfo.FSTFieldInfo subInfo = fieldInfo[j]; if (subInfo.getIntegralType() != subInfo.BOOL) { if (boolcount > 0) { codec.writeFByte(booleanMask << (8 - boolcount)); } break; } else { if (boolcount == 8) { codec.writeFByte(booleanMask << (8 - boolcount)); boolcount = 0; booleanMask = 0; } boolean booleanValue = subInfo.getBooleanValue(toWrite); booleanMask = booleanMask << 1; booleanMask = (booleanMask | (booleanValue ? 1 : 0)); boolcount++; } } } for (int i = j; i < length; i++) { final FSTClazzInfo.FSTFieldInfo subInfo = fieldInfo[i]; if (subInfo.getVersion() != version) { codec.writeVersionTag(subInfo.getVersion()); writeObjectFields(toWrite, serializationInfo, fieldInfo, i, subInfo.getVersion()); return; } codec.writeAttributeName(subInfo); if (subInfo.isPrimitive()) { // speed safe int integralType = subInfo.getIntegralType(); switch (integralType) { case FSTClazzInfo.FSTFieldInfo.BOOL: codec.writeFByte(subInfo.getBooleanValue(toWrite) ? 1 : 0); break; case FSTClazzInfo.FSTFieldInfo.BYTE: codec.writeFByte(subInfo.getByteValue(toWrite)); break; case FSTClazzInfo.FSTFieldInfo.CHAR: codec.writeFChar((char) subInfo.getCharValue(toWrite)); break; case FSTClazzInfo.FSTFieldInfo.SHORT: codec.writeFShort((short) subInfo.getShortValue(toWrite)); break; case FSTClazzInfo.FSTFieldInfo.INT: codec.writeFInt(subInfo.getIntValue(toWrite)); break; case FSTClazzInfo.FSTFieldInfo.LONG: codec.writeFLong(subInfo.getLongValue(toWrite)); break; case FSTClazzInfo.FSTFieldInfo.FLOAT: codec.writeFFloat(subInfo.getFloatValue(toWrite)); break; case FSTClazzInfo.FSTFieldInfo.DOUBLE: codec.writeFDouble(subInfo.getDoubleValue(toWrite)); break; } } else if (subInfo.isConditional()) { final int conditional = codec.getWritten(); codec.skip(4); // object Object subObject = subInfo.getObjectValue(toWrite); if (subObject == null) { codec.writeTag(NULL, null, 0, toWrite); } else { writeObjectWithContext(subInfo, subObject); } int v = codec.getWritten(); codec.writeInt32At(conditional, v); } else { // object Object subObject = subInfo.getObjectValue(toWrite); if (subObject == null) { codec.writeTag(NULL, null, 0, toWrite); } else { writeObjectWithContext(subInfo, subObject); } } } codec.writeVersionTag((byte) 0); } catch (IllegalAccessException ex) { throw FSTUtil.rethrow(ex); } }
@Override public void writeDouble(double v) throws IOException { codec.writeFDouble(v); }