00001 /* 00002 * Copyright (c) 2000, 2025, Oracle and/or its affiliates. 00003 * 00004 * Licensed under the Universal Permissive License v 1.0 as shown at 00005 * https://oss.oracle.com/licenses/upl. 00006 */ 00007 #ifndef COH_POF_HELPER_HPP 00008 #define COH_POF_HELPER_HPP 00009 00010 #include "coherence/lang.ns" 00011 00012 #include "coherence/io/ReadBuffer.hpp" 00013 #include "coherence/io/pof/PofConstants.hpp" 00014 #include "coherence/io/pof/PofContext.hpp" 00015 #include "coherence/io/pof/RawDate.hpp" 00016 #include "coherence/io/pof/RawDateTime.hpp" 00017 #include "coherence/io/pof/RawDayTimeInterval.hpp" 00018 #include "coherence/io/pof/RawTime.hpp" 00019 #include "coherence/io/pof/RawTimeInterval.hpp" 00020 #include "coherence/io/pof/RawYearMonthInterval.hpp" 00021 #include "coherence/util/AbstractMap.hpp" 00022 #include "coherence/util/Binary.hpp" 00023 #include "coherence/util/Collection.hpp" 00024 #include "coherence/util/List.hpp" 00025 #include "coherence/util/Set.hpp" 00026 00027 #include <limits> 00028 00029 COH_OPEN_NAMESPACE3(coherence,io,pof) 00030 00031 using coherence::io::ReadBuffer; 00032 using coherence::util::AbstractMap; 00033 using coherence::util::Binary; 00034 using coherence::util::Collection; 00035 using coherence::util::List; 00036 using coherence::util::Set; 00037 00038 00039 /** 00040 * Collection of helper methods for POF streams. 00041 * 00042 * @author jh 2008.04.09 00043 */ 00044 class COH_EXPORT PofHelper 00045 : public abstract_spec<PofHelper, 00046 extends<PofConstants> > 00047 { 00048 public: 00049 /** 00050 * Return an identifier that represents the C++ type of the specified 00051 * object. 00052 * 00053 * @param v an object to determine the type of 00054 * @param vCtx the PofContext used to determine if the object is an 00055 * instance of a valid user type; must not be NULL 00056 * 00057 * @return one of the {@link PofConstants} class <tt>C_*</tt> 00058 * constants 00059 */ 00060 static int32_t getClassTypeId(Object::View v, PofContext::View vCtx); 00061 00062 /** 00063 * Return an indentifier that represents the POF type of the specified 00064 * class. 00065 * 00066 * @param vClass the class; must not be NULL 00067 * @param vCtx the PofContext used to determine the type identifier 00068 * of a user type; must not be NULL 00069 * 00070 * @return one of the {@link PofConstants} class <tt>T_*</tt> 00071 * constants 00072 * 00073 * @throws IllegalArgumentException if the user type associated with 00074 * the given object is unknown to the specified PofContext 00075 */ 00076 static int32_t getPofTypeId(Class::View vClass, PofContext::View vCtx); 00077 00078 /** 00079 * Encode an int32_t value into one of the reserved single-byte 00080 * combined type and value indicators. 00081 * 00082 * @param n an int32_t between -1 and 22 inclusive 00083 * 00084 * @return the int32_t value that the int32_t is encoded as 00085 */ 00086 static int32_t encodeTinyInt32(int32_t n); 00087 00088 /** 00089 * Decode an int32_t value from one of the reserved single-byte 00090 * combined type and value indicators. 00091 * 00092 * @param n the int32_t value that the int32_t is encoded as 00093 * 00094 * @return an int32_t between -1 and 22 inclusive 00095 */ 00096 static int32_t decodeTinyInt32(int32_t n); 00097 00098 /** 00099 * Read a value of the specified encoding from the POF stream and 00100 * convert it to a wchar16_t. 00101 * 00102 * @param hIn the POF stream containing the value 00103 * @param nType the POF type of the value 00104 * 00105 * @return the POF value as an char 00106 * 00107 * @throws IOException if an I/O error occurs reading the POF stream, 00108 * or the POF value cannot be coerced to a char value 00109 */ 00110 static wchar16_t readAsChar16(ReadBuffer::BufferInput::Handle hIn, 00111 int32_t nType); 00112 00113 /** 00114 * Read a value of the specified encoding from the POF stream and 00115 * convert it to a wchar16_t. 00116 * 00117 * @param hIn the POF stream containing the value 00118 * @param nType the POF type of the value 00119 * 00120 * @return the POF value as an char 00121 * 00122 * @throws IOException if an I/O error occurs reading the POF stream, 00123 * or the POF value cannot be coerced to a char value 00124 */ 00125 static wchar16_t readAsChar16(FinalHandle<ReadBuffer::BufferInput>& hIn, 00126 int32_t nType); 00127 00128 /** 00129 * Read a value of the specified encoding from the POF stream and 00130 * convert it to an int32_t. 00131 * 00132 * @param hIn the POF stream containing the value 00133 * @param nType the POF type of the value 00134 * 00135 * @return the POF value as an int32_t 00136 * 00137 * @throws IOException if an I/O error occurs reading the POF stream, 00138 * or the POF value cannot be coerced to an int32_t value 00139 */ 00140 static int32_t readAsInt32(ReadBuffer::BufferInput::Handle hIn, 00141 int32_t nType); 00142 00143 /** 00144 * Read a value of the specified encoding from the POF stream and 00145 * convert it to an int32_t. 00146 * 00147 * @param hIn the POF stream containing the value 00148 * @param nType the POF type of the value 00149 * 00150 * @return the POF value as an int32_t 00151 * 00152 * @throws IOException if an I/O error occurs reading the POF stream, 00153 * or the POF value cannot be coerced to an int32_t value 00154 */ 00155 static int32_t readAsInt32(FinalHandle<ReadBuffer::BufferInput>& hIn, 00156 int32_t nType); 00157 00158 /** 00159 * Read a value of the specified encoding from the POF stream and 00160 * convert it to an int64_t. 00161 * 00162 * @param hIn the POF stream containing the value 00163 * @param nType the POF type of the value 00164 * 00165 * @return the POF value as an int64_t 00166 * 00167 * @throws IOException if an I/O error occurs reading the POF stream, 00168 * or the POF value cannot be coerced to an int64_t value 00169 */ 00170 static int64_t readAsInt64(ReadBuffer::BufferInput::Handle hIn, 00171 int32_t nType); 00172 00173 /** 00174 * Read a value of the specified encoding from the POF stream and 00175 * convert it to an int64_t. 00176 * 00177 * @param hIn the POF stream containing the value 00178 * @param nType the POF type of the value 00179 * 00180 * @return the POF value as an int64_t 00181 * 00182 * @throws IOException if an I/O error occurs reading the POF stream, 00183 * or the POF value cannot be coerced to an int64_t value 00184 */ 00185 static int64_t readAsInt64(FinalHandle<ReadBuffer::BufferInput>& hIn, 00186 int32_t nType); 00187 00188 /** 00189 * Read a value of the specified encoding from the POF stream and 00190 * convert it to a float32_t. 00191 * 00192 * @param hIn the POF stream containing the value 00193 * @param nType the POF type of the value 00194 * 00195 * @return the POF value as a float32_t 00196 * 00197 * @throws IOException if an I/O error occurs reading the POF stream, 00198 * or the POF value cannot be coerced to a float32_t value 00199 */ 00200 static float32_t readAsFloat32(ReadBuffer::BufferInput::Handle hIn, 00201 int32_t nType); 00202 00203 /** 00204 * Read a value of the specified encoding from the POF stream and 00205 * convert it to a float32_t. 00206 * 00207 * @param hIn the POF stream containing the value 00208 * @param nType the POF type of the value 00209 * 00210 * @return the POF value as a float32_t 00211 * 00212 * @throws IOException if an I/O error occurs reading the POF stream, 00213 * or the POF value cannot be coerced to a float32_t value 00214 */ 00215 static float32_t readAsFloat32(FinalHandle<ReadBuffer::BufferInput>& hIn, 00216 int32_t nType); 00217 00218 /** 00219 * Read a value of the specified encoding from the POF stream and 00220 * convert it to a float64_t. 00221 * 00222 * @param hIn the POF stream containing the value 00223 * @param nType the POF type of the value 00224 * 00225 * @return the POF value as a float64_t 00226 * 00227 * @throws IOException if an I/O error occurs reading the POF stream, 00228 * or the POF value cannot be coerced to a float64_t value 00229 */ 00230 static float64_t readAsFloat64(ReadBuffer::BufferInput::Handle hIn, 00231 int32_t nType); 00232 00233 /** 00234 * Read a value of the specified encoding from the POF stream and 00235 * convert it to a float64_t. 00236 * 00237 * @param hIn the POF stream containing the value 00238 * @param nType the POF type of the value 00239 * 00240 * @return the POF value as a float64_t 00241 * 00242 * @throws IOException if an I/O error occurs reading the POF stream, 00243 * or the POF value cannot be coerced to a float64_t value 00244 */ 00245 static float64_t readAsFloat64(FinalHandle<ReadBuffer::BufferInput>& hIn, 00246 int32_t nType); 00247 00248 /** 00249 * Read a RawDate value from the passed BufferInput. 00250 * 00251 * @param hIn the BufferInput object to read from 00252 * 00253 * @return the RawDate value 00254 */ 00255 static RawDate::View readRawDate( 00256 ReadBuffer::BufferInput::Handle hIn); 00257 00258 /** 00259 * Read a RawDate value from the passed BufferInput. 00260 * 00261 * @param hIn the BufferInput object to read from 00262 * 00263 * @return the RawDate value 00264 */ 00265 static RawDate::View readRawDate( 00266 FinalHandle<ReadBuffer::BufferInput>& hIn); 00267 00268 /** 00269 * Read a RawTime value from the passed BufferInput. 00270 * 00271 * @param hIn the BufferInput object to read from 00272 * 00273 * @return the RawTime value 00274 */ 00275 static RawTime::View readRawTime( 00276 ReadBuffer::BufferInput::Handle hIn); 00277 00278 /** 00279 * Read a RawTime value from the passed BufferInput. 00280 * 00281 * @param hIn the BufferInput object to read from 00282 * 00283 * @return the RawTime value 00284 */ 00285 static RawTime::View readRawTime( 00286 FinalHandle<ReadBuffer::BufferInput>& hIn); 00287 00288 /** 00289 * Within the POF stream, skip the next POF value. 00290 * 00291 * @param hIn the BufferInput containing the POF stream 00292 */ 00293 static void skipValue(ReadBuffer::BufferInput::Handle hIn); 00294 00295 /** 00296 * Within the POF stream, skip the next POF value of the specified 00297 * type. 00298 * 00299 * @param hIn the BufferInput containing the POF stream 00300 * @param nType the type of the value to skip 00301 */ 00302 static void skipUniformValue(ReadBuffer::BufferInput::Handle hIn, 00303 int32_t nType); 00304 00305 /** 00306 * Skip the specified number of integers in the passed POF stream. 00307 * 00308 * @param hIn the BufferInput containing the POF stream 00309 * @param c the number of integers to skip over 00310 */ 00311 static void skipInts(ReadBuffer::BufferInput::Handle hIn, int32_t c); 00312 00313 /** 00314 * Validate that the specified POF collection size as read from a POF 00315 * stream is smaller than the largest value of the size32_t type, and if 00316 * so, return the given size as a size32_t. 00317 * 00318 * @param cElements the POF collection size 00319 * 00320 * @return the POF collection size as a size32_t 00321 * 00322 * @throws Exception if the given POF collection size is greater than 00323 * the largest value of the size32_t type 00324 */ 00325 inline static size32_t validateIncomingSize(int32_t cElements) 00326 { 00327 COH_ENSURE(cElements >= 0); 00328 00329 size32_t nElements = (size32_t) cElements; 00330 if (((int32_t) nElements) != cElements) 00331 { 00332 COH_THROW_STREAM (IllegalStateException, 00333 "incoming POF collection size overflow: " << cElements 00334 << " > " << (std::numeric_limits<size32_t>::max)()); 00335 } 00336 return nElements; 00337 } 00338 00339 /** 00340 * Validate that the specified Collection size is smaller than the 00341 * largest value of the int32_t type, and if so, return the given size 00342 * as an in32_t. 00343 * 00344 * @param cElements the Collection size 00345 * 00346 * @return the Collection size as a int32_t 00347 * 00348 * @throws Exception if the given Collection size is greater than the 00349 * largest value of the int32_t type 00350 */ 00351 inline static int32_t validateOutgoingSize(size32_t cElements) 00352 { 00353 int32_t nElements = (int32_t) cElements; 00354 if (((size32_t) nElements) != cElements || nElements < 0) 00355 { 00356 COH_THROW_STREAM (IllegalStateException, 00357 "outgoing POF collection size overflow: " << cElements 00358 << " > " << Integer32::max_value); 00359 } 00360 return nElements; 00361 } 00362 00363 /** 00364 * Validate date information. 00365 * 00366 * @param nYear the year number 00367 * @param nMonth the month number 00368 * @param nDay the day number 00369 */ 00370 static void checkDate(int32_t nYear, int32_t nMonth, int32_t nDay); 00371 00372 /** 00373 * Validate time information. 00374 * 00375 * @param nHour the hour number 00376 * @param nMinute the minute number 00377 * @param nSecond the second number 00378 * @param nNano the nanosecond number 00379 */ 00380 static void checkTime(int32_t nHour, int32_t nMinute, int32_t nSecond, 00381 int32_t nNano); 00382 00383 /** 00384 * Check the specified timezone offset. 00385 * 00386 * @param nHourOffset the hour offset 00387 * @param nMinuteOffset the minute offset 00388 */ 00389 static void checkTimeZone(int32_t nHourOffset, int32_t nMinuteOffset); 00390 00391 /** 00392 * Validate a time interval. 00393 * 00394 * @param cHours the number of hours 00395 * @param cMinutes the number of minutes 00396 * @param cSeconds the number of seconds 00397 * @param cNanos the number of nanoseconds 00398 */ 00399 static void checkTimeInterval(int32_t cHours, int32_t cMinutes, 00400 int32_t cSeconds, int32_t cNanos); 00401 00402 /** 00403 * Validate a day-time interval. 00404 * 00405 * See http://www.builderau.com.au/architect/database/soa/SQL_basics_Datetime_and_interval_data_types/0,39024547,20269031,00.htm 00406 * 00407 * @param cDays the number of days 00408 * @param cHours the number of hours 00409 * @param cMinutes the number of minutes 00410 * @param cSeconds the number of seconds 00411 * @param cNanos the number of nanoseconds 00412 */ 00413 static void checkDayTimeInterval(int32_t cDays, int32_t cHours, 00414 int32_t cMinutes, int32_t cSeconds, int32_t cNanos); 00415 00416 /** 00417 * Validate a year-month interval. 00418 * 00419 * @param cYears the number of years 00420 * @param cMonths the number of months 00421 */ 00422 static void checkYearMonthInterval(int32_t cYears, int32_t cMonths); 00423 00424 /** 00425 * Format a date in the form YYYY-MM-DD. 00426 * 00427 * @param nYear the year number 00428 * @param nMonth the month number 00429 * @param nDay the day number 00430 */ 00431 static String::View formatDate(int32_t nYear, int32_t nMonth, 00432 int32_t nDay); 00433 00434 /** 00435 * Format a time using the simplest applicable of the following 00436 * formats: 00437 * <ol> 00438 * <li><tt>HH:MM</tt></li> 00439 * <li><tt>HH:MM:SS</tt></li> 00440 * <li><tt>HH:MM:SS.MMM</tt></li> 00441 * <li><tt>HH:MM:SS.NNNNNNNNN</tt></li> 00442 * </ol> 00443 * 00444 * @param nHour the hour number 00445 * @param nMinute the minute number 00446 * @param nSecond the second number 00447 * @param nNano the nanosecond number 00448 * @param fUTC true for UTC, false for no time zone 00449 * 00450 * @return a time String 00451 */ 00452 static String::View formatTime(int32_t nHour, int32_t nMinute, 00453 int32_t nSecond, int32_t nNano, bool fUTC); 00454 00455 /** 00456 * Format a time using the simplest applicable of the following 00457 * formats: 00458 * <ol> 00459 * <li><tt>HH:MM(+|-)HH:MM</tt></li> 00460 * <li><tt>HH:MM:SS(+|-)HH:MM</tt></li> 00461 * <li><tt>HH:MM:SS.MMM(+|-)HH:MM</tt></li> 00462 * <li><tt>HH:MM:SS.NNNNNNNNN(+|-)HH:MM</tt></li> 00463 * </ol> 00464 * 00465 * @param nHour the hour number 00466 * @param nMinute the minute number 00467 * @param nSecond the second number 00468 * @param nNano the nanosecond number 00469 * @param nHourOffset the timezone offset in hours 00470 * @param nMinuteOffset the timezone offset in minutes 00471 * 00472 * @return a time String 00473 */ 00474 static String::View formatTime(int32_t nHour, int32_t nMinute, 00475 int32_t nSecond, int32_t nNano, int32_t nHourOffset, 00476 int32_t nMinuteOffset); 00477 00478 /** 00479 * Write a date value to a BufferOutput object. 00480 * 00481 * @param hOut the BufferOutput to write to 00482 * @param nYear the year number as defined by ISO8601 00483 * @param nMonth the month number between 1 and 12 inclusive as 00484 * defined by ISO8601 00485 * @param nDay the day number between 1 and 31 inclusive as defined 00486 * by ISO8601 00487 * 00488 * @throws IOException thrown if the passed BufferOutput object throws 00489 * an IOException while the value is being written to it 00490 */ 00491 static void writeDate(WriteBuffer::BufferOutput::Handle hOut, 00492 int32_t nYear, int32_t nMonth, int32_t nDay); 00493 00494 /** 00495 * Write a time value to a BufferOutput object. 00496 * 00497 * @param hOut the BufferOutput to write to 00498 * @param nHour the hour between 0 and 23 inclusive 00499 * @param nMinute the minute value between 0 and 59 inclusive 00500 * @param nSecond the second value between 0 and 59 inclusive 00501 * (and theoretically 60 for a leap-second) 00502 * @param nNano the nanosecond value between 0 and 999999999 00503 * inclusive 00504 * @param nTimeZoneType 0 if the time value does not have an explicit 00505 * time zone, 1 if the time value is UTC and 2 if 00506 * the time zone has an explicit hour and minute 00507 * offset 00508 * @param nHourOffset the timezone offset in hours from UTC, for 00509 * example 0 for BST, -5 for EST and 1 for CET 00510 * @param nMinuteOffset the timezone offset in minutes, for example 0 00511 * (in most cases) or 30 00512 * 00513 * @throws IOException thrown if the passed BufferOutput object throws 00514 * an IOException while the value is being written to it 00515 */ 00516 static void writeTime(WriteBuffer::BufferOutput::Handle hOut, 00517 int32_t nHour, int32_t nMinute, int32_t nSecond, 00518 int32_t nNano, int32_t nTimeZoneType, int32_t nHourOffset, 00519 int32_t nMinuteOffset); 00520 00521 /** 00522 * Expand the passed array to contain the specified number of elements. 00523 * 00524 * @param haOld the "template" array or null 00525 * @param cNew the number of desired elements in the new array 00526 * 00527 * @return the old array, if it was big enough, or a new array of the 00528 * same type 00529 * 00530 * @since Coherence 12.1.2 00531 */ 00532 static ObjectArray::Handle resizeArray(ObjectArray::Handle haOld, 00533 size32_t cNew); 00534 00535 00536 // ----- inner class: WriteableEntrySetMap ------------------------------ 00537 00538 public: 00539 /** 00540 * Immutable Map implementation backed by a Set of Map::Entry objects. 00541 * 00542 * @author jh 2008.05.05 00543 */ 00544 class WriteableEntrySetMap 00545 : public class_spec<WriteableEntrySetMap, 00546 extends<AbstractMap> > 00547 { 00548 friend class factory<WriteableEntrySetMap>; 00549 00550 // ----- constructors --------------------------------------- 00551 00552 protected: 00553 /** 00554 * Construct a new WriteableEntrySetMap that is backed by the 00555 * given Set of Map::Entry objects. 00556 * 00557 * @param vSetEntries a Set of Map::Entry objects in the new 00558 * WriteableEntrySetMap; must not be NULL 00559 */ 00560 WriteableEntrySetMap(Set::View vSetEntries); 00561 00562 // ----- Map interface -------------------------------------- 00563 00564 public: 00565 /** 00566 * {@inheritDoc} 00567 */ 00568 virtual Object::Holder put(Object::View vKey, 00569 Object::Holder ohValue); 00570 00571 /** 00572 * {@inheritDoc} 00573 */ 00574 virtual Object::Holder remove(Object::View vKey); 00575 using Map::remove; 00576 00577 /** 00578 * {@inheritDoc} 00579 */ 00580 virtual void clear(); 00581 00582 /** 00583 * {@inheritDoc} 00584 */ 00585 virtual Set::Handle entrySet(); 00586 00587 /** 00588 * {@inheritDoc} 00589 */ 00590 virtual Set::View entrySet() const; 00591 00592 // ----- data members --------------------------------------- 00593 00594 protected: 00595 /** 00596 * The backing Set of Map::Entry objects. 00597 */ 00598 FinalView<Set> f_vSetEntries; 00599 }; 00600 00601 00602 // ----- inner class: ReadableEntrySetMap ------------------------------- 00603 00604 public: 00605 /** 00606 * Map implementation backed by a List of Map.Entry objects. 00607 * 00608 * @author jh 2008.05.05 00609 */ 00610 class ReadableEntrySetMap 00611 : public class_spec<ReadableEntrySetMap, 00612 extends<AbstractMap> > 00613 { 00614 friend class factory<ReadableEntrySetMap>; 00615 00616 // ----- constructors --------------------------------------- 00617 00618 protected: 00619 /** 00620 * Construct a new ReadableEntrySetMap. 00621 */ 00622 ReadableEntrySetMap(); 00623 00624 // ----- Map interface -------------------------------------- 00625 00626 public: 00627 /** 00628 * {@inheritDoc} 00629 */ 00630 virtual Object::Holder put(Object::View vKey, 00631 Object::Holder ohValue); 00632 00633 /** 00634 * {@inheritDoc} 00635 */ 00636 virtual Object::Holder remove(Object::View vKey); 00637 using Map::remove; 00638 00639 /** 00640 * {@inheritDoc} 00641 */ 00642 virtual void clear(); 00643 00644 /** 00645 * {@inheritDoc} 00646 */ 00647 virtual Set::Handle entrySet(); 00648 00649 /** 00650 * {@inheritDoc} 00651 */ 00652 virtual Set::View entrySet() const; 00653 00654 // ----- data members --------------------------------------- 00655 00656 protected: 00657 /** 00658 * The backing List of Map::Entry objects. 00659 */ 00660 mutable FinalHandle<List> f_hListEntries; 00661 }; 00662 00663 00664 // ----- constants ------------------------------------------------------ 00665 00666 public: 00667 /** 00668 * @return an empty array of bool. 00669 */ 00670 static Array<bool>::Handle getEmptyBooleanArray(); 00671 00672 /** 00673 * @return an empty array of octet_t. 00674 */ 00675 static Array<octet_t>::Handle getEmptyOctetArray(); 00676 00677 /** 00678 * @return an empty array of wchar16_t. 00679 */ 00680 static Array<wchar16_t>::Handle getEmptyChar16Array(); 00681 00682 /** 00683 * @return an empty array of int16_t. 00684 */ 00685 static Array<int16_t>::Handle getEmptyInt16Array(); 00686 00687 /** 00688 * @return an empty array of int32_t. 00689 */ 00690 static Array<int32_t>::Handle getEmptyInt32Array(); 00691 00692 /** 00693 * @return an empty array of int64_t. 00694 */ 00695 static Array<int64_t>::Handle getEmptyInt64Array(); 00696 00697 /** 00698 * @return an empty array of float32_t. 00699 */ 00700 static Array<float32_t>::Handle getEmptyFloat32Array(); 00701 00702 /** 00703 * @return an empty array of float64_t. 00704 */ 00705 static Array<float64_t>::Handle getEmptyFloat64Array(); 00706 00707 /** 00708 * @return an empty array of objects. 00709 */ 00710 static ObjectArray::Handle getEmptyObjectArray(); 00711 00712 /** 00713 * A zero-length Binary. 00714 */ 00715 static Binary::Handle getEmptyBinary(); 00716 00717 /** 00718 * @return an empty and immutable Collection. 00719 */ 00720 static Collection::View getEmptyCollection(); 00721 }; 00722 00723 COH_CLOSE_NAMESPACE3 00724 00725 #endif // COH_POF_HELPER_HPP