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 #ifndef _POBJECT_H
00419 #define _POBJECT_H
00420
00421 #ifdef P_USE_PRAGMA
00422 #pragma interface
00423 #endif
00424
00425 #ifdef _WIN32
00426 #include "msos/ptlib/contain.h"
00427 #else
00428 #include "unix/ptlib/contain.h"
00429 #endif
00430
00431 #if defined(P_VXWORKS)
00432 #include <private/stdiop.h>
00433 #endif
00434
00435 #include <stdio.h>
00436 #include <stdarg.h>
00437 #include <stdlib.h>
00438
00439 #ifdef _WIN32
00440 #include <malloc.h>
00441 #endif
00442
00443 #include <string.h>
00444
00445 #ifdef __USE_STL__
00446 #include <string>
00447 #include <iomanip>
00448 #include <iostream>
00449 #if (__GNUC__ >= 3)
00450 #include <sstream>
00451 typedef std::ostringstream ostrstream;
00452 #else
00453 #include <strstream>
00454 #endif
00455
00456 #else
00457 #if (__GNUC__ >= 3)
00458 #include <iostream>
00459 #ifndef __MWERKS__
00460 #include <iomanip>
00461 #endif
00462 #else
00463 #include <iostream.h>
00464 #ifdef __GNUC__
00465 #include <strstream.h>
00466 #else
00467 #include <strstrea.h>
00468 #endif
00469 #ifndef __MWERKS__
00470 #include <iomanip.h>
00471 #endif
00472 #endif
00473 #endif
00474
00475 #ifdef _WIN32_WCE
00476 #include <stdlibx.h>
00477 #endif
00478
00479 #if (__GNUC__ < 3)
00480 typedef long _Ios_Fmtflags;
00481 #endif
00482
00483 #if _MSC_VER<1300
00484 #define _BADOFF -1
00485 #endif
00486
00488
00489
00490
00491 #ifndef P_USE_INLINES
00492 #ifdef _DEBUG
00493 #define P_USE_INLINES 0
00494 #else
00495 #define P_USE_INLINES 0
00496 #endif
00497 #endif
00498
00499 #if P_USE_INLINES
00500 #define PINLINE inline
00501 #else
00502 #define PINLINE
00503 #endif
00504
00505
00507
00508
00509 #ifndef P_USE_ASSERTS
00510 #define P_USE_ASSERTS 1
00511 #endif
00512
00513 #if !P_USE_ASSERTS
00514
00515 #define PAssert(b, m) (b)
00516 #define PAssert2(b, c, m) (b)
00517 #define PAssertOS(b) (b)
00518 #define PAssertNULL(p) (p)
00519 #define PAssertAlways(m)
00520 #define PAssertAlways2(c, m)
00521
00522 #else // P_USE_ASSERTS
00523
00525 enum PStandardAssertMessage {
00526 PLogicError,
00527 POutOfMemory,
00528 PNullPointerReference,
00529 PInvalidCast,
00530 PInvalidArrayIndex,
00531 PInvalidArrayElement,
00532 PStackEmpty,
00533 PUnimplementedFunction,
00534 PInvalidParameter,
00535 POperatingSystemError,
00536 PChannelNotOpen,
00537 PUnsupportedFeature,
00538 PInvalidWindow,
00539 PMaxStandardAssertMessage
00540 };
00541
00542 #define __CLASS__ NULL
00543
00544 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg);
00545 void PAssertFunc(const char * file, int line, const char * className, const char * msg);
00546 void PAssertFunc(const char * full_msg);
00547
00548 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, PStandardAssertMessage msg)
00549 {
00550 if (!b)
00551 PAssertFunc(file, line, className, msg);
00552 return b;
00553 }
00554 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, const char * msg)
00555 {
00556 if (!b)
00557 PAssertFunc(file, line, className, msg);
00558 return b;
00559 }
00560
00567 #define PAssert(b, m) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(m))
00568
00576 #define PAssert2(b, c, m) PAssertFuncInline((b), __FILE__,__LINE__,(c),(m))
00577
00584 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
00585
00595 #define PAssertNULL(p) (((p)!=NULL)?(p): \
00596 (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(p)))
00597
00604 #define PAssertAlways(m) PAssertFunc(__FILE__,__LINE__,__CLASS__,(m))
00605
00612 #define PAssertAlways2(c, m) PAssertFunc(__FILE__,__LINE__,(c),(m))
00613
00614 #endif // P_USE_ASSERTS
00615
00616
00621 ostream & PGetErrorStream();
00622
00626 void PSetErrorStream(ostream * strm );
00627
00642 #define PError (PGetErrorStream())
00643
00644
00645
00647
00648
00649 #ifndef PTRACING
00650 #ifndef _DEBUG
00651 #define PTRACING 0
00652 #else
00653 #define PTRACING 1
00654 #endif
00655 #endif
00656
00661 class PTrace
00662 {
00663 public:
00665 enum Options {
00671 Blocks = 1,
00673 DateAndTime = 2,
00675 Timestamp = 4,
00677 Thread = 8,
00679 TraceLevel = 16,
00681 FileAndLine = 32,
00683 ThreadAddress = 64,
00685 AppendToFile = 128,
00688 GMTTime = 256,
00691 RotateDaily = 512,
00695 SystemLogStream = 32768
00696 };
00697
00705 static void Initialise(
00706 unsigned level,
00707 const char * filename = NULL,
00708 unsigned options = Timestamp | Thread | Blocks
00709 );
00710
00717 static void SetOptions(unsigned options );
00718
00726 static void ClearOptions(unsigned options );
00727
00732 static unsigned GetOptions();
00733
00739 static void SetLevel(unsigned level );
00740
00746 static unsigned GetLevel();
00747
00752 static BOOL CanTrace(unsigned level );
00753
00758 static void SetStream(ostream * out );
00759
00775 static ostream & Begin(
00776 unsigned level,
00777 const char * fileName,
00778 int lineNum
00779 );
00780
00797 static ostream & End(ostream & strm );
00798
00799
00805 class Block {
00806 public:
00808 Block(
00809 const char * fileName,
00810 int lineNum,
00811 const char * traceName
00813 );
00815 ~Block();
00816 private:
00817 const char * file;
00818 int line;
00819 const char * name;
00820 };
00821 };
00822
00823 #if !PTRACING
00824
00825 #define PTRACE_PARAM(param)
00826 #define PTRACE_BLOCK(n)
00827 #define PTRACE_LINE()
00828 #define PTRACE(level, arg)
00829 #define PTRACE_IF(level, cond, args)
00830
00831 #else
00832
00833
00834
00835 #define PTRACE_PARAM(param) param
00836
00843 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
00844
00848 #define PTRACE_LINE() \
00849 if (!PTrace::CanTrace(1)) ; else \
00850 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End
00851
00857 #define PTRACE(level, args) \
00858 if (!PTrace::CanTrace(level)) ; else \
00859 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00860
00868 #define PTRACE_IF(level, cond, args) \
00869 if (!(PTrace::CanTrace(level) && (cond))) ; else \
00870 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00871
00872 #endif
00873
00874 #if PMEMORY_CHECK
00875
00882 class PMemoryHeap {
00883 protected:
00885 PMemoryHeap();
00886
00887 public:
00888
00889 ~PMemoryHeap();
00890
00897 static void * Allocate(
00898 size_t nSize,
00899 const char * file,
00900 int line,
00901 const char * className
00902 );
00909 static void * Allocate(
00910 size_t count,
00911 size_t iSize,
00912 const char * file,
00913 int line
00914 );
00915
00923 static void * Reallocate(
00924 void * ptr,
00925 size_t nSize,
00926 const char * file,
00927 int line
00928 );
00929
00935 static void Deallocate(
00936 void * ptr,
00937 const char * className
00938 );
00939
00942 enum Validation {
00943 Ok, Bad, Trashed
00944 };
00952 static Validation Validate(
00953 void * ptr,
00954 const char * className,
00955 ostream * error
00956 );
00957
00962 static BOOL ValidateHeap(
00963 ostream * error = NULL
00964 );
00965
00971 static BOOL SetIgnoreAllocations(
00972 BOOL ignore
00973 );
00974
00978 static void DumpStatistics();
00982 static void DumpStatistics(ostream & strm );
00983
00984
00985
00986
00987
00988
00989 static DWORD GetAllocationRequest();
00990
00998 static void DumpObjectsSince(
00999 DWORD objectNumber
01000 );
01001
01007 static void DumpObjectsSince(
01008 DWORD objectNumber,
01009 ostream & strm
01010 );
01011
01017 static void SetAllocationBreakpoint(
01018 DWORD point
01019 );
01020
01021 protected:
01022 void * InternalAllocate(
01023 size_t nSize,
01024 const char * file,
01025 int line,
01026 const char * className
01027 );
01028 Validation InternalValidate(
01029 void * ptr,
01030 const char * className,
01031 ostream * error
01032 );
01033 void InternalDumpStatistics(ostream & strm);
01034 void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
01035
01036 class Wrapper {
01037 public:
01038 Wrapper();
01039 ~Wrapper();
01040 PMemoryHeap * operator->() const { return instance; }
01041 private:
01042 PMemoryHeap * instance;
01043 };
01044 friend class Wrapper;
01045
01046 enum Flags {
01047 NoLeakPrint = 1
01048 };
01049
01050 #pragma pack(1)
01051 struct Header {
01052 enum {
01053
01054 NumGuardBytes = 16 - (sizeof(Header *) +
01055 sizeof(Header *) +
01056 sizeof(const char *) +
01057 sizeof(const char *) +
01058 sizeof(size_t) +
01059 sizeof(DWORD) +
01060 sizeof(WORD) +
01061 sizeof(BYTE))%8
01062 };
01063
01064 Header * prev;
01065 Header * next;
01066 const char * className;
01067 const char * fileName;
01068 size_t size;
01069 DWORD request;
01070 WORD line;
01071 BYTE flags;
01072 char guard[NumGuardBytes];
01073
01074 static char GuardBytes[NumGuardBytes];
01075 };
01076 #pragma pack()
01077
01078 BOOL isDestroyed;
01079
01080 Header * listHead;
01081 Header * listTail;
01082
01083 static DWORD allocationBreakpoint;
01084 DWORD allocationRequest;
01085 DWORD firstRealObject;
01086 BYTE flags;
01087
01088 char allocFillChar;
01089 char freeFillChar;
01090
01091 DWORD currentMemoryUsage;
01092 DWORD peakMemoryUsage;
01093 DWORD currentObjects;
01094 DWORD peakObjects;
01095 DWORD totalObjects;
01096
01097 ostream * leakDumpStream;
01098
01099 #if defined(_WIN32)
01100 CRITICAL_SECTION mutex;
01101 #elif defined(P_PTHREADS)
01102 pthread_mutex_t mutex;
01103 #elif defined(P_VXWORKS)
01104 void * mutex;
01105 #endif
01106 };
01107
01108
01113 inline void * runtime_malloc(size_t bytes ) { return malloc(bytes); }
01114
01119 inline void runtime_free(void * ptr ) { free(ptr); }
01120
01121
01128 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
01129
01136 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
01137
01144 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
01145
01146
01153 #define free(p) PMemoryHeap::Deallocate(p, NULL)
01154
01155
01162 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
01163
01164
01179 #define PNEW new (__FILE__, __LINE__)
01180
01181 #if !defined(_MSC_VER) || _MSC_VER<1200
01182 #define PSPECIAL_DELETE_FUNCTION
01183 #else
01184 #define PSPECIAL_DELETE_FUNCTION \
01185 void operator delete(void * ptr, const char *, int) \
01186 { PMemoryHeap::Deallocate(ptr, Class()); } \
01187 void operator delete[](void * ptr, const char *, int) \
01188 { PMemoryHeap::Deallocate(ptr, Class()); }
01189 #endif
01190
01191 #define PNEW_AND_DELETE_FUNCTIONS \
01192 void * operator new(size_t nSize, const char * file, int line) \
01193 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
01194 void * operator new(size_t nSize) \
01195 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
01196 void operator delete(void * ptr) \
01197 { PMemoryHeap::Deallocate(ptr, Class()); } \
01198 void * operator new[](size_t nSize, const char * file, int line) \
01199 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
01200 void * operator new[](size_t nSize) \
01201 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
01202 void operator delete[](void * ptr) \
01203 { PMemoryHeap::Deallocate(ptr, Class()); } \
01204 PSPECIAL_DELETE_FUNCTION
01205
01206
01207 inline void * operator new(size_t nSize, const char * file, int line)
01208 { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
01209
01210 inline void * operator new[](size_t nSize, const char * file, int line)
01211 { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
01212
01213 #ifndef __GNUC__
01214 void * operator new(size_t nSize);
01215 void * operator new[](size_t nSize);
01216
01217 void operator delete(void * ptr);
01218 void operator delete[](void * ptr);
01219
01220 #if defined(_MSC_VER) && _MSC_VER>=1200
01221 inline void operator delete(void * ptr, const char *, int)
01222 { PMemoryHeap::Deallocate(ptr, NULL); }
01223
01224 inline void operator delete[](void * ptr, const char *, int)
01225 { PMemoryHeap::Deallocate(ptr, NULL); }
01226 #endif
01227 #endif
01228
01229
01230 #else // PMEMORY_CHECK
01231
01232 #define PNEW new
01233
01234 #if defined(__GNUC__) || (defined(_WIN32_WCE) && defined(_X86_))
01235
01236 #define PNEW_AND_DELETE_FUNCTIONS
01237
01238 #else
01239
01240 #define PNEW_AND_DELETE_FUNCTIONS \
01241 void * operator new(size_t nSize) \
01242 { return malloc(nSize); } \
01243 void operator delete(void * ptr) \
01244 { free(ptr); } \
01245 void * operator new[](size_t nSize) \
01246 { return malloc(nSize); } \
01247 void operator delete[](void * ptr) \
01248 { free(ptr); }
01249
01250 void * operator new(size_t nSize);
01251 void * operator new[](size_t nSize);
01252
01253 void operator delete(void * ptr);
01254 void operator delete[](void * ptr);
01255
01256 #endif
01257
01258 #define runtime_malloc(s) malloc(s)
01259 #define runtime_free(p) free(p)
01260
01261 #endif // PMEMORY_CHECK
01262
01263
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293 #if P_HAS_TYPEINFO
01294
01295 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
01296 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
01297
01298 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
01299
01300 #if P_USE_ASSERTS
01301 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line)
01302 { if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; }
01303 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
01304 #else
01305 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
01306 #endif
01307
01308 #include <typeinfo>
01309
01310 #define PCLASSNAME(cls) (#cls)
01311
01312 #define PBASECLASSINFO(cls, par) \
01313 public: \
01314 static inline const char * Class() \
01315 { return PCLASSNAME(cls); } \
01316 virtual BOOL InternalIsDescendant(const char * clsName) const \
01317 { return strcmp(clsName, PCLASSNAME(cls)) == 0 || par::InternalIsDescendant(clsName); } \
01318
01319 #else // P_HAS_TYPEINFO
01320
01321 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class()))
01322 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
01323
01324 #define PRemoveConst(cls, ptr) ((cls*)(ptr))
01325
01326 #if P_USE_ASSERTS
01327 template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line)
01328 { if (obj->InternalIsDescendant(BaseClass::Class()) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; }
01329 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
01330 #else
01331 #define PDownCast(cls, ptr) ((cls*)(ptr))
01332 #endif
01333
01334 #define PBASECLASSINFO(cls, par) \
01335 public: \
01336 static const char * Class() \
01337 { return #cls; } \
01338 virtual BOOL InternalIsDescendant(const char * clsName) const \
01339 { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
01340
01341 #endif // P_HAS_TYPEINFO
01342
01343
01344 #define PCLASSINFO(cls, par) \
01345 PBASECLASSINFO(cls, par) \
01346 virtual const char * GetClass(unsigned ancestor = 0) const \
01347 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
01348 virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \
01349 { return (Comparison)memcmp(this, &obj, sizeof(cls)); } \
01350
01351
01359 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
01360 #ifdef DOC_PLUS_PLUS
01361 } Match previous opening brace in doc++
01362 #endif
01363
01365
01366
01371 class PObject {
01372
01373 protected:
01377 PObject() { }
01378
01379 public:
01380
01381
01382
01383 virtual ~PObject() { }
01384
01397 static inline const char * Class() { return PCLASSNAME(PObject); }
01398
01411 virtual const char * GetClass(unsigned = 0) const { return Class(); }
01412
01413 BOOL IsClass(const char * cls) const
01414 { return strcmp(cls, GetClass()) == 0; }
01415
01425 virtual BOOL InternalIsDescendant(
01426 const char * clsName
01427 ) const
01428 { return IsClass(clsName); }
01429
01431
01437 enum Comparison {
01438 LessThan = -1,
01439 EqualTo = 0,
01440 GreaterThan = 1
01441 };
01442
01454 virtual Comparison Compare(
01455 const PObject & obj
01456 ) const;
01457
01469 virtual Comparison CompareObjectMemoryDirect(
01470 const PObject & obj
01471 ) const;
01472
01478 bool operator==(
01479 const PObject & obj
01480 ) const { return Compare(obj) == EqualTo; }
01481
01487 bool operator!=(
01488 const PObject & obj
01489 ) const { return Compare(obj) != EqualTo; }
01490
01496 bool operator<(
01497 const PObject & obj
01498 ) const { return Compare(obj) == LessThan; }
01499
01505 bool operator>(
01506 const PObject & obj
01507 ) const { return Compare(obj) == GreaterThan; }
01508
01514 bool operator<=(
01515 const PObject & obj
01516 ) const { return Compare(obj) != GreaterThan; }
01517
01523 bool operator>=(
01524 const PObject & obj
01525 ) const { return Compare(obj) != LessThan; }
01527
01536 virtual void PrintOn(
01537 ostream &strm
01538 ) const;
01539
01546 virtual void ReadFrom(
01547 istream &strm
01548 );
01549
01550
01556 inline friend ostream & operator<<(
01557 ostream &strm,
01558 const PObject & obj
01559 ) { obj.PrintOn(strm); return strm; }
01560
01566 inline friend istream & operator>>(
01567 istream &strm,
01568 PObject & obj
01569 ) { obj.ReadFrom(strm); return strm; }
01570
01571
01586 virtual PObject * Clone() const;
01587
01599 virtual PINDEX HashFunction() const;
01601 };
01602
01604
01605
01606
01607
01608
01609
01610
01611 #define PANSI_CHAR 1
01612 #define PLITTLE_ENDIAN 2
01613 #define PBIG_ENDIAN 3
01614
01615
01616 #if 0
01617 class PStandardType
01618
01619
01620
01621
01622
01623
01624 {
01625 public:
01626 PStandardType(
01627 type newVal
01628 ) { data = newVal; }
01629
01630
01631
01632
01633 operator type() { return data; }
01634
01635
01636
01637
01638
01639
01640 friend ostream & operator<<(ostream & strm, const PStandardType & val)
01641 { return strm << (type)val; }
01642
01643
01644
01645
01646
01647
01648 friend istream & operator>>(istream & strm, PStandardType & val)
01649 { type data; strm >> data; val = PStandardType(data); return strm; }
01650
01651
01652
01653
01654
01655
01656
01657 private:
01658 type data;
01659 };
01660 #endif
01661
01662
01663 #define PI_SAME(name, type) \
01664 struct name { \
01665 name() { } \
01666 name(type value) { data = value; } \
01667 name(const name & value) { data = value.data; } \
01668 name & operator =(type value) { data = value; return *this; } \
01669 name & operator =(const name & value) { data = value.data; return *this; } \
01670 operator type() const { return data; } \
01671 friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \
01672 friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \
01673 private: type data; \
01674 }
01675
01676 #define PI_LOOP(src, dst) \
01677 BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \
01678 while (s != (BYTE *)&src) *d++ = *--s;
01679
01680 #define PI_DIFF(name, type) \
01681 struct name { \
01682 name() { } \
01683 name(type value) { operator=(value); } \
01684 name(const name & value) { data = value.data; } \
01685 name & operator =(type value) { PI_LOOP(value, data); return *this; } \
01686 name & operator =(const name & value) { data = value.data; return *this; } \
01687 operator type() const { type value; PI_LOOP(data, value); return value; } \
01688 friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \
01689 friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \
01690 private: type data; \
01691 }
01692
01693 #ifndef PCHAR8
01694 #define PCHAR8 PANSI_CHAR
01695 #endif
01696
01697 #if PCHAR8==PANSI_CHAR
01698 PI_SAME(PChar8, char);
01699 #endif
01700
01701 PI_SAME(PInt8, signed char);
01702
01703 PI_SAME(PUInt8, unsigned char);
01704
01705 #if PBYTE_ORDER==PLITTLE_ENDIAN
01706 PI_SAME(PInt16l, PInt16);
01707 #elif PBYTE_ORDER==PBIG_ENDIAN
01708 PI_DIFF(PInt16l, PInt16);
01709 #endif
01710
01711 #if PBYTE_ORDER==PLITTLE_ENDIAN
01712 PI_DIFF(PInt16b, PInt16);
01713 #elif PBYTE_ORDER==PBIG_ENDIAN
01714 PI_SAME(PInt16b, PInt16);
01715 #endif
01716
01717 #if PBYTE_ORDER==PLITTLE_ENDIAN
01718 PI_SAME(PUInt16l, WORD);
01719 #elif PBYTE_ORDER==PBIG_ENDIAN
01720 PI_DIFF(PUInt16l, WORD);
01721 #endif
01722
01723 #if PBYTE_ORDER==PLITTLE_ENDIAN
01724 PI_DIFF(PUInt16b, WORD);
01725 #elif PBYTE_ORDER==PBIG_ENDIAN
01726 PI_SAME(PUInt16b, WORD);
01727 #endif
01728
01729 #if PBYTE_ORDER==PLITTLE_ENDIAN
01730 PI_SAME(PInt32l, PInt32);
01731 #elif PBYTE_ORDER==PBIG_ENDIAN
01732 PI_DIFF(PInt32l, PInt32);
01733 #endif
01734
01735 #if PBYTE_ORDER==PLITTLE_ENDIAN
01736 PI_DIFF(PInt32b, PInt32);
01737 #elif PBYTE_ORDER==PBIG_ENDIAN
01738 PI_SAME(PInt32b, PInt32);
01739 #endif
01740
01741 #if PBYTE_ORDER==PLITTLE_ENDIAN
01742 PI_SAME(PUInt32l, DWORD);
01743 #elif PBYTE_ORDER==PBIG_ENDIAN
01744 PI_DIFF(PUInt32l, DWORD);
01745 #endif
01746
01747 #if PBYTE_ORDER==PLITTLE_ENDIAN
01748 PI_DIFF(PUInt32b, DWORD);
01749 #elif PBYTE_ORDER==PBIG_ENDIAN
01750 PI_SAME(PUInt32b, DWORD);
01751 #endif
01752
01753 #if PBYTE_ORDER==PLITTLE_ENDIAN
01754 PI_SAME(PInt64l, PInt64);
01755 #elif PBYTE_ORDER==PBIG_ENDIAN
01756 PI_DIFF(PInt64l, PInt64);
01757 #endif
01758
01759 #if PBYTE_ORDER==PLITTLE_ENDIAN
01760 PI_DIFF(PInt64b, PInt64);
01761 #elif PBYTE_ORDER==PBIG_ENDIAN
01762 PI_SAME(PInt64b, PInt64);
01763 #endif
01764
01765 #if PBYTE_ORDER==PLITTLE_ENDIAN
01766 PI_SAME(PUInt64l, PUInt64);
01767 #elif PBYTE_ORDER==PBIG_ENDIAN
01768 PI_DIFF(PUInt64l, PUInt64);
01769 #endif
01770
01771 #if PBYTE_ORDER==PLITTLE_ENDIAN
01772 PI_DIFF(PUInt64b, PUInt64);
01773 #elif PBYTE_ORDER==PBIG_ENDIAN
01774 PI_SAME(PUInt64b, PUInt64);
01775 #endif
01776
01777 #if PBYTE_ORDER==PLITTLE_ENDIAN
01778 PI_SAME(PFloat32l, float);
01779 #elif PBYTE_ORDER==PBIG_ENDIAN
01780 PI_DIFF(PFloat32l, float);
01781 #endif
01782
01783 #if PBYTE_ORDER==PLITTLE_ENDIAN
01784 PI_DIFF(PFloat32b, float);
01785 #elif PBYTE_ORDER==PBIG_ENDIAN
01786 PI_SAME(PFloat32b, float);
01787 #endif
01788
01789 #if PBYTE_ORDER==PLITTLE_ENDIAN
01790 PI_SAME(PFloat64l, double);
01791 #elif PBYTE_ORDER==PBIG_ENDIAN
01792 PI_DIFF(PFloat64l, double);
01793 #endif
01794
01795 #if PBYTE_ORDER==PLITTLE_ENDIAN
01796 PI_DIFF(PFloat64b, double);
01797 #elif PBYTE_ORDER==PBIG_ENDIAN
01798 PI_SAME(PFloat64b, double);
01799 #endif
01800
01801 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
01802 #if PBYTE_ORDER==PLITTLE_ENDIAN
01803 PI_SAME(PFloat80l, long double);
01804 #elif PBYTE_ORDER==PBIG_ENDIAN
01805 PI_DIFF(PFloat80l, long double);
01806 #endif
01807
01808 #if PBYTE_ORDER==PLITTLE_ENDIAN
01809 PI_DIFF(PFloat80b, long double);
01810 #elif PBYTE_ORDER==PBIG_ENDIAN
01811 PI_SAME(PFloat80b, long double);
01812 #endif
01813 #endif
01814
01815 #undef PI_LOOP
01816 #undef PI_SAME
01817 #undef PI_DIFF
01818
01819
01821
01822
01823
01824
01825
01826
01827 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
01828
01829
01830
01831
01832
01833
01834 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
01835
01836
01837
01838
01839
01840
01841 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
01842
01843
01844
01845
01846
01847
01848 #define PABS(v) ((v) < 0 ? -(v) : (v))
01849
01850 #endif // _POBJECT_H
01851
01852