00001 /* 00002 * PofHelper.hpp 00003 * 00004 * Copyright (c) 2000, 2020, 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 wchar16_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 wchar16_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 a wchar16_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 char 00130 * 00131 * @throws IOException if an I/O error occurs reading the POF stream, 00132 * or the POF value cannot be coerced to a char value 00133 */ 00134 static wchar16_t readAsChar16(FinalHandle<ReadBuffer::BufferInput>& 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 int32_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 int32_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 int32_t value 00148 */ 00149 static int32_t readAsInt32(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 an int32_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 an int32_t 00160 * 00161 * @throws IOException if an I/O error occurs reading the POF stream, 00162 * or the POF value cannot be coerced to an int32_t value 00163 */ 00164 static int32_t readAsInt32(FinalHandle<ReadBuffer::BufferInput>& hIn, 00165 int32_t nType); 00166 00167 /** 00168 * Read a value of the specified encoding from the POF stream and 00169 * convert it to an int64_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 an int64_t 00175 * 00176 * @throws IOException if an I/O error occurs reading the POF stream, 00177 * or the POF value cannot be coerced to an int64_t value 00178 */ 00179 static int64_t readAsInt64(ReadBuffer::BufferInput::Handle hIn, 00180 int32_t nType); 00181 00182 /** 00183 * Read a value of the specified encoding from the POF stream and 00184 * convert it to an int64_t. 00185 * 00186 * @param hIn the POF stream containing the value 00187 * @param nType the POF type of the value 00188 * 00189 * @return the POF value as an int64_t 00190 * 00191 * @throws IOException if an I/O error occurs reading the POF stream, 00192 * or the POF value cannot be coerced to an int64_t value 00193 */ 00194 static int64_t readAsInt64(FinalHandle<ReadBuffer::BufferInput>& hIn, 00195 int32_t nType); 00196 00197 /** 00198 * Read a value of the specified encoding from the POF stream and 00199 * convert it to a float32_t. 00200 * 00201 * @param hIn the POF stream containing the value 00202 * @param nType the POF type of the value 00203 * 00204 * @return the POF value as a float32_t 00205 * 00206 * @throws IOException if an I/O error occurs reading the POF stream, 00207 * or the POF value cannot be coerced to a float32_t value 00208 */ 00209 static float32_t readAsFloat32(ReadBuffer::BufferInput::Handle hIn, 00210 int32_t nType); 00211 00212 /** 00213 * Read a value of the specified encoding from the POF stream and 00214 * convert it to a float32_t. 00215 * 00216 * @param hIn the POF stream containing the value 00217 * @param nType the POF type of the value 00218 * 00219 * @return the POF value as a float32_t 00220 * 00221 * @throws IOException if an I/O error occurs reading the POF stream, 00222 * or the POF value cannot be coerced to a float32_t value 00223 */ 00224 static float32_t readAsFloat32(FinalHandle<ReadBuffer::BufferInput>& hIn, 00225 int32_t nType); 00226 00227 /** 00228 * Read a value of the specified encoding from the POF stream and 00229 * convert it to a float64_t. 00230 * 00231 * @param hIn the POF stream containing the value 00232 * @param nType the POF type of the value 00233 * 00234 * @return the POF value as a float64_t 00235 * 00236 * @throws IOException if an I/O error occurs reading the POF stream, 00237 * or the POF value cannot be coerced to a float64_t value 00238 */ 00239 static float64_t readAsFloat64(ReadBuffer::BufferInput::Handle hIn, 00240 int32_t nType); 00241 00242 /** 00243 * Read a value of the specified encoding from the POF stream and 00244 * convert it to a float64_t. 00245 * 00246 * @param hIn the POF stream containing the value 00247 * @param nType the POF type of the value 00248 * 00249 * @return the POF value as a float64_t 00250 * 00251 * @throws IOException if an I/O error occurs reading the POF stream, 00252 * or the POF value cannot be coerced to a float64_t value 00253 */ 00254 static float64_t readAsFloat64(FinalHandle<ReadBuffer::BufferInput>& hIn, 00255 int32_t nType); 00256 00257 /** 00258 * Read a RawDate value from the passed BufferInput. 00259 * 00260 * @param hIn the BufferInput object to read from 00261 * 00262 * @return the RawDate value 00263 */ 00264 static RawDate::View readRawDate( 00265 ReadBuffer::BufferInput::Handle hIn); 00266 00267 /** 00268 * Read a RawDate value from the passed BufferInput. 00269 * 00270 * @param hIn the BufferInput object to read from 00271 * 00272 * @return the RawDate value 00273 */ 00274 static RawDate::View readRawDate( 00275 FinalHandle<ReadBuffer::BufferInput>& hIn); 00276 00277 /** 00278 * Read a RawTime value from the passed BufferInput. 00279 * 00280 * @param hIn the BufferInput object to read from 00281 * 00282 * @return the RawTime value 00283 */ 00284 static RawTime::View readRawTime( 00285 ReadBuffer::BufferInput::Handle hIn); 00286 00287 /** 00288 * Read a RawTime value from the passed BufferInput. 00289 * 00290 * @param hIn the BufferInput object to read from 00291 * 00292 * @return the RawTime value 00293 */ 00294 static RawTime::View readRawTime( 00295 FinalHandle<ReadBuffer::BufferInput>& hIn); 00296 00297 /** 00298 * Within the POF stream, skip the next POF value. 00299 * 00300 * @param hIn the BufferInput containing the POF stream 00301 */ 00302 static void skipValue(ReadBuffer::BufferInput::Handle hIn); 00303 00304 /** 00305 * Within the POF stream, skip the next POF value of the specified 00306 * type. 00307 * 00308 * @param hIn the BufferInput containing the POF stream 00309 * @param nType the type of the value to skip 00310 */ 00311 static void skipUniformValue(ReadBuffer::BufferInput::Handle hIn, 00312 int32_t nType); 00313 00314 /** 00315 * Skip the specified number of integers in the passed POF stream. 00316 * 00317 * @param hIn the BufferInput containing the POF stream 00318 * @param c the number of integers to skip over 00319 */ 00320 static void skipInts(ReadBuffer::BufferInput::Handle hIn, int32_t c); 00321 00322 /** 00323 * Validate that the specified POF collection size as read from a POF 00324 * stream is smaller than the largest value of the size32_t type, and if 00325 * so, return the given size as a size32_t. 00326 * 00327 * @param cElements the POF collection size 00328 * 00329 * @return the POF collection size as a size32_t 00330 * 00331 * @throws Exception if the given POF collection size is greater than 00332 * the largest value of the size32_t type 00333 */ 00334 inline static size32_t validateIncomingSize(int32_t cElements) 00335 { 00336 COH_ENSURE(cElements >= 0); 00337 00338 size32_t nElements = (size32_t) cElements; 00339 if (((int32_t) nElements) != cElements) 00340 { 00341 COH_THROW_STREAM (IllegalStateException, 00342 "incoming POF collection size overflow: " << cElements 00343 << " > " << (std::numeric_limits<size32_t>::max)()); 00344 } 00345 return nElements; 00346 } 00347 00348 /** 00349 * Validate that the specified Collection size is smaller than the 00350 * largest value of the int32_t type, and if so, return the given size 00351 * as an in32_t. 00352 * 00353 * @param cElements the Collection size 00354 * 00355 * @return the Collection size as a int32_t 00356 * 00357 * @throws Exception if the given Collection size is greater than the 00358 * largest value of the int32_t type 00359 */ 00360 inline static int32_t validateOutgoingSize(size32_t cElements) 00361 { 00362 int32_t nElements = (int32_t) cElements; 00363 if (((size32_t) nElements) != cElements || nElements < 0) 00364 { 00365 COH_THROW_STREAM (IllegalStateException, 00366 "outgoing POF collection size overflow: " << cElements 00367 << " > " << Integer32::max_value); 00368 } 00369 return nElements; 00370 } 00371 00372 /** 00373 * Validate date information. 00374 * 00375 * @param nYear the year number 00376 * @param nMonth the month number 00377 * @param nDay the day number 00378 */ 00379 static void checkDate(int32_t nYear, int32_t nMonth, int32_t nDay); 00380 00381 /** 00382 * Validate time information. 00383 * 00384 * @param nHour the hour number 00385 * @param nMinute the minute number 00386 * @param nSecond the second number 00387 * @param nNano the nanosecond number 00388 */ 00389 static void checkTime(int32_t nHour, int32_t nMinute, int32_t nSecond, 00390 int32_t nNano); 00391 00392 /** 00393 * Check the specified timezone offset. 00394 * 00395 * @param nHourOffset the hour offset 00396 * @param nMinuteOffset the minute offset 00397 */ 00398 static void checkTimeZone(int32_t nHourOffset, int32_t nMinuteOffset); 00399 00400 /** 00401 * Validate a time interval. 00402 * 00403 * @param cHours the number of hours 00404 * @param cMinutes the number of minutes 00405 * @param cSeconds the number of seconds 00406 * @param cNanos the number of nanoseconds 00407 */ 00408 static void checkTimeInterval(int32_t cHours, int32_t cMinutes, 00409 int32_t cSeconds, int32_t cNanos); 00410 00411 /** 00412 * Validate a day-time interval. 00413 * 00414 * See http://www.builderau.com.au/architect/database/soa/SQL_basics_Datetime_and_interval_data_types/0,39024547,20269031,00.htm 00415 * 00416 * @param cDays the number of days 00417 * @param cHours the number of hours 00418 * @param cMinutes the number of minutes 00419 * @param cSeconds the number of seconds 00420 * @param cNanos the number of nanoseconds 00421 */ 00422 static void checkDayTimeInterval(int32_t cDays, int32_t cHours, 00423 int32_t cMinutes, int32_t cSeconds, int32_t cNanos); 00424 00425 /** 00426 * Validate a year-month interval. 00427 * 00428 * @param cYears the number of years 00429 * @param cMonths the number of months 00430 */ 00431 static void checkYearMonthInterval(int32_t cYears, int32_t cMonths); 00432 00433 /** 00434 * Format a date in the form YYYY-MM-DD. 00435 * 00436 * @param nYear the year number 00437 * @param nMonth the month number 00438 * @param nDay the day number 00439 */ 00440 static String::View formatDate(int32_t nYear, int32_t nMonth, 00441 int32_t nDay); 00442 00443 /** 00444 * Format a time using the simplest applicable of the following 00445 * formats: 00446 * <ol> 00447 * <li><tt>HH:MM</tt></li> 00448 * <li><tt>HH:MM:SS</tt></li> 00449 * <li><tt>HH:MM:SS.MMM</tt></li> 00450 * <li><tt>HH:MM:SS.NNNNNNNNN</tt></li> 00451 * </ol> 00452 * 00453 * @param nHour the hour number 00454 * @param nMinute the minute number 00455 * @param nSecond the second number 00456 * @param nNano the nanosecond number 00457 * @param fUTC true for UTC, false for no time zone 00458 * 00459 * @return a time String 00460 */ 00461 static String::View formatTime(int32_t nHour, int32_t nMinute, 00462 int32_t nSecond, int32_t nNano, bool fUTC); 00463 00464 /** 00465 * Format a time using the simplest applicable of the following 00466 * formats: 00467 * <ol> 00468 * <li><tt>HH:MM�HH:MM</tt></li> 00469 * <li><tt>HH:MM:SS�HH:MM</tt></li> 00470 * <li><tt>HH:MM:SS.MMM�HH:MM</tt></li> 00471 * <li><tt>HH:MM:SS.NNNNNNNNN�HH:MM</tt></li> 00472 * </ol> 00473 * 00474 * @param nHour the hour number 00475 * @param nMinute the minute number 00476 * @param nSecond the second number 00477 * @param nNano the nanosecond number 00478 * @param nHourOffset the timezone offset in hours 00479 * @param nMinuteOffset the timezone offset in minutes 00480 * 00481 * @return a time String 00482 */ 00483 static String::View formatTime(int32_t nHour, int32_t nMinute, 00484 int32_t nSecond, int32_t nNano, int32_t nHourOffset, 00485 int32_t nMinuteOffset); 00486 00487 /** 00488 * Write a date value to a BufferOutput object. 00489 * 00490 * @param hOut the BufferOutput to write to 00491 * @param nYear the year number as defined by ISO8601 00492 * @param nMonth the month number between 1 and 12 inclusive as 00493 * defined by ISO8601 00494 * @param nDay the day number between 1 and 31 inclusive as defined 00495 * by ISO8601 00496 * 00497 * @throws IOException thrown if the passed BufferOutput object throws 00498 * an IOException while the value is being written to it 00499 */ 00500 static void writeDate(WriteBuffer::BufferOutput::Handle hOut, 00501 int32_t nYear, int32_t nMonth, int32_t nDay); 00502 00503 /** 00504 * Write a time value to a BufferOutput object. 00505 * 00506 * @param hOut the BufferOutput to write to 00507 * @param nHour the hour between 0 and 23 inclusive 00508 * @param nMinute the minute value between 0 and 59 inclusive 00509 * @param nSecond the second value between 0 and 59 inclusive 00510 * (and theoretically 60 for a leap-second) 00511 * @param nNano the nanosecond value between 0 and 999999999 00512 * inclusive 00513 * @param nTimeZoneType 0 if the time value does not have an explicit 00514 * time zone, 1 if the time value is UTC and 2 if 00515 * the time zone has an explicit hour and minute 00516 * offset 00517 * @param nHourOffset the timezone offset in hours from UTC, for 00518 * example 0 for BST, -5 for EST and 1 for CET 00519 * @param nMinuteOffset the timezone offset in minutes, for example 0 00520 * (in most cases) or 30 00521 * 00522 * @throws IOException thrown if the passed BufferOutput object throws 00523 * an IOException while the value is being written to it 00524 */ 00525 static void writeTime(WriteBuffer::BufferOutput::Handle hOut, 00526 int32_t nHour, int32_t nMinute, int32_t nSecond, 00527 int32_t nNano, int32_t nTimeZoneType, int32_t nHourOffset, 00528 int32_t nMinuteOffset); 00529 00530 /** 00531 * Expand the passed array to contain the specified number of elements. 00532 * 00533 * @param haOld the "template" array or null 00534 * @param cNew the number of desired elements in the new array 00535 * 00536 * @return the old array, if it was big enough, or a new array of the 00537 * same type 00538 * 00539 * @since Coherence 12.1.2 00540 */ 00541 static ObjectArray::Handle resizeArray(ObjectArray::Handle haOld, 00542 size32_t cNew); 00543 00544 00545 // ----- inner class: WriteableEntrySetMap ------------------------------ 00546 00547 public: 00548 /** 00549 * Immutable Map implementation backed by a Set of Map::Entry objects. 00550 * 00551 * @author jh 2008.05.05 00552 */ 00553 class WriteableEntrySetMap 00554 : public class_spec<WriteableEntrySetMap, 00555 extends<AbstractMap> > 00556 { 00557 friend class factory<WriteableEntrySetMap>; 00558 00559 // ----- constructors --------------------------------------- 00560 00561 protected: 00562 /** 00563 * Construct a new WriteableEntrySetMap that is backed by the 00564 * given Set of Map::Entry objects. 00565 * 00566 * @param vSetEntries a Set of Map::Entry objects in the new 00567 * WriteableEntrySetMap; must not be NULL 00568 */ 00569 WriteableEntrySetMap(Set::View vSetEntries); 00570 00571 // ----- Map interface -------------------------------------- 00572 00573 public: 00574 /** 00575 * {@inheritDoc} 00576 */ 00577 virtual Object::Holder put(Object::View vKey, 00578 Object::Holder ohValue); 00579 00580 /** 00581 * {@inheritDoc} 00582 */ 00583 virtual Object::Holder remove(Object::View vKey); 00584 using Map::remove; 00585 00586 /** 00587 * {@inheritDoc} 00588 */ 00589 virtual void clear(); 00590 00591 /** 00592 * {@inheritDoc} 00593 */ 00594 virtual Set::Handle entrySet(); 00595 00596 /** 00597 * {@inheritDoc} 00598 */ 00599 virtual Set::View entrySet() const; 00600 00601 // ----- data members --------------------------------------- 00602 00603 protected: 00604 /** 00605 * The backing Set of Map::Entry objects. 00606 */ 00607 FinalView<Set> f_vSetEntries; 00608 }; 00609 00610 00611 // ----- inner class: ReadableEntrySetMap ------------------------------- 00612 00613 public: 00614 /** 00615 * Map implementation backed by a List of Map.Entry objects. 00616 * 00617 * @author jh 2008.05.05 00618 */ 00619 class ReadableEntrySetMap 00620 : public class_spec<ReadableEntrySetMap, 00621 extends<AbstractMap> > 00622 { 00623 friend class factory<ReadableEntrySetMap>; 00624 00625 // ----- constructors --------------------------------------- 00626 00627 protected: 00628 /** 00629 * Construct a new ReadableEntrySetMap. 00630 */ 00631 ReadableEntrySetMap(); 00632 00633 // ----- Map interface -------------------------------------- 00634 00635 public: 00636 /** 00637 * {@inheritDoc} 00638 */ 00639 virtual Object::Holder put(Object::View vKey, 00640 Object::Holder ohValue); 00641 00642 /** 00643 * {@inheritDoc} 00644 */ 00645 virtual Object::Holder remove(Object::View vKey); 00646 using Map::remove; 00647 00648 /** 00649 * {@inheritDoc} 00650 */ 00651 virtual void clear(); 00652 00653 /** 00654 * {@inheritDoc} 00655 */ 00656 virtual Set::Handle entrySet(); 00657 00658 /** 00659 * {@inheritDoc} 00660 */ 00661 virtual Set::View entrySet() const; 00662 00663 // ----- data members --------------------------------------- 00664 00665 protected: 00666 /** 00667 * The backing List of Map::Entry objects. 00668 */ 00669 mutable FinalHandle<List> f_hListEntries; 00670 }; 00671 00672 00673 // ----- constants ------------------------------------------------------ 00674 00675 public: 00676 /** 00677 * @return an empty array of bool. 00678 */ 00679 static Array<bool>::Handle getEmptyBooleanArray(); 00680 00681 /** 00682 * @return an empty array of octet_t. 00683 */ 00684 static Array<octet_t>::Handle getEmptyOctetArray(); 00685 00686 /** 00687 * @return an empty array of wchar16_t. 00688 */ 00689 static Array<wchar16_t>::Handle getEmptyChar16Array(); 00690 00691 /** 00692 * @return an empty array of int16_t. 00693 */ 00694 static Array<int16_t>::Handle getEmptyInt16Array(); 00695 00696 /** 00697 * @return an empty array of int32_t. 00698 */ 00699 static Array<int32_t>::Handle getEmptyInt32Array(); 00700 00701 /** 00702 * @return an empty array of int64_t. 00703 */ 00704 static Array<int64_t>::Handle getEmptyInt64Array(); 00705 00706 /** 00707 * @return an empty array of float32_t. 00708 */ 00709 static Array<float32_t>::Handle getEmptyFloat32Array(); 00710 00711 /** 00712 * @return an empty array of float64_t. 00713 */ 00714 static Array<float64_t>::Handle getEmptyFloat64Array(); 00715 00716 /** 00717 * @return an empty array of objects. 00718 */ 00719 static ObjectArray::Handle getEmptyObjectArray(); 00720 00721 /** 00722 * A zero-length Binary. 00723 */ 00724 static Binary::Handle getEmptyBinary(); 00725 00726 /** 00727 * @return an empty and immutable Collection. 00728 */ 00729 static Collection::View getEmptyCollection(); 00730 }; 00731 00732 COH_CLOSE_NAMESPACE3 00733 00734 #endif // COH_POF_HELPER_HPP