1 5 package com.tc.object.dna.impl; 6 7 import com.tc.io.TCByteBufferOutputStream; 8 import com.tc.io.TCByteBufferOutputStream.Mark; 9 import com.tc.object.LiteralValues; 10 import com.tc.object.ObjectID; 11 import com.tc.object.dna.api.DNAWriter; 12 import com.tc.util.Conversion; 13 14 public class DNAWriterImpl implements DNAWriter { 15 16 private static final long NULL_ID = ObjectID.NULL_ID.toLong(); 17 private static final LiteralValues literalValues = new LiteralValues(); 18 19 private final TCByteBufferOutputStream output; 20 private final Mark headerMark; 21 private final Mark parentIdMark; 22 private final Mark arrayLengthMark; 23 private final ObjectStringSerializer serializer; 24 private final DNAEncoding encoding; 25 private final String className; 26 private final ObjectID id; 27 private int actionCount = 0; 28 29 public DNAWriterImpl(TCByteBufferOutputStream output, ObjectID id, String className, 30 ObjectStringSerializer serializer, DNAEncoding encoding, String loaderDesc, boolean isDelta) { 31 this.output = output; 32 this.id = id; 33 this.className = className; 34 this.encoding = encoding; 35 36 this.headerMark = output.mark(); 37 output.writeInt(-1); output.writeInt(-1); output.writeBoolean(isDelta); 40 output.writeLong(id.toLong()); 41 this.parentIdMark = output.mark(); 42 output.writeLong(NULL_ID); this.serializer = serializer; 44 serializer.writeString(output, className); 45 serializer.writeString(output, loaderDesc); 46 this.arrayLengthMark = output.mark(); 47 output.writeInt(-1); } 49 50 public void addLogicalAction(int method, Object [] parameters) { 51 actionCount++; 52 output.writeByte(DNAEncoding.LOGICAL_ACTION_TYPE); 53 output.writeInt(method); 54 output.writeByte(parameters.length); 55 56 for (int i = 0; i < parameters.length; i++) { 57 encoding.encode(parameters[i], output); 58 } 59 } 60 61 public void addSubArrayAction(int start, Object array, int length) { 62 actionCount++; 63 output.writeByte(DNAEncoding.SUB_ARRAY_ACTION_TYPE); 64 output.writeInt(start); 65 encoding.encodeArray(array, output, length); 66 } 67 68 public void addClassLoaderAction(String classLoaderFieldName, Object value) { 69 actionCount++; 70 output.writeByte(DNAEncoding.PHYSICAL_ACTION_TYPE); 71 serializer.writeFieldName(output, classLoaderFieldName); 72 encoding.encodeClassLoader(value, output); 73 } 74 75 81 public void addPhysicalAction(String fieldName, Object value) { 82 addPhysicalAction(fieldName, value, value instanceof ObjectID); 83 } 84 85 public void addPhysicalAction(String fieldName, Object value, boolean canBeReferenced) { 86 if (value == null) { 87 throw new AssertionError ("null value for field " + fieldName + " in type " + className + " " + id); 89 } 90 91 actionCount++; 92 if (canBeReferenced && literalValues.isLiteralInstance(value)) { 93 output.writeByte(DNAEncoding.PHYSICAL_ACTION_TYPE_REF_OBJECT); 95 } else { 96 output.writeByte(DNAEncoding.PHYSICAL_ACTION_TYPE); 97 } 98 serializer.writeFieldName(output, fieldName); 99 encoding.encode(value, output); 100 } 101 102 public void addArrayElementAction(int index, Object value) { 103 actionCount++; 104 output.writeByte(DNAEncoding.ARRAY_ELEMENT_ACTION_TYPE); 105 output.writeInt(index); 106 encoding.encode(value, output); 107 } 108 109 public void addEntireArray(Object value) { 110 actionCount++; 111 output.writeByte(DNAEncoding.ENTIRE_ARRAY_ACTION_TYPE); 112 encoding.encodeArray(value, output); 113 } 114 115 public void addLiteralValue(Object value) { 116 actionCount++; 117 output.writeByte(DNAEncoding.LITERAL_VALUE_ACTION_TYPE); 118 encoding.encode(value, output); 119 } 120 121 private void finalizeHeader() { 122 int totalLength = this.output.getBytesWritten() - this.headerMark.getPosition(); 123 byte[] lengths = new byte[8]; 124 Conversion.writeInt(totalLength, lengths, 0); 125 Conversion.writeInt(actionCount, lengths, 4); 126 this.headerMark.write(lengths); 127 } 128 129 public void finalizeDNA() { 130 finalizeHeader(); 131 } 132 133 public void setParentObjectID(ObjectID id) { 134 this.parentIdMark.write(Conversion.long2Bytes(id.toLong())); 135 } 136 137 public void setArrayLength(int length) { 138 this.arrayLengthMark.write(Conversion.int2Bytes(length)); 139 } 140 } 141 | Popular Tags |