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