1 21 package com.db4o; 22 23 import java.io.*; 24 25 import com.db4o.foundation.*; 26 import com.db4o.foundation.network.*; 27 28 36 public final class YapWriter extends YapReader { 37 38 39 private int i_address; 40 private int _addressOffset; 41 42 private int i_cascadeDelete; 43 44 private Tree i_embedded; 45 private int i_id; 46 47 private int i_instantionDepth; 49 private int i_length; 50 51 Transaction i_trans; 52 53 private int i_updateDepth = 1; 56 57 public int _payloadOffset; 58 59 60 public YapWriter(Transaction a_trans, int a_initialBufferSize) { 61 i_trans = a_trans; 62 i_length = a_initialBufferSize; 63 _buffer = new byte[i_length]; 64 } 65 66 public YapWriter(Transaction a_trans, int a_address, int a_initialBufferSize) { 67 this(a_trans, a_initialBufferSize); 68 i_address = a_address; 69 } 70 71 public YapWriter(YapWriter parent, YapWriter[] previousRead, int previousCount) { 72 previousRead[previousCount++] = this; 73 int parentID = parent.readInt(); 74 i_length = parent.readInt(); 75 i_id = parent.readInt(); 76 previousRead[parentID].addEmbedded(this); 77 i_address = parent.readInt(); 78 i_trans = parent.getTransaction(); 79 _buffer = new byte[i_length]; 80 System.arraycopy(parent._buffer, parent._offset, _buffer, 0, i_length); 81 parent._offset += i_length; 82 if (previousCount < previousRead.length) { 83 new YapWriter(parent, previousRead, previousCount); 84 } 85 } 86 87 100 public void addEmbedded(YapWriter a_bytes) { 101 i_embedded = Tree.add(i_embedded, new TreeIntObject(a_bytes.getID(), a_bytes)); 102 } 103 104 105 public int appendTo(final YapReader a_bytes, int a_id) { 106 a_id++; 107 a_bytes.writeInt(i_length); 108 a_bytes.writeInt(i_id); 109 a_bytes.writeInt(i_address); 110 a_bytes.append(_buffer); 111 final int[] newID = { a_id }; 112 final int myID = a_id; 113 forEachEmbedded(new VisitorYapBytes() { 114 public void visit(YapWriter a_embedded) { 115 a_bytes.writeInt(myID); 116 newID[0] = a_embedded.appendTo(a_bytes, newID[0]); 117 } 118 }); 119 return newID[0]; 120 } 121 122 public int cascadeDeletes() { 123 return i_cascadeDelete; 124 } 125 126 public void debugCheckBytes() { 127 if (Debug.xbytes) { 128 if (_offset != i_length) { 129 } 133 } 134 } 135 136 public int embeddedCount() { 137 final int[] count = { 0 }; 138 forEachEmbedded(new VisitorYapBytes() { 139 public void visit(YapWriter a_bytes) { 140 count[0] += 1 + a_bytes.embeddedCount(); 141 } 142 }); 143 return count[0]; 144 } 145 146 public int embeddedLength() { 147 final int[] length = { 0 }; 148 forEachEmbedded(new VisitorYapBytes() { 149 public void visit(YapWriter a_bytes) { 150 length[0] += a_bytes.getLength() + a_bytes.embeddedLength(); 151 } 152 }); 153 return length[0]; 154 } 155 156 void forEachEmbedded(final VisitorYapBytes a_visitor) { 157 if (i_embedded != null) { 158 i_embedded.traverse(new Visitor4() { 159 public void visit(Object a_object) { 160 a_visitor.visit((YapWriter) ((TreeIntObject)a_object)._object); 161 } 162 }); 163 } 164 } 165 166 public int getAddress() { 167 return i_address; 168 } 169 170 public int addressOffset(){ 171 return _addressOffset; 172 } 173 174 public int getID() { 175 return i_id; 176 } 177 178 public int getInstantiationDepth() { 179 return i_instantionDepth; 180 } 181 182 public int getLength() { 183 return i_length; 184 } 185 186 public YapStream getStream() { 187 return i_trans.stream(); 188 } 189 190 public YapStream stream(){ 191 return i_trans.stream(); 192 } 193 194 public YapFile file(){ 195 return i_trans.i_file; 196 } 197 198 public Transaction getTransaction() { 199 return i_trans; 200 } 201 202 public int getUpdateDepth() { 203 return i_updateDepth; 204 } 205 206 byte[] getWrittenBytes(){ 207 byte[] bytes = new byte[_offset]; 208 System.arraycopy(_buffer, 0, bytes, 0, _offset); 209 return bytes; 210 } 211 212 public int preparePayloadRead() { 213 int newPayLoadOffset = readInt(); 214 int length = readInt(); 215 int linkOffSet = _offset; 216 _offset = newPayLoadOffset; 217 _payloadOffset += length; 218 return linkOffSet; 219 } 220 221 public void read() { 222 stream().readBytes(_buffer, i_address,_addressOffset, i_length); 223 } 224 225 public final boolean read(YapSocket sock) throws IOException { 226 int offset = 0; 227 int length = i_length; 228 while (length > 0) { 229 int read = sock.read(_buffer, offset, length); 230 if(read<0) { 231 return false; 232 } 233 offset += read; 234 length -= read; 235 } 236 return true; 237 } 238 239 public final YapWriter readEmbeddedObject() { 240 int id = readInt(); 241 int length = readInt(); 242 YapWriter bytes = null; 243 Tree tio = TreeInt.find(i_embedded, id); 244 if (tio != null) { 245 bytes = (YapWriter) ((TreeIntObject)tio)._object; 246 }else{ 247 bytes = stream().readWriterByAddress(i_trans, id, length); 248 if (bytes != null) { 249 bytes.setID(id); 250 } 251 } 252 if(bytes != null){ 253 bytes.setUpdateDepth(getUpdateDepth()); 254 bytes.setInstantiationDepth(getInstantiationDepth()); 255 } 256 return bytes; 257 } 258 259 public final YapWriter readYapBytes() { 260 int length = readInt(); 261 if (length == 0) { 262 return null; 263 } 264 YapWriter yb = new YapWriter(i_trans, length); 265 System.arraycopy(_buffer, _offset, yb._buffer, 0, length); 266 _offset += length; 267 return yb; 268 } 269 270 public void removeFirstBytes(int aLength) { 271 i_length -= aLength; 272 byte[] temp = new byte[i_length]; 273 System.arraycopy(_buffer, aLength, temp, 0, i_length); 274 _buffer = temp; 275 _offset -= aLength; 276 if (_offset < 0) { 277 _offset = 0; 278 } 279 } 280 281 public void address(int a_address) { 282 i_address = a_address; 283 } 284 285 public void setCascadeDeletes(int depth) { 286 i_cascadeDelete = depth; 287 } 288 289 public void setID(int a_id) { 290 i_id = a_id; 291 } 292 293 public void setInstantiationDepth(int a_depth) { 294 i_instantionDepth = a_depth; 295 } 296 297 public void setTransaction(Transaction aTrans) { 298 i_trans = aTrans; 299 } 300 301 public void setUpdateDepth(int a_depth) { 302 i_updateDepth = a_depth; 303 } 304 305 public void slotDelete() { 306 i_trans.slotDelete(i_id, i_address, i_length); 307 } 308 309 public void trim4(int a_offset, int a_length) { 310 byte[] temp = new byte[a_length]; 311 System.arraycopy(_buffer, a_offset, temp, 0, a_length); 312 _buffer = temp; 313 i_length = a_length; 314 } 315 316 void useSlot(int a_adress) { 317 i_address = a_adress; 318 _offset = 0; 319 } 320 321 public void useSlot(int a_adress, int a_length) { 322 i_address = a_adress; 323 _offset = 0; 324 if (a_length > _buffer.length) { 325 _buffer = new byte[a_length]; 326 } 327 i_length = a_length; 328 } 329 330 public void useSlot(int a_id, int a_adress, int a_length) { 331 i_id = a_id; 332 useSlot(a_adress, a_length); 333 } 334 335 public void write() { 336 if (Debug.xbytes) { 337 debugCheckBytes(); 338 } 339 file().writeBytes(this, i_address, _addressOffset); 340 } 341 342 public void writeEmbedded() { 343 final YapWriter finalThis = this; 344 forEachEmbedded(new VisitorYapBytes() { 345 public void visit(YapWriter a_bytes) { 346 a_bytes.writeEmbedded(); 347 stream().writeEmbedded(finalThis, a_bytes); 348 } 349 }); 350 351 357 i_embedded = null; } 359 360 public void writeEmbeddedNull() { 361 writeInt(0); 362 writeInt(0); 363 } 364 365 public void writeEncrypt() { 366 if (Deploy.debug) { 367 debugCheckBytes(); 368 } 369 writeEncrypt(file(),i_address, _addressOffset); 370 } 371 372 375 public void writePayload(YapWriter payLoad, boolean topLevel){ 376 checkMinimumPayLoadOffsetAndWritePointerAndLength(payLoad.getLength(), topLevel); 377 System.arraycopy(payLoad._buffer, 0, _buffer, _payloadOffset, payLoad._buffer.length); 378 transferPayLoadAddress(payLoad, _payloadOffset); 379 _payloadOffset += payLoad._buffer.length; 380 } 381 382 private void checkMinimumPayLoadOffsetAndWritePointerAndLength(int length, boolean alignToBlockSize){ 383 if(_payloadOffset <= _offset + (YapConst.INT_LENGTH * 2)){ 384 _payloadOffset = _offset + (YapConst.INT_LENGTH * 2); 385 } 386 if(alignToBlockSize){ 387 _payloadOffset = stream().alignToBlockSize(_payloadOffset); 388 } 389 writeInt(_payloadOffset); 390 391 writeInt(length); 399 } 400 401 public int reserveAndPointToPayLoadSlot(int length){ 402 checkMinimumPayLoadOffsetAndWritePointerAndLength(length, false); 403 int linkOffset = _offset; 404 _offset = _payloadOffset; 405 _payloadOffset += length; 406 return linkOffset; 407 } 408 409 public YapReader readPayloadWriter(int offset, int length){ 410 YapWriter payLoad = new YapWriter(i_trans, 0, length); 411 System.arraycopy(_buffer,offset, payLoad._buffer, 0, length); 412 transferPayLoadAddress(payLoad, offset); 413 return payLoad; 414 } 415 416 private void transferPayLoadAddress(YapWriter toWriter, int offset) { 417 int blockedOffset = offset / stream().blockSize(); 418 toWriter.i_address = i_address + blockedOffset; 419 toWriter.i_id = toWriter.i_address; 420 toWriter._addressOffset = _addressOffset; 421 } 422 423 void writeShortString(String a_string) { 424 writeShortString(i_trans, a_string); 425 } 426 427 public void moveForward(int length) { 428 _addressOffset += length; 429 } 430 431 public void writeForward() { 432 write(); 433 _addressOffset += i_length; 434 _offset = 0; 435 } 436 437 public String toString(){ 438 if(! Debug4.prettyToStrings){ 439 return super.toString(); 440 } 441 return "id " + i_id + " adr " + i_address + " len " + i_length; 442 } 443 444 public void noXByteCheck() { 445 if(Debug.xbytes && Deploy.overwrite){ 446 setID(YapConst.IGNORE_ID); 447 } 448 } 449 450 public void writeIDs(IntIterator4 idIterator, int maxCount ) { 451 int savedOffset = _offset; 452 writeInt(0); 453 int actualCount = 0; 454 while(idIterator.moveNext()){ 455 writeInt(idIterator.currentInt()); 456 actualCount ++; 457 if(actualCount >= maxCount){ 458 break; 459 } 460 } 461 int secondSavedOffset = _offset; 462 _offset = savedOffset; 463 writeInt(actualCount); 464 _offset = secondSavedOffset; 465 } 466 467 468 } 469 | Popular Tags |