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