00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef _POBJECT_H
00035 #define _POBJECT_H
00036
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040
00041 #if defined(_WIN32) || defined(_WIN32_WCE)
00042 #include "msos/ptlib/contain.h"
00043 #else
00044 #include "unix/ptlib/contain.h"
00045 #endif
00046
00047 #if defined(P_VXWORKS)
00048 #include <private/stdiop.h>
00049 #endif
00050
00051 #include <stdio.h>
00052 #include <stdarg.h>
00053 #include <stdlib.h>
00054
00055 #include <string.h>
00056
00057 #include <string>
00058 #include <iomanip>
00059 #include <iostream>
00060 #include <sstream>
00061
00062
00063
00064
00065
00066
00067 #if defined(P_USE_INTEGER_BOOL) || !defined(__cplusplus)
00068 typedef BOOL PBoolean;
00069 # define PTrue TRUE
00070 # define PFalse FALSE
00071 #else
00072 typedef bool PBoolean;
00073 # define PTrue true
00074 # define PFalse false
00075 #endif
00076
00077
00079
00080
00081
00082 #ifndef P_USE_INLINES
00083 #ifdef _DEBUG
00084 #define P_USE_INLINES 0
00085 #else
00086 #define P_USE_INLINES 0
00087 #endif
00088 #endif
00089
00090 #if P_USE_INLINES
00091 #define PINLINE inline
00092 #else
00093 #define PINLINE
00094 #endif
00095
00096
00098
00099
00100 #ifndef P_USE_ASSERTS
00101 #define P_USE_ASSERTS 1
00102 #endif
00103
00104 #if !P_USE_ASSERTS
00105
00106 #define PAssert(b, m) (b)
00107 #define PAssert2(b, c, m) (b)
00108 #define PAssertOS(b) (b)
00109 #define PAssertNULL(p) (p)
00110 #define PAssertAlways(m)
00111 #define PAssertAlways2(c, m)
00112
00113 #else // P_USE_ASSERTS
00114
00116 enum PStandardAssertMessage {
00117 PLogicError,
00118 POutOfMemory,
00119 PNullPointerReference,
00120 PInvalidCast,
00121 PInvalidArrayIndex,
00122 PInvalidArrayElement,
00123 PStackEmpty,
00124 PUnimplementedFunction,
00125 PInvalidParameter,
00126 POperatingSystemError,
00127 PChannelNotOpen,
00128 PUnsupportedFeature,
00129 PInvalidWindow,
00130 PMaxStandardAssertMessage
00131 };
00132
00133 #define __CLASS__ NULL
00134
00135 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg);
00136 void PAssertFunc(const char * file, int line, const char * className, const char * msg);
00137 void PAssertFunc(const char * full_msg);
00138
00139 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, PStandardAssertMessage msg)
00140 {
00141 if (!b)
00142 PAssertFunc(file, line, className, msg);
00143 return b;
00144 }
00145 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, const char * msg)
00146 {
00147 if (!b)
00148 PAssertFunc(file, line, className, msg);
00149 return b;
00150 }
00151
00158 #define PAssert(b, m) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(m))
00159
00167 #define PAssert2(b, c, m) PAssertFuncInline((b), __FILE__,__LINE__,(c),(m))
00168
00175 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
00176
00186 #define PAssertNULL(p) (((p)!=NULL)?(p): \
00187 (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(p)))
00188
00195 #define PAssertAlways(m) PAssertFunc(__FILE__,__LINE__,__CLASS__,(m))
00196
00203 #define PAssertAlways2(c, m) PAssertFunc(__FILE__,__LINE__,(c),(m))
00204
00205 #endif // P_USE_ASSERTS
00206
00207
00212 ostream & PGetErrorStream();
00213
00217 void PSetErrorStream(ostream * strm );
00218
00233 #define PError (PGetErrorStream())
00234
00235
00236
00238
00239
00240 #ifndef PTRACING
00241 #define PTRACING 1
00242 #endif
00243
00244 #if PTRACING
00245
00250 class PTrace
00251 {
00252 public:
00254 enum Options {
00260 Blocks = 1,
00262 DateAndTime = 2,
00264 Timestamp = 4,
00266 Thread = 8,
00268 TraceLevel = 16,
00270 FileAndLine = 32,
00272 ThreadAddress = 64,
00274 AppendToFile = 128,
00277 GMTTime = 256,
00280 RotateDaily = 512,
00284 SystemLogStream = 32768
00285 };
00286
00294 static void Initialise(
00295 unsigned level,
00296 const char * filename = NULL,
00297 unsigned options = Timestamp | Thread | Blocks
00298 );
00299
00310 static void Initialise(
00311 unsigned level,
00312 const char * filename,
00313 const char * rolloverPattern,
00314 unsigned options = Timestamp | Thread | Blocks
00315 );
00316
00323 static void SetOptions(unsigned options );
00324
00332 static void ClearOptions(unsigned options );
00333
00338 static unsigned GetOptions();
00339
00345 static void SetLevel(unsigned level );
00346
00352 static unsigned GetLevel();
00353
00358 static PBoolean CanTrace(unsigned level );
00359
00364 static void SetStream(ostream * out );
00365
00381 static ostream & Begin(
00382 unsigned level,
00383 const char * fileName,
00384 int lineNum
00385 );
00386
00403 static ostream & End(ostream & strm );
00404
00408 static void Cleanup();
00409
00415 class Block {
00416 public:
00418 Block(
00419 const char * fileName,
00420 int lineNum,
00421 const char * traceName
00423 );
00424 Block(const Block & obj)
00425 : file(obj.file), line(obj.line), name(obj.name) { }
00427 ~Block();
00428 private:
00429 Block & operator=(const Block &)
00430 { return *this; }
00431 const char * file;
00432 int line;
00433 const char * name;
00434 };
00435 };
00436
00437
00438
00439 #define PTRACE_PARAM(param) param
00440
00447 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
00448
00452 #define PTRACE_LINE() \
00453 if (PTrace::CanTrace(1)) \
00454 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End; \
00455 else (void)0
00456
00462 #define PTRACE(level, args) \
00463 if (PTrace::CanTrace(level)) \
00464 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
00465 else (void)0
00466
00474 #define PTRACE_IF(level, cond, args) \
00475 if ((PTrace::CanTrace(level) && (cond))) \
00476 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
00477 else (void)0
00478
00479 #else // PTRACING
00480
00481 #define PTRACE_PARAM(param)
00482 #define PTRACE_BLOCK(n)
00483 #define PTRACE_LINE()
00484 #define PTRACE(level, arg)
00485 #define PTRACE_IF(level, cond, args)
00486
00487 #endif // PTRACING
00488
00489
00490
00491 #if PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG) && !defined(_WIN32_WCE))
00492
00493 #define PMEMORY_HEAP 1
00494
00501 class PMemoryHeap {
00502 public:
00504 PMemoryHeap();
00505
00506
00507 ~PMemoryHeap();
00508
00515 static void * Allocate(
00516 size_t nSize,
00517 const char * file,
00518 int line,
00519 const char * className
00520 );
00527 static void * Allocate(
00528 size_t count,
00529 size_t iSize,
00530 const char * file,
00531 int line
00532 );
00533
00541 static void * Reallocate(
00542 void * ptr,
00543 size_t nSize,
00544 const char * file,
00545 int line
00546 );
00547
00553 static void Deallocate(
00554 void * ptr,
00555 const char * className
00556 );
00557
00560 enum Validation {
00561 Ok, Bad, Trashed
00562 };
00570 static Validation Validate(
00571 const void * ptr,
00572 const char * className,
00573 ostream * error
00574 );
00575
00580 static PBoolean ValidateHeap(
00581 ostream * error = NULL
00582 );
00583
00589 static PBoolean SetIgnoreAllocations(
00590 PBoolean ignore
00591 );
00592
00596 static void DumpStatistics();
00600 static void DumpStatistics(ostream & strm );
00601
00602 #if PMEMORY_CHECK
00603 struct State {
00604 DWORD allocationNumber;
00605 };
00606 #else
00607 typedef _CrtMemState State;
00608 #endif
00609
00610
00611
00612
00613
00614 static void GetState(
00615 State & state
00616 );
00617
00625 static void DumpObjectsSince(
00626 const State & when
00627 );
00628
00634 static void DumpObjectsSince(
00635 const State & when,
00636 ostream & strm
00637 );
00638
00644 static void SetAllocationBreakpoint(
00645 DWORD point
00646 );
00647
00648 #if PMEMORY_CHECK
00649
00650 protected:
00651 void * InternalAllocate(
00652 size_t nSize,
00653 const char * file,
00654 int line,
00655 const char * className
00656 );
00657 Validation InternalValidate(
00658 const void * ptr,
00659 const char * className,
00660 ostream * error
00661 );
00662 void InternalDumpStatistics(ostream & strm);
00663 void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
00664
00665 class Wrapper {
00666 public:
00667 Wrapper();
00668 ~Wrapper();
00669 PMemoryHeap * operator->() const { return instance; }
00670 private:
00671 PMemoryHeap * instance;
00672 };
00673 friend class Wrapper;
00674
00675 enum Flags {
00676 NoLeakPrint = 1
00677 };
00678
00679 #pragma pack(1)
00680 struct Header {
00681 enum {
00682
00683 NumGuardBytes = 16 - (sizeof(Header *) +
00684 sizeof(Header *) +
00685 sizeof(const char *) +
00686 sizeof(const char *) +
00687 sizeof(size_t) +
00688 sizeof(DWORD) +
00689 sizeof(WORD) +
00690 sizeof(BYTE)
00691 #ifdef P_LINUX
00692 + sizeof(pthread_t)
00693 #endif
00694 )%8
00695 };
00696
00697 Header * prev;
00698 Header * next;
00699 const char * className;
00700 const char * fileName;
00701 size_t size;
00702 DWORD request;
00703 WORD line;
00704 BYTE flags;
00705 #ifdef P_LINUX
00706 pthread_t thread;
00707 #endif
00708 char guard[NumGuardBytes];
00709
00710 static char GuardBytes[NumGuardBytes];
00711 };
00712 #pragma pack()
00713
00714 PBoolean isDestroyed;
00715
00716 Header * listHead;
00717 Header * listTail;
00718
00719 static DWORD allocationBreakpoint;
00720 DWORD allocationRequest;
00721 DWORD firstRealObject;
00722 BYTE flags;
00723
00724 char allocFillChar;
00725 char freeFillChar;
00726
00727 DWORD currentMemoryUsage;
00728 DWORD peakMemoryUsage;
00729 DWORD currentObjects;
00730 DWORD peakObjects;
00731 DWORD totalObjects;
00732
00733 ostream * leakDumpStream;
00734
00735 #if defined(_WIN32)
00736 CRITICAL_SECTION mutex;
00737 #elif defined(P_PTHREADS)
00738 pthread_mutex_t mutex;
00739 #elif defined(P_VXWORKS)
00740 void * mutex;
00741 #endif
00742
00743 #else
00744
00745 #define P_CLIENT_BLOCK (_CLIENT_BLOCK|(0x61<<16)) // This identifies a PObject derived class
00746 _CrtMemState initialState;
00747
00748 #endif // PMEMORY_CHECK
00749 };
00750
00751
00756 inline void * runtime_malloc(size_t bytes ) { return malloc(bytes); }
00757
00762 inline void runtime_free(void * ptr ) { free(ptr); }
00763
00764
00771 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
00772
00779 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
00780
00787 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
00788
00789
00796 #define free(p) PMemoryHeap::Deallocate(p, NULL)
00797
00798
00805 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
00806
00807
00822 #define PNEW new (__FILE__, __LINE__)
00823
00824 #if !defined(_MSC_VER) || _MSC_VER<1200
00825 #define PSPECIAL_DELETE_FUNCTION
00826 #else
00827 #define PSPECIAL_DELETE_FUNCTION \
00828 void operator delete(void * ptr, const char *, int) \
00829 { PMemoryHeap::Deallocate(ptr, Class()); } \
00830 void operator delete[](void * ptr, const char *, int) \
00831 { PMemoryHeap::Deallocate(ptr, Class()); }
00832 #endif
00833
00834 #define PNEW_AND_DELETE_FUNCTIONS \
00835 void * operator new(size_t nSize, const char * file, int line) \
00836 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
00837 void * operator new(size_t nSize) \
00838 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
00839 void operator delete(void * ptr) \
00840 { PMemoryHeap::Deallocate(ptr, Class()); } \
00841 void * operator new(size_t, void * placement) \
00842 { return placement; } \
00843 void operator delete(void *, void *) \
00844 { } \
00845 void * operator new[](size_t nSize, const char * file, int line) \
00846 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
00847 void * operator new[](size_t nSize) \
00848 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
00849 void operator delete[](void * ptr) \
00850 { PMemoryHeap::Deallocate(ptr, Class()); } \
00851 PSPECIAL_DELETE_FUNCTION
00852
00853
00854 inline void * operator new(size_t nSize, const char * file, int line)
00855 { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
00856
00857 inline void * operator new[](size_t nSize, const char * file, int line)
00858 { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
00859
00860 #ifndef __GNUC__
00861 void * operator new(size_t nSize);
00862 void * operator new[](size_t nSize);
00863
00864 void operator delete(void * ptr);
00865 void operator delete[](void * ptr);
00866
00867 #if defined(_MSC_VER) && _MSC_VER>=1200
00868 inline void operator delete(void * ptr, const char *, int)
00869 { PMemoryHeap::Deallocate(ptr, NULL); }
00870
00871 inline void operator delete[](void * ptr, const char *, int)
00872 { PMemoryHeap::Deallocate(ptr, NULL); }
00873 #endif
00874 #endif
00875
00876
00877 class PMemoryHeapIgnoreAllocationsForScope {
00878 public:
00879 PMemoryHeapIgnoreAllocationsForScope() : previousIgnoreAllocations(PMemoryHeap::SetIgnoreAllocations(PTrue)) { }
00880 ~PMemoryHeapIgnoreAllocationsForScope() { PMemoryHeap::SetIgnoreAllocations(previousIgnoreAllocations); }
00881 private:
00882 PBoolean previousIgnoreAllocations;
00883 };
00884
00885 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE PMemoryHeapIgnoreAllocationsForScope instance_PMemoryHeapIgnoreAllocationsForScope
00886
00887 class PMemoryAllocationBreakpoint {
00888 public:
00889 PMemoryAllocationBreakpoint(DWORD point)
00890 {
00891 PMemoryHeap::SetAllocationBreakpoint(point);
00892 }
00893 };
00894
00895 #define PMEMORY_ALLOCATION_BREAKPOINT(point) PMemoryAllocationBreakpoint PMemoryAllocationBreakpointInstance(point)
00896
00897
00898 #else // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
00899
00900 #define PMEMORY_HEAP 0
00901
00902 #define PNEW new
00903
00904 #define PNEW_AND_DELETE_FUNCTIONS
00905
00906 #define runtime_malloc(s) malloc(s)
00907 #define runtime_free(p) free(p)
00908
00909 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE
00910 #define PMEMORY_ALLOCATION_BREAKPOINT(point)
00911
00912 #endif // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
00913
00914
00925 #define PCLASSINFO(cls, par) \
00926 public: \
00927 static inline const char * Class() \
00928 { return #cls; } \
00929 virtual PBoolean InternalIsDescendant(const char * clsName) const \
00930 { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
00931 virtual const char * GetClass(unsigned ancestor = 0) const \
00932 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
00933 virtual Comparison CompareObjectMemoryDirect(const PObject & _obj) const \
00934 { return (Comparison)memcmp(this, &_obj, sizeof(cls)); } \
00935 PNEW_AND_DELETE_FUNCTIONS
00936
00937
00938 #if P_HAS_TYPEINFO
00939
00940 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
00941 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
00942
00943 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
00944
00945 #if P_USE_ASSERTS
00946 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line)
00947 { if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; }
00948 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
00949 #else
00950 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
00951 #endif
00952
00953 #include <typeinfo>
00954
00955 #else // P_HAS_TYPEINFO
00956
00957 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class()))
00958 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
00959
00960 #define PRemoveConst(cls, ptr) ((cls*)(ptr))
00961
00962 #if P_USE_ASSERTS
00963 template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line)
00964 { if (obj->InternalIsDescendant(BaseClass::Class())) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; }
00965 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
00966 #else
00967 #define PDownCast(cls, ptr) ((cls*)(ptr))
00968 #endif
00969
00970 #endif // P_HAS_TYPEINFO
00971
00972
00981 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
00982 #ifdef DOC_PLUS_PLUS
00983 } Match previous opening brace in doc++
00984 #endif
00985
00987
00988
00993 class PObject {
00994
00995 protected:
00999 PObject() { }
01000
01001 public:
01002
01003
01004
01005 virtual ~PObject() { }
01006
01019 static inline const char * Class() { return "PObject"; }
01020
01033 virtual const char * GetClass(unsigned = 0) const { return Class(); }
01034
01035 PBoolean IsClass(const char * cls) const
01036 { return strcmp(cls, GetClass()) == 0; }
01037
01047 virtual PBoolean InternalIsDescendant(
01048 const char * clsName
01049 ) const
01050 { return IsClass(clsName); }
01051
01053
01059 enum Comparison {
01060 LessThan = -1,
01061 EqualTo = 0,
01062 GreaterThan = 1
01063 };
01064
01076 virtual Comparison Compare(
01077 const PObject & obj
01078 ) const;
01079
01091 virtual Comparison CompareObjectMemoryDirect(
01092 const PObject & obj
01093 ) const;
01094
01100 bool operator==(
01101 const PObject & obj
01102 ) const { return Compare(obj) == EqualTo; }
01103
01109 bool operator!=(
01110 const PObject & obj
01111 ) const { return Compare(obj) != EqualTo; }
01112
01118 bool operator<(
01119 const PObject & obj
01120 ) const { return Compare(obj) == LessThan; }
01121
01127 bool operator>(
01128 const PObject & obj
01129 ) const { return Compare(obj) == GreaterThan; }
01130
01136 bool operator<=(
01137 const PObject & obj
01138 ) const { return Compare(obj) != GreaterThan; }
01139
01145 bool operator>=(
01146 const PObject & obj
01147 ) const { return Compare(obj) != LessThan; }
01149
01158 virtual void PrintOn(
01159 ostream &strm
01160 ) const;
01161
01168 virtual void ReadFrom(
01169 istream &strm
01170 );
01171
01172
01178 inline friend ostream & operator<<(
01179 ostream &strm,
01180 const PObject & obj
01181 ) { obj.PrintOn(strm); return strm; }
01182
01188 inline friend istream & operator>>(
01189 istream &strm,
01190 PObject & obj
01191 ) { obj.ReadFrom(strm); return strm; }
01192
01193
01208 virtual PObject * Clone() const;
01209
01221 virtual PINDEX HashFunction() const;
01223 };
01224
01226
01227
01228
01229
01230
01231
01232
01233 #define PANSI_CHAR 1
01234 #define PLITTLE_ENDIAN 2
01235 #define PBIG_ENDIAN 3
01236
01237
01238 #if 0
01239 class PStandardType
01240
01241
01242
01243
01244
01245
01246 {
01247 public:
01248 PStandardType(
01249 type newVal
01250 ) { data = newVal; }
01251
01252
01253
01254
01255 operator type() { return data; }
01256
01257
01258
01259
01260
01261
01262 friend ostream & operator<<(ostream & strm, const PStandardType & val)
01263 { return strm << (type)val; }
01264
01265
01266
01267
01268
01269
01270 friend istream & operator>>(istream & strm, PStandardType & val)
01271 { type data; strm >> data; val = PStandardType(data); return strm; }
01272
01273
01274
01275
01276
01277
01278
01279 private:
01280 type data;
01281 };
01282 #endif
01283
01284
01285 #define PI_SAME(name, type) \
01286 struct name { \
01287 name() : data(0) { } \
01288 name(type value) : data(value) { } \
01289 name(const name & value) : data(value.data) { } \
01290 name & operator =(type value) { data = value; return *this; } \
01291 name & operator =(const name & value) { data = value.data; return *this; } \
01292 operator type() const { return data; } \
01293 friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \
01294 friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \
01295 private: type data; \
01296 }
01297
01298 #define PI_LOOP(src, dst) \
01299 BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \
01300 while (s != (BYTE *)&src) *d++ = *--s;
01301
01302 #define PI_DIFF(name, type) \
01303 struct name { \
01304 name() : data(0) { } \
01305 name(type value) : data(0) { operator=(value); } \
01306 name(const name & value) : data(value.data) { } \
01307 name & operator =(type value) { PI_LOOP(value, data); return *this; } \
01308 name & operator =(const name & value) { data = value.data; return *this; } \
01309 operator type() const { type value; PI_LOOP(data, value); return value; } \
01310 friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \
01311 friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \
01312 private: type data; \
01313 }
01314
01315 #ifndef PCHAR8
01316 #define PCHAR8 PANSI_CHAR
01317 #endif
01318
01319 #if PCHAR8==PANSI_CHAR
01320 PI_SAME(PChar8, char);
01321 #endif
01322
01323 PI_SAME(PInt8, char);
01324
01325 PI_SAME(PUInt8, unsigned char);
01326
01327 #if PBYTE_ORDER==PLITTLE_ENDIAN
01328 PI_SAME(PInt16l, PInt16);
01329 #elif PBYTE_ORDER==PBIG_ENDIAN
01330 PI_DIFF(PInt16l, PInt16);
01331 #endif
01332
01333 #if PBYTE_ORDER==PLITTLE_ENDIAN
01334 PI_DIFF(PInt16b, PInt16);
01335 #elif PBYTE_ORDER==PBIG_ENDIAN
01336 PI_SAME(PInt16b, PInt16);
01337 #endif
01338
01339 #if PBYTE_ORDER==PLITTLE_ENDIAN
01340 PI_SAME(PUInt16l, WORD);
01341 #elif PBYTE_ORDER==PBIG_ENDIAN
01342 PI_DIFF(PUInt16l, WORD);
01343 #endif
01344
01345 #if PBYTE_ORDER==PLITTLE_ENDIAN
01346 PI_DIFF(PUInt16b, WORD);
01347 #elif PBYTE_ORDER==PBIG_ENDIAN
01348 PI_SAME(PUInt16b, WORD);
01349 #endif
01350
01351 #if PBYTE_ORDER==PLITTLE_ENDIAN
01352 PI_SAME(PInt32l, PInt32);
01353 #elif PBYTE_ORDER==PBIG_ENDIAN
01354 PI_DIFF(PInt32l, PInt32);
01355 #endif
01356
01357 #if PBYTE_ORDER==PLITTLE_ENDIAN
01358 PI_DIFF(PInt32b, PInt32);
01359 #elif PBYTE_ORDER==PBIG_ENDIAN
01360 PI_SAME(PInt32b, PInt32);
01361 #endif
01362
01363 #if PBYTE_ORDER==PLITTLE_ENDIAN
01364 PI_SAME(PUInt32l, DWORD);
01365 #elif PBYTE_ORDER==PBIG_ENDIAN
01366 PI_DIFF(PUInt32l, DWORD);
01367 #endif
01368
01369 #if PBYTE_ORDER==PLITTLE_ENDIAN
01370 PI_DIFF(PUInt32b, DWORD);
01371 #elif PBYTE_ORDER==PBIG_ENDIAN
01372 PI_SAME(PUInt32b, DWORD);
01373 #endif
01374
01375 #if PBYTE_ORDER==PLITTLE_ENDIAN
01376 PI_SAME(PInt64l, PInt64);
01377 #elif PBYTE_ORDER==PBIG_ENDIAN
01378 PI_DIFF(PInt64l, PInt64);
01379 #endif
01380
01381 #if PBYTE_ORDER==PLITTLE_ENDIAN
01382 PI_DIFF(PInt64b, PInt64);
01383 #elif PBYTE_ORDER==PBIG_ENDIAN
01384 PI_SAME(PInt64b, PInt64);
01385 #endif
01386
01387 #if PBYTE_ORDER==PLITTLE_ENDIAN
01388 PI_SAME(PUInt64l, PUInt64);
01389 #elif PBYTE_ORDER==PBIG_ENDIAN
01390 PI_DIFF(PUInt64l, PUInt64);
01391 #endif
01392
01393 #if PBYTE_ORDER==PLITTLE_ENDIAN
01394 PI_DIFF(PUInt64b, PUInt64);
01395 #elif PBYTE_ORDER==PBIG_ENDIAN
01396 PI_SAME(PUInt64b, PUInt64);
01397 #endif
01398
01399 #if PBYTE_ORDER==PLITTLE_ENDIAN
01400 PI_SAME(PFloat32l, float);
01401 #elif PBYTE_ORDER==PBIG_ENDIAN
01402 PI_DIFF(PFloat32l, float);
01403 #endif
01404
01405 #if PBYTE_ORDER==PLITTLE_ENDIAN
01406 PI_DIFF(PFloat32b, float);
01407 #elif PBYTE_ORDER==PBIG_ENDIAN
01408 PI_SAME(PFloat32b, float);
01409 #endif
01410
01411 #if PBYTE_ORDER==PLITTLE_ENDIAN
01412 PI_SAME(PFloat64l, double);
01413 #elif PBYTE_ORDER==PBIG_ENDIAN
01414 PI_DIFF(PFloat64l, double);
01415 #endif
01416
01417 #if PBYTE_ORDER==PLITTLE_ENDIAN
01418 PI_DIFF(PFloat64b, double);
01419 #elif PBYTE_ORDER==PBIG_ENDIAN
01420 PI_SAME(PFloat64b, double);
01421 #endif
01422
01423 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
01424 #if PBYTE_ORDER==PLITTLE_ENDIAN
01425 PI_SAME(PFloat80l, long double);
01426 #elif PBYTE_ORDER==PBIG_ENDIAN
01427 PI_DIFF(PFloat80l, long double);
01428 #endif
01429
01430 #if PBYTE_ORDER==PLITTLE_ENDIAN
01431 PI_DIFF(PFloat80b, long double);
01432 #elif PBYTE_ORDER==PBIG_ENDIAN
01433 PI_SAME(PFloat80b, long double);
01434 #endif
01435 #endif
01436
01437 #undef PI_LOOP
01438 #undef PI_SAME
01439 #undef PI_DIFF
01440
01441
01443
01444
01445
01446
01447
01448
01449 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
01450
01451
01452
01453
01454
01455
01456 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
01457
01458
01459
01460
01461
01462
01463 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
01464
01465
01466
01467
01468
01469
01470 #define PABS(v) ((v) < 0 ? -(v) : (v))
01471
01472 #endif // _POBJECT_H
01473
01474