1. /*
  2. * @(#)BufferManagerWriteStream.java 1.13 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.internal.iiop;
  8. import java.util.Iterator;
  9. import java.util.NoSuchElementException;
  10. import com.sun.corba.se.internal.orbutil.ORBConstants;
  11. import com.sun.corba.se.internal.iiop.messages.Message;
  12. import com.sun.corba.se.internal.iiop.messages.MessageBase;
  13. import com.sun.corba.se.internal.iiop.messages.FragmentMessage;
  14. /**
  15. * Initial implementation of the streaming buffer manager.
  16. */
  17. public class BufferManagerWriteStream extends BufferManagerWrite
  18. {
  19. private int initialFragmentSize = 0, fragmentCount = 0;
  20. private ByteBufferWithInfo finalFragment = null;
  21. public BufferManagerWriteStream(int initialFragmentSize) {
  22. this.stream = null;
  23. this.initialFragmentSize = initialFragmentSize;
  24. }
  25. public ByteBufferWithInfo getInitialBuffer(int size)
  26. {
  27. return new ByteBufferWithInfo(size);
  28. }
  29. public int getInitialBufferSize() {
  30. return initialFragmentSize;
  31. }
  32. public void overflow (ByteBufferWithInfo bbwi)
  33. {
  34. // Set the fragment's moreFragments field to true
  35. MessageBase.setFlag(bbwi.buf, Message.MORE_FRAGMENTS_BIT);
  36. sendFragment(false);
  37. // Reuse the old buffer
  38. // REVISIT - need to account for case when needed > available
  39. // even after fragmenting. This is the large array case, so
  40. // the caller should retry when it runs out of space.
  41. bbwi.index = 0;
  42. bbwi.buflen = bbwi.buf.length;
  43. bbwi.fragmented = true;
  44. // Now we must marshal in the fragment header/GIOP header
  45. // REVISIT - we can optimize this by not creating the fragment message
  46. // each time.
  47. FragmentMessage header = stream.getMessage().createFragmentMessage();
  48. // Is this necessary?
  49. // stream.setMessage(header);
  50. header.write(stream);
  51. }
  52. private void sendFragment(boolean isLastFragment)
  53. {
  54. IIOPConnection conn = (IIOPConnection) stream.getConnection();
  55. conn.writeLock();
  56. if (this.fragmentCount == 0) {
  57. int requestID = MessageBase.getRequestId(stream.getMessage());
  58. // create OutCallDesc once before sending the first fragment
  59. conn.createOutCallDescriptor(requestID);
  60. // Also, remember fragments in progress in case of errors.
  61. conn.createIdToFragmentedOutputStreamEntry(requestID, stream);
  62. }
  63. try {
  64. // Send the fragment
  65. conn.sendWithoutLock(stream);
  66. } finally {
  67. if (isLastFragment) {
  68. int requestID = MessageBase.getRequestId(stream.getMessage());
  69. conn.removeIdToFragmentedOutputStreamEntry(requestID);
  70. }
  71. conn.writeUnlock();
  72. // REVISIT: this should go after sendWithoutLock
  73. this.fragmentCount++; // keeps count of # of fragments sent
  74. }
  75. }
  76. // Sends the last fragment
  77. public void sendMessage ()
  78. {
  79. sendFragment(true);
  80. }
  81. /*
  82. private Iterator iterator ()
  83. {
  84. return new BufferManagerWriteStreamIterator();
  85. }
  86. // Only handles the very last fragment
  87. private class BufferManagerWriteStreamIterator implements Iterator
  88. {
  89. private boolean _hasNext = true;
  90. public boolean hasNext ()
  91. {
  92. return _hasNext;
  93. }
  94. public Object next ()
  95. {
  96. if (_hasNext) {
  97. _hasNext = false;
  98. return finalFragment;
  99. }
  100. throw new NoSuchElementException();
  101. }
  102. public void remove ()
  103. {
  104. throw new UnsupportedOperationException();
  105. }
  106. }
  107. */
  108. }