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 #ifndef _POBJECT_H
00389 #define _POBJECT_H
00390
00391 #ifdef P_USE_PRAGMA
00392 #pragma interface
00393 #endif
00394
00395 #ifdef _WIN32
00396 #include "msos/ptlib/contain.h"
00397 #else
00398 #include "unix/ptlib/contain.h"
00399 #endif
00400
00401 #if defined(P_VXWORKS)
00402 #include <private/stdiop.h>
00403 #endif
00404
00405 #include <stdio.h>
00406 #include <stdarg.h>
00407 #include <stdlib.h>
00408
00409 #ifdef _WIN32
00410 #include <malloc.h>
00411 #endif
00412
00413 #include <string.h>
00414
00415 #ifdef __USE_STL__
00416 #include <string>
00417 #include <iomanip>
00418 #include <iostream>
00419 #if (__GNUC__ >= 3)
00420 #include <sstream>
00421
00422 #else
00423 #include <strstream>
00424 #endif
00425
00426 #else
00427 #if (__GNUC__ >= 3)
00428 #include <iostream>
00429 #ifndef __MWERKS__
00430 #include <iomanip>
00431 #endif
00432 #else
00433 #include <iostream.h>
00434 #ifdef __GNUC__
00435 #include <strstream.h>
00436 #else
00437 #include <strstrea.h>
00438 #endif
00439 #ifndef __MWERKS__
00440 #include <iomanip.h>
00441 #endif
00442 #endif
00443 #endif
00444
00445 #ifdef _WIN32_WCE
00446 #include <stdlibx.h>
00447 #endif
00448
00449 #if (__GNUC__ < 3)
00450 typedef long _Ios_Fmtflags;
00451 #endif
00452
00453 #if _MSC_VER<1300
00454 #define _BADOFF -1
00455 #endif
00456
00458
00459
00460
00461 #ifndef P_USE_INLINES
00462 #ifdef _DEBUG
00463 #define P_USE_INLINES 0
00464 #else
00465 #define P_USE_INLINES 0
00466 #endif
00467 #endif
00468
00469 #if P_USE_INLINES
00470 #define PINLINE inline
00471 #else
00472 #define PINLINE
00473 #endif
00474
00475
00477
00478
00479 #ifndef P_USE_ASSERTS
00480 #define P_USE_ASSERTS 1
00481 #endif
00482
00483 #if !P_USE_ASSERTS
00484
00485 #define PAssert(b, m) (b)
00486 #define PAssert2(b, c, m) (b)
00487 #define PAssertOS(b) (b)
00488 #define PAssertNULL(p) (p)
00489 #define PAssertAlways(m)
00490 #define PAssertAlways2(c, m)
00491
00492 #else // P_USE_ASSERTS
00493
00495 enum PStandardAssertMessage {
00496 PLogicError,
00497 POutOfMemory,
00498 PNullPointerReference,
00499 PInvalidCast,
00500 PInvalidArrayIndex,
00501 PInvalidArrayElement,
00502 PStackEmpty,
00503 PUnimplementedFunction,
00504 PInvalidParameter,
00505 POperatingSystemError,
00506 PChannelNotOpen,
00507 PUnsupportedFeature,
00508 PInvalidWindow,
00509 PMaxStandardAssertMessage
00510 };
00511
00512 #define __CLASS__ NULL
00513
00514 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg);
00515 void PAssertFunc(const char * file, int line, const char * className, const char * msg);
00516 void PAssertFunc(const char * full_msg);
00517
00518 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, PStandardAssertMessage msg)
00519 {
00520 if (!b)
00521 PAssertFunc(file, line, className, msg);
00522 return b;
00523 }
00524 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, const char * msg)
00525 {
00526 if (!b)
00527 PAssertFunc(file, line, className, msg);
00528 return b;
00529 }
00530
00537 #define PAssert(b, m) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(m))
00538
00546 #define PAssert2(b, c, m) PAssertFuncInline((b), __FILE__,__LINE__,(c),(m))
00547
00554 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
00555
00565 #define PAssertNULL(p) ((&(p)&&(p)!=NULL)?(p): \
00566 (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(p)))
00567
00574 #define PAssertAlways(m) PAssertFunc(__FILE__,__LINE__,__CLASS__,(m))
00575
00582 #define PAssertAlways2(c, m) PAssertFunc(__FILE__,__LINE__,(c),(m))
00583
00584 #endif // P_USE_ASSERTS
00585
00586
00591 ostream & PGetErrorStream();
00592
00596 void PSetErrorStream(ostream * strm );
00597
00612 #define PError (PGetErrorStream())
00613
00614
00615
00617
00618
00619 #ifndef PTRACING
00620 #ifndef _DEBUG
00621 #define PTRACING 0
00622 #else
00623 #define PTRACING 1
00624 #endif
00625 #endif
00626
00631 class PTrace
00632 {
00633 public:
00635 enum Options {
00641 Blocks = 1,
00643 DateAndTime = 2,
00645 Timestamp = 4,
00647 Thread = 8,
00649 TraceLevel = 16,
00651 FileAndLine = 32,
00653 ThreadAddress = 64,
00655 AppendToFile = 128,
00659 GMTTime = 256,
00662 SystemLogStream = 32768
00663 };
00664
00672 static void Initialise(
00673 unsigned level,
00674 const char * filename = NULL,
00675 unsigned options = Timestamp | Thread | Blocks
00676 );
00677
00684 static void SetOptions(unsigned options );
00685
00693 static void ClearOptions(unsigned options );
00694
00699 static unsigned GetOptions();
00700
00706 static void SetLevel(unsigned level );
00707
00713 static unsigned GetLevel();
00714
00719 static BOOL CanTrace(unsigned level );
00720
00725 static void SetStream(ostream * out );
00726
00742 static ostream & Begin(
00743 unsigned level,
00744 const char * fileName,
00745 int lineNum
00746 );
00747
00764 static ostream & End(ostream & strm );
00765
00766
00772 class Block {
00773 public:
00775 Block(
00776 const char * fileName,
00777 int lineNum,
00778 const char * traceName
00780 );
00782 ~Block();
00783 private:
00784 const char * file;
00785 int line;
00786 const char * name;
00787 };
00788 };
00789
00790 #if !PTRACING
00791
00792 #define PTRACE_PARAM(param)
00793 #define PTRACE_BLOCK(n)
00794 #define PTRACE_LINE()
00795 #define PTRACE(level, arg)
00796 #define PTRACE_IF(level, cond, args)
00797
00798 #else
00799
00800
00801
00802 #define PTRACE_PARAM(param) param
00803
00810 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
00811
00815 #define PTRACE_LINE() \
00816 if (!PTrace::CanTrace(1)) ; else \
00817 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End
00818
00824 #define PTRACE(level, args) \
00825 if (!PTrace::CanTrace(level)) ; else \
00826 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00827
00835 #define PTRACE_IF(level, cond, args) \
00836 if (!(PTrace::CanTrace(level) && (cond))) ; else \
00837 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00838
00839 #endif
00840
00841 #if PMEMORY_CHECK
00842
00849 class PMemoryHeap {
00850 protected:
00852 PMemoryHeap();
00853
00854 public:
00855
00856 ~PMemoryHeap();
00857
00864 static void * Allocate(
00865 size_t nSize,
00866 const char * file,
00867 int line,
00868 const char * className
00869 );
00876 static void * Allocate(
00877 size_t count,
00878 size_t iSize,
00879 const char * file,
00880 int line
00881 );
00882
00890 static void * Reallocate(
00891 void * ptr,
00892 size_t nSize,
00893 const char * file,
00894 int line
00895 );
00896
00902 static void Deallocate(
00903 void * ptr,
00904 const char * className
00905 );
00906
00909 enum Validation {
00910 Ok, Bad, Trashed
00911 };
00919 static Validation Validate(
00920 void * ptr,
00921 const char * className,
00922 ostream * error
00923 );
00924
00929 static BOOL ValidateHeap(
00930 ostream * error = NULL
00931 );
00932
00938 static BOOL SetIgnoreAllocations(
00939 BOOL ignore
00940 );
00941
00945 static void DumpStatistics();
00949 static void DumpStatistics(ostream & strm );
00950
00951
00952
00953
00954
00955
00956 static DWORD GetAllocationRequest();
00957
00965 static void DumpObjectsSince(
00966 DWORD objectNumber
00967 );
00968
00974 static void DumpObjectsSince(
00975 DWORD objectNumber,
00976 ostream & strm
00977 );
00978
00984 static void SetAllocationBreakpoint(
00985 DWORD point
00986 );
00987
00988 protected:
00989 void * InternalAllocate(
00990 size_t nSize,
00991 const char * file,
00992 int line,
00993 const char * className
00994 );
00995 Validation InternalValidate(
00996 void * ptr,
00997 const char * className,
00998 ostream * error
00999 );
01000 void InternalDumpStatistics(ostream & strm);
01001 void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
01002
01003 class Wrapper {
01004 public:
01005 Wrapper();
01006 ~Wrapper();
01007 PMemoryHeap * operator->() const { return instance; }
01008 private:
01009 PMemoryHeap * instance;
01010 };
01011 friend class Wrapper;
01012
01013 enum Flags {
01014 NoLeakPrint = 1
01015 };
01016
01017 #pragma pack(1)
01018 struct Header {
01019 enum {
01020
01021 NumGuardBytes = 16 - (sizeof(Header *) +
01022 sizeof(Header *) +
01023 sizeof(const char *) +
01024 sizeof(const char *) +
01025 sizeof(size_t) +
01026 sizeof(DWORD) +
01027 sizeof(WORD) +
01028 sizeof(BYTE))%8
01029 };
01030
01031 Header * prev;
01032 Header * next;
01033 const char * className;
01034 const char * fileName;
01035 size_t size;
01036 DWORD request;
01037 WORD line;
01038 BYTE flags;
01039 char guard[NumGuardBytes];
01040
01041 static char GuardBytes[NumGuardBytes];
01042 };
01043 #pragma pack()
01044
01045 BOOL isDestroyed;
01046
01047 Header * listHead;
01048 Header * listTail;
01049
01050 static DWORD allocationBreakpoint;
01051 DWORD allocationRequest;
01052 DWORD firstRealObject;
01053 BYTE flags;
01054
01055 char allocFillChar;
01056 char freeFillChar;
01057
01058 DWORD currentMemoryUsage;
01059 DWORD peakMemoryUsage;
01060 DWORD currentObjects;
01061 DWORD peakObjects;
01062 DWORD totalObjects;
01063
01064 ostream * leakDumpStream;
01065
01066 #if defined(_WIN32)
01067 CRITICAL_SECTION mutex;
01068 #elif defined(P_PTHREADS)
01069 pthread_mutex_t mutex;
01070 #elif defined(P_VXWORKS)
01071 void * mutex;
01072 #endif
01073 };
01074
01075
01080 inline void * runtime_malloc(size_t bytes ) { return malloc(bytes); }
01081
01086 inline void runtime_free(void * ptr ) { free(ptr); }
01087
01088
01095 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
01096
01103 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
01104
01111 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
01112
01113
01120 #define free(p) PMemoryHeap::Deallocate(p, NULL)
01121
01122
01129 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
01130
01131
01146 #define PNEW new (__FILE__, __LINE__)
01147
01148 #if !defined(_MSC_VER) || _MSC_VER<1200
01149 #define PSPECIAL_DELETE_FUNCTION
01150 #else
01151 #define PSPECIAL_DELETE_FUNCTION \
01152 void operator delete(void * ptr, const char *, int) \
01153 { PMemoryHeap::Deallocate(ptr, Class()); } \
01154 void operator delete[](void * ptr, const char *, int) \
01155 { PMemoryHeap::Deallocate(ptr, Class()); }
01156 #endif
01157
01158 #define PNEW_AND_DELETE_FUNCTIONS \
01159 void * operator new(size_t nSize, const char * file, int line) \
01160 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
01161 void * operator new(size_t nSize) \
01162 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
01163 void operator delete(void * ptr) \
01164 { PMemoryHeap::Deallocate(ptr, Class()); } \
01165 void * operator new[](size_t nSize, const char * file, int line) \
01166 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
01167 void * operator new[](size_t nSize) \
01168 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
01169 void operator delete[](void * ptr) \
01170 { PMemoryHeap::Deallocate(ptr, Class()); } \
01171 PSPECIAL_DELETE_FUNCTION
01172
01173
01174 inline void * operator new(size_t nSize, const char * file, int line)
01175 { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
01176
01177 inline void * operator new[](size_t nSize, const char * file, int line)
01178 { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
01179
01180 #ifndef __GNUC__
01181 void * operator new(size_t nSize);
01182 void * operator new[](size_t nSize);
01183
01184 void operator delete(void * ptr);
01185 void operator delete[](void * ptr);
01186
01187 #if defined(_MSC_VER) && _MSC_VER>=1200
01188 inline void operator delete(void * ptr, const char *, int)
01189 { PMemoryHeap::Deallocate(ptr, NULL); }
01190
01191 inline void operator delete[](void * ptr, const char *, int)
01192 { PMemoryHeap::Deallocate(ptr, NULL); }
01193 #endif
01194 #endif
01195
01196
01197 #else // PMEMORY_CHECK
01198
01199 #define PNEW new
01200
01201 #if defined(__GNUC__) || (defined(_WIN32_WCE) && defined(_X86_))
01202
01203 #define PNEW_AND_DELETE_FUNCTIONS
01204
01205 #else
01206
01207 #define PNEW_AND_DELETE_FUNCTIONS \
01208 void * operator new(size_t nSize) \
01209 { return malloc(nSize); } \
01210 void operator delete(void * ptr) \
01211 { free(ptr); } \
01212 void * operator new[](size_t nSize) \
01213 { return malloc(nSize); } \
01214 void operator delete[](void * ptr) \
01215 { free(ptr); }
01216
01217 void * operator new(size_t nSize);
01218 void * operator new[](size_t nSize);
01219
01220 void operator delete(void * ptr);
01221 void operator delete[](void * ptr);
01222
01223 #endif
01224
01225 #define runtime_malloc(s) malloc(s)
01226 #define runtime_free(p) free(p)
01227
01228 #endif // PMEMORY_CHECK
01229
01230
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 #if P_HAS_TYPEINFO
01261
01262 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
01263 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
01264
01265 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
01266
01267 #if P_USE_ASSERTS
01268 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line)
01269 { if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; }
01270 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
01271 #else
01272 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
01273 #endif
01274
01275 #include <typeinfo>
01276
01277 #ifndef PCLASSNAME
01278 #error "Must define PCLASSNAME"
01279 #endif
01280
01281 #define PBASECLASSINFO(cls, par) \
01282 public: \
01283 static inline const char * Class() \
01284 { return PCLASSNAME(cls); } \
01285 virtual BOOL InternalIsDescendant(const char * clsName) const \
01286 { return strcmp(clsName, PCLASSNAME(cls)) == 0 || par::InternalIsDescendant(clsName); } \
01287
01288 #else // P_HAS_TYPEINFO
01289
01290 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class()))
01291 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
01292
01293 #define PRemoveConst(cls, ptr) ((cls*)(ptr))
01294
01295 #if P_USE_ASSERTS
01296 template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line)
01297 { if (obj->InternalIsDescendant(BaseClass::Class()) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; }
01298 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
01299 #else
01300 #define PDownCast(cls, ptr) ((cls*)(ptr))
01301 #endif
01302
01303 #define PBASECLASSINFO(cls, par) \
01304 public: \
01305 static const char * Class() \
01306 { return #cls; } \
01307 virtual BOOL InternalIsDescendant(const char * clsName) const \
01308 { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
01309
01310 #endif // P_HAS_TYPEINFO
01311
01312
01313 #define PCLASSINFO(cls, par) \
01314 PBASECLASSINFO(cls, par) \
01315 virtual const char * GetClass(unsigned ancestor = 0) const \
01316 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
01317 virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \
01318 { return (Comparison)memcmp(this, &obj, sizeof(cls)); } \
01319
01320
01328 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
01329 #ifdef DOC_PLUS_PLUS
01330 } Match previous opening brace in doc++
01331 #endif
01332
01334
01335
01340 class PObject {
01341
01342 protected:
01346 PObject() { }
01347
01348 public:
01349
01350
01351
01352 virtual ~PObject() { }
01353
01366 static inline const char * Class() { return PCLASSNAME(PObject); }
01367
01380 virtual const char * GetClass(unsigned = 0) const { return Class(); }
01381
01382 BOOL IsClass(const char * cls) const
01383 { return strcmp(cls, GetClass()) == 0; }
01384
01394 virtual BOOL InternalIsDescendant(
01395 const char * clsName
01396 ) const
01397 { return IsClass(clsName); }
01398
01400
01406 enum Comparison {
01407 LessThan = -1,
01408 EqualTo = 0,
01409 GreaterThan = 1
01410 };
01411
01423 virtual Comparison Compare(
01424 const PObject & obj
01425 ) const;
01426
01438 virtual Comparison CompareObjectMemoryDirect(
01439 const PObject & obj
01440 ) const;
01441
01447 bool operator==(
01448 const PObject & obj
01449 ) const { return Compare(obj) == EqualTo; }
01450
01456 bool operator!=(
01457 const PObject & obj
01458 ) const { return Compare(obj) != EqualTo; }
01459
01465 bool operator<(
01466 const PObject & obj
01467 ) const { return Compare(obj) == LessThan; }
01468
01474 bool operator>(
01475 const PObject & obj
01476 ) const { return Compare(obj) == GreaterThan; }
01477
01483 bool operator<=(
01484 const PObject & obj
01485 ) const { return Compare(obj) != GreaterThan; }
01486
01492 bool operator>=(
01493 const PObject & obj
01494 ) const { return Compare(obj) != LessThan; }
01496
01505 virtual void PrintOn(
01506 ostream &strm
01507 ) const;
01508
01515 virtual void ReadFrom(
01516 istream &strm
01517 );
01518
01519
01525 inline friend ostream & operator<<(
01526 ostream &strm,
01527 const PObject & obj
01528 ) { obj.PrintOn(strm); return strm; }
01529
01535 inline friend istream & operator>>(
01536 istream &strm,
01537 PObject & obj
01538 ) { obj.ReadFrom(strm); return strm; }
01539
01540
01555 virtual PObject * Clone() const;
01556
01568 virtual PINDEX HashFunction() const;
01570 };
01571
01573
01574
01575
01576
01577
01578
01579
01580 #define PANSI_CHAR 1
01581 #define PLITTLE_ENDIAN 2
01582 #define PBIG_ENDIAN 3
01583
01584
01585 #if 0
01586 class PStandardType
01587
01588
01589
01590
01591
01592
01593 {
01594 public:
01595 PStandardType(
01596 type newVal
01597 ) { data = newVal; }
01598
01599
01600
01601
01602 operator type() { return data; }
01603
01604
01605
01606
01607
01608
01609 friend ostream & operator<<(ostream & strm, const PStandardType & val)
01610 { return strm << (type)val; }
01611
01612
01613
01614
01615
01616
01617 friend istream & operator>>(istream & strm, PStandardType & val)
01618 { type data; strm >> data; val = PStandardType(data); return strm; }
01619
01620
01621
01622
01623
01624
01625
01626 private:
01627 type data;
01628 };
01629 #endif
01630
01631
01632 #define PI_SAME(name, type) \
01633 struct name { \
01634 name() { } \
01635 name(type value) { data = value; } \
01636 name(const name & value) { data = value.data; } \
01637 name & operator =(type value) { data = value; return *this; } \
01638 name & operator =(const name & value) { data = value.data; return *this; } \
01639 operator type() const { return data; } \
01640 friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \
01641 friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \
01642 private: type data; \
01643 }
01644
01645 #define PI_LOOP(src, dst) \
01646 BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \
01647 while (s != (BYTE *)&src) *d++ = *--s;
01648
01649 #define PI_DIFF(name, type) \
01650 struct name { \
01651 name() { } \
01652 name(type value) { operator=(value); } \
01653 name(const name & value) { data = value.data; } \
01654 name & operator =(type value) { PI_LOOP(value, data); return *this; } \
01655 name & operator =(const name & value) { data = value.data; return *this; } \
01656 operator type() const { type value; PI_LOOP(data, value); return value; } \
01657 friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \
01658 friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \
01659 private: type data; \
01660 }
01661
01662 #ifndef PCHAR8
01663 #define PCHAR8 PANSI_CHAR
01664 #endif
01665
01666 #if PCHAR8==PANSI_CHAR
01667 PI_SAME(PChar8, char);
01668 #endif
01669
01670 PI_SAME(PInt8, signed char);
01671
01672 PI_SAME(PUInt8, unsigned char);
01673
01674 #if PBYTE_ORDER==PLITTLE_ENDIAN
01675 PI_SAME(PInt16l, PInt16);
01676 #elif PBYTE_ORDER==PBIG_ENDIAN
01677 PI_DIFF(PInt16l, PInt16);
01678 #endif
01679
01680 #if PBYTE_ORDER==PLITTLE_ENDIAN
01681 PI_DIFF(PInt16b, PInt16);
01682 #elif PBYTE_ORDER==PBIG_ENDIAN
01683 PI_SAME(PInt16b, PInt16);
01684 #endif
01685
01686 #if PBYTE_ORDER==PLITTLE_ENDIAN
01687 PI_SAME(PUInt16l, WORD);
01688 #elif PBYTE_ORDER==PBIG_ENDIAN
01689 PI_DIFF(PUInt16l, WORD);
01690 #endif
01691
01692 #if PBYTE_ORDER==PLITTLE_ENDIAN
01693 PI_DIFF(PUInt16b, WORD);
01694 #elif PBYTE_ORDER==PBIG_ENDIAN
01695 PI_SAME(PUInt16b, WORD);
01696 #endif
01697
01698 #if PBYTE_ORDER==PLITTLE_ENDIAN
01699 PI_SAME(PInt32l, PInt32);
01700 #elif PBYTE_ORDER==PBIG_ENDIAN
01701 PI_DIFF(PInt32l, PInt32);
01702 #endif
01703
01704 #if PBYTE_ORDER==PLITTLE_ENDIAN
01705 PI_DIFF(PInt32b, PInt32);
01706 #elif PBYTE_ORDER==PBIG_ENDIAN
01707 PI_SAME(PInt32b, PInt32);
01708 #endif
01709
01710 #if PBYTE_ORDER==PLITTLE_ENDIAN
01711 PI_SAME(PUInt32l, DWORD);
01712 #elif PBYTE_ORDER==PBIG_ENDIAN
01713 PI_DIFF(PUInt32l, DWORD);
01714 #endif
01715
01716 #if PBYTE_ORDER==PLITTLE_ENDIAN
01717 PI_DIFF(PUInt32b, DWORD);
01718 #elif PBYTE_ORDER==PBIG_ENDIAN
01719 PI_SAME(PUInt32b, DWORD);
01720 #endif
01721
01722 #if PBYTE_ORDER==PLITTLE_ENDIAN
01723 PI_SAME(PInt64l, PInt64);
01724 #elif PBYTE_ORDER==PBIG_ENDIAN
01725 PI_DIFF(PInt64l, PInt64);
01726 #endif
01727
01728 #if PBYTE_ORDER==PLITTLE_ENDIAN
01729 PI_DIFF(PInt64b, PInt64);
01730 #elif PBYTE_ORDER==PBIG_ENDIAN
01731 PI_SAME(PInt64b, PInt64);
01732 #endif
01733
01734 #if PBYTE_ORDER==PLITTLE_ENDIAN
01735 PI_SAME(PUInt64l, PUInt64);
01736 #elif PBYTE_ORDER==PBIG_ENDIAN
01737 PI_DIFF(PUInt64l, PUInt64);
01738 #endif
01739
01740 #if PBYTE_ORDER==PLITTLE_ENDIAN
01741 PI_DIFF(PUInt64b, PUInt64);
01742 #elif PBYTE_ORDER==PBIG_ENDIAN
01743 PI_SAME(PUInt64b, PUInt64);
01744 #endif
01745
01746 #if PBYTE_ORDER==PLITTLE_ENDIAN
01747 PI_SAME(PFloat32l, float);
01748 #elif PBYTE_ORDER==PBIG_ENDIAN
01749 PI_DIFF(PFloat32l, float);
01750 #endif
01751
01752 #if PBYTE_ORDER==PLITTLE_ENDIAN
01753 PI_DIFF(PFloat32b, float);
01754 #elif PBYTE_ORDER==PBIG_ENDIAN
01755 PI_SAME(PFloat32b, float);
01756 #endif
01757
01758 #if PBYTE_ORDER==PLITTLE_ENDIAN
01759 PI_SAME(PFloat64l, double);
01760 #elif PBYTE_ORDER==PBIG_ENDIAN
01761 PI_DIFF(PFloat64l, double);
01762 #endif
01763
01764 #if PBYTE_ORDER==PLITTLE_ENDIAN
01765 PI_DIFF(PFloat64b, double);
01766 #elif PBYTE_ORDER==PBIG_ENDIAN
01767 PI_SAME(PFloat64b, double);
01768 #endif
01769
01770 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
01771 #if PBYTE_ORDER==PLITTLE_ENDIAN
01772 PI_SAME(PFloat80l, long double);
01773 #elif PBYTE_ORDER==PBIG_ENDIAN
01774 PI_DIFF(PFloat80l, long double);
01775 #endif
01776
01777 #if PBYTE_ORDER==PLITTLE_ENDIAN
01778 PI_DIFF(PFloat80b, long double);
01779 #elif PBYTE_ORDER==PBIG_ENDIAN
01780 PI_SAME(PFloat80b, long double);
01781 #endif
01782 #endif
01783
01784 #undef PI_LOOP
01785 #undef PI_SAME
01786 #undef PI_DIFF
01787
01788
01790
01791
01792
01793
01794
01795
01796 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
01797
01798
01799
01800
01801
01802
01803 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
01804
01805
01806
01807
01808
01809
01810 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
01811
01812
01813
01814
01815
01816
01817 #define PABS(v) ((v) < 0 ? -(v) : (v))
01818
01819 #endif // _POBJECT_H
01820
01821