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