object.h

Go to the documentation of this file.
00001 /*
00002  * object.h
00003  *
00004  * Mother of all ancestor classes.
00005  *
00006  * Portable Windows Library
00007  *
00008  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
00009  *
00010  * The contents of this file are subject to the Mozilla Public License
00011  * Version 1.0 (the "License"); you may not use this file except in
00012  * compliance with the License. You may obtain a copy of the License at
00013  * http://www.mozilla.org/MPL/
00014  *
00015  * Software distributed under the License is distributed on an "AS IS"
00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00017  * the License for the specific language governing rights and limitations
00018  * under the License.
00019  *
00020  * The Original Code is Portable Windows Library.
00021  *
00022  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00023  *
00024  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
00025  * All Rights Reserved.
00026  *
00027  * Contributor(s): ______________________________________.
00028  *
00029  * $Revision: 19008 $
00030  * $Author: rjongbloed $
00031  * $Date: 2007-11-29 09:17:41 +0000 (Thu, 29 Nov 2007) $
00032  */
00033 
00034 #ifndef _POBJECT_H
00035 #define _POBJECT_H
00036 
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040 
00041 #ifdef _WIN32
00042 #include "msos/ptlib/contain.h"
00043 #else
00044 #include "unix/ptlib/contain.h"
00045 #endif
00046 
00047 #if defined(P_VXWORKS)
00048 #include <private/stdiop.h>
00049 #endif
00050 
00051 #include <stdio.h>
00052 #include <stdarg.h>
00053 #include <stdlib.h>
00054 
00055 #include <string.h>
00056 
00057 #ifdef __USE_STL__
00058   #include <string>
00059   #include <iomanip>
00060   #include <iostream>
00061   #if (__GNUC__ >= 3)
00062     #include <sstream>
00063     typedef std::ostringstream ostrstream;
00064   #else
00065     #include <strstream>
00066   #endif
00067   //using namespace std;
00068   #ifdef _STLP_IOS_BASE_H
00069   typedef std::ios_base::fmtflags _Ios_Fmtflags;
00070   #endif
00071 #else
00072   #if (__GNUC__ >= 3)
00073     #include <iosfwd>
00074     #ifndef __MWERKS__
00075       #include <iomanip>
00076     #endif
00077   #else
00078     #include <iosfwd>
00079     #ifdef __GNUC__
00080       #include <strstream.h>
00081     #else
00082       #include <strstrea.h>
00083     #endif
00084     #ifndef __MWERKS__
00085       #include <iomanip.h>
00086     #endif
00087   #endif
00088 #endif
00089 
00090 #if (__GNUC__ < 3) && !defined(_STLP_IOS_BASE_H)
00091 typedef long _Ios_Fmtflags;
00092 #endif
00093 
00094 #if _MSC_VER<1300
00095 #define _BADOFF -1
00096 #endif
00097 
00098 
00099 // P_USE_INTEGER_BOOL is the default and gives the old behaviour (it
00100 // is also used for C translation units).
00101 // without P_USE_INTEGER_BOOL, the ANSI C++ bool is used.
00102 
00103 #if defined(P_USE_INTEGER_BOOL) || !defined(__cplusplus)
00104    typedef BOOL PBoolean;
00105 #  define PTrue TRUE
00106 #  define PFalse FALSE
00107 #else
00108    typedef bool PBoolean;
00109 #  define PTrue true
00110 #  define PFalse false
00111 #endif
00112 
00113 
00115 // Disable inlines when debugging for faster compiles (the compiler doesn't
00116 // actually inline the function with debug on any way).
00117 
00118 #ifndef P_USE_INLINES
00119 #ifdef _DEBUG
00120 #define P_USE_INLINES 0
00121 #else
00122 #define P_USE_INLINES 0
00123 #endif
00124 #endif
00125 
00126 #if P_USE_INLINES
00127 #define PINLINE inline
00128 #else
00129 #define PINLINE
00130 #endif
00131 
00132 
00134 // Declare the debugging support
00135 
00136 #ifndef P_USE_ASSERTS
00137 #define P_USE_ASSERTS 1
00138 #endif
00139 
00140 #if !P_USE_ASSERTS
00141 
00142 #define PAssert(b, m) (b)
00143 #define PAssert2(b, c, m) (b)
00144 #define PAssertOS(b) (b)
00145 #define PAssertNULL(p) (p)
00146 #define PAssertAlways(m)
00147 #define PAssertAlways2(c, m)
00148 
00149 #else // P_USE_ASSERTS
00150 
00152 enum PStandardAssertMessage {
00153   PLogicError,              // A logic error occurred.
00154   POutOfMemory,             // A new or malloc failed.
00155   PNullPointerReference,    // A reference was made through a NULL pointer.
00156   PInvalidCast,             // An invalid cast to descendant is required.
00157   PInvalidArrayIndex,       // An index into an array was negative.
00158   PInvalidArrayElement,     // A NULL array element object was accessed.
00159   PStackEmpty,              // A Pop() was made of a stack with no elements.
00160   PUnimplementedFunction,   // Funtion is not implemented.
00161   PInvalidParameter,        // Invalid parameter was passed to a function.
00162   POperatingSystemError,    // Error was returned by Operating System.
00163   PChannelNotOpen,          // Operation attempted when channel not open.
00164   PUnsupportedFeature,      // Feature is not supported.
00165   PInvalidWindow,           // Access through invalid window.
00166   PMaxStandardAssertMessage
00167 };
00168 
00169 #define __CLASS__ NULL
00170 
00171 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg);
00172 void PAssertFunc(const char * file, int line, const char * className, const char * msg);
00173 void PAssertFunc(const char * full_msg);
00174 
00175 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, PStandardAssertMessage msg)
00176 {
00177   if (!b) 
00178     PAssertFunc(file, line, className, msg);
00179   return b;
00180 }
00181 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, const char * msg)
00182 {
00183   if (!b) 
00184     PAssertFunc(file, line, className, msg);
00185   return b;
00186 }
00187 
00194 #define PAssert(b, m) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(m))
00195 
00203 #define PAssert2(b, c, m) PAssertFuncInline((b), __FILE__,__LINE__,(c),(m))
00204 
00211 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
00212 
00222 #define PAssertNULL(p) (((p)!=NULL)?(p): \
00223                      (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(p)))
00224 
00231 #define PAssertAlways(m) PAssertFunc(__FILE__,__LINE__,__CLASS__,(m))
00232 
00239 #define PAssertAlways2(c, m) PAssertFunc(__FILE__,__LINE__,(c),(m))
00240 
00241 #endif // P_USE_ASSERTS
00242 
00243 
00248 ostream & PGetErrorStream();
00249 
00253 void PSetErrorStream(ostream * strm  );
00254 
00269 #define PError (PGetErrorStream())
00270 
00271 
00272 
00274 // Debug and tracing
00275 
00276 #ifndef PTRACING
00277 #define PTRACING 1
00278 #endif
00279 
00280 #if PTRACING
00281 
00286 class PTrace
00287 {
00288 public:
00290   enum Options {
00296     Blocks = 1,
00298     DateAndTime = 2,
00300     Timestamp = 4,
00302     Thread = 8,
00304     TraceLevel = 16,
00306     FileAndLine = 32,
00308     ThreadAddress = 64,
00310     AppendToFile = 128,
00313     GMTTime = 256,
00316     RotateDaily = 512,
00320     SystemLogStream = 32768
00321   };
00322 
00330   static void Initialise(
00331     unsigned level,
00332     const char * filename = NULL,
00333     unsigned options = Timestamp | Thread | Blocks
00334   );
00335 
00346   static void Initialise(
00347     unsigned level,
00348     const char * filename,
00349     const char * rolloverPattern,
00350     unsigned options = Timestamp | Thread | Blocks
00351   );
00352 
00359   static void SetOptions(unsigned options  );
00360 
00368   static void ClearOptions(unsigned options  );
00369 
00374   static unsigned GetOptions();
00375 
00381   static void SetLevel(unsigned level  );
00382 
00388   static unsigned GetLevel();
00389 
00394   static PBoolean CanTrace(unsigned level );
00395 
00400   static void SetStream(ostream * out  );
00401 
00417   static ostream & Begin(
00418     unsigned level,         
00419     const char * fileName,  
00420     int lineNum             
00421   );
00422 
00439   static ostream & End(ostream & strm );
00440 
00441 
00447   class Block {
00448     public:
00450       Block(
00451         const char * fileName, 
00452         int lineNum,           
00453         const char * traceName
00455        );
00456       Block(const Block & obj)
00457         : file(obj.file), line(obj.line), name(obj.name) { }
00459       ~Block();
00460     private:
00461       Block & operator=(const Block &)
00462       { return *this; }
00463       const char * file;
00464       int          line;
00465       const char * name;
00466   };
00467 };
00468 
00469 /* Macro to conditionally declare a parameter to a function to avoid compiler
00470    warning due that parameter only being used in a PTRACE */
00471 #define PTRACE_PARAM(param) param
00472 
00479 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
00480 
00484 #define PTRACE_LINE() \
00485     if (!PTrace::CanTrace(1)) ; else \
00486       PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End
00487 
00493 #define PTRACE(level, args) \
00494     if (!PTrace::CanTrace(level)) ; else \
00495       PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00496 
00504 #define PTRACE_IF(level, cond, args) \
00505     if (!(PTrace::CanTrace(level)  && (cond))) ; else \
00506       PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
00507 
00508 #else // PTRACING
00509 
00510 #define PTRACE_PARAM(param)
00511 #define PTRACE_BLOCK(n)
00512 #define PTRACE_LINE()
00513 #define PTRACE(level, arg)
00514 #define PTRACE_IF(level, cond, args)
00515 
00516 #endif // PTRACING
00517 
00518 
00519 
00520 #if PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG) && !defined(_WIN32_WCE)) 
00521 
00522 #define PMEMORY_HEAP 1
00523 
00530 class PMemoryHeap {
00531   public:
00533     PMemoryHeap();
00534 
00535     // Clear up the memory checking subsystem, dumping memory leaks.
00536     ~PMemoryHeap();
00537 
00544     static void * Allocate(
00545       size_t nSize,           
00546       const char * file,      
00547       int line,               
00548       const char * className  
00549     );
00556     static void * Allocate(
00557       size_t count,       
00558       size_t iSize,       
00559       const char * file,  
00560       int line            
00561     );
00562 
00570     static void * Reallocate(
00571       void * ptr,         
00572       size_t nSize,       
00573       const char * file,  
00574       int line            
00575     );
00576 
00582     static void Deallocate(
00583       void * ptr,             
00584       const char * className  
00585     );
00586 
00589     enum Validation {
00590       Ok, Bad, Trashed
00591     };
00599     static Validation Validate(
00600       const void * ptr,       
00601       const char * className, 
00602       ostream * error         
00603     );
00604 
00609     static PBoolean ValidateHeap(
00610       ostream * error = NULL  
00611     );
00612 
00618     static PBoolean SetIgnoreAllocations(
00619       PBoolean ignore  
00620     );
00621 
00625     static void DumpStatistics();
00629     static void DumpStatistics(ostream & strm );
00630 
00631 #if PMEMORY_CHECK
00632     struct State {
00633       DWORD allocationNumber;
00634     };
00635 #else
00636         typedef _CrtMemState State;
00637 #endif
00638 
00639     /* Get memory state.
00640       This returns a state that may be used to determine where to start dumping
00641       objects from.
00642      */
00643     static void GetState(
00644       State & state  
00645     );
00646 
00654     static void DumpObjectsSince(
00655       const State & when    
00656     );
00657 
00663     static void DumpObjectsSince(
00664       const State & when,   
00665       ostream & strm        
00666     );
00667 
00673     static void SetAllocationBreakpoint(
00674       DWORD point   
00675     );
00676 
00677 #if PMEMORY_CHECK
00678 
00679   protected:
00680     void * InternalAllocate(
00681       size_t nSize,           // Number of bytes to allocate.
00682       const char * file,      // Source file name for allocating function.
00683       int line,               // Source file line for allocating function.
00684       const char * className  // Class name for allocating function.
00685     );
00686     Validation InternalValidate(
00687       const void * ptr,       // Pointer to memory block to check
00688       const char * className, // Class name it should be.
00689       ostream * error         // Stream to receive error message (may be NULL)
00690     );
00691     void InternalDumpStatistics(ostream & strm);
00692     void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
00693 
00694     class Wrapper {
00695       public:
00696         Wrapper();
00697         ~Wrapper();
00698         PMemoryHeap * operator->() const { return instance; }
00699       private:
00700         PMemoryHeap * instance;
00701     };
00702     friend class Wrapper;
00703 
00704     enum Flags {
00705       NoLeakPrint = 1
00706     };
00707 
00708 #pragma pack(1)
00709     struct Header {
00710       enum {
00711         // Assure that the Header struct is aligned to 8 byte boundary
00712         NumGuardBytes = 16 - (sizeof(Header *) +
00713                               sizeof(Header *) +
00714                               sizeof(const char *) +
00715                               sizeof(const char *) +
00716                               sizeof(size_t) +
00717                               sizeof(DWORD) +
00718                               sizeof(WORD) +
00719                               sizeof(BYTE)
00720 #ifdef P_LINUX
00721                               + sizeof(pthread_t)
00722 #endif
00723                               )%8
00724       };
00725 
00726       Header     * prev;
00727       Header     * next;
00728       const char * className;
00729       const char * fileName;
00730       size_t       size;
00731       DWORD        request;
00732       WORD         line;
00733       BYTE         flags;
00734 #ifdef P_LINUX
00735       pthread_t    thread;
00736 #endif
00737       char         guard[NumGuardBytes];
00738 
00739       static char GuardBytes[NumGuardBytes];
00740     };
00741 #pragma pack()
00742 
00743     PBoolean isDestroyed;
00744 
00745     Header * listHead;
00746     Header * listTail;
00747 
00748     static DWORD allocationBreakpoint;
00749     DWORD allocationRequest;
00750     DWORD firstRealObject;
00751     BYTE  flags;
00752 
00753     char  allocFillChar;
00754     char  freeFillChar;
00755 
00756     DWORD currentMemoryUsage;
00757     DWORD peakMemoryUsage;
00758     DWORD currentObjects;
00759     DWORD peakObjects;
00760     DWORD totalObjects;
00761 
00762     ostream * leakDumpStream;
00763 
00764 #if defined(_WIN32)
00765     CRITICAL_SECTION mutex;
00766 #elif defined(P_PTHREADS)
00767     pthread_mutex_t mutex;
00768 #elif defined(P_VXWORKS)
00769     void * mutex;
00770 #endif
00771 
00772 #else
00773 
00774 #define P_CLIENT_BLOCK (_CLIENT_BLOCK|(0x61<<16)) // This identifies a PObject derived class
00775     _CrtMemState initialState;
00776 
00777 #endif // PMEMORY_CHECK
00778 };
00779 
00780 
00785 inline void * runtime_malloc(size_t bytes  ) { return malloc(bytes); }
00786 
00791 inline void runtime_free(void * ptr  ) { free(ptr); }
00792 
00793 
00800 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
00801 
00808 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
00809 
00816 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
00817 
00818 
00825 #define free(p) PMemoryHeap::Deallocate(p, NULL)
00826 
00827 
00834 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
00835 
00836 
00851 #define PNEW  new (__FILE__, __LINE__)
00852 
00853 #if !defined(_MSC_VER) || _MSC_VER<1200
00854 #define PSPECIAL_DELETE_FUNCTION
00855 #else
00856 #define PSPECIAL_DELETE_FUNCTION \
00857     void operator delete(void * ptr, const char *, int) \
00858       { PMemoryHeap::Deallocate(ptr, Class()); } \
00859     void operator delete[](void * ptr, const char *, int) \
00860       { PMemoryHeap::Deallocate(ptr, Class()); }
00861 #endif
00862 
00863 #define PNEW_AND_DELETE_FUNCTIONS \
00864     void * operator new(size_t nSize, const char * file, int line) \
00865       { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
00866     void * operator new(size_t nSize) \
00867       { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
00868     void operator delete(void * ptr) \
00869       { PMemoryHeap::Deallocate(ptr, Class()); } \
00870     void * operator new(size_t, void * placement) \
00871       { return placement; } \
00872     void operator delete(void *, void *) \
00873       { } \
00874     void * operator new[](size_t nSize, const char * file, int line) \
00875       { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
00876     void * operator new[](size_t nSize) \
00877       { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
00878     void operator delete[](void * ptr) \
00879       { PMemoryHeap::Deallocate(ptr, Class()); } \
00880     PSPECIAL_DELETE_FUNCTION
00881 
00882 
00883 inline void * operator new(size_t nSize, const char * file, int line)
00884   { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
00885 
00886 inline void * operator new[](size_t nSize, const char * file, int line)
00887   { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
00888 
00889 #ifndef __GNUC__
00890 void * operator new(size_t nSize);
00891 void * operator new[](size_t nSize);
00892 
00893 void operator delete(void * ptr);
00894 void operator delete[](void * ptr);
00895 
00896 #if defined(_MSC_VER) && _MSC_VER>=1200
00897 inline void operator delete(void * ptr, const char *, int)
00898   { PMemoryHeap::Deallocate(ptr, NULL); }
00899 
00900 inline void operator delete[](void * ptr, const char *, int)
00901   { PMemoryHeap::Deallocate(ptr, NULL); }
00902 #endif
00903 #endif
00904 
00905 
00906 class PMemoryHeapIgnoreAllocationsForScope {
00907 public:
00908   PMemoryHeapIgnoreAllocationsForScope() : previousIgnoreAllocations(PMemoryHeap::SetIgnoreAllocations(PTrue)) { }
00909   ~PMemoryHeapIgnoreAllocationsForScope() { PMemoryHeap::SetIgnoreAllocations(previousIgnoreAllocations); }
00910 private:
00911   PBoolean previousIgnoreAllocations;
00912 };
00913 
00914 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE PMemoryHeapIgnoreAllocationsForScope instance_PMemoryHeapIgnoreAllocationsForScope
00915 
00916 class PMemoryAllocationBreakpoint {
00917 public:
00918   PMemoryAllocationBreakpoint(DWORD point)
00919   {
00920     PMemoryHeap::SetAllocationBreakpoint(point);
00921   }
00922 };
00923 
00924 #define PMEMORY_ALLOCATION_BREAKPOINT(point) PMemoryAllocationBreakpoint PMemoryAllocationBreakpointInstance(point)
00925 
00926 
00927 #else // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
00928 
00929 #define PMEMORY_HEAP 0
00930 
00931 #define PNEW new
00932 
00933 #define PNEW_AND_DELETE_FUNCTIONS
00934 
00935 #define runtime_malloc(s) malloc(s)
00936 #define runtime_free(p) free(p)
00937 
00938 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE
00939 #define PMEMORY_ALLOCATION_BREAKPOINT(point)
00940 
00941 #endif // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
00942 
00943 
00954 #define PCLASSINFO(cls, par) \
00955   public: \
00956     static inline const char * Class() \
00957       { return #cls; } \
00958     virtual PBoolean InternalIsDescendant(const char * clsName) const \
00959       { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
00960     virtual const char * GetClass(unsigned ancestor = 0) const \
00961       { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
00962     virtual Comparison CompareObjectMemoryDirect(const PObject & _obj) const \
00963       { return (Comparison)memcmp(this, &_obj, sizeof(cls)); } \
00964     PNEW_AND_DELETE_FUNCTIONS
00965 
00966 
00967 #if P_HAS_TYPEINFO
00968 
00969 #define PIsDescendant(ptr, cls)    (dynamic_cast<const cls *>(ptr) != NULL) 
00970 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str)) 
00971 
00972 #define PRemoveConst(cls, ptr)  (const_cast<cls*>(ptr))
00973 
00974 #if P_USE_ASSERTS
00975 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line) 
00976   { if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; }
00977 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
00978 #else
00979 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
00980 #endif
00981 
00982 #include <typeinfo>
00983 
00984 #else // P_HAS_TYPEINFO
00985 
00986 #define PIsDescendant(ptr, cls)    ((ptr)->InternalIsDescendant(cls::Class()))
00987 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
00988 
00989 #define PRemoveConst(cls, ptr)  ((cls*)(ptr))
00990 
00991 #if P_USE_ASSERTS
00992 template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line) 
00993   { if (obj->InternalIsDescendant(BaseClass::Class())) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; }
00994 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
00995 #else
00996 #define PDownCast(cls, ptr) ((cls*)(ptr))
00997 #endif
00998 
00999 #endif // P_HAS_TYPEINFO
01000 
01001 
01010 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
01011 #ifdef DOC_PLUS_PLUS
01012 } Match previous opening brace in doc++
01013 #endif
01014 
01016 // The root of all evil ... umm classes
01017 
01022 class PObject {
01023 
01024   protected:
01028     PObject() { }
01029 
01030   public:
01031     /* Destructor required to get the "virtual". A PObject really has nothing
01032        to destroy.
01033      */
01034     virtual ~PObject() { }
01035 
01048     static inline const char * Class()    { return "PObject"; }
01049 
01062     virtual const char * GetClass(unsigned /*ancestor*/ = 0) const { return Class(); }
01063 
01064     PBoolean IsClass(const char * cls) const 
01065     { return strcmp(cls, GetClass()) == 0; }
01066 
01076     virtual PBoolean InternalIsDescendant(
01077       const char * clsName    // Ancestor class name to compare against.
01078     ) const
01079     { return IsClass(clsName); }
01080 
01082 
01088     enum Comparison {
01089       LessThan = -1,
01090       EqualTo = 0,
01091       GreaterThan = 1
01092     };
01093 
01105     virtual Comparison Compare(
01106       const PObject & obj   // Object to compare against.
01107     ) const;
01108     
01120     virtual Comparison CompareObjectMemoryDirect(
01121       const PObject & obj   // Object to compare against.
01122     ) const;
01123 
01129     bool operator==(
01130       const PObject & obj   // Object to compare against.
01131     ) const { return Compare(obj) == EqualTo; }
01132 
01138     bool operator!=(
01139       const PObject & obj   // Object to compare against.
01140     ) const { return Compare(obj) != EqualTo; }
01141 
01147     bool operator<(
01148       const PObject & obj   // Object to compare against.
01149     ) const { return Compare(obj) == LessThan; }
01150 
01156     bool operator>(
01157       const PObject & obj   // Object to compare against.
01158     ) const { return Compare(obj) == GreaterThan; }
01159 
01165     bool operator<=(
01166       const PObject & obj   // Object to compare against.
01167     ) const { return Compare(obj) != GreaterThan; }
01168 
01174     bool operator>=(
01175       const PObject & obj   // Object to compare against.
01176     ) const { return Compare(obj) != LessThan; }
01178 
01187     virtual void PrintOn(
01188       ostream &strm   // Stream to print the object into.
01189     ) const;
01190 
01197     virtual void ReadFrom(
01198       istream &strm   // Stream to read the objects contents from.
01199     );
01200 
01201 
01207     inline friend ostream & operator<<(
01208       ostream &strm,       // Stream to print the object into.
01209       const PObject & obj  // Object to print to the stream.
01210     ) { obj.PrintOn(strm); return strm; }
01211 
01217     inline friend istream & operator>>(
01218       istream &strm,   // Stream to read the objects contents from.
01219       PObject & obj    // Object to read inormation into.
01220     ) { obj.ReadFrom(strm); return strm; }
01221 
01222 
01237     virtual PObject * Clone() const;
01238 
01250     virtual PINDEX HashFunction() const;
01252 };
01253 
01255 // Platform independent types
01256 
01257 // All these classes encapsulate primitive types such that they may be
01258 // transfered in a platform independent manner. In particular it is used to
01259 // do byte swapping for little endien and big endien processor architectures
01260 // as well as accommodating structure packing rules for memory structures.
01261 
01262 #define PANSI_CHAR 1
01263 #define PLITTLE_ENDIAN 2
01264 #define PBIG_ENDIAN 3
01265 
01266 
01267 #if 0
01268 class PStandardType
01269 /* Encapsulate a standard 8 bit character into a portable format. This would
01270    rarely need to do translation, only if the target platform uses EBCDIC
01271    would it do anything.
01272 
01273    The platform independent form here is always 8 bit ANSI.
01274  */
01275 {
01276   public:
01277     PStandardType(
01278       type newVal   // Value to initialise data in platform dependent form.
01279     ) { data = newVal; }
01280     /* Create a new instance of the platform independent type using platform
01281        dependent data, or platform independent streams.
01282      */
01283 
01284     operator type() { return data; }
01285     /* Get the platform dependent value for the type.
01286 
01287        @return
01288        data for instance.
01289      */
01290 
01291     friend ostream & operator<<(ostream & strm, const PStandardType & val)
01292       { return strm << (type)val; }
01293     /* Output the platform dependent value for the type to the stream.
01294 
01295        @return
01296        the stream output was made to.
01297      */
01298 
01299     friend istream & operator>>(istream & strm, PStandardType & val)
01300       { type data; strm >> data; val = PStandardType(data); return strm; }
01301     /* Input the platform dependent value for the type from the stream.
01302 
01303        @return
01304        the stream input was made from.
01305      */
01306 
01307 
01308   private:
01309     type data;
01310 };
01311 #endif
01312 
01313 
01314 #define PI_SAME(name, type) \
01315   struct name { \
01316     name() : data(0) { } \
01317     name(type value) : data(value) { } \
01318     name(const name & value) : data(value.data) { } \
01319     name & operator =(type value) { data = value; return *this; } \
01320     name & operator =(const name & value) { data = value.data; return *this; } \
01321     operator type() const { return data; } \
01322     friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \
01323     friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \
01324     private: type data; \
01325   }
01326 
01327 #define PI_LOOP(src, dst) \
01328     BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \
01329     while (s != (BYTE *)&src) *d++ = *--s;
01330 
01331 #define PI_DIFF(name, type) \
01332   struct name { \
01333     name() : data(0) { } \
01334     name(type value) : data(0) { operator=(value); } \
01335     name(const name & value) : data(value.data) { } \
01336     name & operator =(type value) { PI_LOOP(value, data); return *this; } \
01337     name & operator =(const name & value) { data = value.data; return *this; } \
01338     operator type() const { type value; PI_LOOP(data, value); return value; } \
01339     friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \
01340     friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \
01341     private: type data; \
01342   }
01343 
01344 #ifndef PCHAR8
01345 #define PCHAR8 PANSI_CHAR
01346 #endif
01347 
01348 #if PCHAR8==PANSI_CHAR
01349 PI_SAME(PChar8, char);
01350 #endif
01351 
01352 PI_SAME(PInt8, signed char);
01353 
01354 PI_SAME(PUInt8, unsigned char);
01355 
01356 #if PBYTE_ORDER==PLITTLE_ENDIAN
01357 PI_SAME(PInt16l, PInt16);
01358 #elif PBYTE_ORDER==PBIG_ENDIAN
01359 PI_DIFF(PInt16l, PInt16);
01360 #endif
01361 
01362 #if PBYTE_ORDER==PLITTLE_ENDIAN
01363 PI_DIFF(PInt16b, PInt16);
01364 #elif PBYTE_ORDER==PBIG_ENDIAN
01365 PI_SAME(PInt16b, PInt16);
01366 #endif
01367 
01368 #if PBYTE_ORDER==PLITTLE_ENDIAN
01369 PI_SAME(PUInt16l, WORD);
01370 #elif PBYTE_ORDER==PBIG_ENDIAN
01371 PI_DIFF(PUInt16l, WORD);
01372 #endif
01373 
01374 #if PBYTE_ORDER==PLITTLE_ENDIAN
01375 PI_DIFF(PUInt16b, WORD);
01376 #elif PBYTE_ORDER==PBIG_ENDIAN
01377 PI_SAME(PUInt16b, WORD);
01378 #endif
01379 
01380 #if PBYTE_ORDER==PLITTLE_ENDIAN
01381 PI_SAME(PInt32l, PInt32);
01382 #elif PBYTE_ORDER==PBIG_ENDIAN
01383 PI_DIFF(PInt32l, PInt32);
01384 #endif
01385 
01386 #if PBYTE_ORDER==PLITTLE_ENDIAN
01387 PI_DIFF(PInt32b, PInt32);
01388 #elif PBYTE_ORDER==PBIG_ENDIAN
01389 PI_SAME(PInt32b, PInt32);
01390 #endif
01391 
01392 #if PBYTE_ORDER==PLITTLE_ENDIAN
01393 PI_SAME(PUInt32l, DWORD);
01394 #elif PBYTE_ORDER==PBIG_ENDIAN
01395 PI_DIFF(PUInt32l, DWORD);
01396 #endif
01397 
01398 #if PBYTE_ORDER==PLITTLE_ENDIAN
01399 PI_DIFF(PUInt32b, DWORD);
01400 #elif PBYTE_ORDER==PBIG_ENDIAN
01401 PI_SAME(PUInt32b, DWORD);
01402 #endif
01403 
01404 #if PBYTE_ORDER==PLITTLE_ENDIAN
01405 PI_SAME(PInt64l, PInt64);
01406 #elif PBYTE_ORDER==PBIG_ENDIAN
01407 PI_DIFF(PInt64l, PInt64);
01408 #endif
01409 
01410 #if PBYTE_ORDER==PLITTLE_ENDIAN
01411 PI_DIFF(PInt64b, PInt64);
01412 #elif PBYTE_ORDER==PBIG_ENDIAN
01413 PI_SAME(PInt64b, PInt64);
01414 #endif
01415 
01416 #if PBYTE_ORDER==PLITTLE_ENDIAN
01417 PI_SAME(PUInt64l, PUInt64);
01418 #elif PBYTE_ORDER==PBIG_ENDIAN
01419 PI_DIFF(PUInt64l, PUInt64);
01420 #endif
01421 
01422 #if PBYTE_ORDER==PLITTLE_ENDIAN
01423 PI_DIFF(PUInt64b, PUInt64);
01424 #elif PBYTE_ORDER==PBIG_ENDIAN
01425 PI_SAME(PUInt64b, PUInt64);
01426 #endif
01427 
01428 #if PBYTE_ORDER==PLITTLE_ENDIAN
01429 PI_SAME(PFloat32l, float);
01430 #elif PBYTE_ORDER==PBIG_ENDIAN
01431 PI_DIFF(PFloat32l, float);
01432 #endif
01433 
01434 #if PBYTE_ORDER==PLITTLE_ENDIAN
01435 PI_DIFF(PFloat32b, float);
01436 #elif PBYTE_ORDER==PBIG_ENDIAN
01437 PI_SAME(PFloat32b, float);
01438 #endif
01439 
01440 #if PBYTE_ORDER==PLITTLE_ENDIAN
01441 PI_SAME(PFloat64l, double);
01442 #elif PBYTE_ORDER==PBIG_ENDIAN
01443 PI_DIFF(PFloat64l, double);
01444 #endif
01445 
01446 #if PBYTE_ORDER==PLITTLE_ENDIAN
01447 PI_DIFF(PFloat64b, double);
01448 #elif PBYTE_ORDER==PBIG_ENDIAN
01449 PI_SAME(PFloat64b, double);
01450 #endif
01451 
01452 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
01453 #if PBYTE_ORDER==PLITTLE_ENDIAN
01454 PI_SAME(PFloat80l, long double);
01455 #elif PBYTE_ORDER==PBIG_ENDIAN
01456 PI_DIFF(PFloat80l, long double);
01457 #endif
01458 
01459 #if PBYTE_ORDER==PLITTLE_ENDIAN
01460 PI_DIFF(PFloat80b, long double);
01461 #elif PBYTE_ORDER==PBIG_ENDIAN
01462 PI_SAME(PFloat80b, long double);
01463 #endif
01464 #endif
01465 
01466 #undef PI_LOOP
01467 #undef PI_SAME
01468 #undef PI_DIFF
01469 
01470 
01472 // Miscellaneous
01473 
01474 /*$MACRO PARRAYSIZE(array)
01475    This macro is used to calculate the number of array elements in a static
01476    array.
01477  */
01478 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
01479 
01480 /*$MACRO PMIN(v1, v2)
01481    This macro is used to calculate the minimum of two values. As this is a
01482    macro the expression in #v1# or #v2# is executed
01483    twice so extreme care should be made in its use.
01484  */
01485 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
01486 
01487 /*$MACRO PMAX(v1, v2)
01488    This macro is used to calculate the maximum of two values. As this is a
01489    macro the expression in #v1# or #v2# is executed
01490    twice so extreme care should be made in its use.
01491  */
01492 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
01493 
01494 /*$MACRO PABS(val)
01495    This macro is used to calculate an absolute value. As this is a macro the
01496    expression in #val# is executed twice so extreme care should be
01497    made in its use.
01498  */
01499 #define PABS(v) ((v) < 0 ? -(v) : (v))
01500 
01501 #endif // _POBJECT_H
01502 
01503 // End Of File ///////////////////////////////////////////////////////////////

Generated on Mon Dec 10 11:18:57 2007 for PTLib by  doxygen 1.5.1