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,
00281 RotateHourly = 1024,
00282 RotateMinutely = 2048,
00283 RotateLogMask = RotateDaily + RotateHourly + RotateMinutely,
00287 SystemLogStream = 32768
00288 };
00289
00290
00298 static void Initialise(
00299 unsigned level,
00300 const char * filename = NULL,
00301 unsigned options = Timestamp | Thread | Blocks
00302 );
00303
00314 static void Initialise(
00315 unsigned level,
00316 const char * filename,
00317 const char * rolloverPattern,
00318 unsigned options = Timestamp | Thread | Blocks
00319 );
00320
00327 static void SetOptions(unsigned options );
00328
00336 static void ClearOptions(unsigned options );
00337
00342 static unsigned GetOptions();
00343
00349 static void SetLevel(unsigned level );
00350
00356 static unsigned GetLevel();
00357
00362 static PBoolean CanTrace(unsigned level );
00363
00368 static void SetStream(ostream * out );
00369
00385 static ostream & Begin(
00386 unsigned level,
00387 const char * fileName,
00388 int lineNum
00389 );
00390
00407 static ostream & End(ostream & strm );
00408
00412 static void Cleanup();
00413
00419 class Block {
00420 public:
00422 Block(
00423 const char * fileName,
00424 int lineNum,
00425 const char * traceName
00427 );
00428 Block(const Block & obj)
00429 : file(obj.file), line(obj.line), name(obj.name) { }
00431 ~Block();
00432 private:
00433 Block & operator=(const Block &)
00434 { return *this; }
00435 const char * file;
00436 int line;
00437 const char * name;
00438 };
00439 };
00440
00441
00442
00443 #define PTRACE_PARAM(param) param
00444
00451 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
00452
00456 #define PTRACE_LINE() \
00457 if (PTrace::CanTrace(1)) \
00458 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End; \
00459 else (void)0
00460
00466 #define PTRACE(level, args) \
00467 if (PTrace::CanTrace(level)) \
00468 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
00469 else (void)0
00470
00478 #define PTRACE_IF(level, cond, args) \
00479 if ((PTrace::CanTrace(level) && (cond))) \
00480 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
00481 else (void)0
00482
00483 #else // PTRACING
00484
00485 #define PTRACE_PARAM(param)
00486 #define PTRACE_BLOCK(n)
00487 #define PTRACE_LINE()
00488 #define PTRACE(level, arg)
00489 #define PTRACE_IF(level, cond, args)
00490
00491 #endif // PTRACING
00492
00493
00494
00495 #if PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG) && !defined(_WIN32_WCE))
00496
00497 #define PMEMORY_HEAP 1
00498
00505 class PMemoryHeap {
00506 public:
00508 PMemoryHeap();
00509
00510
00511 ~PMemoryHeap();
00512
00519 static void * Allocate(
00520 size_t nSize,
00521 const char * file,
00522 int line,
00523 const char * className
00524 );
00531 static void * Allocate(
00532 size_t count,
00533 size_t iSize,
00534 const char * file,
00535 int line
00536 );
00537
00545 static void * Reallocate(
00546 void * ptr,
00547 size_t nSize,
00548 const char * file,
00549 int line
00550 );
00551
00557 static void Deallocate(
00558 void * ptr,
00559 const char * className
00560 );
00561
00564 enum Validation {
00565 Ok, Bad, Trashed
00566 };
00574 static Validation Validate(
00575 const void * ptr,
00576 const char * className,
00577 ostream * error
00578 );
00579
00584 static PBoolean ValidateHeap(
00585 ostream * error = NULL
00586 );
00587
00593 static PBoolean SetIgnoreAllocations(
00594 PBoolean ignore
00595 );
00596
00600 static void DumpStatistics();
00604 static void DumpStatistics(ostream & strm );
00605
00606 #if PMEMORY_CHECK
00607 struct State {
00608 DWORD allocationNumber;
00609 };
00610 #else
00611 typedef _CrtMemState State;
00612 #endif
00613
00614
00615
00616
00617
00618 static void GetState(
00619 State & state
00620 );
00621
00629 static void DumpObjectsSince(
00630 const State & when
00631 );
00632
00638 static void DumpObjectsSince(
00639 const State & when,
00640 ostream & strm
00641 );
00642
00648 static void SetAllocationBreakpoint(
00649 DWORD point
00650 );
00651
00652 #if PMEMORY_CHECK
00653
00654 protected:
00655 void * InternalAllocate(
00656 size_t nSize,
00657 const char * file,
00658 int line,
00659 const char * className
00660 );
00661 Validation InternalValidate(
00662 const void * ptr,
00663 const char * className,
00664 ostream * error
00665 );
00666 void InternalDumpStatistics(ostream & strm);
00667 void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
00668
00669 class Wrapper {
00670 public:
00671 Wrapper();
00672 ~Wrapper();
00673 PMemoryHeap * operator->() const { return instance; }
00674 private:
00675 PMemoryHeap * instance;
00676 };
00677 friend class Wrapper;
00678
00679 enum Flags {
00680 NoLeakPrint = 1
00681 };
00682
00683 #pragma pack(1)
00684 struct Header {
00685 enum {
00686
00687 NumGuardBytes = 16 - (sizeof(Header *) +
00688 sizeof(Header *) +
00689 sizeof(const char *) +
00690 sizeof(const char *) +
00691 sizeof(size_t) +
00692 sizeof(DWORD) +
00693 sizeof(WORD) +
00694 sizeof(BYTE)
00695 #ifdef P_LINUX
00696 + sizeof(pthread_t)
00697 #endif
00698 )%8
00699 };
00700
00701 Header * prev;
00702 Header * next;
00703 const char * className;
00704 const char * fileName;
00705 size_t size;
00706 DWORD request;
00707 WORD line;
00708 BYTE flags;
00709 #ifdef P_LINUX
00710 pthread_t thread;
00711 #endif
00712 char guard[NumGuardBytes];
00713
00714 static char GuardBytes[NumGuardBytes];
00715 };
00716 #pragma pack()
00717
00718 PBoolean isDestroyed;
00719
00720 Header * listHead;
00721 Header * listTail;
00722
00723 static DWORD allocationBreakpoint;
00724 DWORD allocationRequest;
00725 DWORD firstRealObject;
00726 BYTE flags;
00727
00728 char allocFillChar;
00729 char freeFillChar;
00730
00731 DWORD currentMemoryUsage;
00732 DWORD peakMemoryUsage;
00733 DWORD currentObjects;
00734 DWORD peakObjects;
00735 DWORD totalObjects;
00736
00737 ostream * leakDumpStream;
00738
00739 #if defined(_WIN32)
00740 CRITICAL_SECTION mutex;
00741 #elif defined(P_PTHREADS)
00742 pthread_mutex_t mutex;
00743 #elif defined(P_VXWORKS)
00744 void * mutex;
00745 #endif
00746
00747 #else
00748
00749 #define P_CLIENT_BLOCK (_CLIENT_BLOCK|(0x61<<16)) // This identifies a PObject derived class
00750 _CrtMemState initialState;
00751
00752 #endif // PMEMORY_CHECK
00753 };
00754
00755
00760 inline void * runtime_malloc(size_t bytes ) { return malloc(bytes); }
00761
00766 inline void runtime_free(void * ptr ) { free(ptr); }
00767
00768
00775 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
00776
00783 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
00784
00791 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
00792
00793
00800 #define free(p) PMemoryHeap::Deallocate(p, NULL)
00801
00802
00809 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
00810
00811
00826 #define PNEW new (__FILE__, __LINE__)
00827
00828 #if !defined(_MSC_VER) || _MSC_VER<1200
00829 #define PSPECIAL_DELETE_FUNCTION
00830 #else
00831 #define PSPECIAL_DELETE_FUNCTION \
00832 void operator delete(void * ptr, const char *, int) \
00833 { PMemoryHeap::Deallocate(ptr, Class()); } \
00834 void operator delete[](void * ptr, const char *, int) \
00835 { PMemoryHeap::Deallocate(ptr, Class()); }
00836 #endif
00837
00838 #define PNEW_AND_DELETE_FUNCTIONS \
00839 void * operator new(size_t nSize, const char * file, int line) \
00840 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
00841 void * operator new(size_t nSize) \
00842 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
00843 void operator delete(void * ptr) \
00844 { PMemoryHeap::Deallocate(ptr, Class()); } \
00845 void * operator new(size_t, void * placement) \
00846 { return placement; } \
00847 void operator delete(void *, void *) \
00848 { } \
00849 void * operator new[](size_t nSize, const char * file, int line) \
00850 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
00851 void * operator new[](size_t nSize) \
00852 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
00853 void operator delete[](void * ptr) \
00854 { PMemoryHeap::Deallocate(ptr, Class()); } \
00855 PSPECIAL_DELETE_FUNCTION
00856
00857
00858 inline void * operator new(size_t nSize, const char * file, int line)
00859 { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
00860
00861 inline void * operator new[](size_t nSize, const char * file, int line)
00862 { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
00863
00864 #ifndef __GNUC__
00865 void * operator new(size_t nSize);
00866 void * operator new[](size_t nSize);
00867
00868 void operator delete(void * ptr);
00869 void operator delete[](void * ptr);
00870
00871 #if defined(_MSC_VER) && _MSC_VER>=1200
00872 inline void operator delete(void * ptr, const char *, int)
00873 { PMemoryHeap::Deallocate(ptr, NULL); }
00874
00875 inline void operator delete[](void * ptr, const char *, int)
00876 { PMemoryHeap::Deallocate(ptr, NULL); }
00877 #endif
00878 #endif
00879
00880
00881 class PMemoryHeapIgnoreAllocationsForScope {
00882 public:
00883 PMemoryHeapIgnoreAllocationsForScope() : previousIgnoreAllocations(PMemoryHeap::SetIgnoreAllocations(PTrue)) { }
00884 ~PMemoryHeapIgnoreAllocationsForScope() { PMemoryHeap::SetIgnoreAllocations(previousIgnoreAllocations); }
00885 private:
00886 PBoolean previousIgnoreAllocations;
00887 };
00888
00889 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE PMemoryHeapIgnoreAllocationsForScope instance_PMemoryHeapIgnoreAllocationsForScope
00890
00891 class PMemoryAllocationBreakpoint {
00892 public:
00893 PMemoryAllocationBreakpoint(DWORD point)
00894 {
00895 PMemoryHeap::SetAllocationBreakpoint(point);
00896 }
00897 };
00898
00899 #define PMEMORY_ALLOCATION_BREAKPOINT(point) PMemoryAllocationBreakpoint PMemoryAllocationBreakpointInstance(point)
00900
00901
00902 #else // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
00903
00904 #define PMEMORY_HEAP 0
00905
00906 #define PNEW new
00907
00908 #define PNEW_AND_DELETE_FUNCTIONS
00909
00910 #define runtime_malloc(s) malloc(s)
00911 #define runtime_free(p) free(p)
00912
00913 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE
00914 #define PMEMORY_ALLOCATION_BREAKPOINT(point)
00915
00916 #endif // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
00917
00918
00929 #define PCLASSINFO(cls, par) \
00930 public: \
00931 static inline const char * Class() \
00932 { return #cls; } \
00933 virtual PBoolean InternalIsDescendant(const char * clsName) const \
00934 { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
00935 virtual const char * GetClass(unsigned ancestor = 0) const \
00936 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
00937 virtual Comparison CompareObjectMemoryDirect(const PObject & _obj) const \
00938 { return (Comparison)memcmp(this, &_obj, sizeof(cls)); } \
00939 PNEW_AND_DELETE_FUNCTIONS
00940
00941
00942 #if P_HAS_TYPEINFO
00943
00944 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
00945 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
00946
00947 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
00948
00949 #if P_USE_ASSERTS
00950 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line)
00951 { if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; }
00952 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
00953 #else
00954 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
00955 #endif
00956
00957 #include <typeinfo>
00958
00959 #else // P_HAS_TYPEINFO
00960
00961 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class()))
00962 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
00963
00964 #define PRemoveConst(cls, ptr) ((cls*)(ptr))
00965
00966 #if P_USE_ASSERTS
00967 template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line)
00968 { if (obj->InternalIsDescendant(BaseClass::Class())) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; }
00969 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
00970 #else
00971 #define PDownCast(cls, ptr) ((cls*)(ptr))
00972 #endif
00973
00974 #endif // P_HAS_TYPEINFO
00975
00976
00985 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
00986 #ifdef DOC_PLUS_PLUS
00987 } Match previous opening brace in doc++
00988 #endif
00989
00991
00992
00997 class PObject {
00998
00999 protected:
01003 PObject() { }
01004
01005 public:
01006
01007
01008
01009 virtual ~PObject() { }
01010
01023 static inline const char * Class() { return "PObject"; }
01024
01037 virtual const char * GetClass(unsigned = 0) const { return Class(); }
01038
01039 PBoolean IsClass(const char * cls) const
01040 { return strcmp(cls, GetClass()) == 0; }
01041
01051 virtual PBoolean InternalIsDescendant(
01052 const char * clsName
01053 ) const
01054 { return IsClass(clsName); }
01055
01057
01063 enum Comparison {
01064 LessThan = -1,
01065 EqualTo = 0,
01066 GreaterThan = 1
01067 };
01068
01080 virtual Comparison Compare(
01081 const PObject & obj
01082 ) const;
01083
01095 virtual Comparison CompareObjectMemoryDirect(
01096 const PObject & obj
01097 ) const;
01098
01104 bool operator==(
01105 const PObject & obj
01106 ) const { return Compare(obj) == EqualTo; }
01107
01113 bool operator!=(
01114 const PObject & obj
01115 ) const { return Compare(obj) != EqualTo; }
01116
01122 bool operator<(
01123 const PObject & obj
01124 ) const { return Compare(obj) == LessThan; }
01125
01131 bool operator>(
01132 const PObject & obj
01133 ) const { return Compare(obj) == GreaterThan; }
01134
01140 bool operator<=(
01141 const PObject & obj
01142 ) const { return Compare(obj) != GreaterThan; }
01143
01149 bool operator>=(
01150 const PObject & obj
01151 ) const { return Compare(obj) != LessThan; }
01153
01162 virtual void PrintOn(
01163 ostream &strm
01164 ) const;
01165
01172 virtual void ReadFrom(
01173 istream &strm
01174 );
01175
01176
01182 inline friend ostream & operator<<(
01183 ostream &strm,
01184 const PObject & obj
01185 ) { obj.PrintOn(strm); return strm; }
01186
01192 inline friend istream & operator>>(
01193 istream &strm,
01194 PObject & obj
01195 ) { obj.ReadFrom(strm); return strm; }
01196
01197
01212 virtual PObject * Clone() const;
01213
01225 virtual PINDEX HashFunction() const;
01227 };
01228
01230
01231
01232
01233
01234
01235
01236
01237 #define PANSI_CHAR 1
01238 #define PLITTLE_ENDIAN 2
01239 #define PBIG_ENDIAN 3
01240
01241
01242 #if 0
01243 class PStandardType
01244
01245
01246
01247
01248
01249
01250 {
01251 public:
01252 PStandardType(
01253 type newVal
01254 ) { data = newVal; }
01255
01256
01257
01258
01259 operator type() { return data; }
01260
01261
01262
01263
01264
01265
01266 friend ostream & operator<<(ostream & strm, const PStandardType & val)
01267 { return strm << (type)val; }
01268
01269
01270
01271
01272
01273
01274 friend istream & operator>>(istream & strm, PStandardType & val)
01275 { type data; strm >> data; val = PStandardType(data); return strm; }
01276
01277
01278
01279
01280
01281
01282
01283 private:
01284 type data;
01285 };
01286 #endif
01287
01288
01289 #define PI_SAME(name, type) \
01290 struct name { \
01291 name() : data(0) { } \
01292 name(type value) : data(value) { } \
01293 name(const name & value) : data(value.data) { } \
01294 name & operator =(type value) { data = value; return *this; } \
01295 name & operator =(const name & value) { data = value.data; return *this; } \
01296 operator type() const { return data; } \
01297 friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \
01298 friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \
01299 private: type data; \
01300 }
01301
01302 #define PI_LOOP(src, dst) \
01303 BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \
01304 while (s != (BYTE *)&src) *d++ = *--s;
01305
01306 #define PI_DIFF(name, type) \
01307 struct name { \
01308 name() : data(0) { } \
01309 name(type value) : data(0) { operator=(value); } \
01310 name(const name & value) : data(value.data) { } \
01311 name & operator =(type value) { PI_LOOP(value, data); return *this; } \
01312 name & operator =(const name & value) { data = value.data; return *this; } \
01313 operator type() const { type value; PI_LOOP(data, value); return value; } \
01314 friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \
01315 friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \
01316 private: type data; \
01317 }
01318
01319 #ifndef PCHAR8
01320 #define PCHAR8 PANSI_CHAR
01321 #endif
01322
01323 #if PCHAR8==PANSI_CHAR
01324 PI_SAME(PChar8, char);
01325 #endif
01326
01327 PI_SAME(PInt8, char);
01328
01329 PI_SAME(PUInt8, unsigned char);
01330
01331 #if PBYTE_ORDER==PLITTLE_ENDIAN
01332 PI_SAME(PInt16l, PInt16);
01333 #elif PBYTE_ORDER==PBIG_ENDIAN
01334 PI_DIFF(PInt16l, PInt16);
01335 #endif
01336
01337 #if PBYTE_ORDER==PLITTLE_ENDIAN
01338 PI_DIFF(PInt16b, PInt16);
01339 #elif PBYTE_ORDER==PBIG_ENDIAN
01340 PI_SAME(PInt16b, PInt16);
01341 #endif
01342
01343 #if PBYTE_ORDER==PLITTLE_ENDIAN
01344 PI_SAME(PUInt16l, WORD);
01345 #elif PBYTE_ORDER==PBIG_ENDIAN
01346 PI_DIFF(PUInt16l, WORD);
01347 #endif
01348
01349 #if PBYTE_ORDER==PLITTLE_ENDIAN
01350 PI_DIFF(PUInt16b, WORD);
01351 #elif PBYTE_ORDER==PBIG_ENDIAN
01352 PI_SAME(PUInt16b, WORD);
01353 #endif
01354
01355 #if PBYTE_ORDER==PLITTLE_ENDIAN
01356 PI_SAME(PInt32l, PInt32);
01357 #elif PBYTE_ORDER==PBIG_ENDIAN
01358 PI_DIFF(PInt32l, PInt32);
01359 #endif
01360
01361 #if PBYTE_ORDER==PLITTLE_ENDIAN
01362 PI_DIFF(PInt32b, PInt32);
01363 #elif PBYTE_ORDER==PBIG_ENDIAN
01364 PI_SAME(PInt32b, PInt32);
01365 #endif
01366
01367 #if PBYTE_ORDER==PLITTLE_ENDIAN
01368 PI_SAME(PUInt32l, DWORD);
01369 #elif PBYTE_ORDER==PBIG_ENDIAN
01370 PI_DIFF(PUInt32l, DWORD);
01371 #endif
01372
01373 #if PBYTE_ORDER==PLITTLE_ENDIAN
01374 PI_DIFF(PUInt32b, DWORD);
01375 #elif PBYTE_ORDER==PBIG_ENDIAN
01376 PI_SAME(PUInt32b, DWORD);
01377 #endif
01378
01379 #if PBYTE_ORDER==PLITTLE_ENDIAN
01380 PI_SAME(PInt64l, PInt64);
01381 #elif PBYTE_ORDER==PBIG_ENDIAN
01382 PI_DIFF(PInt64l, PInt64);
01383 #endif
01384
01385 #if PBYTE_ORDER==PLITTLE_ENDIAN
01386 PI_DIFF(PInt64b, PInt64);
01387 #elif PBYTE_ORDER==PBIG_ENDIAN
01388 PI_SAME(PInt64b, PInt64);
01389 #endif
01390
01391 #if PBYTE_ORDER==PLITTLE_ENDIAN
01392 PI_SAME(PUInt64l, PUInt64);
01393 #elif PBYTE_ORDER==PBIG_ENDIAN
01394 PI_DIFF(PUInt64l, PUInt64);
01395 #endif
01396
01397 #if PBYTE_ORDER==PLITTLE_ENDIAN
01398 PI_DIFF(PUInt64b, PUInt64);
01399 #elif PBYTE_ORDER==PBIG_ENDIAN
01400 PI_SAME(PUInt64b, PUInt64);
01401 #endif
01402
01403 #if PBYTE_ORDER==PLITTLE_ENDIAN
01404 PI_SAME(PFloat32l, float);
01405 #elif PBYTE_ORDER==PBIG_ENDIAN
01406 PI_DIFF(PFloat32l, float);
01407 #endif
01408
01409 #if PBYTE_ORDER==PLITTLE_ENDIAN
01410 PI_DIFF(PFloat32b, float);
01411 #elif PBYTE_ORDER==PBIG_ENDIAN
01412 PI_SAME(PFloat32b, float);
01413 #endif
01414
01415 #if PBYTE_ORDER==PLITTLE_ENDIAN
01416 PI_SAME(PFloat64l, double);
01417 #elif PBYTE_ORDER==PBIG_ENDIAN
01418 PI_DIFF(PFloat64l, double);
01419 #endif
01420
01421 #if PBYTE_ORDER==PLITTLE_ENDIAN
01422 PI_DIFF(PFloat64b, double);
01423 #elif PBYTE_ORDER==PBIG_ENDIAN
01424 PI_SAME(PFloat64b, double);
01425 #endif
01426
01427 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
01428 #if PBYTE_ORDER==PLITTLE_ENDIAN
01429 PI_SAME(PFloat80l, long double);
01430 #elif PBYTE_ORDER==PBIG_ENDIAN
01431 PI_DIFF(PFloat80l, long double);
01432 #endif
01433
01434 #if PBYTE_ORDER==PLITTLE_ENDIAN
01435 PI_DIFF(PFloat80b, long double);
01436 #elif PBYTE_ORDER==PBIG_ENDIAN
01437 PI_SAME(PFloat80b, long double);
01438 #endif
01439 #endif
01440
01441 #undef PI_LOOP
01442 #undef PI_SAME
01443 #undef PI_DIFF
01444
01445
01447
01448
01449
01450
01451
01452
01453 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
01454
01455
01456
01457
01458
01459
01460 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
01461
01462
01463
01464
01465
01466
01467 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
01468
01469
01470
01471
01472
01473
01474 #define PABS(v) ((v) < 0 ? -(v) : (v))
01475
01476 #endif // _POBJECT_H
01477
01478