coherence/io/WriteBuffer.hpp

00001 /*
00002 * WriteBuffer.hpp
00003 *
00004 * Copyright (c) 2000, 2009, 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
Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.