Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

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 * $Log: object.h,v $ 00030 * Revision 1.108 2004/07/11 07:56:35 csoutheren 00031 * Applied jumbo VxWorks patch, thanks to Eize Slange 00032 * 00033 * Revision 1.107 2004/07/03 06:49:49 rjongbloed 00034 * Added PTRACE_PARAM() macro to fix warnings on parameters used in PTRACE 00035 * macros only. 00036 * 00037 * Revision 1.106 2004/06/01 07:42:19 csoutheren 00038 * Restored memory allocation checking 00039 * Added configure flag to enable, thanks to Derek Smithies 00040 * 00041 * Revision 1.105 2004/06/01 05:22:43 csoutheren 00042 * Restored memory check functionality 00043 * 00044 * Revision 1.104 2004/05/12 04:36:17 csoutheren 00045 * Fixed problems with using sem_wait and friends on systems that do not 00046 * support atomic integers 00047 * 00048 * Revision 1.103 2004/04/18 04:33:36 rjongbloed 00049 * Changed all operators that return BOOL to return standard type bool. This is primarily 00050 * for improved compatibility with std STL usage removing many warnings. 00051 * 00052 * Revision 1.102 2004/04/11 13:26:25 csoutheren 00053 * Removed namespace problems and removed warnings for Windows <string> 00054 * 00055 * Revision 1.101 2004/04/11 03:20:41 csoutheren 00056 * Added Unix implementation of PCriticalSection 00057 * 00058 * Revision 1.100 2004/04/11 02:55:17 csoutheren 00059 * Added PCriticalSection for Windows 00060 * Added compile time option for PContainer to use critical sections to provide thread safety under some circumstances 00061 * 00062 * Revision 1.99 2004/04/09 11:54:46 csoutheren 00063 * Added configure.in check for STL streams, and tested with gcc 2.95.3, 00064 * gcc 3.3.1, and gcc 3.3.3 00065 * 00066 * Revision 1.98 2004/04/09 07:53:51 rjongbloed 00067 * Fixed backward compatibility after STL streams change 00068 * 00069 * Revision 1.97 2004/04/09 00:56:35 csoutheren 00070 * Fixed problem with new class name code 00071 * 00072 * Revision 1.96 2004/04/09 00:42:58 csoutheren 00073 * Changed Unix build to use slightly different method for 00074 * keep class names, as GCC does not use actual class names for typeinfo 00075 * 00076 * Revision 1.95 2004/04/04 13:24:18 rjongbloed 00077 * Changes to support native C++ Run Time Type Information 00078 * 00079 * Revision 1.94 2004/04/03 08:57:31 csoutheren 00080 * Replaced pseudo-RTTI with real RTTI 00081 * 00082 * Revision 1.93 2004/04/03 08:22:20 csoutheren 00083 * Remove pseudo-RTTI and replaced with real RTTI 00084 * 00085 * Revision 1.92 2004/04/03 07:41:00 csoutheren 00086 * Fixed compile problem with ostringstream/ostrstream 00087 * 00088 * Revision 1.91 2004/04/03 07:16:05 rjongbloed 00089 * Fixed backward compatibility with MSVC 6 00090 * 00091 * Revision 1.90 2004/04/03 06:54:22 rjongbloed 00092 * Many and various changes to support new Visual C++ 2003 00093 * 00094 * Revision 1.89 2003/09/17 09:00:59 csoutheren 00095 * Moved PSmartPointer and PNotifier into seperate files 00096 * Added detection for system regex libraries on all platforms 00097 * 00098 * Revision 1.88 2003/09/17 05:41:58 csoutheren 00099 * Removed recursive includes 00100 * 00101 * Revision 1.87 2003/09/17 01:18:02 csoutheren 00102 * Removed recursive include file system and removed all references 00103 * to deprecated coooperative threading support 00104 * 00105 * Revision 1.86 2002/10/14 21:42:37 rogerh 00106 * Only use malloc.h on Windows 00107 * 00108 * Revision 1.85 2002/10/10 04:43:43 robertj 00109 * VxWorks port, thanks Martijn Roest 00110 * 00111 * Revision 1.84 2002/10/08 12:41:51 robertj 00112 * Changed for IPv6 support, thanks Sébastien Josset. 00113 * 00114 * Revision 1.83 2002/09/16 01:08:59 robertj 00115 * Added #define so can select if #pragma interface/implementation is used on 00116 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan. 00117 * 00118 * Revision 1.82 2002/08/06 02:27:58 robertj 00119 * GNU C++ v3 compatibility. 00120 * 00121 * Revision 1.81 2002/06/25 02:22:47 robertj 00122 * Improved assertion system to allow C++ class name to be displayed if 00123 * desired, especially relevant to container classes. 00124 * 00125 * Revision 1.80 2002/06/14 10:29:43 rogerh 00126 * STL + gcc 3.1 compile fix. Submitted by Klaus Kaempf <kkaempf@suse.de> 00127 * 00128 * Revision 1.79 2002/06/13 08:34:05 rogerh 00129 * gcc 3.1 needs iostream instead of iostream.h 00130 * 00131 * Revision 1.78 2002/05/22 00:23:31 craigs 00132 * Added GMTTime flag to tracing options 00133 * 00134 * Revision 1.77 2002/04/19 00:20:51 craigs 00135 * Added option to append to log file rather than create anew each time 00136 * 00137 * Revision 1.76 2002/01/26 23:55:55 craigs 00138 * Changed for GCC 3.0 compatibility, thanks to manty@manty.net 00139 * 00140 * Revision 1.75 2001/10/18 19:56:26 yurik 00141 * Fixed WinCE x86 compilation problems with memory check off 00142 * 00143 * Revision 1.74 2001/08/12 11:26:07 robertj 00144 * Put back PMEMORY_CHECK taken out by the Carbon port. 00145 * 00146 * Revision 1.73 2001/08/11 07:57:30 rogerh 00147 * Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com> 00148 * 00149 * Revision 1.72 2001/05/03 06:27:29 robertj 00150 * Added return value to PMemoryCheck::SetIgnoreAllocations() so get previous state. 00151 * 00152 * Revision 1.71 2001/03/24 01:11:10 robertj 00153 * Added missing PTRACE_IF define in non PTRACING mode. 00154 * 00155 * Revision 1.70 2001/03/23 05:34:09 robertj 00156 * Added PTRACE_IF to output trace if a conditional is TRUE. 00157 * 00158 * Revision 1.69 2001/03/01 02:15:16 robertj 00159 * Fixed PTRACE_LINE() so drops filename and line which may not be in trace otherwise. 00160 * 00161 * Revision 1.68 2001/02/22 08:16:41 robertj 00162 * Added standard trace file setup subroutine. 00163 * 00164 * Revision 1.67 2001/02/13 03:27:24 robertj 00165 * Added function to do heap validation. 00166 * 00167 * Revision 1.66 2001/02/09 04:41:27 robertj 00168 * Removed added non memrycheck implementations of new/delete when using GNU C++. 00169 * 00170 * Revision 1.65 2001/02/07 04:47:49 robertj 00171 * Added changes for possible random crashes in multi DLL environment 00172 * due to memory allocation wierdness, thanks Milan Dimitrijevic. 00173 * 00174 * Revision 1.64 2001/01/24 06:15:44 yurik 00175 * Windows CE port-related declarations 00176 * 00177 * Revision 1.63 2000/07/28 05:13:47 robertj 00178 * Fixed silly mistake in runtime_malloc() function, should return a pointer! 00179 * 00180 * Revision 1.62 2000/07/20 05:46:34 robertj 00181 * Added runtime_malloc() function for cases where memory check code must be bypassed. 00182 * 00183 * Revision 1.61 2000/07/13 15:45:35 robertj 00184 * Removed #define std that causes everyone so much grief! 00185 * 00186 * Revision 1.60 2000/06/26 11:17:19 robertj 00187 * Nucleus++ port (incomplete). 00188 * 00189 * Revision 1.59 2000/02/29 12:26:14 robertj 00190 * Added named threads to tracing, thanks to Dave Harvey 00191 * 00192 * Revision 1.58 2000/01/07 12:31:12 robertj 00193 * Fixed 8 byte alignment on memory heap checking. 00194 * 00195 * Revision 1.57 2000/01/05 00:29:12 robertj 00196 * Fixed alignment problems in memory checking debug functions. 00197 * 00198 * Revision 1.56 1999/11/30 00:22:54 robertj 00199 * Updated documentation for doc++ 00200 * 00201 * Revision 1.55 1999/11/01 00:10:27 robertj 00202 * Added override of new functions for MSVC memory check code. 00203 * 00204 * Revision 1.54 1999/10/19 09:21:30 robertj 00205 * Added functions to get current trace options and level. 00206 * 00207 * Revision 1.53 1999/09/13 13:15:06 robertj 00208 * Changed PTRACE so will output to system log in PServiceProcess applications. 00209 * 00210 * Revision 1.52 1999/08/24 08:15:23 robertj 00211 * Added missing operator on smart pointer to return the pointer! 00212 * 00213 * Revision 1.51 1999/08/24 06:54:36 robertj 00214 * Cleaned up the smart pointer code (macros). 00215 * 00216 * Revision 1.50 1999/08/22 13:38:39 robertj 00217 * Fixed termination hang up problem with memory check code under unix pthreads. 00218 * 00219 * Revision 1.49 1999/08/17 03:46:40 robertj 00220 * Fixed usage of inlines in optimised version. 00221 * 00222 * Revision 1.48 1999/08/10 10:45:09 robertj 00223 * Added mutex in memory check detection code. 00224 * 00225 * Revision 1.47 1999/07/18 15:08:24 robertj 00226 * Fixed 64 bit compatibility 00227 * 00228 * Revision 1.46 1999/06/14 07:59:37 robertj 00229 * Enhanced tracing again to add options to trace output (timestamps etc). 00230 * 00231 * Revision 1.45 1999/05/01 11:29:19 robertj 00232 * Alpha linux port changes. 00233 * 00234 * Revision 1.44 1999/04/18 12:58:39 robertj 00235 * MSVC 5 backward compatibility 00236 * 00237 * Revision 1.43 1999/03/09 10:30:17 robertj 00238 * Fixed ability to have PMEMORY_CHECK on/off on both debug/release versions. 00239 * 00240 * Revision 1.42 1999/03/09 02:59:50 robertj 00241 * Changed comments to doc++ compatible documentation. 00242 * 00243 * Revision 1.41 1999/02/23 07:11:26 robertj 00244 * Improved trace facility adding trace levels and #define to remove all trace code. 00245 * 00246 * Revision 1.40 1999/02/22 10:48:14 robertj 00247 * Fixed delete operator prototypes for MSVC6 and GNU compatibility. 00248 * 00249 * Revision 1.39 1999/02/19 11:33:02 robertj 00250 * Fixed compatibility problems with GNU/MSVC6 00251 * 00252 * Revision 1.38 1999/02/16 08:12:22 robertj 00253 * MSVC 6.0 compatibility changes. 00254 * 00255 * Revision 1.37 1999/01/07 03:35:35 robertj 00256 * Added default for PCHAR8 to ANSI, removes need for compiler option. 00257 * 00258 * Revision 1.36 1998/12/15 09:00:29 robertj 00259 * Fixed 8 byte alignment problem in memory leak check code for sparc. 00260 * 00261 * Revision 1.35 1998/11/03 00:57:19 robertj 00262 * Added allocation breakpoint variable. 00263 * 00264 * Revision 1.34 1998/10/26 11:05:26 robertj 00265 * Added raw free for things allocated within the runtime library. 00266 * 00267 * Revision 1.33 1998/10/18 14:26:55 robertj 00268 * Improved tracing functions. 00269 * 00270 * Revision 1.32 1998/10/15 07:47:21 robertj 00271 * Added ability to ignore G++lib memory leaks. 00272 * 00273 * Revision 1.31 1998/10/15 01:53:58 robertj 00274 * GNU compatibility. 00275 * 00276 * Revision 1.30 1998/10/13 14:23:29 robertj 00277 * Complete rewrite of memory leak detection. 00278 * 00279 * Revision 1.29 1998/09/23 06:20:57 robertj 00280 * Added open source copyright license. 00281 * 00282 * Revision 1.28 1998/09/14 12:29:11 robertj 00283 * Fixed memory leak dump under windows to not include static globals. 00284 * Fixed problem with notifier declaration not allowing implementation inline after macro. 00285 * 00286 * Revision 1.27 1997/07/08 13:13:45 robertj 00287 * DLL support. 00288 * 00289 * Revision 1.26 1997/04/27 05:50:11 robertj 00290 * DLL support. 00291 * 00292 * Revision 1.25 1997/02/05 11:54:10 robertj 00293 * Fixed problems with memory check and leak detection. 00294 * 00295 * Revision 1.24 1996/09/16 12:57:23 robertj 00296 * DLL support 00297 * 00298 * Revision 1.23 1996/08/17 10:00:23 robertj 00299 * Changes for Windows DLL support. 00300 * 00301 * Revision 1.22 1996/07/15 10:27:51 robertj 00302 * Changed endian classes to be memory mapped. 00303 * 00304 * Revision 1.21 1996/05/09 12:14:48 robertj 00305 * Fixed up 64 bit integer class for Mac platform. 00306 * 00307 * Revision 1.20 1996/02/24 14:19:29 robertj 00308 * Fixed bug in endian independent integer code for memory transfers. 00309 * 00310 * Revision 1.19 1996/01/28 02:46:43 robertj 00311 * Removal of MemoryPointer classes as usage didn't work for GNU. 00312 * Added missing bit shift operators to 64 bit integer class. 00313 * 00314 * Revision 1.18 1996/01/23 13:14:32 robertj 00315 * Added const version of PMemoryPointer. 00316 * Added constructor to endian classes for the base type. 00317 * 00318 * Revision 1.17 1996/01/02 11:54:11 robertj 00319 * Mac OS compatibility changes. 00320 * 00321 * Revision 1.16 1995/11/09 12:17:10 robertj 00322 * Added platform independent base type access classes. 00323 * 00324 * Revision 1.15 1995/06/17 11:12:47 robertj 00325 * Documentation update. 00326 * 00327 * Revision 1.14 1995/06/04 12:34:19 robertj 00328 * Added trace functions. 00329 * 00330 * Revision 1.13 1995/04/25 12:04:35 robertj 00331 * Fixed borland compatibility. 00332 * Fixed function hiding ancestor virtuals. 00333 * 00334 * Revision 1.12 1995/03/14 12:41:54 robertj 00335 * Updated documentation to use HTML codes. 00336 * 00337 * Revision 1.11 1995/03/12 04:40:55 robertj 00338 * Changed standard error code for not open from file to channel. 00339 * 00340 * Revision 1.10 1995/02/19 04:19:14 robertj 00341 * Added dynamically linked command processing. 00342 * 00343 * Revision 1.9 1995/02/05 00:48:07 robertj 00344 * Fixed template version. 00345 * 00346 * Revision 1.8 1995/01/15 04:51:31 robertj 00347 * Mac compatibility. 00348 * Added levels of memory checking. 00349 * 00350 * Revision 1.7 1995/01/09 12:38:31 robertj 00351 * Changed variable names around during documentation run. 00352 * Fixed smart pointer comparison. 00353 * Fixed serialisation stuff. 00354 * Documentation. 00355 * 00356 * Revision 1.6 1995/01/03 09:39:06 robertj 00357 * Put standard malloc style memory allocation etc into memory check system. 00358 * 00359 * Revision 1.5 1994/12/12 10:08:30 robertj 00360 * Renamed PWrapper to PSmartPointer.. 00361 * 00362 * Revision 1.4 1994/12/05 11:23:28 robertj 00363 * Fixed PWrapper macros. 00364 * 00365 * Revision 1.3 1994/11/19 00:22:55 robertj 00366 * Changed PInteger to be INT, ie standard type like BOOL/WORD etc. 00367 * Moved null object check in notifier to construction rather than use. 00368 * Added virtual to the callback function in notifier destination class. 00369 * 00370 * Revision 1.2 1994/11/03 09:25:30 robertj 00371 * Made notifier destination object not to be descendent of PObject. 00372 * 00373 * Revision 1.1 1994/10/30 12:01:37 robertj 00374 * Initial revision 00375 * 00376 */ 00377 00378 #ifndef _POBJECT_H 00379 #define _POBJECT_H 00380 00381 #ifdef P_USE_PRAGMA 00382 #pragma interface 00383 #endif 00384 00385 #ifdef _WIN32 00386 #include "msos/ptlib/contain.h" 00387 #else 00388 #include "unix/ptlib/contain.h" 00389 #endif 00390 00391 #if defined(P_VXWORKS) 00392 #include <private/stdiop.h> 00393 #endif 00394 00395 #include <stdio.h> 00396 #include <stdarg.h> 00397 #include <stdlib.h> 00398 00399 #ifdef _WIN32 00400 #include <malloc.h> 00401 #endif 00402 00403 #include <string.h> 00404 00405 #ifdef __USE_STL__ 00406 #include <string> 00407 #include <iomanip> 00408 #include <iostream> 00409 #if (__GNUC__ >= 3) 00410 #include <sstream> 00411 //typedef std::ostringstream ostrstream; 00412 #else 00413 #include <strstream> 00414 #endif 00415 //using namespace std; 00416 #else 00417 #if (__GNUC__ >= 3) 00418 #include <iostream> 00419 #ifndef __MWERKS__ 00420 #include <iomanip> 00421 #endif 00422 #else 00423 #include <iostream.h> 00424 #ifdef __GNUC__ 00425 #include <strstream.h> 00426 #else 00427 #include <strstrea.h> 00428 #endif 00429 #ifndef __MWERKS__ 00430 #include <iomanip.h> 00431 #endif 00432 #endif 00433 #endif 00434 00435 #ifdef _WIN32_WCE 00436 #include <stdlibx.h> 00437 #endif 00438 00439 #if (__GNUC__ < 3) 00440 typedef long _Ios_Fmtflags; 00441 #endif 00442 00443 #if _MSC_VER<1300 00444 #define _BADOFF -1 00445 #endif 00446 00448 // Disable inlines when debugging for faster compiles (the compiler doesn't 00449 // actually inline the function with debug on any way). 00450 00451 #ifndef P_USE_INLINES 00452 #ifdef _DEBUG 00453 #define P_USE_INLINES 0 00454 #else 00455 #define P_USE_INLINES 0 00456 #endif 00457 #endif 00458 00459 #if P_USE_INLINES 00460 #define PINLINE inline 00461 #else 00462 #define PINLINE 00463 #endif 00464 00465 00467 // Declare the debugging support 00468 00470 enum PStandardAssertMessage { 00471 PLogicError, // A logic error occurred. 00472 POutOfMemory, // A new or malloc failed. 00473 PNullPointerReference, // A reference was made through a NULL pointer. 00474 PInvalidCast, // An invalid cast to descendant is required. 00475 PInvalidArrayIndex, // An index into an array was negative. 00476 PInvalidArrayElement, // A NULL array element object was accessed. 00477 PStackEmpty, // A Pop() was made of a stack with no elements. 00478 PUnimplementedFunction, // Funtion is not implemented. 00479 PInvalidParameter, // Invalid parameter was passed to a function. 00480 POperatingSystemError, // Error was returned by Operating System. 00481 PChannelNotOpen, // Operation attempted when channel not open. 00482 PUnsupportedFeature, // Feature is not supported. 00483 PInvalidWindow, // Access through invalid window. 00484 PMaxStandardAssertMessage 00485 }; 00486 00487 #define __CLASS__ NULL 00488 00495 #define PAssert(b, m) if(b);else PAssertFunc(__FILE__, __LINE__, __CLASS__, (m)) 00496 00504 #define PAssert2(b, c, m) if(b);else PAssertFunc(__FILE__, __LINE__, (c), (m)) 00505 00512 #define PAssertOS(b) \ 00513 if(b);else PAssertFunc(__FILE__, __LINE__, __CLASS__, POperatingSystemError) 00514 00524 #define PAssertNULL(p) ((&(p)&&(p)!=NULL)?(p):(PAssertFunc(__FILE__, \ 00525 __LINE__, __CLASS__, PNullPointerReference), (p))) 00526 00533 #define PAssertAlways(m) PAssertFunc(__FILE__, __LINE__, __CLASS__, (m)) 00534 00541 #define PAssertAlways2(c, m) PAssertFunc(__FILE__, __LINE__, (c), (m)) 00542 00543 00544 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg); 00545 void PAssertFunc(const char * file, int line, const char * className, const char * msg); 00546 void PAssertFunc(const char * full_msg); 00547 00548 00553 ostream & PGetErrorStream(); 00554 00558 void PSetErrorStream(ostream * strm ); 00559 00574 #define PError (PGetErrorStream()) 00575 00576 00577 00579 // Debug and tracing 00580 00581 #ifndef PTRACING 00582 #ifndef _DEBUG 00583 #define PTRACING 0 00584 #else 00585 #define PTRACING 1 00586 #endif 00587 #endif 00588 00593 class PTrace 00594 { 00595 public: 00597 enum Options { 00603 Blocks = 1, 00605 DateAndTime = 2, 00607 Timestamp = 4, 00609 Thread = 8, 00611 TraceLevel = 16, 00613 FileAndLine = 32, 00615 ThreadAddress = 64, 00617 AppendToFile = 128, 00621 GMTTime = 256, 00624 SystemLogStream = 32768 00625 }; 00626 00634 static void Initialise( 00635 unsigned level, 00636 const char * filename = NULL, 00637 unsigned options = Timestamp | Thread | Blocks 00638 ); 00639 00646 static void SetOptions(unsigned options ); 00647 00655 static void ClearOptions(unsigned options ); 00656 00661 static unsigned GetOptions(); 00662 00668 static void SetLevel(unsigned level ); 00669 00675 static unsigned GetLevel(); 00676 00681 static BOOL CanTrace(unsigned level ); 00682 00687 static void SetStream(ostream * out ); 00688 00704 static ostream & Begin( 00705 unsigned level, 00706 const char * fileName, 00707 int lineNum 00708 ); 00709 00726 static ostream & End(ostream & strm ); 00727 00728 00734 class Block { 00735 public: 00737 Block( 00738 const char * fileName, 00739 int lineNum, 00740 const char * traceName 00742 ); 00744 ~Block(); 00745 private: 00746 const char * file; 00747 int line; 00748 const char * name; 00749 }; 00750 }; 00751 00752 #if !PTRACING 00753 00754 #define PTRACE_PARAM(param) 00755 #define PTRACE_BLOCK(n) 00756 #define PTRACE_LINE() 00757 #define PTRACE(level, arg) 00758 #define PTRACE_IF(level, cond, args) 00759 00760 #else 00761 00762 /* Macro to conditionally declare a parameter to a function to avoid compiler 00763 warning due that parameter only being used in a PTRACE */ 00764 #define PTRACE_PARAM(param) param 00765 00772 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name) 00773 00777 #define PTRACE_LINE() \ 00778 if (!PTrace::CanTrace(1)) ; else \ 00779 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End 00780 00786 #define PTRACE(level, args) \ 00787 if (!PTrace::CanTrace(level)) ; else \ 00788 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End 00789 00797 #define PTRACE_IF(level, cond, args) \ 00798 if (!(PTrace::CanTrace(level) && (cond))) ; else \ 00799 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End 00800 00801 #endif 00802 00803 #if PMEMORY_CHECK 00804 00811 class PMemoryHeap { 00812 protected: 00814 PMemoryHeap(); 00815 00816 public: 00817 // Clear up the memory checking subsystem, dumping memory leaks. 00818 ~PMemoryHeap(); 00819 00826 static void * Allocate( 00827 size_t nSize, 00828 const char * file, 00829 int line, 00830 const char * className 00831 ); 00838 static void * Allocate( 00839 size_t count, 00840 size_t iSize, 00841 const char * file, 00842 int line 00843 ); 00844 00852 static void * Reallocate( 00853 void * ptr, 00854 size_t nSize, 00855 const char * file, 00856 int line 00857 ); 00858 00864 static void Deallocate( 00865 void * ptr, 00866 const char * className 00867 ); 00868 00871 enum Validation { 00872 Ok, Bad, Trashed 00873 }; 00881 static Validation Validate( 00882 void * ptr, 00883 const char * className, 00884 ostream * error 00885 ); 00886 00891 static BOOL ValidateHeap( 00892 ostream * error = NULL // Stream to output, use default if NULL 00893 ); 00894 00900 static BOOL SetIgnoreAllocations( 00901 BOOL ignore 00902 ); 00903 00907 static void DumpStatistics(); 00911 static void DumpStatistics(ostream & strm ); 00912 00913 /* Get number of allocation. 00914 Each allocation is counted and if desired the next allocation request 00915 number may be obtained via this function. 00916 @return Allocation request number. 00917 */ 00918 static DWORD GetAllocationRequest(); 00919 00927 static void DumpObjectsSince( 00928 DWORD objectNumber 00929 ); 00930 00936 static void DumpObjectsSince( 00937 DWORD objectNumber, 00938 ostream & strm 00939 ); 00940 00946 static void SetAllocationBreakpoint( 00947 DWORD point 00948 ); 00949 00950 protected: 00951 void * InternalAllocate( 00952 size_t nSize, // Number of bytes to allocate. 00953 const char * file, // Source file name for allocating function. 00954 int line, // Source file line for allocating function. 00955 const char * className // Class name for allocating function. 00956 ); 00957 Validation InternalValidate( 00958 void * ptr, // Pointer to memory block to check 00959 const char * className, // Class name it should be. 00960 ostream * error // Stream to receive error message (may be NULL) 00961 ); 00962 void InternalDumpStatistics(ostream & strm); 00963 void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm); 00964 00965 class Wrapper { 00966 public: 00967 Wrapper(); 00968 ~Wrapper(); 00969 PMemoryHeap * operator->() const { return instance; } 00970 private: 00971 PMemoryHeap * instance; 00972 }; 00973 friend class Wrapper; 00974 00975 enum Flags { 00976 NoLeakPrint = 1 00977 }; 00978 00979 #pragma pack(1) 00980 struct Header { 00981 enum { 00982 // Assure that the Header struct is aligned to 8 byte boundary 00983 NumGuardBytes = 16 - (sizeof(Header *) + 00984 sizeof(Header *) + 00985 sizeof(const char *) + 00986 sizeof(const char *) + 00987 sizeof(size_t) + 00988 sizeof(DWORD) + 00989 sizeof(WORD) + 00990 sizeof(BYTE))%8 00991 }; 00992 00993 Header * prev; 00994 Header * next; 00995 const char * className; 00996 const char * fileName; 00997 size_t size; 00998 DWORD request; 00999 WORD line; 01000 BYTE flags; 01001 char guard[NumGuardBytes]; 01002 01003 static char GuardBytes[NumGuardBytes]; 01004 }; 01005 #pragma pack() 01006 01007 BOOL isDestroyed; 01008 01009 Header * listHead; 01010 Header * listTail; 01011 01012 static DWORD allocationBreakpoint; 01013 DWORD allocationRequest; 01014 DWORD firstRealObject; 01015 BYTE flags; 01016 01017 char allocFillChar; 01018 char freeFillChar; 01019 01020 DWORD currentMemoryUsage; 01021 DWORD peakMemoryUsage; 01022 DWORD currentObjects; 01023 DWORD peakObjects; 01024 DWORD totalObjects; 01025 01026 ostream * leakDumpStream; 01027 01028 #if defined(_WIN32) 01029 CRITICAL_SECTION mutex; 01030 #elif defined(P_PTHREADS) 01031 pthread_mutex_t mutex; 01032 #elif defined(P_VXWORKS) 01033 void * mutex; 01034 #endif 01035 }; 01036 01037 01042 inline void * runtime_malloc(size_t bytes ) { return malloc(bytes); } 01043 01048 inline void runtime_free(void * ptr ) { free(ptr); } 01049 01050 01057 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL) 01058 01065 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__) 01066 01073 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__) 01074 01075 01082 #define free(p) PMemoryHeap::Deallocate(p, NULL) 01083 01084 01091 #define cfree(p) PMemoryHeap::Deallocate(p, NULL) 01092 01093 01108 #define PNEW new (__FILE__, __LINE__) 01109 01110 #if !defined(_MSC_VER) || _MSC_VER<1200 01111 #define PSPECIAL_DELETE_FUNCTION 01112 #else 01113 #define PSPECIAL_DELETE_FUNCTION \ 01114 void operator delete(void * ptr, const char *, int) \ 01115 { PMemoryHeap::Deallocate(ptr, Class()); } \ 01116 void operator delete[](void * ptr, const char *, int) \ 01117 { PMemoryHeap::Deallocate(ptr, Class()); } 01118 #endif 01119 01120 #define PNEW_AND_DELETE_FUNCTIONS \ 01121 void * operator new(size_t nSize, const char * file, int line) \ 01122 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \ 01123 void * operator new(size_t nSize) \ 01124 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \ 01125 void operator delete(void * ptr) \ 01126 { PMemoryHeap::Deallocate(ptr, Class()); } \ 01127 void * operator new[](size_t nSize, const char * file, int line) \ 01128 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \ 01129 void * operator new[](size_t nSize) \ 01130 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \ 01131 void operator delete[](void * ptr) \ 01132 { PMemoryHeap::Deallocate(ptr, Class()); } \ 01133 PSPECIAL_DELETE_FUNCTION 01134 01135 01136 inline void * operator new(size_t nSize, const char * file, int line) 01137 { return PMemoryHeap::Allocate(nSize, file, line, NULL); } 01138 01139 inline void * operator new[](size_t nSize, const char * file, int line) 01140 { return PMemoryHeap::Allocate(nSize, file, line, NULL); } 01141 01142 #ifndef __GNUC__ 01143 void * operator new(size_t nSize); 01144 void * operator new[](size_t nSize); 01145 01146 void operator delete(void * ptr); 01147 void operator delete[](void * ptr); 01148 01149 #if defined(_MSC_VER) && _MSC_VER>=1200 01150 inline void operator delete(void * ptr, const char *, int) 01151 { PMemoryHeap::Deallocate(ptr, NULL); } 01152 01153 inline void operator delete[](void * ptr, const char *, int) 01154 { PMemoryHeap::Deallocate(ptr, NULL); } 01155 #endif 01156 #endif 01157 01158 01159 #else // PMEMORY_CHECK 01160 01161 #define PNEW new 01162 01163 #if defined(__GNUC__) || (defined(_WIN32_WCE) && defined(_X86_)) 01164 01165 #define PNEW_AND_DELETE_FUNCTIONS 01166 01167 #else 01168 01169 #define PNEW_AND_DELETE_FUNCTIONS \ 01170 void * operator new(size_t nSize) \ 01171 { return malloc(nSize); } \ 01172 void operator delete(void * ptr) \ 01173 { free(ptr); } \ 01174 void * operator new[](size_t nSize) \ 01175 { return malloc(nSize); } \ 01176 void operator delete[](void * ptr) \ 01177 { free(ptr); } 01178 01179 void * operator new(size_t nSize); 01180 void * operator new[](size_t nSize); 01181 01182 void operator delete(void * ptr); 01183 void operator delete[](void * ptr); 01184 01185 #endif 01186 01187 #define runtime_malloc(s) malloc(s) 01188 #define runtime_free(p) free(p) 01189 01190 #endif // PMEMORY_CHECK 01191 01192 01203 /* 01204 01205 ORIGINAL 01206 01207 #define PCLASSINFO(cls, par) \ 01208 public: \ 01209 static const char * Class() \ 01210 { return #cls; } \ 01211 virtual const char * GetClass(unsigned ancestor = 0) const \ 01212 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \ 01213 virtual BOOL IsClass(const char * clsName) const \ 01214 { return strcmp(clsName, cls::Class()) == 0; } \ 01215 virtual BOOL IsDescendant(const char * clsName) const \ 01216 { return strcmp(clsName, cls::Class()) == 0 || par::IsDescendant(clsName); } \ 01217 virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \ 01218 { return (Comparison)memcmp(this, &obj, sizeof(cls)); } 01219 */ 01220 01221 01222 #if P_HAS_TYPEINFO 01223 01224 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL) 01225 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str)) 01226 01227 #include <typeinfo> 01228 01229 #ifndef PCLASSNAME 01230 #error "Must define PCLASSNAME" 01231 #endif 01232 01233 #define PBASECLASSINFO(cls, par) \ 01234 public: \ 01235 static inline const char * Class() \ 01236 { return PCLASSNAME(cls); } \ 01237 virtual BOOL InternalIsDescendant(const char * clsName) const \ 01238 { return strcmp(clsName, PCLASSNAME(cls)) == 0 || par::InternalIsDescendant(clsName); } \ 01239 01240 #else // P_HAS_TYPEINFO 01241 01242 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class())) 01243 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str)) 01244 01245 #define PBASECLASSINFO(cls, par) \ 01246 public: \ 01247 static const char * Class() \ 01248 { return #cls; } \ 01249 virtual BOOL InternalIsDescendant(const char * clsName) const \ 01250 { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \ 01251 01252 #endif // P_HAS_TYPEINFO 01253 01254 01255 #define PCLASSINFO(cls, par) \ 01256 PBASECLASSINFO(cls, par) \ 01257 virtual const char * GetClass(unsigned ancestor = 0) const \ 01258 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \ 01259 virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \ 01260 { return (Comparison)memcmp(this, &obj, sizeof(cls)); } \ 01261 01262 01270 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par) 01271 #ifdef DOC_PLUS_PLUS 01272 } Match previous opening brace in doc++ 01273 #endif 01274 01276 // The root of all evil ... umm classes 01277 01282 class PObject { 01283 01284 protected: 01288 PObject() { } 01289 01290 public: 01291 /* Destructor required to get the "virtual". A PObject really has nothing 01292 to destroy. 01293 */ 01294 virtual ~PObject() { } 01295 01308 static inline const char * Class() { return PCLASSNAME(PObject); } 01309 01322 virtual const char * GetClass(unsigned /*ancestor*/ = 0) const { return Class(); } 01323 01324 BOOL IsClass(const char * cls) const 01325 { return strcmp(cls, GetClass()) == 0; } 01326 01336 virtual BOOL InternalIsDescendant( 01337 const char * clsName // Ancestor class name to compare against. 01338 ) const 01339 { return IsClass(clsName); } 01340 01342 01348 enum Comparison { 01349 LessThan = -1, 01350 EqualTo = 0, 01351 GreaterThan = 1 01352 }; 01353 01365 virtual Comparison Compare( 01366 const PObject & obj // Object to compare against. 01367 ) const; 01368 01380 virtual Comparison CompareObjectMemoryDirect( 01381 const PObject & obj // Object to compare against. 01382 ) const; 01383 01389 bool operator==( 01390 const PObject & obj // Object to compare against. 01391 ) const { return Compare(obj) == EqualTo; } 01392 01398 bool operator!=( 01399 const PObject & obj // Object to compare against. 01400 ) const { return Compare(obj) != EqualTo; } 01401 01407 bool operator<( 01408 const PObject & obj // Object to compare against. 01409 ) const { return Compare(obj) == LessThan; } 01410 01416 bool operator>( 01417 const PObject & obj // Object to compare against. 01418 ) const { return Compare(obj) == GreaterThan; } 01419 01425 bool operator<=( 01426 const PObject & obj // Object to compare against. 01427 ) const { return Compare(obj) != GreaterThan; } 01428 01434 bool operator>=( 01435 const PObject & obj // Object to compare against. 01436 ) const { return Compare(obj) != LessThan; } 01438 01447 virtual void PrintOn( 01448 ostream &strm // Stream to print the object into. 01449 ) const; 01450 01457 virtual void ReadFrom( 01458 istream &strm // Stream to read the objects contents from. 01459 ); 01460 01461 01467 inline friend ostream & operator<<( 01468 ostream &strm, // Stream to print the object into. 01469 const PObject & obj // Object to print to the stream. 01470 ) { obj.PrintOn(strm); return strm; } 01471 01477 inline friend istream & operator>>( 01478 istream &strm, // Stream to read the objects contents from. 01479 PObject & obj // Object to read inormation into. 01480 ) { obj.ReadFrom(strm); return strm; } 01481 01482 01497 virtual PObject * Clone() const; 01498 01510 virtual PINDEX HashFunction() const; 01512 }; 01513 01515 // Platform independent types 01516 01517 // All these classes encapsulate primitive types such that they may be 01518 // transfered in a platform independent manner. In particular it is used to 01519 // do byte swapping for little endien and big endien processor architectures 01520 // as well as accommodating structure packing rules for memory structures. 01521 01522 #define PANSI_CHAR 1 01523 #define PLITTLE_ENDIAN 2 01524 #define PBIG_ENDIAN 3 01525 01526 01527 #if 0 01528 class PStandardType 01529 /* Encapsulate a standard 8 bit character into a portable format. This would 01530 rarely need to do translation, only if the target platform uses EBCDIC 01531 would it do anything. 01532 01533 The platform independent form here is always 8 bit ANSI. 01534 */ 01535 { 01536 public: 01537 PStandardType( 01538 type newVal // Value to initialise data in platform dependent form. 01539 ) { data = newVal; } 01540 /* Create a new instance of the platform independent type using platform 01541 dependent data, or platform independent streams. 01542 */ 01543 01544 operator type() { return data; } 01545 /* Get the platform dependent value for the type. 01546 01547 @return 01548 data for instance. 01549 */ 01550 01551 friend ostream & operator<<(ostream & strm, const PStandardType & val) 01552 { return strm << (type)val; } 01553 /* Output the platform dependent value for the type to the stream. 01554 01555 @return 01556 the stream output was made to. 01557 */ 01558 01559 friend istream & operator>>(istream & strm, PStandardType & val) 01560 { type data; strm >> data; val = PStandardType(data); return strm; } 01561 /* Input the platform dependent value for the type from the stream. 01562 01563 @return 01564 the stream input was made from. 01565 */ 01566 01567 01568 private: 01569 type data; 01570 }; 01571 #endif 01572 01573 01574 #define PI_SAME(name, type) \ 01575 struct name { \ 01576 name() { } \ 01577 name(type value) { data = value; } \ 01578 name(const name & value) { data = value.data; } \ 01579 name & operator =(type value) { data = value; return *this; } \ 01580 name & operator =(const name & value) { data = value.data; return *this; } \ 01581 operator type() const { return data; } \ 01582 friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \ 01583 friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \ 01584 private: type data; \ 01585 } 01586 01587 #define PI_LOOP(src, dst) \ 01588 BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \ 01589 while (s != (BYTE *)&src) *d++ = *--s; 01590 01591 #define PI_DIFF(name, type) \ 01592 struct name { \ 01593 name() { } \ 01594 name(type value) { operator=(value); } \ 01595 name(const name & value) { data = value.data; } \ 01596 name & operator =(type value) { PI_LOOP(value, data); return *this; } \ 01597 name & operator =(const name & value) { data = value.data; return *this; } \ 01598 operator type() const { type value; PI_LOOP(data, value); return value; } \ 01599 friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \ 01600 friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \ 01601 private: type data; \ 01602 } 01603 01604 #ifndef PCHAR8 01605 #define PCHAR8 PANSI_CHAR 01606 #endif 01607 01608 #if PCHAR8==PANSI_CHAR 01609 PI_SAME(PChar8, char); 01610 #endif 01611 01612 PI_SAME(PInt8, signed char); 01613 01614 PI_SAME(PUInt8, unsigned char); 01615 01616 #if PBYTE_ORDER==PLITTLE_ENDIAN 01617 PI_SAME(PInt16l, PInt16); 01618 #elif PBYTE_ORDER==PBIG_ENDIAN 01619 PI_DIFF(PInt16l, PInt16); 01620 #endif 01621 01622 #if PBYTE_ORDER==PLITTLE_ENDIAN 01623 PI_DIFF(PInt16b, PInt16); 01624 #elif PBYTE_ORDER==PBIG_ENDIAN 01625 PI_SAME(PInt16b, PInt16); 01626 #endif 01627 01628 #if PBYTE_ORDER==PLITTLE_ENDIAN 01629 PI_SAME(PUInt16l, WORD); 01630 #elif PBYTE_ORDER==PBIG_ENDIAN 01631 PI_DIFF(PUInt16l, WORD); 01632 #endif 01633 01634 #if PBYTE_ORDER==PLITTLE_ENDIAN 01635 PI_DIFF(PUInt16b, WORD); 01636 #elif PBYTE_ORDER==PBIG_ENDIAN 01637 PI_SAME(PUInt16b, WORD); 01638 #endif 01639 01640 #if PBYTE_ORDER==PLITTLE_ENDIAN 01641 PI_SAME(PInt32l, PInt32); 01642 #elif PBYTE_ORDER==PBIG_ENDIAN 01643 PI_DIFF(PInt32l, PInt32); 01644 #endif 01645 01646 #if PBYTE_ORDER==PLITTLE_ENDIAN 01647 PI_DIFF(PInt32b, PInt32); 01648 #elif PBYTE_ORDER==PBIG_ENDIAN 01649 PI_SAME(PInt32b, PInt32); 01650 #endif 01651 01652 #if PBYTE_ORDER==PLITTLE_ENDIAN 01653 PI_SAME(PUInt32l, DWORD); 01654 #elif PBYTE_ORDER==PBIG_ENDIAN 01655 PI_DIFF(PUInt32l, DWORD); 01656 #endif 01657 01658 #if PBYTE_ORDER==PLITTLE_ENDIAN 01659 PI_DIFF(PUInt32b, DWORD); 01660 #elif PBYTE_ORDER==PBIG_ENDIAN 01661 PI_SAME(PUInt32b, DWORD); 01662 #endif 01663 01664 #if PBYTE_ORDER==PLITTLE_ENDIAN 01665 PI_SAME(PInt64l, PInt64); 01666 #elif PBYTE_ORDER==PBIG_ENDIAN 01667 PI_DIFF(PInt64l, PInt64); 01668 #endif 01669 01670 #if PBYTE_ORDER==PLITTLE_ENDIAN 01671 PI_DIFF(PInt64b, PInt64); 01672 #elif PBYTE_ORDER==PBIG_ENDIAN 01673 PI_SAME(PInt64b, PInt64); 01674 #endif 01675 01676 #if PBYTE_ORDER==PLITTLE_ENDIAN 01677 PI_SAME(PUInt64l, PUInt64); 01678 #elif PBYTE_ORDER==PBIG_ENDIAN 01679 PI_DIFF(PUInt64l, PUInt64); 01680 #endif 01681 01682 #if PBYTE_ORDER==PLITTLE_ENDIAN 01683 PI_DIFF(PUInt64b, PUInt64); 01684 #elif PBYTE_ORDER==PBIG_ENDIAN 01685 PI_SAME(PUInt64b, PUInt64); 01686 #endif 01687 01688 #if PBYTE_ORDER==PLITTLE_ENDIAN 01689 PI_SAME(PFloat32l, float); 01690 #elif PBYTE_ORDER==PBIG_ENDIAN 01691 PI_DIFF(PFloat32l, float); 01692 #endif 01693 01694 #if PBYTE_ORDER==PLITTLE_ENDIAN 01695 PI_DIFF(PFloat32b, float); 01696 #elif PBYTE_ORDER==PBIG_ENDIAN 01697 PI_SAME(PFloat32b, float); 01698 #endif 01699 01700 #if PBYTE_ORDER==PLITTLE_ENDIAN 01701 PI_SAME(PFloat64l, double); 01702 #elif PBYTE_ORDER==PBIG_ENDIAN 01703 PI_DIFF(PFloat64l, double); 01704 #endif 01705 01706 #if PBYTE_ORDER==PLITTLE_ENDIAN 01707 PI_DIFF(PFloat64b, double); 01708 #elif PBYTE_ORDER==PBIG_ENDIAN 01709 PI_SAME(PFloat64b, double); 01710 #endif 01711 01712 #ifndef NO_LONG_DOUBLE // stupid OSX compiler 01713 #if PBYTE_ORDER==PLITTLE_ENDIAN 01714 PI_SAME(PFloat80l, long double); 01715 #elif PBYTE_ORDER==PBIG_ENDIAN 01716 PI_DIFF(PFloat80l, long double); 01717 #endif 01718 01719 #if PBYTE_ORDER==PLITTLE_ENDIAN 01720 PI_DIFF(PFloat80b, long double); 01721 #elif PBYTE_ORDER==PBIG_ENDIAN 01722 PI_SAME(PFloat80b, long double); 01723 #endif 01724 #endif 01725 01726 #undef PI_LOOP 01727 #undef PI_SAME 01728 #undef PI_DIFF 01729 01730 01732 // Miscellaneous 01733 01734 /*$MACRO PARRAYSIZE(array) 01735 This macro is used to calculate the number of array elements in a static 01736 array. 01737 */ 01738 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0]))) 01739 01740 /*$MACRO PMIN(v1, v2) 01741 This macro is used to calculate the minimum of two values. As this is a 01742 macro the expression in #v1# or #v2# is executed 01743 twice so extreme care should be made in its use. 01744 */ 01745 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2)) 01746 01747 /*$MACRO PMAX(v1, v2) 01748 This macro is used to calculate the maximum of two values. As this is a 01749 macro the expression in #v1# or #v2# is executed 01750 twice so extreme care should be made in its use. 01751 */ 01752 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2)) 01753 01754 /*$MACRO PABS(val) 01755 This macro is used to calculate an absolute value. As this is a macro the 01756 expression in #val# is executed twice so extreme care should be 01757 made in its use. 01758 */ 01759 #define PABS(v) ((v) < 0 ? -(v) : (v)) 01760 01761 #endif // _POBJECT_H 01762 01763 // End Of File ///////////////////////////////////////////////////////////////

Generated on Sat Jul 24 15:35:56 2004 for PWLib by doxygen 1.3.7