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
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 #ifndef _POBJECT_H
00432 #define _POBJECT_H
00433
00434 #ifdef P_USE_PRAGMA
00435 #pragma interface
00436 #endif
00437
00438 #ifdef _WIN32
00439 #include "msos/ptlib/contain.h"
00440 #else
00441 #include "unix/ptlib/contain.h"
00442 #endif
00443
00444 #if defined(P_VXWORKS)
00445 #include <private/stdiop.h>
00446 #endif
00447
00448 #include <stdio.h>
00449 #include <stdarg.h>
00450 #include <stdlib.h>
00451
00452 #ifdef _WIN32
00453 #include <malloc.h>
00454 #endif
00455
00456 #include <string.h>
00457
00458 #ifdef __USE_STL__
00459 #include <string>
00460 #include <iomanip>
00461 #include <iostream>
00462 #if (__GNUC__ >= 3)
00463 #include <sstream>
00464 typedef std::ostringstream ostrstream;
00465 #else
00466 #include <strstream>
00467 #endif
00468
00469 #ifdef _STLP_IOS_BASE_H
00470 typedef std::ios_base::fmtflags _Ios_Fmtflags;
00471 #endif
00472 #else
00473 #if (__GNUC__ >= 3)
00474 #include <iostream>
00475 #ifndef __MWERKS__
00476 #include <iomanip>
00477 #endif
00478 #else
00479 #include <iostream.h>
00480 #ifdef __GNUC__
00481 #include <strstream.h>
00482 #else
00483 #include <strstrea.h>
00484 #endif
00485 #ifndef __MWERKS__
00486 #include <iomanip.h>
00487 #endif
00488 #endif
00489 #endif
00490
00491 #ifdef _WIN32_WCE
00492 #include <stdlibx.h>
00493 #endif
00494
00495 #if (__GNUC__ < 3) && !defined(_STLP_IOS_BASE_H)
00496 typedef long _Ios_Fmtflags;
00497 #endif
00498
00499 #if _MSC_VER<1300
00500 #define _BADOFF -1
00501 #endif
00502
00504
00505
00506
00507 #ifndef P_USE_INLINES
00508 #ifdef _DEBUG
00509 #define P_USE_INLINES 0
00510 #else
00511 #define P_USE_INLINES 0
00512 #endif
00513 #endif
00514
00515 #if P_USE_INLINES
00516 #define PINLINE inline
00517 #else
00518 #define PINLINE
00519 #endif
00520
00521
00523
00524
00525 #ifndef P_USE_ASSERTS
00526 #define P_USE_ASSERTS 1
00527 #endif
00528
00529 #if !P_USE_ASSERTS
00530
00531 #define PAssert(b, m) (b)
00532 #define PAssert2(b, c, m) (b)
00533 #define PAssertOS(b) (b)
00534 #define PAssertNULL(p) (p)
00535 #define PAssertAlways(m)
00536 #define PAssertAlways2(c, m)
00537
00538 #else // P_USE_ASSERTS
00539
00541 enum PStandardAssertMessage {
00542 PLogicError,
00543 POutOfMemory,
00544 PNullPointerReference,
00545 PInvalidCast,
00546 PInvalidArrayIndex,
00547 PInvalidArrayElement,
00548 PStackEmpty,
00549 PUnimplementedFunction,
00550 PInvalidParameter,
00551 POperatingSystemError,
00552 PChannelNotOpen,
00553 PUnsupportedFeature,
00554 PInvalidWindow,
00555 PMaxStandardAssertMessage
00556 };
00557
00558 #define __CLASS__ NULL
00559
00560 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg);
00561 void PAssertFunc(const char * file, int line, const char * className, const char * msg);
00562 void PAssertFunc(const char * full_msg);
00563
00564 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, PStandardAssertMessage msg)
00565 {
00566 if (!b)
00567 PAssertFunc(file, line, className, msg);
00568 return b;
00569 }
00570 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, const char * msg)
00571 {
00572 if (!b)
00573 PAssertFunc(file, line, className, msg);
00574 return b;
00575 }
00576
00583 #define PAssert(b, m) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(m))
00584
00592 #define PAssert2(b, c, m) PAssertFuncInline((b), __FILE__,__LINE__,(c),(m))
00593
00600 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
00601
00611 #define PAssertNULL(p) ((&(p)&&(p)!=NULL)?(p): \
00612 (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(p)))
00613
00620 #define PAssertAlways(m) PAssertFunc(__FILE__,__LINE__,__CLASS__,(m))
00621
00628 #define PAssertAlways2(c, m) PAssertFunc(__FILE__,__LINE__,(c),(m))
00629
00630 #endif // P_USE_ASSERTS
00631
00632
00637 ostream & PGetErrorStream();
00638
00642 void PSetErrorStream(ostream * strm );
00643
00658 #define PError (PGetErrorStream())
00659
00660
00661
00663
00664
00665 #ifndef PTRACING
00666 #ifndef _DEBUG
00667 #define PTRACING 0
00668 #else
00669 #define PTRACING 1
00670 #endif
00671 #endif
00672
00677 class PTrace
00678 {
00679 public:
00681 enum Options {
00687 Blocks = 1,
00689 DateAndTime = 2,
00691 Timestamp = 4,
00693 Thread = 8,
00695 TraceLevel = 16,
00697 FileAndLine = 32,
00699 ThreadAddress = 64,
00701 AppendToFile = 128,
00704 GMTTime = 256,
00707 RotateDaily = 512,
00711 SystemLogStream = 32768
00712 };
00713
00721 static void Initialise(
00722 unsigned level,
00723 const char * filename = NULL,
00724 unsigned options = Timestamp | Thread | Blocks
00725 );
00726
00737 static void Initialise(
00738 unsigned level,
00739 const char * filename,
00740 const char * rolloverPattern,
00741 unsigned options = Timestamp | Thread | Blocks
00742 );
00743
00750 static void SetOptions(unsigned options );
00751
00759 static void ClearOptions(unsigned options );
00760
00765 static unsigned GetOptions();
00766
00772 static void SetLevel(unsigned level );
00773
00779 static unsigned GetLevel();
00780
00785 static BOOL CanTrace(unsigned level );
00786
00791 static void SetStream(ostream * out );
00792
00808 static ostream & Begin(
00809 unsigned level,
00810 const char * fileName,
00811 int lineNum
00812 );
00813
00830 static ostream & End(ostream & strm );
00831
00832
00838 class Block {
00839 public:
00841 Block(
00842 const char * fileName,
00843 int lineNum,
00844 const char * traceName
00846 );
00847 Block(const Block & obj)
00848 : file(obj.file), line(obj.line), name(obj.name) { }
00850 ~Block();
00851 private:
00852 Block & operator=(const Block &)
00853 { return *this; }
00854 const char * file;
00855 int line;
00856 const char * name;
00857 };
00858 };
00859
00860 #if !PTRACING
00861
00862 #define PTRACE_PARAM(param)
00863 #define PTRACE_BLOCK(n)
00864 #define PTRACE_LINE()
00865 #define PTRACE(level, arg)
00866 #define PTRACE_IF(level, cond, args)
00867
00868 #else
00869
00870
00871
00872 #define PTRACE_PARAM(param) param
00873
00880 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
00881
00885 #define PTRACE_LINE() \
00886 if (!PTrace::CanTrace(1)) ; else \
00887 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End
00888
00894 #define PTRACE(level, args) \
00895 if (!PTrace::CanTrace(level)) ; else \
00896 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00897
00905 #define PTRACE_IF(level, cond, args) \
00906 if (!(PTrace::CanTrace(level) && (cond))) ; else \
00907 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00908
00909 #endif
00910
00911 #if PMEMORY_CHECK
00912
00919 class PMemoryHeap {
00920 protected:
00922 PMemoryHeap();
00923
00924 public:
00925
00926 ~PMemoryHeap();
00927
00934 static void * Allocate(
00935 size_t nSize,
00936 const char * file,
00937 int line,
00938 const char * className
00939 );
00946 static void * Allocate(
00947 size_t count,
00948 size_t iSize,
00949 const char * file,
00950 int line
00951 );
00952
00960 static void * Reallocate(
00961 void * ptr,
00962 size_t nSize,
00963 const char * file,
00964 int line
00965 );
00966
00972 static void Deallocate(
00973 void * ptr,
00974 const char * className
00975 );
00976
00979 enum Validation {
00980 Ok, Bad, Trashed
00981 };
00989 static Validation Validate(
00990 void * ptr,
00991 const char * className,
00992 ostream * error
00993 );
00994
00999 static BOOL ValidateHeap(
01000 ostream * error = NULL
01001 );
01002
01008 static BOOL SetIgnoreAllocations(
01009 BOOL ignore
01010 );
01011
01015 static void DumpStatistics();
01019 static void DumpStatistics(ostream & strm );
01020
01021
01022
01023
01024
01025
01026 static DWORD GetAllocationRequest();
01027
01035 static void DumpObjectsSince(
01036 DWORD objectNumber
01037 );
01038
01044 static void DumpObjectsSince(
01045 DWORD objectNumber,
01046 ostream & strm
01047 );
01048
01054 static void SetAllocationBreakpoint(
01055 DWORD point
01056 );
01057
01058 protected:
01059 void * InternalAllocate(
01060 size_t nSize,
01061 const char * file,
01062 int line,
01063 const char * className
01064 );
01065 Validation InternalValidate(
01066 void * ptr,
01067 const char * className,
01068 ostream * error
01069 );
01070 void InternalDumpStatistics(ostream & strm);
01071 void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
01072
01073 class Wrapper {
01074 public:
01075 Wrapper();
01076 ~Wrapper();
01077 PMemoryHeap * operator->() const { return instance; }
01078 private:
01079 PMemoryHeap * instance;
01080 };
01081 friend class Wrapper;
01082
01083 enum Flags {
01084 NoLeakPrint = 1
01085 };
01086
01087 #pragma pack(1)
01088 struct Header {
01089 enum {
01090
01091 NumGuardBytes = 16 - (sizeof(Header *) +
01092 sizeof(Header *) +
01093 sizeof(const char *) +
01094 sizeof(const char *) +
01095 sizeof(size_t) +
01096 sizeof(DWORD) +
01097 sizeof(WORD) +
01098 sizeof(BYTE))%8
01099 };
01100
01101 Header * prev;
01102 Header * next;
01103 const char * className;
01104 const char * fileName;
01105 size_t size;
01106 DWORD request;
01107 WORD line;
01108 BYTE flags;
01109 char guard[NumGuardBytes];
01110
01111 static char GuardBytes[NumGuardBytes];
01112 };
01113 #pragma pack()
01114
01115 BOOL isDestroyed;
01116
01117 Header * listHead;
01118 Header * listTail;
01119
01120 static DWORD allocationBreakpoint;
01121 DWORD allocationRequest;
01122 DWORD firstRealObject;
01123 BYTE flags;
01124
01125 char allocFillChar;
01126 char freeFillChar;
01127
01128 DWORD currentMemoryUsage;
01129 DWORD peakMemoryUsage;
01130 DWORD currentObjects;
01131 DWORD peakObjects;
01132 DWORD totalObjects;
01133
01134 ostream * leakDumpStream;
01135
01136 #if defined(_WIN32)
01137 CRITICAL_SECTION mutex;
01138 #elif defined(P_PTHREADS)
01139 pthread_mutex_t mutex;
01140 #elif defined(P_VXWORKS)
01141 void * mutex;
01142 #endif
01143 };
01144
01145
01150 inline void * runtime_malloc(size_t bytes ) { return malloc(bytes); }
01151
01156 inline void runtime_free(void * ptr ) { free(ptr); }
01157
01158
01165 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
01166
01173 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
01174
01181 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
01182
01183
01190 #define free(p) PMemoryHeap::Deallocate(p, NULL)
01191
01192
01199 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
01200
01201
01216 #define PNEW new (__FILE__, __LINE__)
01217
01218 #if !defined(_MSC_VER) || _MSC_VER<1200
01219 #define PSPECIAL_DELETE_FUNCTION
01220 #else
01221 #define PSPECIAL_DELETE_FUNCTION \
01222 void operator delete(void * ptr, const char *, int) \
01223 { PMemoryHeap::Deallocate(ptr, Class()); } \
01224 void operator delete[](void * ptr, const char *, int) \
01225 { PMemoryHeap::Deallocate(ptr, Class()); }
01226 #endif
01227
01228 #define PNEW_AND_DELETE_FUNCTIONS \
01229 void * operator new(size_t nSize, const char * file, int line) \
01230 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
01231 void * operator new(size_t nSize) \
01232 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
01233 void operator delete(void * ptr) \
01234 { PMemoryHeap::Deallocate(ptr, Class()); } \
01235 void * operator new[](size_t nSize, const char * file, int line) \
01236 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
01237 void * operator new[](size_t nSize) \
01238 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
01239 void operator delete[](void * ptr) \
01240 { PMemoryHeap::Deallocate(ptr, Class()); } \
01241 PSPECIAL_DELETE_FUNCTION
01242
01243
01244 inline void * operator new(size_t nSize, const char * file, int line)
01245 { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
01246
01247 inline void * operator new[](size_t nSize, const char * file, int line)
01248 { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
01249
01250 #ifndef __GNUC__
01251 void * operator new(size_t nSize);
01252 void * operator new[](size_t nSize);
01253
01254 void operator delete(void * ptr);
01255 void operator delete[](void * ptr);
01256
01257 #if defined(_MSC_VER) && _MSC_VER>=1200
01258 inline void operator delete(void * ptr, const char *, int)
01259 { PMemoryHeap::Deallocate(ptr, NULL); }
01260
01261 inline void operator delete[](void * ptr, const char *, int)
01262 { PMemoryHeap::Deallocate(ptr, NULL); }
01263 #endif
01264 #endif
01265
01266
01267 #else // PMEMORY_CHECK
01268
01269 #define PNEW new
01270
01271 #if defined(__GNUC__) || (defined(_WIN32_WCE) && defined(_X86_))
01272
01273 #define PNEW_AND_DELETE_FUNCTIONS
01274
01275 #else
01276
01277 #define PNEW_AND_DELETE_FUNCTIONS \
01278 void * operator new(size_t nSize) \
01279 { return malloc(nSize); } \
01280 void operator delete(void * ptr) \
01281 { free(ptr); } \
01282 void * operator new[](size_t nSize) \
01283 { return malloc(nSize); } \
01284 void operator delete[](void * ptr) \
01285 { free(ptr); }
01286
01287 void * operator new(size_t nSize);
01288 void * operator new[](size_t nSize);
01289
01290 void operator delete(void * ptr);
01291 void operator delete[](void * ptr);
01292
01293 #endif
01294
01295 #define runtime_malloc(s) malloc(s)
01296 #define runtime_free(p) free(p)
01297
01298 #endif // PMEMORY_CHECK
01299
01300
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330 #if P_HAS_TYPEINFO
01331
01332 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
01333 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
01334
01335 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
01336
01337 #if P_USE_ASSERTS
01338 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line)
01339 { if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; }
01340 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
01341 #else
01342 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
01343 #endif
01344
01345 #include <typeinfo>
01346
01347 #define PCLASSNAME(cls) (#cls)
01348
01349 #define PBASECLASSINFO(cls, par) \
01350 public: \
01351 static inline const char * Class() \
01352 { return PCLASSNAME(cls); } \
01353 virtual BOOL InternalIsDescendant(const char * clsName) const \
01354 { return strcmp(clsName, PCLASSNAME(cls)) == 0 || par::InternalIsDescendant(clsName); } \
01355
01356 #else // P_HAS_TYPEINFO
01357
01358 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class()))
01359 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
01360
01361 #define PRemoveConst(cls, ptr) ((cls*)(ptr))
01362
01363 #if P_USE_ASSERTS
01364 template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line)
01365 { if (obj->InternalIsDescendant(BaseClass::Class()) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; }
01366 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
01367 #else
01368 #define PDownCast(cls, ptr) ((cls*)(ptr))
01369 #endif
01370
01371 #define PBASECLASSINFO(cls, par) \
01372 public: \
01373 static const char * Class() \
01374 { return #cls; } \
01375 virtual BOOL InternalIsDescendant(const char * clsName) const \
01376 { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
01377
01378 #endif // P_HAS_TYPEINFO
01379
01380
01381 #define PCLASSINFO(cls, par) \
01382 PBASECLASSINFO(cls, par) \
01383 virtual const char * GetClass(unsigned ancestor = 0) const \
01384 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
01385 virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \
01386 { return (Comparison)memcmp(this, &obj, sizeof(cls)); } \
01387
01388
01396 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
01397 #ifdef DOC_PLUS_PLUS
01398 } Match previous opening brace in doc++
01399 #endif
01400
01402
01403
01408 class PObject {
01409
01410 protected:
01414 PObject() { }
01415
01416 public:
01417
01418
01419
01420 virtual ~PObject() { }
01421
01434 static inline const char * Class() { return PCLASSNAME(PObject); }
01435
01448 virtual const char * GetClass(unsigned = 0) const { return Class(); }
01449
01450 BOOL IsClass(const char * cls) const
01451 { return strcmp(cls, GetClass()) == 0; }
01452
01462 virtual BOOL InternalIsDescendant(
01463 const char * clsName
01464 ) const
01465 { return IsClass(clsName); }
01466
01468
01474 enum Comparison {
01475 LessThan = -1,
01476 EqualTo = 0,
01477 GreaterThan = 1
01478 };
01479
01491 virtual Comparison Compare(
01492 const PObject & obj
01493 ) const;
01494
01506 virtual Comparison CompareObjectMemoryDirect(
01507 const PObject & obj
01508 ) const;
01509
01515 bool operator==(
01516 const PObject & obj
01517 ) const { return Compare(obj) == EqualTo; }
01518
01524 bool operator!=(
01525 const PObject & obj
01526 ) const { return Compare(obj) != EqualTo; }
01527
01533 bool operator<(
01534 const PObject & obj
01535 ) const { return Compare(obj) == LessThan; }
01536
01542 bool operator>(
01543 const PObject & obj
01544 ) const { return Compare(obj) == GreaterThan; }
01545
01551 bool operator<=(
01552 const PObject & obj
01553 ) const { return Compare(obj) != GreaterThan; }
01554
01560 bool operator>=(
01561 const PObject & obj
01562 ) const { return Compare(obj) != LessThan; }
01564
01573 virtual void PrintOn(
01574 ostream &strm
01575 ) const;
01576
01583 virtual void ReadFrom(
01584 istream &strm
01585 );
01586
01587
01593 inline friend ostream & operator<<(
01594 ostream &strm,
01595 const PObject & obj
01596 ) { obj.PrintOn(strm); return strm; }
01597
01603 inline friend istream & operator>>(
01604 istream &strm,
01605 PObject & obj
01606 ) { obj.ReadFrom(strm); return strm; }
01607
01608
01623 virtual PObject * Clone() const;
01624
01636 virtual PINDEX HashFunction() const;
01638 };
01639
01641
01642
01643
01644
01645
01646
01647
01648 #define PANSI_CHAR 1
01649 #define PLITTLE_ENDIAN 2
01650 #define PBIG_ENDIAN 3
01651
01652
01653 #if 0
01654 class PStandardType
01655
01656
01657
01658
01659
01660
01661 {
01662 public:
01663 PStandardType(
01664 type newVal
01665 ) { data = newVal; }
01666
01667
01668
01669
01670 operator type() { return data; }
01671
01672
01673
01674
01675
01676
01677 friend ostream & operator<<(ostream & strm, const PStandardType & val)
01678 { return strm << (type)val; }
01679
01680
01681
01682
01683
01684
01685 friend istream & operator>>(istream & strm, PStandardType & val)
01686 { type data; strm >> data; val = PStandardType(data); return strm; }
01687
01688
01689
01690
01691
01692
01693
01694 private:
01695 type data;
01696 };
01697 #endif
01698
01699
01700 #define PI_SAME(name, type) \
01701 struct name { \
01702 name() : data(0) { } \
01703 name(type value) : data(value) { } \
01704 name(const name & value) : data(value.data) { } \
01705 name & operator =(type value) { data = value; return *this; } \
01706 name & operator =(const name & value) { data = value.data; return *this; } \
01707 operator type() const { return data; } \
01708 friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \
01709 friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \
01710 private: type data; \
01711 }
01712
01713 #define PI_LOOP(src, dst) \
01714 BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \
01715 while (s != (BYTE *)&src) *d++ = *--s;
01716
01717 #define PI_DIFF(name, type) \
01718 struct name { \
01719 name() : data(0) { } \
01720 name(type value) : data(0) { operator=(value); } \
01721 name(const name & value) : data(value.data) { } \
01722 name & operator =(type value) { PI_LOOP(value, data); return *this; } \
01723 name & operator =(const name & value) { data = value.data; return *this; } \
01724 operator type() const { type value; PI_LOOP(data, value); return value; } \
01725 friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \
01726 friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \
01727 private: type data; \
01728 }
01729
01730 #ifndef PCHAR8
01731 #define PCHAR8 PANSI_CHAR
01732 #endif
01733
01734 #if PCHAR8==PANSI_CHAR
01735 PI_SAME(PChar8, char);
01736 #endif
01737
01738 PI_SAME(PInt8, signed char);
01739
01740 PI_SAME(PUInt8, unsigned char);
01741
01742 #if PBYTE_ORDER==PLITTLE_ENDIAN
01743 PI_SAME(PInt16l, PInt16);
01744 #elif PBYTE_ORDER==PBIG_ENDIAN
01745 PI_DIFF(PInt16l, PInt16);
01746 #endif
01747
01748 #if PBYTE_ORDER==PLITTLE_ENDIAN
01749 PI_DIFF(PInt16b, PInt16);
01750 #elif PBYTE_ORDER==PBIG_ENDIAN
01751 PI_SAME(PInt16b, PInt16);
01752 #endif
01753
01754 #if PBYTE_ORDER==PLITTLE_ENDIAN
01755 PI_SAME(PUInt16l, WORD);
01756 #elif PBYTE_ORDER==PBIG_ENDIAN
01757 PI_DIFF(PUInt16l, WORD);
01758 #endif
01759
01760 #if PBYTE_ORDER==PLITTLE_ENDIAN
01761 PI_DIFF(PUInt16b, WORD);
01762 #elif PBYTE_ORDER==PBIG_ENDIAN
01763 PI_SAME(PUInt16b, WORD);
01764 #endif
01765
01766 #if PBYTE_ORDER==PLITTLE_ENDIAN
01767 PI_SAME(PInt32l, PInt32);
01768 #elif PBYTE_ORDER==PBIG_ENDIAN
01769 PI_DIFF(PInt32l, PInt32);
01770 #endif
01771
01772 #if PBYTE_ORDER==PLITTLE_ENDIAN
01773 PI_DIFF(PInt32b, PInt32);
01774 #elif PBYTE_ORDER==PBIG_ENDIAN
01775 PI_SAME(PInt32b, PInt32);
01776 #endif
01777
01778 #if PBYTE_ORDER==PLITTLE_ENDIAN
01779 PI_SAME(PUInt32l, DWORD);
01780 #elif PBYTE_ORDER==PBIG_ENDIAN
01781 PI_DIFF(PUInt32l, DWORD);
01782 #endif
01783
01784 #if PBYTE_ORDER==PLITTLE_ENDIAN
01785 PI_DIFF(PUInt32b, DWORD);
01786 #elif PBYTE_ORDER==PBIG_ENDIAN
01787 PI_SAME(PUInt32b, DWORD);
01788 #endif
01789
01790 #if PBYTE_ORDER==PLITTLE_ENDIAN
01791 PI_SAME(PInt64l, PInt64);
01792 #elif PBYTE_ORDER==PBIG_ENDIAN
01793 PI_DIFF(PInt64l, PInt64);
01794 #endif
01795
01796 #if PBYTE_ORDER==PLITTLE_ENDIAN
01797 PI_DIFF(PInt64b, PInt64);
01798 #elif PBYTE_ORDER==PBIG_ENDIAN
01799 PI_SAME(PInt64b, PInt64);
01800 #endif
01801
01802 #if PBYTE_ORDER==PLITTLE_ENDIAN
01803 PI_SAME(PUInt64l, PUInt64);
01804 #elif PBYTE_ORDER==PBIG_ENDIAN
01805 PI_DIFF(PUInt64l, PUInt64);
01806 #endif
01807
01808 #if PBYTE_ORDER==PLITTLE_ENDIAN
01809 PI_DIFF(PUInt64b, PUInt64);
01810 #elif PBYTE_ORDER==PBIG_ENDIAN
01811 PI_SAME(PUInt64b, PUInt64);
01812 #endif
01813
01814 #if PBYTE_ORDER==PLITTLE_ENDIAN
01815 PI_SAME(PFloat32l, float);
01816 #elif PBYTE_ORDER==PBIG_ENDIAN
01817 PI_DIFF(PFloat32l, float);
01818 #endif
01819
01820 #if PBYTE_ORDER==PLITTLE_ENDIAN
01821 PI_DIFF(PFloat32b, float);
01822 #elif PBYTE_ORDER==PBIG_ENDIAN
01823 PI_SAME(PFloat32b, float);
01824 #endif
01825
01826 #if PBYTE_ORDER==PLITTLE_ENDIAN
01827 PI_SAME(PFloat64l, double);
01828 #elif PBYTE_ORDER==PBIG_ENDIAN
01829 PI_DIFF(PFloat64l, double);
01830 #endif
01831
01832 #if PBYTE_ORDER==PLITTLE_ENDIAN
01833 PI_DIFF(PFloat64b, double);
01834 #elif PBYTE_ORDER==PBIG_ENDIAN
01835 PI_SAME(PFloat64b, double);
01836 #endif
01837
01838 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
01839 #if PBYTE_ORDER==PLITTLE_ENDIAN
01840 PI_SAME(PFloat80l, long double);
01841 #elif PBYTE_ORDER==PBIG_ENDIAN
01842 PI_DIFF(PFloat80l, long double);
01843 #endif
01844
01845 #if PBYTE_ORDER==PLITTLE_ENDIAN
01846 PI_DIFF(PFloat80b, long double);
01847 #elif PBYTE_ORDER==PBIG_ENDIAN
01848 PI_SAME(PFloat80b, long double);
01849 #endif
01850 #endif
01851
01852 #undef PI_LOOP
01853 #undef PI_SAME
01854 #undef PI_DIFF
01855
01856
01858
01859
01860
01861
01862
01863
01864 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
01865
01866
01867
01868
01869
01870
01871 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
01872
01873
01874
01875
01876
01877
01878 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
01879
01880
01881
01882
01883
01884
01885 #define PABS(v) ((v) < 0 ? -(v) : (v))
01886
01887 #endif // _POBJECT_H
01888
01889