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 #ifndef _POBJECT_H
00416 #define _POBJECT_H
00417
00418 #ifdef P_USE_PRAGMA
00419 #pragma interface
00420 #endif
00421
00422 #ifdef _WIN32
00423 #include "msos/ptlib/contain.h"
00424 #else
00425 #include "unix/ptlib/contain.h"
00426 #endif
00427
00428 #if defined(P_VXWORKS)
00429 #include <private/stdiop.h>
00430 #endif
00431
00432 #include <stdio.h>
00433 #include <stdarg.h>
00434 #include <stdlib.h>
00435
00436 #ifdef _WIN32
00437 #include <malloc.h>
00438 #endif
00439
00440 #include <string.h>
00441
00442 #ifdef __USE_STL__
00443 #include <string>
00444 #include <iomanip>
00445 #include <iostream>
00446 #if (__GNUC__ >= 3)
00447 #include <sstream>
00448 typedef std::ostringstream ostrstream;
00449 #else
00450 #include <strstream>
00451 #endif
00452
00453 #else
00454 #if (__GNUC__ >= 3)
00455 #include <iostream>
00456 #ifndef __MWERKS__
00457 #include <iomanip>
00458 #endif
00459 #else
00460 #include <iostream.h>
00461 #ifdef __GNUC__
00462 #include <strstream.h>
00463 #else
00464 #include <strstrea.h>
00465 #endif
00466 #ifndef __MWERKS__
00467 #include <iomanip.h>
00468 #endif
00469 #endif
00470 #endif
00471
00472 #ifdef _WIN32_WCE
00473 #include <stdlibx.h>
00474 #endif
00475
00476 #if (__GNUC__ < 3)
00477 typedef long _Ios_Fmtflags;
00478 #endif
00479
00480 #if _MSC_VER<1300
00481 #define _BADOFF -1
00482 #endif
00483
00485
00486
00487
00488 #ifndef P_USE_INLINES
00489 #ifdef _DEBUG
00490 #define P_USE_INLINES 0
00491 #else
00492 #define P_USE_INLINES 0
00493 #endif
00494 #endif
00495
00496 #if P_USE_INLINES
00497 #define PINLINE inline
00498 #else
00499 #define PINLINE
00500 #endif
00501
00502
00504
00505
00506 #ifndef P_USE_ASSERTS
00507 #define P_USE_ASSERTS 1
00508 #endif
00509
00510 #if !P_USE_ASSERTS
00511
00512 #define PAssert(b, m) (b)
00513 #define PAssert2(b, c, m) (b)
00514 #define PAssertOS(b) (b)
00515 #define PAssertNULL(p) (p)
00516 #define PAssertAlways(m)
00517 #define PAssertAlways2(c, m)
00518
00519 #else // P_USE_ASSERTS
00520
00522 enum PStandardAssertMessage {
00523 PLogicError,
00524 POutOfMemory,
00525 PNullPointerReference,
00526 PInvalidCast,
00527 PInvalidArrayIndex,
00528 PInvalidArrayElement,
00529 PStackEmpty,
00530 PUnimplementedFunction,
00531 PInvalidParameter,
00532 POperatingSystemError,
00533 PChannelNotOpen,
00534 PUnsupportedFeature,
00535 PInvalidWindow,
00536 PMaxStandardAssertMessage
00537 };
00538
00539 #define __CLASS__ NULL
00540
00541 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg);
00542 void PAssertFunc(const char * file, int line, const char * className, const char * msg);
00543 void PAssertFunc(const char * full_msg);
00544
00545 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, PStandardAssertMessage msg)
00546 {
00547 if (!b)
00548 PAssertFunc(file, line, className, msg);
00549 return b;
00550 }
00551 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, const char * msg)
00552 {
00553 if (!b)
00554 PAssertFunc(file, line, className, msg);
00555 return b;
00556 }
00557
00564 #define PAssert(b, m) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(m))
00565
00573 #define PAssert2(b, c, m) PAssertFuncInline((b), __FILE__,__LINE__,(c),(m))
00574
00581 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
00582
00592 #define PAssertNULL(p) ((&(p)&&(p)!=NULL)?(p): \
00593 (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(p)))
00594
00601 #define PAssertAlways(m) PAssertFunc(__FILE__,__LINE__,__CLASS__,(m))
00602
00609 #define PAssertAlways2(c, m) PAssertFunc(__FILE__,__LINE__,(c),(m))
00610
00611 #endif // P_USE_ASSERTS
00612
00613
00618 ostream & PGetErrorStream();
00619
00623 void PSetErrorStream(ostream * strm );
00624
00639 #define PError (PGetErrorStream())
00640
00641
00642
00644
00645
00646 #ifndef PTRACING
00647 #ifndef _DEBUG
00648 #define PTRACING 0
00649 #else
00650 #define PTRACING 1
00651 #endif
00652 #endif
00653
00658 class PTrace
00659 {
00660 public:
00662 enum Options {
00668 Blocks = 1,
00670 DateAndTime = 2,
00672 Timestamp = 4,
00674 Thread = 8,
00676 TraceLevel = 16,
00678 FileAndLine = 32,
00680 ThreadAddress = 64,
00682 AppendToFile = 128,
00685 GMTTime = 256,
00688 RotateDaily = 512,
00692 SystemLogStream = 32768
00693 };
00694
00702 static void Initialise(
00703 unsigned level,
00704 const char * filename = NULL,
00705 unsigned options = Timestamp | Thread | Blocks
00706 );
00707
00714 static void SetOptions(unsigned options );
00715
00723 static void ClearOptions(unsigned options );
00724
00729 static unsigned GetOptions();
00730
00736 static void SetLevel(unsigned level );
00737
00743 static unsigned GetLevel();
00744
00749 static BOOL CanTrace(unsigned level );
00750
00755 static void SetStream(ostream * out );
00756
00772 static ostream & Begin(
00773 unsigned level,
00774 const char * fileName,
00775 int lineNum
00776 );
00777
00794 static ostream & End(ostream & strm );
00795
00796
00802 class Block {
00803 public:
00805 Block(
00806 const char * fileName,
00807 int lineNum,
00808 const char * traceName
00810 );
00812 ~Block();
00813 private:
00814 const char * file;
00815 int line;
00816 const char * name;
00817 };
00818 };
00819
00820 #if !PTRACING
00821
00822 #define PTRACE_PARAM(param)
00823 #define PTRACE_BLOCK(n)
00824 #define PTRACE_LINE()
00825 #define PTRACE(level, arg)
00826 #define PTRACE_IF(level, cond, args)
00827
00828 #else
00829
00830
00831
00832 #define PTRACE_PARAM(param) param
00833
00840 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
00841
00845 #define PTRACE_LINE() \
00846 if (!PTrace::CanTrace(1)) ; else \
00847 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End
00848
00854 #define PTRACE(level, args) \
00855 if (!PTrace::CanTrace(level)) ; else \
00856 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00857
00865 #define PTRACE_IF(level, cond, args) \
00866 if (!(PTrace::CanTrace(level) && (cond))) ; else \
00867 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00868
00869 #endif
00870
00871 #if PMEMORY_CHECK
00872
00879 class PMemoryHeap {
00880 protected:
00882 PMemoryHeap();
00883
00884 public:
00885
00886 ~PMemoryHeap();
00887
00894 static void * Allocate(
00895 size_t nSize,
00896 const char * file,
00897 int line,
00898 const char * className
00899 );
00906 static void * Allocate(
00907 size_t count,
00908 size_t iSize,
00909 const char * file,
00910 int line
00911 );
00912
00920 static void * Reallocate(
00921 void * ptr,
00922 size_t nSize,
00923 const char * file,
00924 int line
00925 );
00926
00932 static void Deallocate(
00933 void * ptr,
00934 const char * className
00935 );
00936
00939 enum Validation {
00940 Ok, Bad, Trashed
00941 };
00949 static Validation Validate(
00950 void * ptr,
00951 const char * className,
00952 ostream * error
00953 );
00954
00959 static BOOL ValidateHeap(
00960 ostream * error = NULL
00961 );
00962
00968 static BOOL SetIgnoreAllocations(
00969 BOOL ignore
00970 );
00971
00975 static void DumpStatistics();
00979 static void DumpStatistics(ostream & strm );
00980
00981
00982
00983
00984
00985
00986 static DWORD GetAllocationRequest();
00987
00995 static void DumpObjectsSince(
00996 DWORD objectNumber
00997 );
00998
01004 static void DumpObjectsSince(
01005 DWORD objectNumber,
01006 ostream & strm
01007 );
01008
01014 static void SetAllocationBreakpoint(
01015 DWORD point
01016 );
01017
01018 protected:
01019 void * InternalAllocate(
01020 size_t nSize,
01021 const char * file,
01022 int line,
01023 const char * className
01024 );
01025 Validation InternalValidate(
01026 void * ptr,
01027 const char * className,
01028 ostream * error
01029 );
01030 void InternalDumpStatistics(ostream & strm);
01031 void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
01032
01033 class Wrapper {
01034 public:
01035 Wrapper();
01036 ~Wrapper();
01037 PMemoryHeap * operator->() const { return instance; }
01038 private:
01039 PMemoryHeap * instance;
01040 };
01041 friend class Wrapper;
01042
01043 enum Flags {
01044 NoLeakPrint = 1
01045 };
01046
01047 #pragma pack(1)
01048 struct Header {
01049 enum {
01050
01051 NumGuardBytes = 16 - (sizeof(Header *) +
01052 sizeof(Header *) +
01053 sizeof(const char *) +
01054 sizeof(const char *) +
01055 sizeof(size_t) +
01056 sizeof(DWORD) +
01057 sizeof(WORD) +
01058 sizeof(BYTE))%8
01059 };
01060
01061 Header * prev;
01062 Header * next;
01063 const char * className;
01064 const char * fileName;
01065 size_t size;
01066 DWORD request;
01067 WORD line;
01068 BYTE flags;
01069 char guard[NumGuardBytes];
01070
01071 static char GuardBytes[NumGuardBytes];
01072 };
01073 #pragma pack()
01074
01075 BOOL isDestroyed;
01076
01077 Header * listHead;
01078 Header * listTail;
01079
01080 static DWORD allocationBreakpoint;
01081 DWORD allocationRequest;
01082 DWORD firstRealObject;
01083 BYTE flags;
01084
01085 char allocFillChar;
01086 char freeFillChar;
01087
01088 DWORD currentMemoryUsage;
01089 DWORD peakMemoryUsage;
01090 DWORD currentObjects;
01091 DWORD peakObjects;
01092 DWORD totalObjects;
01093
01094 ostream * leakDumpStream;
01095
01096 #if defined(_WIN32)
01097 CRITICAL_SECTION mutex;
01098 #elif defined(P_PTHREADS)
01099 pthread_mutex_t mutex;
01100 #elif defined(P_VXWORKS)
01101 void * mutex;
01102 #endif
01103 };
01104
01105
01110 inline void * runtime_malloc(size_t bytes ) { return malloc(bytes); }
01111
01116 inline void runtime_free(void * ptr ) { free(ptr); }
01117
01118
01125 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
01126
01133 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
01134
01141 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
01142
01143
01150 #define free(p) PMemoryHeap::Deallocate(p, NULL)
01151
01152
01159 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
01160
01161
01176 #define PNEW new (__FILE__, __LINE__)
01177
01178 #if !defined(_MSC_VER) || _MSC_VER<1200
01179 #define PSPECIAL_DELETE_FUNCTION
01180 #else
01181 #define PSPECIAL_DELETE_FUNCTION \
01182 void operator delete(void * ptr, const char *, int) \
01183 { PMemoryHeap::Deallocate(ptr, Class()); } \
01184 void operator delete[](void * ptr, const char *, int) \
01185 { PMemoryHeap::Deallocate(ptr, Class()); }
01186 #endif
01187
01188 #define PNEW_AND_DELETE_FUNCTIONS \
01189 void * operator new(size_t nSize, const char * file, int line) \
01190 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
01191 void * operator new(size_t nSize) \
01192 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
01193 void operator delete(void * ptr) \
01194 { PMemoryHeap::Deallocate(ptr, Class()); } \
01195 void * operator new[](size_t nSize, const char * file, int line) \
01196 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
01197 void * operator new[](size_t nSize) \
01198 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
01199 void operator delete[](void * ptr) \
01200 { PMemoryHeap::Deallocate(ptr, Class()); } \
01201 PSPECIAL_DELETE_FUNCTION
01202
01203
01204 inline void * operator new(size_t nSize, const char * file, int line)
01205 { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
01206
01207 inline void * operator new[](size_t nSize, const char * file, int line)
01208 { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
01209
01210 #ifndef __GNUC__
01211 void * operator new(size_t nSize);
01212 void * operator new[](size_t nSize);
01213
01214 void operator delete(void * ptr);
01215 void operator delete[](void * ptr);
01216
01217 #if defined(_MSC_VER) && _MSC_VER>=1200
01218 inline void operator delete(void * ptr, const char *, int)
01219 { PMemoryHeap::Deallocate(ptr, NULL); }
01220
01221 inline void operator delete[](void * ptr, const char *, int)
01222 { PMemoryHeap::Deallocate(ptr, NULL); }
01223 #endif
01224 #endif
01225
01226
01227 #else // PMEMORY_CHECK
01228
01229 #define PNEW new
01230
01231 #if defined(__GNUC__) || (defined(_WIN32_WCE) && defined(_X86_))
01232
01233 #define PNEW_AND_DELETE_FUNCTIONS
01234
01235 #else
01236
01237 #define PNEW_AND_DELETE_FUNCTIONS \
01238 void * operator new(size_t nSize) \
01239 { return malloc(nSize); } \
01240 void operator delete(void * ptr) \
01241 { free(ptr); } \
01242 void * operator new[](size_t nSize) \
01243 { return malloc(nSize); } \
01244 void operator delete[](void * ptr) \
01245 { free(ptr); }
01246
01247 void * operator new(size_t nSize);
01248 void * operator new[](size_t nSize);
01249
01250 void operator delete(void * ptr);
01251 void operator delete[](void * ptr);
01252
01253 #endif
01254
01255 #define runtime_malloc(s) malloc(s)
01256 #define runtime_free(p) free(p)
01257
01258 #endif // PMEMORY_CHECK
01259
01260
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290 #if P_HAS_TYPEINFO
01291
01292 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
01293 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
01294
01295 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
01296
01297 #if P_USE_ASSERTS
01298 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line)
01299 { if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; }
01300 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
01301 #else
01302 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
01303 #endif
01304
01305 #include <typeinfo>
01306
01307 #define PCLASSNAME(cls) (#cls)
01308
01309 #define PBASECLASSINFO(cls, par) \
01310 public: \
01311 static inline const char * Class() \
01312 { return PCLASSNAME(cls); } \
01313 virtual BOOL InternalIsDescendant(const char * clsName) const \
01314 { return strcmp(clsName, PCLASSNAME(cls)) == 0 || par::InternalIsDescendant(clsName); } \
01315
01316 #else // P_HAS_TYPEINFO
01317
01318 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class()))
01319 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
01320
01321 #define PRemoveConst(cls, ptr) ((cls*)(ptr))
01322
01323 #if P_USE_ASSERTS
01324 template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line)
01325 { if (obj->InternalIsDescendant(BaseClass::Class()) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; }
01326 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
01327 #else
01328 #define PDownCast(cls, ptr) ((cls*)(ptr))
01329 #endif
01330
01331 #define PBASECLASSINFO(cls, par) \
01332 public: \
01333 static const char * Class() \
01334 { return #cls; } \
01335 virtual BOOL InternalIsDescendant(const char * clsName) const \
01336 { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
01337
01338 #endif // P_HAS_TYPEINFO
01339
01340
01341 #define PCLASSINFO(cls, par) \
01342 PBASECLASSINFO(cls, par) \
01343 virtual const char * GetClass(unsigned ancestor = 0) const \
01344 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
01345 virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \
01346 { return (Comparison)memcmp(this, &obj, sizeof(cls)); } \
01347
01348
01356 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
01357 #ifdef DOC_PLUS_PLUS
01358 } Match previous opening brace in doc++
01359 #endif
01360
01362
01363
01368 class PObject {
01369
01370 protected:
01374 PObject() { }
01375
01376 public:
01377
01378
01379
01380 virtual ~PObject() { }
01381
01394 static inline const char * Class() { return PCLASSNAME(PObject); }
01395
01408 virtual const char * GetClass(unsigned = 0) const { return Class(); }
01409
01410 BOOL IsClass(const char * cls) const
01411 { return strcmp(cls, GetClass()) == 0; }
01412
01422 virtual BOOL InternalIsDescendant(
01423 const char * clsName
01424 ) const
01425 { return IsClass(clsName); }
01426
01428
01434 enum Comparison {
01435 LessThan = -1,
01436 EqualTo = 0,
01437 GreaterThan = 1
01438 };
01439
01451 virtual Comparison Compare(
01452 const PObject & obj
01453 ) const;
01454
01466 virtual Comparison CompareObjectMemoryDirect(
01467 const PObject & obj
01468 ) const;
01469
01475 bool operator==(
01476 const PObject & obj
01477 ) const { return Compare(obj) == EqualTo; }
01478
01484 bool operator!=(
01485 const PObject & obj
01486 ) const { return Compare(obj) != EqualTo; }
01487
01493 bool operator<(
01494 const PObject & obj
01495 ) const { return Compare(obj) == LessThan; }
01496
01502 bool operator>(
01503 const PObject & obj
01504 ) const { return Compare(obj) == GreaterThan; }
01505
01511 bool operator<=(
01512 const PObject & obj
01513 ) const { return Compare(obj) != GreaterThan; }
01514
01520 bool operator>=(
01521 const PObject & obj
01522 ) const { return Compare(obj) != LessThan; }
01524
01533 virtual void PrintOn(
01534 ostream &strm
01535 ) const;
01536
01543 virtual void ReadFrom(
01544 istream &strm
01545 );
01546
01547
01553 inline friend ostream & operator<<(
01554 ostream &strm,
01555 const PObject & obj
01556 ) { obj.PrintOn(strm); return strm; }
01557
01563 inline friend istream & operator>>(
01564 istream &strm,
01565 PObject & obj
01566 ) { obj.ReadFrom(strm); return strm; }
01567
01568
01583 virtual PObject * Clone() const;
01584
01596 virtual PINDEX HashFunction() const;
01598 };
01599
01601
01602
01603
01604
01605
01606
01607
01608 #define PANSI_CHAR 1
01609 #define PLITTLE_ENDIAN 2
01610 #define PBIG_ENDIAN 3
01611
01612
01613 #if 0
01614 class PStandardType
01615
01616
01617
01618
01619
01620
01621 {
01622 public:
01623 PStandardType(
01624 type newVal
01625 ) { data = newVal; }
01626
01627
01628
01629
01630 operator type() { return data; }
01631
01632
01633
01634
01635
01636
01637 friend ostream & operator<<(ostream & strm, const PStandardType & val)
01638 { return strm << (type)val; }
01639
01640
01641
01642
01643
01644
01645 friend istream & operator>>(istream & strm, PStandardType & val)
01646 { type data; strm >> data; val = PStandardType(data); return strm; }
01647
01648
01649
01650
01651
01652
01653
01654 private:
01655 type data;
01656 };
01657 #endif
01658
01659
01660 #define PI_SAME(name, type) \
01661 struct name { \
01662 name() { } \
01663 name(type value) { data = value; } \
01664 name(const name & value) { data = value.data; } \
01665 name & operator =(type value) { data = value; return *this; } \
01666 name & operator =(const name & value) { data = value.data; return *this; } \
01667 operator type() const { return data; } \
01668 friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \
01669 friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \
01670 private: type data; \
01671 }
01672
01673 #define PI_LOOP(src, dst) \
01674 BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \
01675 while (s != (BYTE *)&src) *d++ = *--s;
01676
01677 #define PI_DIFF(name, type) \
01678 struct name { \
01679 name() { } \
01680 name(type value) { operator=(value); } \
01681 name(const name & value) { data = value.data; } \
01682 name & operator =(type value) { PI_LOOP(value, data); return *this; } \
01683 name & operator =(const name & value) { data = value.data; return *this; } \
01684 operator type() const { type value; PI_LOOP(data, value); return value; } \
01685 friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \
01686 friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \
01687 private: type data; \
01688 }
01689
01690 #ifndef PCHAR8
01691 #define PCHAR8 PANSI_CHAR
01692 #endif
01693
01694 #if PCHAR8==PANSI_CHAR
01695 PI_SAME(PChar8, char);
01696 #endif
01697
01698 PI_SAME(PInt8, signed char);
01699
01700 PI_SAME(PUInt8, unsigned char);
01701
01702 #if PBYTE_ORDER==PLITTLE_ENDIAN
01703 PI_SAME(PInt16l, PInt16);
01704 #elif PBYTE_ORDER==PBIG_ENDIAN
01705 PI_DIFF(PInt16l, PInt16);
01706 #endif
01707
01708 #if PBYTE_ORDER==PLITTLE_ENDIAN
01709 PI_DIFF(PInt16b, PInt16);
01710 #elif PBYTE_ORDER==PBIG_ENDIAN
01711 PI_SAME(PInt16b, PInt16);
01712 #endif
01713
01714 #if PBYTE_ORDER==PLITTLE_ENDIAN
01715 PI_SAME(PUInt16l, WORD);
01716 #elif PBYTE_ORDER==PBIG_ENDIAN
01717 PI_DIFF(PUInt16l, WORD);
01718 #endif
01719
01720 #if PBYTE_ORDER==PLITTLE_ENDIAN
01721 PI_DIFF(PUInt16b, WORD);
01722 #elif PBYTE_ORDER==PBIG_ENDIAN
01723 PI_SAME(PUInt16b, WORD);
01724 #endif
01725
01726 #if PBYTE_ORDER==PLITTLE_ENDIAN
01727 PI_SAME(PInt32l, PInt32);
01728 #elif PBYTE_ORDER==PBIG_ENDIAN
01729 PI_DIFF(PInt32l, PInt32);
01730 #endif
01731
01732 #if PBYTE_ORDER==PLITTLE_ENDIAN
01733 PI_DIFF(PInt32b, PInt32);
01734 #elif PBYTE_ORDER==PBIG_ENDIAN
01735 PI_SAME(PInt32b, PInt32);
01736 #endif
01737
01738 #if PBYTE_ORDER==PLITTLE_ENDIAN
01739 PI_SAME(PUInt32l, DWORD);
01740 #elif PBYTE_ORDER==PBIG_ENDIAN
01741 PI_DIFF(PUInt32l, DWORD);
01742 #endif
01743
01744 #if PBYTE_ORDER==PLITTLE_ENDIAN
01745 PI_DIFF(PUInt32b, DWORD);
01746 #elif PBYTE_ORDER==PBIG_ENDIAN
01747 PI_SAME(PUInt32b, DWORD);
01748 #endif
01749
01750 #if PBYTE_ORDER==PLITTLE_ENDIAN
01751 PI_SAME(PInt64l, PInt64);
01752 #elif PBYTE_ORDER==PBIG_ENDIAN
01753 PI_DIFF(PInt64l, PInt64);
01754 #endif
01755
01756 #if PBYTE_ORDER==PLITTLE_ENDIAN
01757 PI_DIFF(PInt64b, PInt64);
01758 #elif PBYTE_ORDER==PBIG_ENDIAN
01759 PI_SAME(PInt64b, PInt64);
01760 #endif
01761
01762 #if PBYTE_ORDER==PLITTLE_ENDIAN
01763 PI_SAME(PUInt64l, PUInt64);
01764 #elif PBYTE_ORDER==PBIG_ENDIAN
01765 PI_DIFF(PUInt64l, PUInt64);
01766 #endif
01767
01768 #if PBYTE_ORDER==PLITTLE_ENDIAN
01769 PI_DIFF(PUInt64b, PUInt64);
01770 #elif PBYTE_ORDER==PBIG_ENDIAN
01771 PI_SAME(PUInt64b, PUInt64);
01772 #endif
01773
01774 #if PBYTE_ORDER==PLITTLE_ENDIAN
01775 PI_SAME(PFloat32l, float);
01776 #elif PBYTE_ORDER==PBIG_ENDIAN
01777 PI_DIFF(PFloat32l, float);
01778 #endif
01779
01780 #if PBYTE_ORDER==PLITTLE_ENDIAN
01781 PI_DIFF(PFloat32b, float);
01782 #elif PBYTE_ORDER==PBIG_ENDIAN
01783 PI_SAME(PFloat32b, float);
01784 #endif
01785
01786 #if PBYTE_ORDER==PLITTLE_ENDIAN
01787 PI_SAME(PFloat64l, double);
01788 #elif PBYTE_ORDER==PBIG_ENDIAN
01789 PI_DIFF(PFloat64l, double);
01790 #endif
01791
01792 #if PBYTE_ORDER==PLITTLE_ENDIAN
01793 PI_DIFF(PFloat64b, double);
01794 #elif PBYTE_ORDER==PBIG_ENDIAN
01795 PI_SAME(PFloat64b, double);
01796 #endif
01797
01798 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
01799 #if PBYTE_ORDER==PLITTLE_ENDIAN
01800 PI_SAME(PFloat80l, long double);
01801 #elif PBYTE_ORDER==PBIG_ENDIAN
01802 PI_DIFF(PFloat80l, long double);
01803 #endif
01804
01805 #if PBYTE_ORDER==PLITTLE_ENDIAN
01806 PI_DIFF(PFloat80b, long double);
01807 #elif PBYTE_ORDER==PBIG_ENDIAN
01808 PI_SAME(PFloat80b, long double);
01809 #endif
01810 #endif
01811
01812 #undef PI_LOOP
01813 #undef PI_SAME
01814 #undef PI_DIFF
01815
01816
01818
01819
01820
01821
01822
01823
01824 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
01825
01826
01827
01828
01829
01830
01831 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
01832
01833
01834
01835
01836
01837
01838 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
01839
01840
01841
01842
01843
01844
01845 #define PABS(v) ((v) < 0 ? -(v) : (v))
01846
01847 #endif // _POBJECT_H
01848
01849