1 30 31 package org.objectweb.fractal.rmi.io; 32 33 import org.objectweb.jonathan.apis.binding.NamingContext; 34 import org.objectweb.jonathan.apis.kernel.Context; 35 import org.objectweb.jonathan.apis.kernel.ContextFactory; 36 import org.objectweb.jonathan.apis.kernel.InternalException; 37 import org.objectweb.jonathan.apis.kernel.JonathanException; 38 import org.objectweb.jonathan.apis.presentation.Marshaller; 39 import org.objectweb.jonathan.apis.resources.Chunk; 40 import org.objectweb.jonathan.apis.resources.ChunkFactory; 41 42 import java.io.IOException ; 43 import java.io.OutputStream ; 44 45 49 50 public class RmiMarshaller extends OutputStream implements Marshaller { 51 52 55 56 protected NamingContext domain; 57 58 61 62 protected ChunkFactory chunkFactory; 63 64 68 69 protected ContextFactory contextFactory; 70 71 76 77 protected RmiObjectOutputStream os; 78 79 private Chunk first; 80 81 private Chunk current; 82 83 private int offset; 84 85 private int top; 86 87 private Context context; 88 89 93 102 103 public RmiMarshaller ( 104 final NamingContext domain, 105 final ChunkFactory chunkFactory, 106 final ContextFactory contextFactory) 107 { 108 super(); 109 this.domain = domain; 110 this.chunkFactory = chunkFactory; 111 this.contextFactory = contextFactory; 112 first = chunkFactory.newChunk(); 113 current = first; 114 top = current.data.length; 115 } 116 117 121 126 127 public boolean isLittleEndian () { 128 return false; 129 } 130 131 136 137 public Context getContext () { 138 if (context == null) { 139 try { 140 context = contextFactory.newContext(); 141 } catch (NullPointerException e) { 142 e.printStackTrace(System.err); 143 throw new InternalException("Context factory required."); 144 } 145 } 146 return context; 147 } 148 149 156 157 public Chunk getState () { 158 if (current.next == null) { 159 current.top = offset; 160 } 161 return first; 162 } 163 164 170 171 public int getOffset () { 172 Chunk c = first; 173 int size = 0; 174 while (c != current) { 175 size += c.top - c.offset; 176 c = c.next; 177 } 178 return size + offset - current.offset; 179 } 180 181 188 189 public void setOffset (int off) { 190 if (current.next == null && offset > current.top) { 191 current.top = offset; 192 } 193 Chunk c = first; 194 int sz = c.top - c.offset; 195 while (off > sz) { 196 off -= sz; 197 c = c.next; 198 sz = c.top - c.offset; 199 } 200 offset = c.offset + off; 201 current = c; 202 if (current.next == null) { 203 top = current.data.length; 204 } else { 205 top = current.top; 206 } 207 } 208 209 216 217 public boolean sameContents (final Marshaller other) { 218 if (other == null) { 219 return false; 220 } else { 221 Chunk mine = getState(), yours = other.getState(); 222 if (mine == yours) { 223 return true; 224 } 225 226 byte[] my_data = null, your_data = null; 227 int my_top = 0, my_offset = 0, your_top = 0, your_offset = 0; 228 if (mine != null) { 229 my_data = mine.data; 230 my_top = mine.top; 231 my_offset = mine.offset; 232 } 233 if (yours != null) { 234 your_data = yours.data; 235 your_top = yours.top; 236 your_offset = yours.offset; 237 } 238 while (mine != null && yours != null) { 239 if (your_top - your_offset > my_top - my_offset) { 240 while (my_offset < my_top && 241 my_data[my_offset] == your_data[your_offset++]) { 242 my_offset++; 243 } 244 if (my_offset < my_top) { 245 return false; 246 } else { 247 mine = mine.next; 248 if (mine != null) { 249 my_data = mine.data; 250 my_top = mine.top; 251 my_offset = mine.offset; 252 } 253 } 254 } else { 255 while (your_offset < your_top && 256 my_data[my_offset++] == your_data[your_offset]) { 257 your_offset++; 258 } 259 if (your_offset < your_top) { 260 return false; 261 } else { 262 yours = yours.next; 263 if (yours != null) { 264 your_data = yours.data; 265 your_top = yours.top; 266 your_offset = yours.offset; 267 } 268 } 269 } 270 } 271 if (yours == null) { 272 if (mine != null && mine.top == my_offset) { 273 mine = mine.next; 274 } 275 while (mine != null && mine.top == mine.offset) { 276 mine = mine.next; 277 } 278 return mine == null; 279 } else { 280 if (yours.top == your_offset) { 281 yours = yours.next; 282 } 283 while (yours != null && yours.top == yours.offset) { 284 yours = yours.next; 285 } 286 return yours == null; 287 } 288 } 289 } 290 291 298 299 public void reset () { 300 first = null; 301 current = null; 302 offset = 0; 303 top = 0; 304 context = null; 305 } 306 307 313 314 public OutputStream outputStream () { 315 return this; 316 } 317 318 324 325 public void writeByte (final byte v) throws JonathanException { 326 if (offset >= top) { 327 prepare(); 328 } 329 current.data[offset++] = v; 330 } 331 332 338 339 public void writeBoolean (final boolean v) throws JonathanException { 340 if (offset >= top) { 341 prepare(); 342 } 343 current.data[offset++] = (byte)(v ? 1 : 0); 344 } 345 346 353 354 public void writeChar8 (final char v) throws JonathanException { 355 if (offset >= top) { 356 prepare(); 357 } 358 current.data[offset++] = (byte)v; 359 } 360 361 367 368 public void writeChar16 (final char v) throws JonathanException { 369 if (top - offset < 2) { 370 prepare(); 371 } 372 byte[] data = current.data; 373 data[offset++] = (byte)(v >>> 8); 374 data[offset++] = (byte)v; 375 } 376 377 383 384 public void writeShort (final short v) throws JonathanException { 385 if (top - offset < 2) { 386 prepare(); 387 } 388 byte[] data = current.data; 389 data[offset++] = (byte)(v >>> 8); 390 data[offset++] = (byte)v; 391 } 392 393 399 400 public void writeInt (final int v) throws JonathanException { 401 if (top - offset < 4) { 402 prepare(); 403 } 404 byte[] data = current.data; 405 data[offset++] = (byte)(v >>> 24); 406 data[offset++] = (byte)(v >>> 16); 407 data[offset++] = (byte)(v >>> 8); 408 data[offset++] = (byte)v; 409 } 410 411 417 418 public void writeFloat (final float v) throws JonathanException { 419 int i = Float.floatToIntBits(v); 420 if (top - offset < 4) { 421 prepare(); 422 } 423 byte[] data = current.data; 424 data[offset++] = (byte)(i >>> 24); 425 data[offset++] = (byte)(i >>> 16); 426 data[offset++] = (byte)(i >>> 8); 427 data[offset++] = (byte)i; 428 } 429 430 436 437 public void writeLong (final long v) throws JonathanException { 438 if (top - offset < 8) { 439 prepare(); 440 } 441 byte[] data = current.data; 442 data[offset++] = (byte)(v >>> 56); 443 data[offset++] = (byte)(v >>> 48); 444 data[offset++] = (byte)(v >>> 40); 445 data[offset++] = (byte)(v >>> 32); 446 data[offset++] = (byte)(v >>> 24); 447 data[offset++] = (byte)(v >>> 16); 448 data[offset++] = (byte)(v >>> 8); 449 data[offset++] = (byte)v; 450 } 451 452 458 459 public void writeDouble (final double v) throws JonathanException { 460 long l = Double.doubleToLongBits(v); 461 if (top - offset < 8) { 462 prepare(); 463 } 464 byte[] data = current.data; 465 data[offset++] = (byte)(l >>> 56); 466 data[offset++] = (byte)(l >>> 48); 467 data[offset++] = (byte)(l >>> 40); 468 data[offset++] = (byte)(l >>> 32); 469 data[offset++] = (byte)(l >>> 24); 470 data[offset++] = (byte)(l >>> 16); 471 data[offset++] = (byte)(l >>> 8); 472 data[offset++] = (byte)l; 473 } 474 475 481 482 public void writeString8 (final String v) throws JonathanException { 483 int len = v.length(); 484 writeInt(len + 1); 485 byte[] data = current.data; 486 int off = 0; 487 int max = top - offset; 488 while (max < len) { 489 while (off < max) { 490 data[offset++] = (byte)(v.charAt(off++)); 491 } 492 prepare(); 493 data = current.data; 494 max = top - offset + off; 495 } 496 while (off < len) { 497 data[offset++] = (byte)(v.charAt(off++)); 498 } 499 if (offset >= top) { 500 prepare(); 501 } 502 current.data[offset++] = (byte)0; 503 } 504 505 511 512 public void writeString16 (final String v) throws JonathanException { 513 throw new InternalException("Not implemented"); 514 } 515 516 524 525 public void write (final Chunk chunk) { 526 if (current.next != null) { 527 throw new InternalException("Illicit operation"); 528 } 529 current.top = offset; 530 current.next = chunk; 531 Chunk c = chunk; 532 while (c != null) { 533 current = c; 534 c = c.next; 535 } 536 offset = current.top; 537 top = current.data.length; 538 } 539 540 548 549 public void writeByteArray (final byte[] array, int off, int len) 550 throws JonathanException 551 { 552 int max = top - offset; 553 while (max < len) { 554 if (max > 0) { 555 System.arraycopy(array, off, current.data, offset, max); 556 off += max; 557 len -= max; 558 offset = top; 559 } 560 prepare(); 561 max = top - offset; 562 } 563 System.arraycopy(array,off,current.data,offset,len); 564 offset += len; 565 } 566 567 573 574 public void writeReference (final Object v) throws JonathanException { 575 try { 576 initObjectStream(); 577 os.writeObject(v); 578 os.drain(); 579 } catch (IOException e) { 580 throw new JonathanException(e); 581 } 582 } 583 584 590 591 public void writeValue (final Object v) throws JonathanException { 592 try { 593 initObjectStream(); 594 os.writeObject(v); 595 os.drain(); 596 } catch (IOException e) { 597 throw new JonathanException(e); 598 } 599 } 600 601 605 public void write (final int b) throws IOException { 606 try { 607 if (top <= offset) { 608 prepare(); 609 } 610 current.data[offset++] = (byte)b; 611 } catch (JonathanException e) { 612 throw new IOException (e.getMessage()); 613 } 614 } 615 616 public void write (final byte[] b, final int off, final int len) 617 throws IOException 618 { 619 try { 620 writeByteArray(b, off, len); 621 } catch (JonathanException e) { 622 throw new IOException (e.getMessage()); 623 } 624 } 625 626 public void close () { 627 Chunk cur = first; 628 Chunk next; 629 while (cur != null) { 630 next = cur.next; 631 cur.release(); 632 cur = next; 633 } 634 first = null; 635 current = null; 636 offset = 0; 637 top = 0; 638 if (context != null) { 639 context.release(); 640 context = null; 641 } 642 } 643 644 648 654 655 protected void initObjectStream () throws IOException { 656 if (os == null) { 657 os = new RmiObjectOutputStream(this, domain); 658 } 659 } 660 661 private void prepare () throws JonathanException { 662 if (current == null) { 663 Chunk chunk = chunkFactory.newChunk(); 664 first = chunk; 665 current = chunk; 666 offset = 0; 667 top = current.data.length; 668 } else if (current.next == null) { 669 current.top = offset; 670 Chunk chunk = chunkFactory.newChunk(); 671 current.next = chunk; 672 current = chunk; 673 offset = 0; 674 top = current.data.length; 675 } else { 676 current = current.next; 677 offset = current.offset; 678 if (current.next != null) { 679 top = current.top; 680 } else { 681 top = current.data.length; 682 } 683 } 684 } 685 } 686 | Popular Tags |