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