coherence/io/pof/WritingPofHandler.hpp

00001 /*
00002 * WritingPofHandler.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_WRITING_POF_HANDLER_HPP
00017 #define COH_WRITING_POF_HANDLER_HPP
00018 
00019 #include "coherence/lang.ns"
00020 
00021 #include "coherence/io/WriteBuffer.hpp"
00022 #include "coherence/io/pof/PofHandler.hpp"
00023 #include "coherence/io/pof/PofHelper.hpp"
00024 #include "coherence/util/Binary.hpp"
00025 
00026 COH_OPEN_NAMESPACE3(coherence,io,pof)
00027 
00028 using coherence::io::WriteBuffer;
00029 using coherence::util::Binary;
00030 
00031 
00032 /**
00033 * An implementation of PofHandler that writes a POF stream to a WriteBuffer
00034 * using a BufferOutput object.
00035 *
00036 * @author jh  2008.04.09
00037 */
00038 class COH_EXPORT WritingPofHandler
00039     : public class_spec<WritingPofHandler,
00040         extends<PofHelper>,
00041         implements<PofHandler> >
00042     {
00043     friend class factory<WritingPofHandler>;
00044 
00045     // ----- constructors ---------------------------------------------------
00046 
00047     protected:
00048         /**
00049         * Construct a Writing POF Handler that will write a POF stream to the
00050         * passed BufferOutput object.
00051         *
00052         * @param hOut  the BufferOutput to write to
00053         *
00054         * @return the new WritingPofHandler
00055         */
00056         WritingPofHandler(WriteBuffer::BufferOutput::Handle hOut);
00057 
00058 
00059     // ----- PofHandler interface -------------------------------------------
00060 
00061     public:
00062         /**
00063         * {@inheritDoc}
00064         */
00065         virtual void registerIdentity(int32_t nId);
00066 
00067         /**
00068         * {@inheritDoc}
00069         */
00070         virtual void onNullReference(int32_t iPos);
00071 
00072         /**
00073         * {@inheritDoc}
00074         */
00075         virtual void onIdentityReference(int32_t iPos, int32_t nId);
00076 
00077         /**
00078         * {@inheritDoc}
00079         */
00080         virtual void onInt16(int32_t iPos, int16_t n);
00081 
00082         /**
00083         * {@inheritDoc}
00084         */
00085         virtual void onInt32(int32_t iPos, int32_t n);
00086 
00087         /**
00088         * {@inheritDoc}
00089         */
00090         virtual void onInt64(int32_t iPos, int64_t n);
00091 
00092         /**
00093         * {@inheritDoc}
00094         */
00095         virtual void onFloat32(int32_t iPos, float32_t fl);
00096 
00097         /**
00098         * {@inheritDoc}
00099         */
00100         virtual void onFloat64(int32_t iPos, float64_t dfl);
00101 
00102         /**
00103         * {@inheritDoc}
00104         */
00105         virtual void onBoolean(int32_t iPos, bool f);
00106 
00107         /**
00108         * {@inheritDoc}
00109         */
00110         virtual void onOctet(int32_t iPos, octet_t b);
00111 
00112         /**
00113         * {@inheritDoc}
00114         */
00115         virtual void onOctetString(int32_t iPos, Binary::View vBin);
00116 
00117         /**
00118         * {@inheritDoc}
00119         */
00120         virtual void onChar(int32_t iPos, char16_t ch);
00121 
00122         /**
00123         * {@inheritDoc}
00124         */
00125         virtual void onCharString(int32_t iPos, String::View vs);
00126 
00127         /**
00128         * {@inheritDoc}
00129         */
00130         virtual void onDate(int32_t iPos, int32_t nYear, int32_t nMonth,
00131                 int32_t nDay);
00132 
00133         /**
00134         * {@inheritDoc}
00135         */
00136         virtual void onYearMonthInterval(int32_t iPos, int32_t cYears,
00137                 int32_t cMonths);
00138 
00139         /**
00140         * {@inheritDoc}
00141         */
00142         virtual void onTime(int32_t iPos, int32_t nHour, int32_t nMinute,
00143                 int32_t nSecond, int32_t nNano, bool fUTC);
00144 
00145         /**
00146         * {@inheritDoc}
00147         */
00148         virtual void onTime(int32_t iPos, int32_t nHour, int32_t nMinute,
00149                 int32_t nSecond, int32_t nNano, int32_t nHourOffset,
00150                 int32_t nMinuteOffset);
00151 
00152         /**
00153         * {@inheritDoc}
00154         */
00155         virtual void onTimeInterval(int32_t iPos, int32_t cHours,
00156                 int32_t cMinutes, int32_t cSeconds, int32_t cNanos);
00157 
00158         /**
00159         * {@inheritDoc}
00160         */
00161         virtual void onDateTime(int32_t iPos, int32_t nYear, int32_t nMonth,
00162                 int32_t nDay, int32_t nHour, int32_t nMinute, int32_t nSecond,
00163                 int32_t nNano, bool fUTC);
00164 
00165         /**
00166         * {@inheritDoc}
00167         */
00168         virtual void onDateTime(int32_t iPos, int32_t nYear, int32_t nMonth,
00169                 int32_t nDay, int32_t nHour, int32_t nMinute, int32_t nSecond,
00170                 int32_t nNano, int32_t nHourOffset, int32_t nMinuteOffset);
00171 
00172         /**
00173         * {@inheritDoc}
00174         */
00175         virtual void onDayTimeInterval(int32_t iPos, int32_t cDays,
00176                 int32_t cHours, int32_t cMinutes, int32_t cSeconds,
00177                 int32_t cNanos);
00178 
00179         /**
00180         * {@inheritDoc}
00181         */
00182         virtual void beginCollection(int32_t iPos, size32_t cElements);
00183 
00184         /**
00185         * {@inheritDoc}
00186         */
00187         virtual void beginUniformCollection(int32_t iPos, size32_t cElements,
00188                 int32_t nType);
00189 
00190         /**
00191         * {@inheritDoc}
00192         */
00193         virtual void beginArray(int32_t iPos, size32_t cElements);
00194 
00195         /**
00196         * {@inheritDoc}
00197         */
00198         virtual void beginUniformArray(int32_t iPos, size32_t cElements,
00199                 int32_t nType);
00200 
00201         /**
00202         * {@inheritDoc}
00203         */
00204         virtual void beginSparseArray(int32_t iPos, size32_t cElements);
00205 
00206         /**
00207         * {@inheritDoc}
00208         */
00209         virtual void beginUniformSparseArray(int32_t iPos, size32_t cElements,
00210                 int32_t nType);
00211 
00212         /**
00213         * {@inheritDoc}
00214         */
00215         virtual void beginMap(int32_t iPos, size32_t cElements);
00216 
00217         /**
00218         * {@inheritDoc}
00219         */
00220         virtual void beginUniformKeysMap(int32_t iPos, size32_t cElements,
00221                 int32_t nTypeKeys);
00222 
00223         /**
00224         * {@inheritDoc}
00225         */
00226         virtual void beginUniformMap(int32_t iPos, size32_t cElements,
00227                 int32_t nTypeKeys, int32_t nTypeValues);
00228 
00229         /**
00230         * {@inheritDoc}
00231         */
00232         virtual void beginUserType(int32_t iPos, int32_t nUserTypeId,
00233                 int32_t nVersionId);
00234 
00235         /**
00236         * {@inheritDoc}
00237         */
00238         virtual void endComplexValue();
00239 
00240 
00241     // ----- internal methods -----------------------------------------------
00242 
00243     protected:
00244         /**
00245         * Determine if the value encoding can be skipped. A value can be
00246         * skipped if it is a default value and if it does not have an
00247         * identity and if it is in a sparse data structure.
00248         *
00249         * @return true iff value encoding of default values can be skipped
00250         *         altogether
00251         */
00252         virtual bool isSkippable() const;
00253 
00254         /**
00255         * Determine if the value encoding can be compressed by combining type
00256         * and value information in such a way that type information could be
00257         * lost.
00258         *
00259         * @return true iff values can be encoded without type information
00260         */
00261         virtual bool isCompressable() const;
00262 
00263         /**
00264         * Called for each and every value going into the POF stream, in case
00265         * the value needs its position to be encoded into the stream.
00266         *
00267         * @param iPos  the position (property index, array index, etc.)
00268         */
00269         virtual void encodePosition(int32_t iPos);
00270 
00271         /**
00272         * Determine if the type should be encoded for the current value.
00273         *
00274         * @param nTypeId  the type of the current value
00275         *
00276         * @return true if the type ID should be placed into the POF stream,
00277         *         and false if only the value itself should be placed into
00278         *         the stream
00279         */
00280         virtual bool isTypeIdEncoded(int32_t nTypeId) const;
00281 
00282 
00283     // ----- inner class: Complex -------------------------------------------
00284 
00285     public:
00286         /**
00287         * A Complex object represents the current complex data structure in
00288         * the POF stream.
00289         */
00290         class COH_EXPORT Complex
00291             : public class_spec<Complex>
00292             {
00293             friend class factory<Complex>;
00294 
00295             // ----- constructors ---------------------------------------
00296 
00297             protected:
00298                 /**
00299                 * Construct a Complex object for a data collection or user
00300                 * type.
00301                 *
00302                 * @param hComplexCurrent  the current Complex object or NULL
00303                 * @param fEncodePosition  true to encode the position
00304                 *                         information
00305                 */
00306                 Complex(Complex::Handle hComplexCurrent,
00307                         bool fEncodePosition);
00308 
00309                 /**
00310                 * Construct a Complex object for a uniformly-typed data
00311                 * collection.
00312                 *
00313                 * @param hComplexCurrent  the current Complex object or NULL
00314                 * @param fEncodePosition  true to encode the position
00315                 *                         information
00316                 * @param nUniformTypeId   the type identifier of the uniform
00317                 *                         type
00318                 */
00319                 Complex(Complex::Handle hComplexCurrent,
00320                         bool fEncodePosition, int32_t nUniformTypeId);
00321 
00322             // ----- Complex interface ----------------------------------
00323 
00324             public:
00325                 /**
00326                 * Notify the Complex object that a value has been encountered.
00327                 *
00328                 * @param iPos  the position that accompanied the value
00329                 */
00330                 virtual void onValue(int32_t iPos);
00331 
00332             // ----- accessors ------------------------------------------
00333 
00334             public:
00335                 /**
00336                 * Determine if the object encoding within the Complex type is
00337                 * uniform.
00338                 *
00339                 * @return true iff values within the Complex type are of a
00340                 *         uniform type and are encoded uniformly
00341                 */
00342                 virtual bool isUniform() const;
00343 
00344                 /**
00345                 * If the object encoding is using uniform encoding, obtain
00346                 * the type id of the uniform type.
00347                 *
00348                 * @return the type id used for the uniform encoding
00349                 */
00350                 virtual int32_t getUniformType() const;
00351 
00352                 /**
00353                 * Determine if the position information is encoded with the
00354                 * values of the complex type, and if the Complex type is
00355                 * terminated in the POF stream with an illegal position (-1).
00356                 *
00357                 * @return true iff the complex value is a sparse type
00358                 */
00359                 virtual bool isSparse() const;
00360 
00361                 /**
00362                 * Pop this Complex object off the stack, returning the outer
00363                 * Complex object or NULL if there is none.
00364                 *
00365                 * @return the outer Complex object or NULL if there is none
00366                 */
00367                 virtual Complex::Handle pop();
00368 
00369                 /**
00370                 * Pop this Complex object off the stack, returning the outer
00371                 * Complex object or NULL if there is none.
00372                 *
00373                 * @return the outer Complex object or NULL if there is none
00374                 */
00375                 virtual Complex::View pop() const;
00376 
00377             // ----- data members ---------------------------------------
00378 
00379             protected:
00380                 /**
00381                 * Whether or not the position information is encoded. This is
00382                 * true for user type properties and array elements.
00383                 */
00384                 const bool m_fSparse;
00385 
00386                 /**
00387                 * Whether or not values within the complex type are uniformly
00388                 * encoded. This is expected for arrays of primitive types,
00389                 * for example.
00390                 */
00391                 const bool m_fUniform;
00392 
00393                 /**
00394                 * The type ID, if uniform encoding is used.
00395                 */
00396                 const int32_t m_nTypeId;
00397 
00398                 /**
00399                 * The Complex within which this Complex exists, to support
00400                 * nesting.
00401                 */
00402                 FinalHandle<Complex> m_hComplexOuter;
00403             };
00404 
00405 
00406     // ----- inner class: ComplexMap ----------------------------------------
00407 
00408     public:
00409         /**
00410         * A ComplexMap object represents a map data structure (with uniform
00411         * keys or with uniform keys and values) in the POF stream.
00412         */
00413         class COH_EXPORT ComplexMap
00414             : public class_spec<ComplexMap,
00415                 extends<Complex> >
00416             {
00417             friend class factory<ComplexMap>;
00418 
00419             // ----- constructors ---------------------------------------
00420 
00421             protected:
00422                 /**
00423                 * Construct a ComplexMap object for maps with uniformly-typed
00424                 * keys.
00425                 *
00426                 * @param hcomplexCurrent    the current Complex object or
00427                 *                           NULL
00428                 * @param nUniformKeyTypeId  the type identifier of the
00429                 *                           uniform type
00430                 */
00431                 ComplexMap(Complex::Handle hComplexCurrent,
00432                         int32_t nUniformKeyTypeId);
00433 
00434                 /**
00435                 * Construct a ComplexMap object for maps with uniformly-typed
00436                 * keys and values.
00437                 *
00438                 * @param hComplexCurrent    the current Complex object or
00439                 *                           NULL
00440                 * @param nUniformKeyTypeId  the type identifier of the
00441                 *                           uniform type for keys in the map
00442                 * @param nUniformValTypeId  the type identifier of the
00443                 *                           uniform type for values in the
00444                 *                           map
00445                 */
00446                 ComplexMap(Complex::Handle hComplexCurrent,
00447                         int32_t nUniformKeyTypeId, int32_t nUniformValTypeId);
00448 
00449             // ----- Complex interface ----------------------------------
00450 
00451             public:
00452                 /**
00453                 * {@inheritDoc}
00454                 */
00455                 virtual void onValue(int32_t iPos);
00456 
00457             // ----- accessors ------------------------------------------
00458 
00459             public:
00460                 /**
00461                 * Determine if the object encoding within the Complex type is
00462                 * uniform.
00463                 *
00464                 * @return true iff values within the Complex type are of a
00465                 *         uniform type and are encoded uniformly
00466                 */
00467                 virtual bool isUniform() const;
00468 
00469                 /**
00470                 * If the object encoding is using uniform encoding, obtain
00471                 * the type id of the uniform type.
00472                 *
00473                 * @return the type id used for the uniform encoding
00474                 */
00475                 virtual int32_t getUniformType() const;
00476 
00477             // ----- data members ---------------------------------------
00478 
00479             protected:
00480                 /**
00481                 * Toggles between key and value processing every time the
00482                 * caller invokes {@link #onValue}.
00483                 */
00484                 bool m_fKey;
00485 
00486                 /**
00487                 * Whether or not values within the map are uniformly encoded.
00488                 */
00489                 const bool m_fUniformValue;
00490 
00491                 /**
00492                 * The value type ID, if uniform encoding is used for values.
00493                 */
00494                 const int32_t m_nValueTypeId;
00495             };
00496 
00497 
00498     // ----- accessors ------------------------------------------------------
00499 
00500     public:
00501         /**
00502         * Obtain the DataOutput object that this Writing POF Handler is
00503         * writing to.
00504         *
00505         * @return the DataOutput object that this POF handler is writing to
00506         */
00507         virtual WriteBuffer::BufferOutput::Handle getBufferOutput();
00508 
00509         /**
00510         * Obtain the DataOutput object that this Writing POF Handler is
00511         * writing to.
00512         *
00513         * @return the DataOutput object that this POF handler is writing to
00514         */
00515         virtual WriteBuffer::BufferOutput::View getBufferOutput() const;
00516 
00517         /**
00518         * Obtain the current Complex object that represents the complex type
00519         * that is being written to the POF stream.
00520         *
00521         * @return the current Complex object
00522         */
00523         virtual Complex::Handle getComplex();
00524 
00525         /**
00526         * Obtain the current Complex object that represents the complex type
00527         * that is being written to the POF stream.
00528         *
00529         * @return the current Complex object
00530         */
00531         virtual Complex::View getComplex() const;
00532 
00533 
00534     // ----- data members ---------------------------------------------------
00535 
00536     protected:
00537         /**
00538         * The BufferOutput to write to.
00539         */
00540         FinalHandle<WriteBuffer::BufferOutput> m_hOut;
00541 
00542         /**
00543         * The current containing Complex value in the POF stream.
00544         */
00545         MemberHandle<Complex> m_hComplex;
00546 
00547         /**
00548         * Set to true when the next value to write has been tagged with an
00549         * identity.
00550         */
00551         bool m_fHasIdentity;
00552     };
00553 
00554 COH_CLOSE_NAMESPACE3
00555 
00556 #endif // COH_WRITING_POF_HANDLER_HPP
Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.