PTLib  Version 2.10.11
object.h
Go to the documentation of this file.
1 /*
2  * object.h
3  *
4  * Mother of all ancestor classes.
5  *
6  * Portable Tools Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 28201 $
30  * $Author: rjongbloed $
31  * $Date: 2012-08-14 21:30:31 -0500 (Tue, 14 Aug 2012) $
32  */
33 
34 #ifndef PTLIB_OBJECT_H
35 #define PTLIB_OBJECT_H
36 
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40 
41 #if defined(_WIN32) || defined(_WIN32_WCE)
42 #include "msos/ptlib/contain.h"
43 #else
44 #include "unix/ptlib/contain.h"
45 #endif
46 
47 #if defined(P_VXWORKS)
48 #include <private/stdiop.h>
49 #endif
50 
51 #include <stdio.h>
52 #include <stdarg.h>
53 #include <stdlib.h>
54 
55 #include <string.h>
56 
57 #include <string>
58 #include <iomanip>
59 #include <iostream>
60 #include <sstream>
61 #include <vector>
62 #include <list>
63 #include <map>
64 #include <algorithm>
65 
66 
67 #define P_REMOVE_VIRTUAL_INTERNAL_BASE(fn) __inline virtual struct ptlib_virtual_function_changed_or_removed ****** fn { return 0; }
68 
69 #if defined(_MSC_VER)
70  #if _MSC_VER < 1310
71  #define P_DEPRECATED
72  #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
73  #elif _MSC_VER < 1400
74  #define P_DEPRECATED __declspec(deprecated)
75  #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated) type fn body
76  #else
77  #define P_DEPRECATED __declspec(deprecated)
78  #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated("Virtual function signature changed or function deprecated")) type fn body
79  #endif
80 #elif defined(__GNUC__)
81  #if __GNUC__ < 4
82  #define P_DEPRECATED
83  #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
84  #else
85  #define P_DEPRECATED __attribute__((deprecated))
86  #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __attribute__((warn_unused_result)) __attribute__((deprecated)) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
87  #endif
88 #else
89  #define P_DEPRECATED
90  #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
91 #endif
92 
93 #define P_REMOVE_VIRTUAL_VOID(fn) P_REMOVE_VIRTUAL_INTERNAL(void, fn, {})
94 #define P_REMOVE_VIRTUAL(type, fn, ret) P_REMOVE_VIRTUAL_INTERNAL(type, fn, { return ret; })
95 
96 
97 // P_USE_INTEGER_BOOL is the default and gives the old behaviour (it
98 // is also used for C translation units).
99 // without P_USE_INTEGER_BOOL, the ANSI C++ bool is used.
100 
101 #if defined(P_USE_INTEGER_BOOL) || !defined(__cplusplus)
102  typedef BOOL PBoolean;
103 # define PTrue TRUE
104 # define PFalse FALSE
105 #else
106  typedef bool PBoolean;
107 # define PTrue true
108 # define PFalse false
109 #endif
110 
111 
113 // Disable inlines when debugging for faster compiles (the compiler doesn't
114 // actually inline the function with debug on any way).
115 
116 #ifndef P_USE_INLINES
117 #ifdef _DEBUG
118 #define P_USE_INLINES 0
119 #else
120 #define P_USE_INLINES 0
121 #endif
122 #endif
123 
124 #if P_USE_INLINES
125 #define PINLINE inline
126 #else
127 #define PINLINE
128 #endif
129 
130 
132 // Declare the debugging support
133 
134 #ifndef P_USE_ASSERTS
135 #define P_USE_ASSERTS 1
136 #endif
137 
138 #if !P_USE_ASSERTS
139 
140 #define PAssert(b, m) (b)
141 #define PAssert2(b, c, m) (b)
142 #define PAssertOS(b) (b)
143 #define PAssertNULL(p) (p)
144 #define PAssertAlways(m) {}
145 #define PAssertAlways2(c, m) {}
146 
147 #else // P_USE_ASSERTS
148 
165 };
166 
167 #define __CLASS__ NULL
168 
169 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg);
170 void PAssertFunc(const char * file, int line, const char * className, const char * msg);
171 void PAssertFunc(const char * full_msg);
172 
173 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, PStandardAssertMessage msg)
174 {
175  if (!b)
176  PAssertFunc(file, line, className, msg);
177  return b;
178 }
179 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, const char * msg)
180 {
181  if (!b)
182  PAssertFunc(file, line, className, msg);
183  return b;
184 }
185 
192 #define PAssert(b, msg) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(msg))
193 
201 #define PAssert2(b, cls, msg) PAssertFuncInline((b), __FILE__,__LINE__,(cls),(msg))
202 
209 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
210 
220 #define PAssertNULL(ptr) (((ptr)!=NULL)?(ptr): \
221  (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(ptr)))
222 
229 #define PAssertAlways(msg) PAssertFunc(__FILE__,__LINE__,__CLASS__,(msg))
230 
237 #define PAssertAlways2(cls, msg) PAssertFunc(__FILE__,__LINE__,(cls),(msg))
238 
239 #endif // P_USE_ASSERTS
240 
241 
246 ostream & PGetErrorStream();
247 
251 void PSetErrorStream(ostream * strm );
252 
267 #define PError (PGetErrorStream())
268 
269 
270 
272 // Debug and tracing
273 
274 #ifndef PTRACING
275 #define PTRACING 1
276 #endif
277 
278 #if PTRACING
279 
292 class PTrace
293 {
294 public:
296  enum Options {
302  Blocks = 1,
308  Thread = 8,
318  GMTTime = 256,
320  RotateDaily = 512,
322  RotateHourly = 1024,
331  };
332 
333 
347  static void Initialise(
348  unsigned level,
349  const char * filename = NULL,
350  unsigned options = Timestamp | Thread | Blocks
351  );
352 
363  static void Initialise(
364  unsigned level,
365  const char * filename,
366  const char * rolloverPattern,
367  unsigned options = Timestamp | Thread | Blocks
368  );
369 
376  static void SetOptions(
377  unsigned options
378  );
379 
388  static void ClearOptions(
389  unsigned options
390  );
391 
397  static unsigned GetOptions();
398 
404  static void SetLevel(
405  unsigned level
406  );
407 
413  static unsigned GetLevel();
414 
419  static PBoolean CanTrace(
420  unsigned level
421  );
422 
427  static void SetStream(
428  ostream * out
429  );
430 
446  static ostream & Begin(
447  unsigned level,
448  const char * fileName,
449  int lineNum
450  );
451 
469  static ostream & End(
470  ostream & strm
471  );
472 
476  static void Cleanup();
477 
483  class Block {
484  public:
486  Block(
487  const char * fileName,
488  int lineNum,
489  const char * traceName
491  );
492  Block(const Block & obj)
493  : file(obj.file), line(obj.line), name(obj.name) { }
495  ~Block();
496  private:
497  Block & operator=(const Block &)
498  { return *this; }
499  const char * file;
500  int line;
501  const char * name;
502  };
503 };
504 
505 /* Macro to conditionally declare a parameter to a function to avoid compiler
506  warning due that parameter only being used in a <code>PTRACE()</code> */
507 #define PTRACE_PARAM(param) param
508 
515 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
516 
520 #define PTRACE_LINE() \
521  if (PTrace::CanTrace(1)) \
522  PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End; \
523  else (void)0
524 
530 #define PTRACE(level, args) \
531  if (PTrace::CanTrace(level)) \
532  PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
533  else (void)0
534 
542 #define PTRACE_IF(level, cond, args) \
543  if ((PTrace::CanTrace(level) && (cond))) \
544  PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
545  else (void)0
546 
547 #else // PTRACING
548 
549 #define PTRACE_PARAM(param)
550 #define PTRACE_BLOCK(n)
551 #define PTRACE_LINE()
552 #define PTRACE(level, arg)
553 #define PTRACE_IF(level, cond, args)
554 
555 #endif // PTRACING
556 
557 
558 
559 #if PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG) && !defined(_WIN32_WCE))
560 
561 #define PMEMORY_HEAP 1
562 
569 class PMemoryHeap {
570  public:
572  PMemoryHeap();
573 
574  // Clear up the memory checking subsystem, dumping memory leaks.
575  ~PMemoryHeap();
576 
583  static void * Allocate(
584  size_t nSize,
585  const char * file,
586  int line,
587  const char * className
588  );
595  static void * Allocate(
596  size_t count,
597  size_t iSize,
598  const char * file,
599  int line
600  );
601 
609  static void * Reallocate(
610  void * ptr,
611  size_t nSize,
612  const char * file,
613  int line
614  );
615 
621  static void Deallocate(
622  void * ptr,
623  const char * className
624  );
625 
628  enum Validation {
629  Ok, Bad, Trashed
630  };
638  static Validation Validate(
639  const void * ptr,
640  const char * className,
641  ostream * error
642  );
643 
648  static PBoolean ValidateHeap(
649  ostream * error = NULL
650  );
651 
657  static PBoolean SetIgnoreAllocations(
658  PBoolean ignore
659  );
660 
664  static void DumpStatistics();
668  static void DumpStatistics(ostream & strm );
669 
670 #if PMEMORY_CHECK
671  struct State {
673  };
674 #else
675  typedef _CrtMemState State;
676 #endif
677 
678  /* Get memory state.
679  This returns a state that may be used to determine where to start dumping
680  objects from.
681  */
682  static void GetState(
683  State & state
684  );
685 
693  static void DumpObjectsSince(
694  const State & when
695  );
696 
702  static void DumpObjectsSince(
703  const State & when,
704  ostream & strm
705  );
706 
712  static void SetAllocationBreakpoint(
713  DWORD point
714  );
715 
716 #if PMEMORY_CHECK
717 
718  protected:
719  void * InternalAllocate(
720  size_t nSize, // Number of bytes to allocate.
721  const char * file, // Source file name for allocating function.
722  int line, // Source file line for allocating function.
723  const char * className // Class name for allocating function.
724  );
725  Validation InternalValidate(
726  const void * ptr, // Pointer to memory block to check
727  const char * className, // Class name it should be.
728  ostream * error // Stream to receive error message (may be NULL)
729  );
730  void InternalDumpStatistics(ostream & strm);
731  void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
732 
733  class Wrapper {
734  public:
735  Wrapper();
736  ~Wrapper();
737  PMemoryHeap * operator->() const { return instance; }
738  private:
739  PMemoryHeap * instance;
740  };
741  friend class Wrapper;
742 
743  enum Flags {
744  NoLeakPrint = 1
745  };
746 
747 #pragma pack(1)
748  struct Header {
749  enum {
750  // Assure that the Header struct is aligned to 8 byte boundary
751  NumGuardBytes = 16 - (sizeof(Header *) +
752  sizeof(Header *) +
753  sizeof(const char *) +
754  sizeof(const char *) +
755  sizeof(size_t) +
756  sizeof(DWORD) +
757  sizeof(WORD) +
758  sizeof(BYTE)
759 #if P_PTHREADS
760  + sizeof(pthread_t)
761 #endif
762  )%8
763  };
764 
767  const char * className;
768  const char * fileName;
769  size_t size;
770  DWORD request;
771  WORD line;
772  BYTE flags;
773 #if P_PTHREADS
774  pthread_t thread;
775 #endif
776  char guard[NumGuardBytes];
777 
778  static char GuardBytes[NumGuardBytes];
779  };
780 #pragma pack()
781 
783 
786 
787  static DWORD allocationBreakpoint;
790  BYTE flags;
791 
794 
798  DWORD peakObjects;
800 
801  ostream * leakDumpStream;
802 
803 #if defined(_WIN32)
804  CRITICAL_SECTION mutex;
805 #elif defined(P_PTHREADS)
806  pthread_mutex_t mutex;
807 #elif defined(P_VXWORKS)
808  void * mutex;
809 #endif
810 
811 #else
812 
813 #define P_CLIENT_BLOCK (_CLIENT_BLOCK|(0x61<<16)) // This identifies a PObject derived class
814  _CrtMemState initialState;
815 
816 #endif // PMEMORY_CHECK
817 };
818 
819 
824 inline void * runtime_malloc(size_t bytes ) { return malloc(bytes); }
825 
830 inline void runtime_free(void * ptr ) { free(ptr); }
831 
832 
839 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
840 
847 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
848 
855 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
856 
857 
864 #define free(p) PMemoryHeap::Deallocate(p, NULL)
865 
866 
873 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
874 
875 
890 #define PNEW new (__FILE__, __LINE__)
891 
892 #if !defined(_MSC_VER) || _MSC_VER<1200
893 #define PSPECIAL_DELETE_FUNCTION
894 #else
895 #define PSPECIAL_DELETE_FUNCTION \
896  void operator delete(void * ptr, const char *, int) \
897  { PMemoryHeap::Deallocate(ptr, Class()); } \
898  void operator delete[](void * ptr, const char *, int) \
899  { PMemoryHeap::Deallocate(ptr, Class()); }
900 #endif
901 
902 #define PNEW_AND_DELETE_FUNCTIONS \
903  void * operator new(size_t nSize, const char * file, int line) \
904  { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
905  void * operator new(size_t nSize) \
906  { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
907  void operator delete(void * ptr) \
908  { PMemoryHeap::Deallocate(ptr, Class()); } \
909  void * operator new(size_t, void * placement) \
910  { return placement; } \
911  void operator delete(void *, void *) \
912  { } \
913  void * operator new[](size_t nSize, const char * file, int line) \
914  { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
915  void * operator new[](size_t nSize) \
916  { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
917  void operator delete[](void * ptr) \
918  { PMemoryHeap::Deallocate(ptr, Class()); } \
919  PSPECIAL_DELETE_FUNCTION
920 
921 
922 inline void * operator new(size_t nSize, const char * file, int line)
923  { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
924 
925 inline void * operator new[](size_t nSize, const char * file, int line)
926  { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
927 
928 #ifndef __GNUC__
929 void * operator new(size_t nSize);
930 void * operator new[](size_t nSize);
931 
932 void operator delete(void * ptr);
933 void operator delete[](void * ptr);
934 
935 #if defined(_MSC_VER) && _MSC_VER>=1200
936 inline void operator delete(void * ptr, const char *, int)
937  { PMemoryHeap::Deallocate(ptr, NULL); }
938 
939 inline void operator delete[](void * ptr, const char *, int)
940  { PMemoryHeap::Deallocate(ptr, NULL); }
941 #endif
942 #endif
943 
944 
946 public:
947  PMemoryHeapIgnoreAllocationsForScope() : previousIgnoreAllocations(PMemoryHeap::SetIgnoreAllocations(true)) { }
949 private:
950  PBoolean previousIgnoreAllocations;
951 };
952 
953 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE PMemoryHeapIgnoreAllocationsForScope instance_PMemoryHeapIgnoreAllocationsForScope
954 
956 public:
958  {
960  }
961 };
962 
963 #define PMEMORY_ALLOCATION_BREAKPOINT(point) PMemoryAllocationBreakpoint PMemoryAllocationBreakpointInstance(point)
964 
965 
966 #else // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
967 
968 #define PMEMORY_HEAP 0
969 
970 #define PNEW new
971 
972 #define PNEW_AND_DELETE_FUNCTIONS
973 
974 #define runtime_malloc(s) malloc(s)
975 #define runtime_free(p) free(p)
976 
977 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE
978 #define PMEMORY_ALLOCATION_BREAKPOINT(point)
979 
980 #endif // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
981 
982 
983 
984 /*
985  * Implement "construct on first use" paradigm
986  */
987 
988 template <class GnuAllocator, class Type>
990 {
991  Type * allocate(size_t v)
992  {
993  return GetAllocator().allocate(v);
994  }
995 
996  void deallocate(Type * p, size_t v)
997  {
998  GetAllocator().deallocate(p, v);
999  }
1000 
1001  private:
1002  static GnuAllocator & GetAllocator()
1003  {
1004  static GnuAllocator instance;
1005  return instance;
1006  }
1007 };
1008 
1009 #define GCC_VERSION (__GNUC__ * 10000 \
1010  + __GNUC_MINOR__ * 100 \
1011  + __GNUC_PATCHLEVEL__)
1012 
1013 // Memory pooling allocators
1014 #if defined(__GNUC__) && (GCC_VERSION > 40000) && !defined(P_MINGW) && !defined(P_MACOSX)
1015 #include <ext/mt_allocator.h>
1016 template <class Type> struct PFixedPoolAllocator : public PAllocatorTemplate<__gnu_cxx::__mt_alloc<Type>, Type> { };
1017 template <class Type> struct PVariablePoolAllocator : public PAllocatorTemplate<__gnu_cxx::__mt_alloc<Type>, Type> { };
1018 
1019 #else
1020 
1021 template <class Type> struct PFixedPoolAllocator : public PAllocatorTemplate<std::allocator<Type>, Type> { };
1022 template <class Type> struct PVariablePoolAllocator : public PAllocatorTemplate<std::allocator<Type>, Type> { };
1023 #endif
1024 
1025 #define PDECLARE_POOL_ALLOCATOR() \
1026  void * operator new(size_t nSize); \
1027  void * operator new(size_t nSize, const char * file, int line); \
1028  void operator delete(void * ptr); \
1029  void operator delete(void * ptr, const char *, int)
1030 
1031 #define PDEFINE_POOL_ALLOCATOR(cls) \
1032  static PFixedPoolAllocator<cls> cls##_allocator; \
1033  void * cls::operator new(size_t) { return cls##_allocator.allocate(1); } \
1034  void * cls::operator new(size_t, const char *, int) { return cls##_allocator.allocate(1); } \
1035  void cls::operator delete(void * ptr) { cls##_allocator.deallocate((cls *)ptr, 1); } \
1036  void cls::operator delete(void * ptr, const char *, int) { cls##_allocator.deallocate((cls *)ptr, 1); }
1037 
1038 
1049 #define PCLASSINFO(cls, par) \
1050  public: \
1051  typedef cls P_thisClass; \
1052  static inline const char * Class() \
1053  { return #cls; } \
1054  virtual PBoolean InternalIsDescendant(const char * clsName) const \
1055  { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
1056  virtual const char * GetClass(unsigned ancestor = 0) const \
1057  { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
1058  virtual PObject::Comparison CompareObjectMemoryDirect(const PObject & obj) const \
1059  { return PObject::InternalCompareObjectMemoryDirect(this, dynamic_cast<const cls *>(&obj), sizeof(cls)); } \
1060  PNEW_AND_DELETE_FUNCTIONS
1061 
1062 
1063 #if P_HAS_TYPEINFO
1064 
1065 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
1066 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
1067 
1068 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
1069 
1070 #if P_USE_ASSERTS
1071 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line)
1072  { if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; }
1073 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
1074 #else
1075 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
1076 #endif
1077 
1078 #include <typeinfo>
1079 
1080 #else // P_HAS_TYPEINFO
1081 
1082 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class()))
1083 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
1084 
1085 #define PRemoveConst(cls, ptr) ((cls*)(ptr))
1086 
1087 #if P_USE_ASSERTS
1088 template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line)
1089  { if (obj->InternalIsDescendant(BaseClass::Class())) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; }
1090 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
1091 #else
1092 #define PDownCast(cls, ptr) ((cls*)(ptr))
1093 #endif
1094 
1095 #endif // P_HAS_TYPEINFO
1096 
1097 
1106 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
1107 #ifdef DOC_PLUS_PLUS
1108 } Match previous opening brace in doc++
1109 #endif
1110 
1112 // The root of all evil ... umm classes
1113 
1118 class PObject {
1119 
1120  protected:
1124  PObject() { }
1125 
1126  public:
1127  /* Destructor required to get the "virtual". A PObject really has nothing
1128  to destroy.
1129  */
1130  virtual ~PObject() { }
1131 
1144  static inline const char * Class() { return "PObject"; }
1145 
1158  virtual const char * GetClass(unsigned ancestor = 0) const { return ancestor > 0 ? "" : Class(); }
1159 
1160  PBoolean IsClass(const char * cls) const
1161  { return strcmp(cls, GetClass()) == 0; }
1162 
1173  const char * clsName // Ancestor class name to compare against.
1174  ) const
1175  { return IsClass(clsName); }
1176 
1178 
1184  enum Comparison {
1185  LessThan = -1,
1186  EqualTo = 0,
1187  GreaterThan = 1
1188  };
1189 
1201  virtual Comparison Compare(
1202  const PObject & obj // Object to compare against.
1203  ) const;
1204 
1216  virtual Comparison CompareObjectMemoryDirect(
1217  const PObject & obj // Object to compare against.
1218  ) const;
1219 
1221  static Comparison InternalCompareObjectMemoryDirect(
1222  const PObject * obj1,
1223  const PObject * obj2,
1224  PINDEX size
1225  );
1226 
1233  const PObject & obj // Object to compare against.
1234  ) const { return Compare(obj) == EqualTo; }
1235 
1242  const PObject & obj // Object to compare against.
1243  ) const { return Compare(obj) != EqualTo; }
1244 
1251  const PObject & obj // Object to compare against.
1252  ) const { return Compare(obj) == LessThan; }
1253 
1260  const PObject & obj // Object to compare against.
1261  ) const { return Compare(obj) == GreaterThan; }
1262 
1269  const PObject & obj // Object to compare against.
1270  ) const { return Compare(obj) != GreaterThan; }
1271 
1278  const PObject & obj // Object to compare against.
1279  ) const { return Compare(obj) != LessThan; }
1281 
1290  virtual void PrintOn(
1291  ostream &strm // Stream to print the object into.
1292  ) const;
1293 
1300  virtual void ReadFrom(
1301  istream &strm // Stream to read the objects contents from.
1302  );
1303 
1304 
1310  inline friend ostream & operator<<(
1311  ostream &strm,
1312  const PObject & obj
1313  ) { obj.PrintOn(strm); return strm; }
1314 
1320  inline friend istream & operator>>(
1321  istream &strm,
1322  PObject & obj
1323  ) { obj.ReadFrom(strm); return strm; }
1324 
1325 
1340  virtual PObject * Clone() const;
1341 
1353  virtual PINDEX HashFunction() const;
1355 };
1356 
1358 // Platform independent types
1359 
1360 // All these classes encapsulate primitive types such that they may be
1361 // transfered in a platform independent manner. In particular it is used to
1362 // do byte swapping for little endien and big endien processor architectures
1363 // as well as accommodating structure packing rules for memory structures.
1364 
1365 #define PANSI_CHAR 1
1366 #define PLITTLE_ENDIAN 2
1367 #define PBIG_ENDIAN 3
1368 
1369 
1370 template <typename type>
1372  __inline PIntSameOrder() : data(0) { }
1373  __inline PIntSameOrder(type value) : data(value) { }
1374  __inline PIntSameOrder(const PIntSameOrder & value) : data(value.data) { }
1375  __inline PIntSameOrder & operator=(type value) { data = value; return *this; }
1376  __inline PIntSameOrder & operator=(const PIntSameOrder & value) { data = value.data; return *this; }
1377  __inline operator type() const { return data; }
1378  __inline friend ostream & operator<<(ostream & s, const PIntSameOrder & v) { return s << v.data; }
1379  __inline friend istream & operator>>(istream & s, PIntSameOrder & v) { return s >> v.data; }
1380 
1381  private:
1382  type data;
1383 };
1384 
1385 
1386 template <typename type>
1388  __inline PIntReversedOrder() : data(0) { }
1389  __inline PIntReversedOrder(type value) { ReverseBytes(value, data); }
1390  __inline PIntReversedOrder(const PIntReversedOrder & value) : data(value.data) { }
1391  __inline PIntReversedOrder & operator=(type value) { ReverseBytes(value, data); return *this; }
1392  __inline PIntReversedOrder & operator=(const PIntReversedOrder & value) { data = value.data; return *this; }
1393  __inline operator type() const { type value; ReverseBytes(data, value); return value; }
1394  __inline friend ostream & operator<<(ostream & s, const PIntReversedOrder & value) { return s << (type)value; }
1395  __inline friend istream & operator>>(istream & s, PIntReversedOrder & v) { type val; s >> val; v = val; return s; }
1396 
1397  private:
1398  type data;
1399 
1400  static __inline void ReverseBytes(const type & src, type & dst)
1401  {
1402  size_t s = sizeof(type)-1;
1403  for (size_t d = 0; d < sizeof(type); ++d,--s)
1404  ((BYTE *)&dst)[d] = ((const BYTE *)&src)[s];
1405  }
1406 };
1407 
1408 #ifndef PCHAR8
1409 #define PCHAR8 PANSI_CHAR
1410 #endif
1411 
1412 #if PCHAR8==PANSI_CHAR
1414 #endif
1415 
1417 
1419 
1420 #if PBYTE_ORDER==PLITTLE_ENDIAN
1421 typedef PIntSameOrder<PInt16> PInt16l;
1422 #elif PBYTE_ORDER==PBIG_ENDIAN
1423 typedef PIntReversedOrder<PInt16> PInt16l;
1424 #endif
1425 
1426 #if PBYTE_ORDER==PLITTLE_ENDIAN
1427 typedef PIntReversedOrder<PInt16> PInt16b;
1428 #elif PBYTE_ORDER==PBIG_ENDIAN
1429 typedef PIntSameOrder<PInt16> PInt16b;
1430 #endif
1431 
1432 #if PBYTE_ORDER==PLITTLE_ENDIAN
1433 typedef PIntSameOrder<WORD> PUInt16l;
1434 #elif PBYTE_ORDER==PBIG_ENDIAN
1435 typedef PIntReversedOrder<WORD> PUInt16l;
1436 #endif
1437 
1438 #if PBYTE_ORDER==PLITTLE_ENDIAN
1439 typedef PIntReversedOrder<WORD> PUInt16b;
1440 #elif PBYTE_ORDER==PBIG_ENDIAN
1441 typedef PIntSameOrder<WORD> PUInt16b;
1442 #endif
1443 
1444 #if PBYTE_ORDER==PLITTLE_ENDIAN
1445 typedef PIntSameOrder<PInt32> PInt32l;
1446 #elif PBYTE_ORDER==PBIG_ENDIAN
1447 typedef PIntReversedOrder<PInt32> PInt32l;
1448 #endif
1449 
1450 #if PBYTE_ORDER==PLITTLE_ENDIAN
1451 typedef PIntReversedOrder<PInt32> PInt32b;
1452 #elif PBYTE_ORDER==PBIG_ENDIAN
1453 typedef PIntSameOrder<PInt32> PInt32b;
1454 #endif
1455 
1456 #if PBYTE_ORDER==PLITTLE_ENDIAN
1457 typedef PIntSameOrder<DWORD> PUInt32l;
1458 #elif PBYTE_ORDER==PBIG_ENDIAN
1459 typedef PIntReversedOrder<DWORD> PUInt32l;
1460 #endif
1461 
1462 #if PBYTE_ORDER==PLITTLE_ENDIAN
1463 typedef PIntReversedOrder<DWORD> PUInt32b;
1464 #elif PBYTE_ORDER==PBIG_ENDIAN
1465 typedef PIntSameOrder<DWORD> PUInt32b;
1466 #endif
1467 
1468 #if PBYTE_ORDER==PLITTLE_ENDIAN
1469 typedef PIntSameOrder<PInt64> PInt64l;
1470 #elif PBYTE_ORDER==PBIG_ENDIAN
1471 typedef PIntReversedOrder<PInt64> PInt64l;
1472 #endif
1473 
1474 #if PBYTE_ORDER==PLITTLE_ENDIAN
1475 typedef PIntReversedOrder<PInt64> PInt64b;
1476 #elif PBYTE_ORDER==PBIG_ENDIAN
1477 typedef PIntSameOrder<PInt64> PInt64b;
1478 #endif
1479 
1480 #if PBYTE_ORDER==PLITTLE_ENDIAN
1481 typedef PIntSameOrder<PUInt64> PUInt64l;
1482 #elif PBYTE_ORDER==PBIG_ENDIAN
1483 typedef PIntReversedOrder<PUInt64> PUInt64l;
1484 #endif
1485 
1486 #if PBYTE_ORDER==PLITTLE_ENDIAN
1487 typedef PIntReversedOrder<PUInt64> PUInt64b;
1488 #elif PBYTE_ORDER==PBIG_ENDIAN
1489 typedef PIntSameOrder<PUInt64> PUInt64b;
1490 #endif
1491 
1492 #if PBYTE_ORDER==PLITTLE_ENDIAN
1493 typedef PIntSameOrder<float> PFloat32l;
1494 #elif PBYTE_ORDER==PBIG_ENDIAN
1495 typedef PIntReversedOrder<float> PFloat32l;
1496 #endif
1497 
1498 #if PBYTE_ORDER==PLITTLE_ENDIAN
1499 typedef PIntReversedOrder<float> PFloat32b;
1500 #elif PBYTE_ORDER==PBIG_ENDIAN
1501 typedef PIntSameOrder<float> PFloat32b;
1502 #endif
1503 
1504 #if PBYTE_ORDER==PLITTLE_ENDIAN
1505 typedef PIntSameOrder<double> PFloat64l;
1506 #elif PBYTE_ORDER==PBIG_ENDIAN
1507 typedef PIntReversedOrder<double> PFloat64l;
1508 #endif
1509 
1510 #if PBYTE_ORDER==PLITTLE_ENDIAN
1511 typedef PIntReversedOrder<double> PFloat64b;
1512 #elif PBYTE_ORDER==PBIG_ENDIAN
1513 typedef PIntSameOrder<double> PFloat64b;
1514 #endif
1515 
1516 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
1517 #if PBYTE_ORDER==PLITTLE_ENDIAN
1518 typedef PIntSameOrder<long double> PFloat80l;
1519 #elif PBYTE_ORDER==PBIG_ENDIAN
1520 typedef PIntReversedOrder<long double> PFloat80l;
1521 #endif
1522 
1523 #if PBYTE_ORDER==PLITTLE_ENDIAN
1524 typedef PIntReversedOrder<long double> PFloat80b;
1525 #elif PBYTE_ORDER==PBIG_ENDIAN
1526 typedef PIntSameOrder<long double> PFloat80b;
1527 #endif
1528 #endif
1529 
1530 
1532 // Miscellaneous
1533 
1534 /*$MACRO PARRAYSIZE(array)
1535  This macro is used to calculate the number of array elements in a static
1536  array.
1537  */
1538 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
1539 
1540 /*$MACRO PMIN(v1, v2)
1541  This macro is used to calculate the minimum of two values. As this is a
1542  macro the expression in <code>v1</code> or <code>v2</code> is executed
1543  twice so extreme care should be made in its use.
1544  */
1545 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
1546 
1547 /*$MACRO PMAX(v1, v2)
1548  This macro is used to calculate the maximum of two values. As this is a
1549  macro the expression in <code>v1</code> or <code>v2</code> is executed
1550  twice so extreme care should be made in its use.
1551  */
1552 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
1553 
1554 /*$MACRO PABS(val)
1555  This macro is used to calculate an absolute value. As this is a macro the
1556  expression in <code>val</code> is executed twice so extreme care should be
1557  made in its use.
1558  */
1559 #define PABS(v) ((v) < 0 ? -(v) : (v))
1560 
1561 
1562 #endif // PTLIB_OBJECT_H
1563 
1564 
1565 // End Of File ///////////////////////////////////////////////////////////////
Options
Options for trace output.
Definition: object.h:296
Memory heap checking class.
Definition: object.h:569
PIntSameOrder< unsigned char > PUInt8
Definition: object.h:1418
Include date and time in all output.
Definition: object.h:304
static void Deallocate(void *ptr, const char *className)
Free a memory block.
DWORD currentObjects
Definition: object.h:797
PBoolean IsClass(const char *cls) const
Definition: object.h:1160
__inline PIntReversedOrder & operator=(const PIntReversedOrder &value)
Definition: object.h:1392
BYTE flags
Definition: object.h:790
virtual void PrintOn(ostream &strm) const
Print the array.
static unsigned GetLevel()
Get the trace level.
Class to encapsulate tracing functions.
Definition: object.h:292
__inline friend ostream & operator<<(ostream &s, const PIntSameOrder &v)
Definition: object.h:1378
Definition: object.h:1387
static void * Allocate(size_t nSize, const char *file, int line, const char *className)
Allocate a memory block.
Number of standard assert message.
Definition: object.h:164
__inline PIntSameOrder & operator=(type value)
Definition: object.h:1375
DWORD firstRealObject
Definition: object.h:789
PMemoryHeapIgnoreAllocationsForScope()
Definition: object.h:947
DWORD currentMemoryUsage
Definition: object.h:795
static void SetAllocationBreakpoint(DWORD point)
Set break point allocation number.
static PBoolean SetIgnoreAllocations(PBoolean ignore)
Ignore/Monitor allocations.
Flags
Definition: object.h:743
__inline friend ostream & operator<<(ostream &s, const PIntReversedOrder &value)
Definition: object.h:1394
__inline PIntSameOrder & operator=(const PIntSameOrder &value)
Definition: object.h:1376
Comparison
Result of the comparison operation performed by the Compare() function.
Definition: object.h:1184
ostream * leakDumpStream
Definition: object.h:801
PMemoryHeap * operator->() const
Definition: object.h:737
PStandardAssertMessage
Standard assert messages for the PAssert macro.
Definition: object.h:150
A new or malloc failed.
Definition: object.h:152
__inline friend istream & operator>>(istream &s, PIntSameOrder &v)
Definition: object.h:1379
A Pop() was made of a stack with no elements.
Definition: object.h:157
DWORD peakMemoryUsage
Definition: object.h:796
ostream & PGetErrorStream()
Get the stream being used for error output.
Definition: object.h:1022
static void Initialise(unsigned level, const char *filename=NULL, unsigned options=Timestamp|Thread|Blocks)
Set the most common trace options.
DWORD allocationRequest
Definition: object.h:788
static void SetOptions(unsigned options)
Set the trace options.
PBoolean isDestroyed
Definition: object.h:782
bool operator!=(const PObject &obj) const
Compare the two objects.
Definition: object.h:1241
void runtime_free(void *ptr)
Free memory allocated by run time library.
Definition: object.h:830
static ostream & End(ostream &strm)
End a trace output.
char freeFillChar
Definition: object.h:793
BaseClass * PAssertCast(BaseClass *obj, const char *file, int line)
Definition: object.h:1071
virtual void ReadFrom(istream &strm)
Input the contents of the object from the stream.
An index into an array was negative.
Definition: object.h:155
const char * fileName
Definition: object.h:768
A reference was made through a NULL pointer.
Definition: object.h:153
bool PAssertFuncInline(bool b, const char *file, int line, const char *className, PStandardAssertMessage msg)
Definition: object.h:173
static DWORD allocationBreakpoint
Definition: object.h:787
virtual ~PObject()
Definition: object.h:1130
__inline PIntReversedOrder()
Definition: object.h:1388
PIntSameOrder< char > PChar8
Definition: object.h:1413
Operation attempted when channel not open.
Definition: object.h:161
Definition: object.h:1371
PObject()
Constructor for PObject, made protected so cannot ever create one on its own.
Definition: object.h:1124
void * runtime_malloc(size_t bytes)
Allocate memory for the run time library.
Definition: object.h:824
BOOL PBoolean
Definition: object.h:102
Definition: object.h:989
Access through invalid window.
Definition: object.h:163
Include PTrace::Block constructs in output If this is bit is clear, all PTrace::Block output is inhib...
Definition: object.h:302
Definition: object.h:945
Definition: object.h:955
Definition: object.h:748
DWORD peakObjects
Definition: object.h:798
If set, log file will be rotated hourly.
Definition: object.h:322
virtual const char * GetClass(unsigned ancestor=0) const
Get the current dynamic type of the object instance.
Definition: object.h:1158
static ostream & Begin(unsigned level, const char *fileName, int lineNum)
Begin a trace output.
#define free(p)
Override of system call for memory check system.
Definition: object.h:864
static void ClearOptions(unsigned options)
Clear the trace options.
__inline PIntReversedOrder(const PIntReversedOrder &value)
Definition: object.h:1390
friend ostream & operator<<(ostream &strm, const PObject &obj)
Global function for using the standard << operator on objects descended from PObject.
Definition: object.h:1310
static void Cleanup()
Cleanup the trace system for a specific thread When using thread local storage, this will delete the ...
const char * className
Definition: object.h:767
__inline PIntSameOrder(type value)
Definition: object.h:1373
bool operator==(const PObject &obj) const
Compare the two objects.
Definition: object.h:1232
__inline friend istream & operator>>(istream &s, PIntReversedOrder &v)
Definition: object.h:1395
bool operator<(const PObject &obj) const
Compare the two objects.
Definition: object.h:1250
__inline PIntReversedOrder & operator=(type value)
Definition: object.h:1391
void deallocate(Type *p, size_t v)
Definition: object.h:996
WORD line
Definition: object.h:771
Block(const Block &obj)
Definition: object.h:492
Definition: object.h:733
If set, log file will be rotated daily.
Definition: object.h:320
Feature is not supported.
Definition: object.h:162
~Block()
Output exit trace message.
bool operator<=(const PObject &obj) const
Compare the two objects.
Definition: object.h:1268
size_t size
Definition: object.h:769
bool operator>=(const PObject &obj) const
Compare the two objects.
Definition: object.h:1277
BYTE flags
Definition: object.h:772
Header * listHead
Definition: object.h:784
Include (millisecond) timestamp in all output.
Definition: object.h:306
An invalid cast to descendant is required.
Definition: object.h:154
Include the file and line for the trace call in all output.
Definition: object.h:312
char allocFillChar
Definition: object.h:792
#define malloc(s)
Override of system call for memory check system.
Definition: object.h:839
Append to log file rather than resetting every time.
Definition: object.h:316
Include thread object pointer address in all trace output.
Definition: object.h:314
Header * listTail
Definition: object.h:785
friend istream & operator>>(istream &strm, PObject &obj)
Global function for using the standard >> operator on objects descended from PObject.
Definition: object.h:1320
static unsigned GetOptions()
Get the current trace options.
Error was returned by Operating System.
Definition: object.h:160
~PMemoryHeapIgnoreAllocationsForScope()
Definition: object.h:948
__inline PIntSameOrder(const PIntSameOrder &value)
Definition: object.h:1374
Invalid parameter was passed to a function.
Definition: object.h:159
Funtion is not implemented.
Definition: object.h:158
Include identifier for thread trace is made from in all output.
Definition: object.h:308
Type * allocate(size_t v)
Definition: object.h:991
DWORD allocationNumber
Definition: object.h:672
Block(const char *fileName, int lineNum, const char *traceName)
Output entry trace message.
Include trace level in all output.
Definition: object.h:310
void PSetErrorStream(ostream *strm)
Set the stream to be used for error output.
Definition: object.h:1021
SystemLog flag for tracing within a PServiceProcess application.
Definition: object.h:330
A NULL array element object was accessed.
Definition: object.h:156
void PAssertFunc(const char *file, int line, const char *className, PStandardAssertMessage msg)
__inline PIntSameOrder()
Definition: object.h:1372
virtual PBoolean InternalIsDescendant(const char *clsName) const
Determine if the dynamic type of the current instance is a descendent of the specified class...
Definition: object.h:1172
__inline PIntReversedOrder(type value)
Definition: object.h:1389
PIntSameOrder< char > PInt8
Definition: object.h:1416
Class to trace Execution blocks.
Definition: object.h:483
bool operator>(const PObject &obj) const
Compare the two objects.
Definition: object.h:1259
static void SetLevel(unsigned level)
Set the trace level.
PMemoryAllocationBreakpoint(DWORD point)
Definition: object.h:957
Header * next
Definition: object.h:766
static void SetStream(ostream *out)
Set the stream to be used for trace output.
static const char * Class()
Get the name of the class as a C string.
Definition: object.h:1144
Ultimate parent class for all objects in the class library.
Definition: object.h:1118
Header * prev
Definition: object.h:765
A logic error occurred.
Definition: object.h:151
virtual void PrintOn(ostream &strm) const
Output the contents of the object to the stream.
Output timestamps in GMT time rather than local time.
Definition: object.h:318
Definition: object.h:671
Mask for all the rotate bits.
Definition: object.h:326
Validation
Validation result.
Definition: object.h:628
If set, log file will be rotated every minute.
Definition: object.h:324
virtual void ReadFrom(istream &strm)
Read the array.
static PBoolean CanTrace(unsigned level)
Determine if the level may cause trace output.
DWORD request
Definition: object.h:770
DWORD totalObjects
Definition: object.h:799