00001 /* 00002 * WriteBuffer.hpp 00003 * 00004 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 00005 * 00006 * Oracle is a registered trademarks of Oracle Corporation and/or its 00007 * affiliates. 00008 * 00009 * This software is the confidential and proprietary information of Oracle 00010 * Corporation. You shall not disclose such confidential and proprietary 00011 * information and shall use it only in accordance with the terms of the 00012 * license agreement you entered into with Oracle. 00013 * 00014 * This notice may not be removed or altered. 00015 */ 00016 #ifndef COH_WRITE_BUFFER_HPP 00017 #define COH_WRITE_BUFFER_HPP 00018 00019 #include "coherence/lang.ns" 00020 00021 #include "coherence/io/ReadBuffer.hpp" 00022 00023 COH_OPEN_NAMESPACE2(coherence,io) 00024 00025 00026 /** 00027 * The WriteBuffer interface represents an in-memory block of binary data 00028 * that is being accumulated (written to). 00029 * 00030 * @author jh 2007.12.20 00031 */ 00032 class COH_EXPORT WriteBuffer 00033 : public interface_spec<WriteBuffer> 00034 { 00035 // ----- handle definitions (needed for nested classes) ----------------- 00036 00037 public: 00038 typedef this_spec::Handle Handle; 00039 typedef this_spec::View View; 00040 typedef this_spec::Holder Holder; 00041 00042 00043 // ----- WriteBuffer interface ------------------------------------------ 00044 00045 public: 00046 /** 00047 * Determine the length of the data that is in the buffer. This is the 00048 * actual number of octets of data that have been written to the 00049 * buffer, not the capacity of the buffer. 00050 * 00051 * @return the number of octets of data represented by this 00052 * WriteBuffer 00053 */ 00054 virtual size32_t length() const = 0; 00055 00056 /** 00057 * Determine the number of octets that the buffer can hold without 00058 * resizing itself. In other words, a WriteBuffer has <tt> 00059 * getCapacity() - #length()</tt> octets that can be written 00060 * to it without overflowing the current underlying buffer allocation. 00061 * Since the buffer is an abstract concept, the actual mechanism for 00062 * the underlying buffer is not known. 00063 * 00064 * Note that if the maximum size returned by 00065 * #getMaximumCapacity() is greater than the current size 00066 * returned by this method, then the WriteBuffer will automatically 00067 * resize itself to allocate more space when the amount of data 00068 * written to it passes the current size. 00069 * 00070 * @return the number of octets of data that this WriteBuffer can hold 00071 * without resizing its underlying buffer 00072 */ 00073 virtual size32_t getCapacity() const = 0; 00074 00075 /** 00076 * Determine the maximum number of octets that the buffer can hold. If 00077 * the maximum size is greater than the current size, then the buffer 00078 * is expected to resize itself as necessary up to the maximum size in 00079 * order to contain the data given to it. 00080 * 00081 * @return the maximum number of octets of data that the WriteBuffer 00082 * can hold 00083 */ 00084 virtual size32_t getMaximumCapacity() const = 0; 00085 00086 /** 00087 * Store the specified octet at the specified offset within the 00088 * buffer. 00089 * 00090 * For purposes of side-effects and potential exceptions, this method 00091 * is functionally equivalent to the following code: 00092 * <pre><code> 00093 * Array<octet_t>::Handle habSrc = Array<octet_t>::create(1); 00094 * habSrc[0] = b; 00095 * write(ofDest, habSrc, 0, 1); 00096 * </code></pre> 00097 * 00098 * @param ofDest the offset within this buffer to store the passed 00099 * data 00100 * @param b the octet to store in this buffer 00101 */ 00102 virtual void write(size32_t ofDest, octet_t b) = 0; 00103 00104 /** 00105 * Store the specified octets at the specified offset within the 00106 * buffer. 00107 * 00108 * For purposes of side-effects and potential exceptions, this method 00109 * is functionally equivalent to the following code: 00110 * <pre><code> 00111 * write(ofDest, vabSrc, 0, vabSrc.length); 00112 * </code></pre> 00113 * 00114 * @param ofDest the offset within this buffer to store the passed 00115 * data 00116 * @param vabSrc the array of octets to store in this buffer 00117 */ 00118 virtual void write(size32_t ofDest, Array<octet_t>::View vabSrc) = 0; 00119 00120 /** 00121 * Store the specified number of octets from the specified location 00122 * within the passed octet array at the specified offset within this 00123 * buffer. 00124 * 00125 * As a result of this method, the buffer length as reported by the 00126 * <tt>#length()</tt> method will become 00127 * <tt>max(#length(), ofDest + cbSrc)</tt>. 00128 * 00129 * As a result of this method, the buffer capacity as reported by the 00130 * <tt>#getCapacity()</tt> method will not change if the new 00131 * value returned by <tt>#length()</tt> would not exceed the 00132 * old value returned by <tt>#getCapacity()</tt>; otherwise, 00133 * the capacity will be increased such that <tt>{#getCapacity() 00134 * >= #length()</tt>. Regardless, it is always true that 00135 * <tt>#getCapacity() >= #length()</tt> and <tt> 00136 * #getMaximumCapacity() >= #getCapacity()</tt>. If the buffer 00137 * capacity cannot be increased due to resource constraints, an 00138 * undesignated Exception will be thrown. 00139 * 00140 * @param ofDest the offset within this buffer to store the passed 00141 * data 00142 * @param vabSrc the array containing the octets to store in this 00143 * buffer 00144 * @param ofSrc the offset within the passed octet array to copy 00145 * from 00146 * @param cbSrc the number of octets to copy from the passed octet 00147 * array 00148 * 00149 * @throws NullPointerException if <code>vabSrc</code> is NULL 00150 * @throws IndexOutOfBoundsException if <tt>ofSrc + cbSrc</tt> is 00151 * greater than <tt>vabSrc->length</tt>, or if 00152 * <tt>ofDest + cbSrc</tt> is greater than 00153 * <tt>#getMaximumCapacity()</tt> 00154 */ 00155 virtual void write(size32_t ofDest, Array<octet_t>::View vabSrc, 00156 size32_t ofSrc, size32_t cbSrc) = 0; 00157 00158 /** 00159 * Store the contents of the specified ReadBuffer at the specified 00160 * offset within this buffer. 00161 * 00162 * For purposes of side-effects and potential exceptions, this method 00163 * is functionally equivalent to the following code: 00164 * <pre><code> 00165 * Array<octet_t>::View vabSrc = vBufSrc->toOctetArray(); 00166 * write(ofDest, vabSrc, 0, vabSrc->length); 00167 * </code></pre> 00168 * 00169 * @param ofDest the offset within this buffer to store the passed 00170 * data 00171 * @param vBufSrc the array of octets to store in this buffer 00172 */ 00173 virtual void write(size32_t ofDest, ReadBuffer::View vBufSrc) = 0; 00174 00175 /** 00176 * Store the specified portion of the contents of the specified 00177 * ReadBuffer at the specified offset within this buffer. 00178 * 00179 * For purposes of side-effects and potential exceptions, this method 00180 * is functionally equivalent to the following code: 00181 * <pre><code> 00182 * Array<octet_t>::View vabSrc = vbufSrc.toOctetArray(ofSrc, cbSrc); 00183 * write(ofDest, vabSrc, 0, vabSrc->length); 00184 * </code></pre> 00185 * 00186 * @param ofDest the offset within this buffer to store the passed 00187 * data 00188 * @param vBufSrc the source ReadBuffer 00189 * @param ofSrc the offset within the passed ReadBuffer to copy 00190 * from 00191 * @param cbSrc the number of octets to copy from the passed 00192 * ReadBuffer 00193 */ 00194 virtual void write(size32_t ofDest, ReadBuffer::View vBufSrc, 00195 size32_t ofSrc, size32_t cbSrc) = 0; 00196 00197 /** 00198 * Starting with the octet at offset <tt>of</tt>, retain the remainder 00199 * of this WriteBuffer, such that the octet at offset <tt>of</tt> is 00200 * shifted to offset 0, the octet at offset <tt>of + 1</tt> is shifted 00201 * to offset 1, and so on up to the octet at offset 00202 * <tt>#length() - 1</tt>, which is shifted to offset 00203 * <tt>#length() - of - 1</tt>. After this method, the length 00204 * of of the buffer as indicated by the #length() method will 00205 * be equal to <tt>#length() - of</tt>. 00206 * 00207 * This method is functionally equivalent to the following code: 00208 * <pre><code> 00209 * retain(of, length() - of); 00210 * </code></pre> 00211 * 00212 * @param of the offset of the first octet within the WriteBuffer 00213 * that will be retained 00214 * 00215 * @throws IndexOutOfBoundsException if <tt>of</tt> is greater than 00216 * <tt>#length()</tt> 00217 */ 00218 virtual void retain(size32_t of) = 0; 00219 00220 /** 00221 * Starting with the octet at offset <tt>of</tt>, retain <tt>cb</tt> 00222 * octets in this WriteBuffer, such that the octet at offset 00223 * <tt>of</tt> is shifted to offset 0, the octet at offset <tt>of + 00224 * 1</tt> is shifted to offset 1, and so on up to the octet at offset 00225 * <tt>of + cb - 1</tt>, which is shifted to offset <tt>cb - 1</tt>. 00226 * After this method, the length of the buffer as indicated by the 00227 * #length() method will be equal to <tt>cb</tt>. 00228 * 00229 * Legal values for the offset of the first octet to retain 00230 * <tt>of</tt> are <tt>(of >= 0 && of <= #length())</tt>. 00231 * Legal values for the number of octets to retain <tt>cb</tt> are 00232 * <tt>(cb >= 0 && cb <= #length())</tt>, such that 00233 * <tt>(of + cb <= #length())</tt>. 00234 * 00235 * If <tt>cb</tt> is zero, then this method will have the same effect 00236 * as clear. If <tt>of</tt> is zero, then this method will have the 00237 * effect of truncating the data in the buffer, but no octets will be 00238 * shifted within the buffer. 00239 * 00240 * The effect on the capacity of the buffer is implementation- 00241 * specific; some implementations are expected to retain the same 00242 * capacity while others are expected to shrink accordingly. 00243 * 00244 * @param of the offset of the first octet within the WriteBuffer 00245 * that will be retained 00246 * @param cb the number of octets to retain 00247 * 00248 * @throws IndexOutOfBoundsException if <tt>of + cb</tt> is greater 00249 * than <tt>#length()</tt> 00250 */ 00251 virtual void retain(size32_t of, size32_t cb) = 0; 00252 00253 /** 00254 * Set the length of the buffer as indicated by the #length() 00255 * method to zero. 00256 * 00257 * The effect on the capacity of the buffer is implementation-specific; 00258 * some implementations are expected to retain the same capacity while 00259 * others are expected to shrink accordingly. 00260 */ 00261 virtual void clear() = 0; 00262 00263 /** 00264 * Obtain a WriteBuffer starting at a particular offset within this 00265 * WriteBuffer. 00266 * 00267 * This is functionally equivalent to: 00268 * <code><pre> 00269 * return getWriteBuffer(of, getMaximumCapacity() - of); 00270 * </pre></code> 00271 * 00272 * @param of the beginning index, inclusive 00273 * 00274 * @return a WriteBuffer that represents a portion of this WriteBuffer 00275 * 00276 * @throws IndexOutOfBoundsException if <tt>of</tt> is larger than the 00277 * <tt>#getMaximumCapacity()</tt> of this WriteBuffer 00278 */ 00279 virtual WriteBuffer::Handle getWriteBuffer(size32_t of) = 0; 00280 00281 /** 00282 * Obtain a WriteBuffer for a portion of this WriteBuffer. 00283 * 00284 * Use of the resulting buffer will correspond to using this buffer 00285 * directly but with the offset being passed to the buffer methods 00286 * automatically having <tt>of</tt> added. As a result, the length of 00287 * this buffer can be modified by writing to the new buffer; however, 00288 * changes made directly to this buffer will not affect the length of 00289 * the new buffer. 00290 * 00291 * Note that the resulting WriteBuffer is limited in the number of 00292 * octets that can be written to it; in other words, its 00293 * <tt>#getMaximumCapacity()</tt> must return the same value 00294 * as was passed in <tt>cb</tt>. 00295 * 00296 * @param of the offset of the first octet within this WriteBuffer to 00297 * map to offset 0 of the new WriteBuffer 00298 * @param cb the number of octets to cover in the resulting 00299 * WriteBuffer 00300 * 00301 * @return a WriteBuffer that represents a portion of this WriteBuffer 00302 * 00303 * @throws IndexOutOfBoundsException if <tt>of + cb</tt> is larger 00304 * than the <tt>#getMaximumCapacity()</tt> of this 00305 * WriteBuffer 00306 */ 00307 virtual WriteBuffer::Handle getWriteBuffer(size32_t of, size32_t cb) = 0; 00308 00309 /** 00310 * Get a ReadBuffer object that is a snapshot of this WriteBuffer's 00311 * data. 00312 * 00313 * This method is functionally equivalent to the following code: 00314 * <pre><code> 00315 * Array<octet_t>::View vab = toOctetArray(); 00316 * return OctetArrayReadBuffer::create(vab, 0, vab->length(), true); 00317 * </code></pre> 00318 * 00319 * @return a ReadBuffer that reflects the point-in-time contents of 00320 * this WriteBuffer; the returned ReadBuffer is inherently 00321 * immutable 00322 */ 00323 virtual ReadBuffer::View getReadBuffer() const = 0; 00324 00325 /** 00326 * Get a ReadBuffer object to read data from this buffer. This method 00327 * is not guaranteed to return a snapshot of this buffer's data, nor 00328 * is it guaranteed to return a live view of this buffer, which means 00329 * that subsequent changes to this WriteBuffer may or may not affect 00330 * the contents and / or the length of the returned ReadBuffer. 00331 * 00332 * To get a snapshot, use the #getReadBuffer() method. 00333 * 00334 * @return a ReadBuffer that reflects the contents of this WriteBuffer 00335 * but whose behavior is undefined if the WriteBuffer is 00336 * modified 00337 */ 00338 virtual ReadBuffer::View getUnsafeReadBuffer() const = 0; 00339 00340 /** 00341 * Returns an octet array that holds the complete contents of this 00342 * WriteBuffer. 00343 * 00344 * This method is functionally equivalent to the following code: 00345 * <pre><code> 00346 * return getUnsafeReadBuffer()->toOctetArray(); 00347 * </code></pre> 00348 * 00349 * @return the contents of this WriteBuffer as an octet array 00350 */ 00351 virtual Array<octet_t>::View toOctetArray() const = 0; 00352 00353 00354 // ----- BufferOutput inner interface ----------------------------------- 00355 00356 public: 00357 /** 00358 * The BufferOutput interface represents a data output stream on top 00359 * of a WriteBuffer. 00360 * 00361 * @author jh 2007.12.20 00362 */ 00363 class COH_EXPORT BufferOutput 00364 : public interface_spec<BufferOutput> 00365 { 00366 // ----- BufferOutput interface ----------------------------- 00367 00368 public: 00369 /** 00370 * Get the WriteBuffer object that this BufferOutput is 00371 * writing to. 00372 * 00373 * @return the underlying WriteBuffer object 00374 */ 00375 virtual WriteBuffer::Handle getBuffer() = 0; 00376 00377 /** 00378 * Get the WriteBuffer object that this BufferOutput is 00379 * writing to. 00380 * 00381 * @return the underlying WriteBuffer object 00382 */ 00383 virtual WriteBuffer::View getBuffer() const = 0; 00384 00385 /** 00386 * Determine the current offset of this BufferOutput within 00387 * the underlying WriteBuffer. 00388 * 00389 * @return the offset of the next octet to write to the 00390 * WriteBuffer 00391 */ 00392 virtual size32_t getOffset() const = 0; 00393 00394 /** 00395 * Specify the offset of the next octet to write to the 00396 * underlying WriteBuffer. 00397 * 00398 * @param of the offset of the next octet to write to the 00399 * WriteBuffer 00400 * 00401 * @throws IndexOutOfBoundsException if 00402 * <code>of > getBuffer()->getMaximumCapacity()</code> 00403 */ 00404 virtual void setOffset(size32_t of) = 0; 00405 00406 /** 00407 * Write the given octet. 00408 * 00409 * @param b the octet to write 00410 * 00411 * @throws IOException if an I/O error occurs 00412 */ 00413 virtual void write(octet_t b) = 0; 00414 00415 /** 00416 * Writes all the octets in the array <tt>vab</tt>. 00417 * 00418 * @param vab the octet array to write 00419 * 00420 * @throws IOException if an I/O error occurs 00421 * @throws NullPointerException if <tt>vab</tt> is NULL 00422 */ 00423 virtual void write(Array<octet_t>::View vab) = 0; 00424 00425 /** 00426 * Writes <code>cb</code> octets starting at offset 00427 * <code>of</code> from the array <code>vab</code>. 00428 * 00429 * @param vab the octet array to write from 00430 * @param of the offset into <code>vab</code> to start 00431 * writing from 00432 * @param cb the number of octets from <code>vab</code> to 00433 * write 00434 * 00435 * @throws IOException if an I/O error occurs 00436 * @throws NullPointerException if <code>vab</code> is NULL 00437 * @throws IndexOutOfBoundsException if <code>of+cb</code> is 00438 * greater than <code>vab->length</code> 00439 */ 00440 virtual void write(Array<octet_t>::View vab, size32_t of, 00441 size32_t cb) = 0; 00442 00443 /** 00444 * Write all the octets from the passed ReadBuffer object. 00445 * 00446 * This is functionally equivalent to the following code: 00447 * <code><pre> 00448 * getBuffer()->write(getOffset(), vBuf); 00449 * </pre></code> 00450 * 00451 * @param vBuf a ReadBuffer object 00452 * 00453 * @throws IOException if an I/O error occurs 00454 */ 00455 virtual void writeBuffer(ReadBuffer::View vBuf) = 0; 00456 00457 /** 00458 * Write <code>cb</code> octets from the passed ReadBuffer 00459 * object starting at offset <code>of</code> within the passed 00460 * ReadBuffer. 00461 * 00462 * This is functionally equivalent to the following code: 00463 * <code><pre> 00464 * getBuffer()->write(getOffset(), vbuf, of, cb); 00465 * </pre></code> 00466 * 00467 * @param vBuf a ReadBuffer object 00468 * @param of the offset within the ReadBuffer of the first 00469 * octet to write to this BufferOutput 00470 * @param cb the number of octets to write 00471 * 00472 * @throws IOException if an I/O error occurs 00473 */ 00474 virtual void writeBuffer(ReadBuffer::View vBuf, size32_t of, 00475 size32_t cb) = 0; 00476 00477 /** 00478 * Write a boolean value. 00479 * 00480 * @param f the <tt>bool</tt> to be written 00481 * 00482 * @throws IOException if an I/O error occurs 00483 */ 00484 virtual void writeBoolean(bool f) = 0; 00485 00486 /** 00487 * Write a 16-bit Unicode character value. 00488 * 00489 * @param ch the Unicode character as a <code>char16_t</code> 00490 * value 00491 * 00492 * @throws IOException if an I/O error occurs 00493 */ 00494 virtual void writeChar16(char16_t ch) = 0; 00495 00496 /** 00497 * Write a sequence of UTF-8 encoded 16-bit Unicode 00498 * characters. 00499 * 00500 * @param vs a String value to write; may be NULL 00501 * 00502 * @throws IOException if an I/O error occurs 00503 */ 00504 virtual void writeString(String::View vs) = 0; 00505 00506 /** 00507 * Write a 16-bit integer value. 00508 * 00509 * @param n the <code>int16_t</code> value to be written 00510 * 00511 * @throws IOException if an I/O error occurs 00512 */ 00513 virtual void writeInt16(int16_t n) = 0; 00514 00515 /** 00516 * Write a 32-bit integer value. 00517 * 00518 * @param n the <code>int32_t</code> value to be written 00519 * 00520 * @throws IOException if an I/O error occurs 00521 */ 00522 virtual void writeInt32(int32_t n) = 0; 00523 00524 /** 00525 * Write a 64-bit integer value. 00526 * 00527 * @param n the <code>int64_t</code> value to be written 00528 * 00529 * @throws IOException if an I/O error occurs 00530 */ 00531 virtual void writeInt64(int64_t n) = 0; 00532 00533 /** 00534 * Write a 32-bit floating-point value. 00535 * 00536 * @param fl the <code>float32_t</code> value to be written 00537 * 00538 * @throws IOException if an I/O error occurs 00539 */ 00540 virtual void writeFloat32(float32_t fl) = 0; 00541 00542 /** 00543 * Write a 64-bit floating-point value. 00544 * 00545 * @param dfl the <code>float64_t</code> value to be written 00546 * 00547 * @throws IOException if an I/O error occurs 00548 */ 00549 virtual void writeFloat64(float64_t dfl) = 0; 00550 }; 00551 00552 /** 00553 * Get a BufferOutput object to write data to this buffer starting at 00554 * a particular offset. 00555 * 00556 * Note that each call to this method will return a new BufferOutput 00557 * object, with the possible exception being that a zero-length 00558 * non-resizing WriteBuffer could always return the same instance 00559 * (since it is not writable). 00560 * 00561 * @param of the offset of the first octet of this buffer that the 00562 * BufferOutput will write to 00563 * 00564 * @return a BufferOutput that will write to this buffer 00565 */ 00566 virtual BufferOutput::Handle getBufferOutput(size32_t of = 0) = 0; 00567 00568 /** 00569 * Get a BufferOutput object to write data to this buffer. The 00570 * BufferOutput object returned by this method is set to append to the 00571 * WriteBuffer, meaning that its offset is pre-set to the 00572 * #length() of this buffer. 00573 * 00574 * This is functionally equivalent to: 00575 * <pre><code> 00576 * return getBufferOutput(length()); 00577 * </code></pre> 00578 * 00579 * @return a BufferOutput configured to append to this buffer 00580 */ 00581 virtual BufferOutput::Handle getAppendingBufferOutput() = 0; 00582 }; 00583 00584 COH_CLOSE_NAMESPACE2 00585 00586 #endif // COH_WRITE_BUFFER_HPP