PWLib
1.10.10
|
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.115.2.1 2007/09/18 08:20:21 dsandras 00031 * Fixed GCC 4.2 warnings. 00032 * 00033 * Revision 1.115 2005/11/30 12:47:37 csoutheren 00034 * Removed tabs, reformatted some code, and changed tags for Doxygen 00035 * 00036 * Revision 1.114 2005/11/25 03:43:47 csoutheren 00037 * Fixed function argument comments to be compatible with Doxygen 00038 * 00039 * Revision 1.113 2005/09/18 11:05:36 dominance 00040 * include/ptlib/channel.h, include/ptlib/pstring.h, src/ptlib/common/contain.cxx, 00041 * src/ptlib/common/pchannel.cxx: 00042 * correct the STL defined checking to use proper syntax. 00043 * 00044 * include/ptlib/object.h: 00045 * re-add typedef to compile on mingw 00046 * 00047 * make/ptlib-config.in: 00048 * import a long-standing fix from the Debian packs which allows usage of 00049 * ptlib-config without manually adding -lpt for each of the subsequent 00050 * projects 00051 * 00052 * Revision 1.112 2005/08/30 06:36:39 csoutheren 00053 * Added ability to rotate output logs on a daily basis 00054 * 00055 * Revision 1.111 2005/03/10 06:37:20 csoutheren 00056 * Removed use of typeid on WIndows to get class name because it is not threadsafe 00057 * In fact, lets just use #classname everywhere because that will always work 00058 * Thanks to Vyacheslav Frolov 00059 * 00060 * Revision 1.110 2004/08/14 14:17:29 csoutheren 00061 * Fixed problem with PAssert and associated functions caused by using expressions 00062 * as statements. inline functions are your friend :) 00063 * 00064 * Revision 1.109 2004/08/05 12:09:35 rjongbloed 00065 * Added macros for "remove const" and "down cast" funcions with and without RTTI. 00066 * Added ability to disable Asserts. 00067 * Change PAssert macros so pass through the boolean result so that they can be used 00068 * in if statements, allowing a chance to continue if ignore assert. 00069 * 00070 * Revision 1.108 2004/07/11 07:56:35 csoutheren 00071 * Applied jumbo VxWorks patch, thanks to Eize Slange 00072 * 00073 * Revision 1.107 2004/07/03 06:49:49 rjongbloed 00074 * Added PTRACE_PARAM() macro to fix warnings on parameters used in PTRACE 00075 * macros only. 00076 * 00077 * Revision 1.106 2004/06/01 07:42:19 csoutheren 00078 * Restored memory allocation checking 00079 * Added configure flag to enable, thanks to Derek Smithies 00080 * 00081 * Revision 1.105 2004/06/01 05:22:43 csoutheren 00082 * Restored memory check functionality 00083 * 00084 * Revision 1.104 2004/05/12 04:36:17 csoutheren 00085 * Fixed problems with using sem_wait and friends on systems that do not 00086 * support atomic integers 00087 * 00088 * Revision 1.103 2004/04/18 04:33:36 rjongbloed 00089 * Changed all operators that return BOOL to return standard type bool. This is primarily 00090 * for improved compatibility with std STL usage removing many warnings. 00091 * 00092 * Revision 1.102 2004/04/11 13:26:25 csoutheren 00093 * Removed namespace problems and removed warnings for Windows <string> 00094 * 00095 * Revision 1.101 2004/04/11 03:20:41 csoutheren 00096 * Added Unix implementation of PCriticalSection 00097 * 00098 * Revision 1.100 2004/04/11 02:55:17 csoutheren 00099 * Added PCriticalSection for Windows 00100 * Added compile time option for PContainer to use critical sections to provide thread safety under some circumstances 00101 * 00102 * Revision 1.99 2004/04/09 11:54:46 csoutheren 00103 * Added configure.in check for STL streams, and tested with gcc 2.95.3, 00104 * gcc 3.3.1, and gcc 3.3.3 00105 * 00106 * Revision 1.98 2004/04/09 07:53:51 rjongbloed 00107 * Fixed backward compatibility after STL streams change 00108 * 00109 * Revision 1.97 2004/04/09 00:56:35 csoutheren 00110 * Fixed problem with new class name code 00111 * 00112 * Revision 1.96 2004/04/09 00:42:58 csoutheren 00113 * Changed Unix build to use slightly different method for 00114 * keep class names, as GCC does not use actual class names for typeinfo 00115 * 00116 * Revision 1.95 2004/04/04 13:24:18 rjongbloed 00117 * Changes to support native C++ Run Time Type Information 00118 * 00119 * Revision 1.94 2004/04/03 08:57:31 csoutheren 00120 * Replaced pseudo-RTTI with real RTTI 00121 * 00122 * Revision 1.93 2004/04/03 08:22:20 csoutheren 00123 * Remove pseudo-RTTI and replaced with real RTTI 00124 * 00125 * Revision 1.92 2004/04/03 07:41:00 csoutheren 00126 * Fixed compile problem with ostringstream/ostrstream 00127 * 00128 * Revision 1.91 2004/04/03 07:16:05 rjongbloed 00129 * Fixed backward compatibility with MSVC 6 00130 * 00131 * Revision 1.90 2004/04/03 06:54:22 rjongbloed 00132 * Many and various changes to support new Visual C++ 2003 00133 * 00134 * Revision 1.89 2003/09/17 09:00:59 csoutheren 00135 * Moved PSmartPointer and PNotifier into seperate files 00136 * Added detection for system regex libraries on all platforms 00137 * 00138 * Revision 1.88 2003/09/17 05:41:58 csoutheren 00139 * Removed recursive includes 00140 * 00141 * Revision 1.87 2003/09/17 01:18:02 csoutheren 00142 * Removed recursive include file system and removed all references 00143 * to deprecated coooperative threading support 00144 * 00145 * Revision 1.86 2002/10/14 21:42:37 rogerh 00146 * Only use malloc.h on Windows 00147 * 00148 * Revision 1.85 2002/10/10 04:43:43 robertj 00149 * VxWorks port, thanks Martijn Roest 00150 * 00151 * Revision 1.84 2002/10/08 12:41:51 robertj 00152 * Changed for IPv6 support, thanks Sébastien Josset. 00153 * 00154 * Revision 1.83 2002/09/16 01:08:59 robertj 00155 * Added #define so can select if #pragma interface/implementation is used on 00156 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan. 00157 * 00158 * Revision 1.82 2002/08/06 02:27:58 robertj 00159 * GNU C++ v3 compatibility. 00160 * 00161 * Revision 1.81 2002/06/25 02:22:47 robertj 00162 * Improved assertion system to allow C++ class name to be displayed if 00163 * desired, especially relevant to container classes. 00164 * 00165 * Revision 1.80 2002/06/14 10:29:43 rogerh 00166 * STL + gcc 3.1 compile fix. Submitted by Klaus Kaempf <kkaempf@suse.de> 00167 * 00168 * Revision 1.79 2002/06/13 08:34:05 rogerh 00169 * gcc 3.1 needs iostream instead of iostream.h 00170 * 00171 * Revision 1.78 2002/05/22 00:23:31 craigs 00172 * Added GMTTime flag to tracing options 00173 * 00174 * Revision 1.77 2002/04/19 00:20:51 craigs 00175 * Added option to append to log file rather than create anew each time 00176 * 00177 * Revision 1.76 2002/01/26 23:55:55 craigs 00178 * Changed for GCC 3.0 compatibility, thanks to manty@manty.net 00179 * 00180 * Revision 1.75 2001/10/18 19:56:26 yurik 00181 * Fixed WinCE x86 compilation problems with memory check off 00182 * 00183 * Revision 1.74 2001/08/12 11:26:07 robertj 00184 * Put back PMEMORY_CHECK taken out by the Carbon port. 00185 * 00186 * Revision 1.73 2001/08/11 07:57:30 rogerh 00187 * Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com> 00188 * 00189 * Revision 1.72 2001/05/03 06:27:29 robertj 00190 * Added return value to PMemoryCheck::SetIgnoreAllocations() so get previous state. 00191 * 00192 * Revision 1.71 2001/03/24 01:11:10 robertj 00193 * Added missing PTRACE_IF define in non PTRACING mode. 00194 * 00195 * Revision 1.70 2001/03/23 05:34:09 robertj 00196 * Added PTRACE_IF to output trace if a conditional is TRUE. 00197 * 00198 * Revision 1.69 2001/03/01 02:15:16 robertj 00199 * Fixed PTRACE_LINE() so drops filename and line which may not be in trace otherwise. 00200 * 00201 * Revision 1.68 2001/02/22 08:16:41 robertj 00202 * Added standard trace file setup subroutine. 00203 * 00204 * Revision 1.67 2001/02/13 03:27:24 robertj 00205 * Added function to do heap validation. 00206 * 00207 * Revision 1.66 2001/02/09 04:41:27 robertj 00208 * Removed added non memrycheck implementations of new/delete when using GNU C++. 00209 * 00210 * Revision 1.65 2001/02/07 04:47:49 robertj 00211 * Added changes for possible random crashes in multi DLL environment 00212 * due to memory allocation wierdness, thanks Milan Dimitrijevic. 00213 * 00214 * Revision 1.64 2001/01/24 06:15:44 yurik 00215 * Windows CE port-related declarations 00216 * 00217 * Revision 1.63 2000/07/28 05:13:47 robertj 00218 * Fixed silly mistake in runtime_malloc() function, should return a pointer! 00219 * 00220 * Revision 1.62 2000/07/20 05:46:34 robertj 00221 * Added runtime_malloc() function for cases where memory check code must be bypassed. 00222 * 00223 * Revision 1.61 2000/07/13 15:45:35 robertj 00224 * Removed #define std that causes everyone so much grief! 00225 * 00226 * Revision 1.60 2000/06/26 11:17:19 robertj 00227 * Nucleus++ port (incomplete). 00228 * 00229 * Revision 1.59 2000/02/29 12:26:14 robertj 00230 * Added named threads to tracing, thanks to Dave Harvey 00231 * 00232 * Revision 1.58 2000/01/07 12:31:12 robertj 00233 * Fixed 8 byte alignment on memory heap checking. 00234 * 00235 * Revision 1.57 2000/01/05 00:29:12 robertj 00236 * Fixed alignment problems in memory checking debug functions. 00237 * 00238 * Revision 1.56 1999/11/30 00:22:54 robertj 00239 * Updated documentation for doc++ 00240 * 00241 * Revision 1.55 1999/11/01 00:10:27 robertj 00242 * Added override of new functions for MSVC memory check code. 00243 * 00244 * Revision 1.54 1999/10/19 09:21:30 robertj 00245 * Added functions to get current trace options and level. 00246 * 00247 * Revision 1.53 1999/09/13 13:15:06 robertj 00248 * Changed PTRACE so will output to system log in PServiceProcess applications. 00249 * 00250 * Revision 1.52 1999/08/24 08:15:23 robertj 00251 * Added missing operator on smart pointer to return the pointer! 00252 * 00253 * Revision 1.51 1999/08/24 06:54:36 robertj 00254 * Cleaned up the smart pointer code (macros). 00255 * 00256 * Revision 1.50 1999/08/22 13:38:39 robertj 00257 * Fixed termination hang up problem with memory check code under unix pthreads. 00258 * 00259 * Revision 1.49 1999/08/17 03:46:40 robertj 00260 * Fixed usage of inlines in optimised version. 00261 * 00262 * Revision 1.48 1999/08/10 10:45:09 robertj 00263 * Added mutex in memory check detection code. 00264 * 00265 * Revision 1.47 1999/07/18 15:08:24 robertj 00266 * Fixed 64 bit compatibility 00267 * 00268 * Revision 1.46 1999/06/14 07:59:37 robertj 00269 * Enhanced tracing again to add options to trace output (timestamps etc). 00270 * 00271 * Revision 1.45 1999/05/01 11:29:19 robertj 00272 * Alpha linux port changes. 00273 * 00274 * Revision 1.44 1999/04/18 12:58:39 robertj 00275 * MSVC 5 backward compatibility 00276 * 00277 * Revision 1.43 1999/03/09 10:30:17 robertj 00278 * Fixed ability to have PMEMORY_CHECK on/off on both debug/release versions. 00279 * 00280 * Revision 1.42 1999/03/09 02:59:50 robertj 00281 * Changed comments to doc++ compatible documentation. 00282 * 00283 * Revision 1.41 1999/02/23 07:11:26 robertj 00284 * Improved trace facility adding trace levels and #define to remove all trace code. 00285 * 00286 * Revision 1.40 1999/02/22 10:48:14 robertj 00287 * Fixed delete operator prototypes for MSVC6 and GNU compatibility. 00288 * 00289 * Revision 1.39 1999/02/19 11:33:02 robertj 00290 * Fixed compatibility problems with GNU/MSVC6 00291 * 00292 * Revision 1.38 1999/02/16 08:12:22 robertj 00293 * MSVC 6.0 compatibility changes. 00294 * 00295 * Revision 1.37 1999/01/07 03:35:35 robertj 00296 * Added default for PCHAR8 to ANSI, removes need for compiler option. 00297 * 00298 * Revision 1.36 1998/12/15 09:00:29 robertj 00299 * Fixed 8 byte alignment problem in memory leak check code for sparc. 00300 * 00301 * Revision 1.35 1998/11/03 00:57:19 robertj 00302 * Added allocation breakpoint variable. 00303 * 00304 * Revision 1.34 1998/10/26 11:05:26 robertj 00305 * Added raw free for things allocated within the runtime library. 00306 * 00307 * Revision 1.33 1998/10/18 14:26:55 robertj 00308 * Improved tracing functions. 00309 * 00310 * Revision 1.32 1998/10/15 07:47:21 robertj 00311 * Added ability to ignore G++lib memory leaks. 00312 * 00313 * Revision 1.31 1998/10/15 01:53:58 robertj 00314 * GNU compatibility. 00315 * 00316 * Revision 1.30 1998/10/13 14:23:29 robertj 00317 * Complete rewrite of memory leak detection. 00318 * 00319 * Revision 1.29 1998/09/23 06:20:57 robertj 00320 * Added open source copyright license. 00321 * 00322 * Revision 1.28 1998/09/14 12:29:11 robertj 00323 * Fixed memory leak dump under windows to not include static globals. 00324 * Fixed problem with notifier declaration not allowing implementation inline after macro. 00325 * 00326 * Revision 1.27 1997/07/08 13:13:45 robertj 00327 * DLL support. 00328 * 00329 * Revision 1.26 1997/04/27 05:50:11 robertj 00330 * DLL support. 00331 * 00332 * Revision 1.25 1997/02/05 11:54:10 robertj 00333 * Fixed problems with memory check and leak detection. 00334 * 00335 * Revision 1.24 1996/09/16 12:57:23 robertj 00336 * DLL support 00337 * 00338 * Revision 1.23 1996/08/17 10:00:23 robertj 00339 * Changes for Windows DLL support. 00340 * 00341 * Revision 1.22 1996/07/15 10:27:51 robertj 00342 * Changed endian classes to be memory mapped. 00343 * 00344 * Revision 1.21 1996/05/09 12:14:48 robertj 00345 * Fixed up 64 bit integer class for Mac platform. 00346 * 00347 * Revision 1.20 1996/02/24 14:19:29 robertj 00348 * Fixed bug in endian independent integer code for memory transfers. 00349 * 00350 * Revision 1.19 1996/01/28 02:46:43 robertj 00351 * Removal of MemoryPointer classes as usage didn't work for GNU. 00352 * Added missing bit shift operators to 64 bit integer class. 00353 * 00354 * Revision 1.18 1996/01/23 13:14:32 robertj 00355 * Added const version of PMemoryPointer. 00356 * Added constructor to endian classes for the base type. 00357 * 00358 * Revision 1.17 1996/01/02 11:54:11 robertj 00359 * Mac OS compatibility changes. 00360 * 00361 * Revision 1.16 1995/11/09 12:17:10 robertj 00362 * Added platform independent base type access classes. 00363 * 00364 * Revision 1.15 1995/06/17 11:12:47 robertj 00365 * Documentation update. 00366 * 00367 * Revision 1.14 1995/06/04 12:34:19 robertj 00368 * Added trace functions. 00369 * 00370 * Revision 1.13 1995/04/25 12:04:35 robertj 00371 * Fixed borland compatibility. 00372 * Fixed function hiding ancestor virtuals. 00373 * 00374 * Revision 1.12 1995/03/14 12:41:54 robertj 00375 * Updated documentation to use HTML codes. 00376 * 00377 * Revision 1.11 1995/03/12 04:40:55 robertj 00378 * Changed standard error code for not open from file to channel. 00379 * 00380 * Revision 1.10 1995/02/19 04:19:14 robertj 00381 * Added dynamically linked command processing. 00382 * 00383 * Revision 1.9 1995/02/05 00:48:07 robertj 00384 * Fixed template version. 00385 * 00386 * Revision 1.8 1995/01/15 04:51:31 robertj 00387 * Mac compatibility. 00388 * Added levels of memory checking. 00389 * 00390 * Revision 1.7 1995/01/09 12:38:31 robertj 00391 * Changed variable names around during documentation run. 00392 * Fixed smart pointer comparison. 00393 * Fixed serialisation stuff. 00394 * Documentation. 00395 * 00396 * Revision 1.6 1995/01/03 09:39:06 robertj 00397 * Put standard malloc style memory allocation etc into memory check system. 00398 * 00399 * Revision 1.5 1994/12/12 10:08:30 robertj 00400 * Renamed PWrapper to PSmartPointer.. 00401 * 00402 * Revision 1.4 1994/12/05 11:23:28 robertj 00403 * Fixed PWrapper macros. 00404 * 00405 * Revision 1.3 1994/11/19 00:22:55 robertj 00406 * Changed PInteger to be INT, ie standard type like BOOL/WORD etc. 00407 * Moved null object check in notifier to construction rather than use. 00408 * Added virtual to the callback function in notifier destination class. 00409 * 00410 * Revision 1.2 1994/11/03 09:25:30 robertj 00411 * Made notifier destination object not to be descendent of PObject. 00412 * 00413 * Revision 1.1 1994/10/30 12:01:37 robertj 00414 * Initial revision 00415 * 00416 */ 00417 00418 #ifndef _POBJECT_H 00419 #define _POBJECT_H 00420 00421 #ifdef P_USE_PRAGMA 00422 #pragma interface 00423 #endif 00424 00425 #ifdef _WIN32 00426 #include "msos/ptlib/contain.h" 00427 #else 00428 #include "unix/ptlib/contain.h" 00429 #endif 00430 00431 #if defined(P_VXWORKS) 00432 #include <private/stdiop.h> 00433 #endif 00434 00435 #include <stdio.h> 00436 #include <stdarg.h> 00437 #include <stdlib.h> 00438 00439 #ifdef _WIN32 00440 #include <malloc.h> 00441 #endif 00442 00443 #include <string.h> 00444 00445 #ifdef __USE_STL__ 00446 #include <string> 00447 #include <iomanip> 00448 #include <iostream> 00449 #if (__GNUC__ >= 3) 00450 #include <sstream> 00451 typedef std::ostringstream ostrstream; 00452 #else 00453 #include <strstream> 00454 #endif 00455 //using namespace std; 00456 #else 00457 #if (__GNUC__ >= 3) 00458 #include <iostream> 00459 #ifndef __MWERKS__ 00460 #include <iomanip> 00461 #endif 00462 #else 00463 #include <iostream.h> 00464 #ifdef __GNUC__ 00465 #include <strstream.h> 00466 #else 00467 #include <strstrea.h> 00468 #endif 00469 #ifndef __MWERKS__ 00470 #include <iomanip.h> 00471 #endif 00472 #endif 00473 #endif 00474 00475 #ifdef _WIN32_WCE 00476 #include <stdlibx.h> 00477 #endif 00478 00479 #if (__GNUC__ < 3) 00480 typedef long _Ios_Fmtflags; 00481 #endif 00482 00483 #if _MSC_VER<1300 00484 #define _BADOFF -1 00485 #endif 00486 00488 // Disable inlines when debugging for faster compiles (the compiler doesn't 00489 // actually inline the function with debug on any way). 00490 00491 #ifndef P_USE_INLINES 00492 #ifdef _DEBUG 00493 #define P_USE_INLINES 0 00494 #else 00495 #define P_USE_INLINES 0 00496 #endif 00497 #endif 00498 00499 #if P_USE_INLINES 00500 #define PINLINE inline 00501 #else 00502 #define PINLINE 00503 #endif 00504 00505 00507 // Declare the debugging support 00508 00509 #ifndef P_USE_ASSERTS 00510 #define P_USE_ASSERTS 1 00511 #endif 00512 00513 #if !P_USE_ASSERTS 00514 00515 #define PAssert(b, m) (b) 00516 #define PAssert2(b, c, m) (b) 00517 #define PAssertOS(b) (b) 00518 #define PAssertNULL(p) (p) 00519 #define PAssertAlways(m) 00520 #define PAssertAlways2(c, m) 00521 00522 #else // P_USE_ASSERTS 00523 00525 enum PStandardAssertMessage { 00526 PLogicError, // A logic error occurred. 00527 POutOfMemory, // A new or malloc failed. 00528 PNullPointerReference, // A reference was made through a NULL pointer. 00529 PInvalidCast, // An invalid cast to descendant is required. 00530 PInvalidArrayIndex, // An index into an array was negative. 00531 PInvalidArrayElement, // A NULL array element object was accessed. 00532 PStackEmpty, // A Pop() was made of a stack with no elements. 00533 PUnimplementedFunction, // Funtion is not implemented. 00534 PInvalidParameter, // Invalid parameter was passed to a function. 00535 POperatingSystemError, // Error was returned by Operating System. 00536 PChannelNotOpen, // Operation attempted when channel not open. 00537 PUnsupportedFeature, // Feature is not supported. 00538 PInvalidWindow, // Access through invalid window. 00539 PMaxStandardAssertMessage 00540 }; 00541 00542 #define __CLASS__ NULL 00543 00544 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg); 00545 void PAssertFunc(const char * file, int line, const char * className, const char * msg); 00546 void PAssertFunc(const char * full_msg); 00547 00548 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, PStandardAssertMessage msg) 00549 { 00550 if (!b) 00551 PAssertFunc(file, line, className, msg); 00552 return b; 00553 } 00554 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, const char * msg) 00555 { 00556 if (!b) 00557 PAssertFunc(file, line, className, msg); 00558 return b; 00559 } 00560 00567 #define PAssert(b, m) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(m)) 00568 00576 #define PAssert2(b, c, m) PAssertFuncInline((b), __FILE__,__LINE__,(c),(m)) 00577 00584 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError) 00585 00595 #define PAssertNULL(p) (((p)!=NULL)?(p): \ 00596 (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(p))) 00597 00604 #define PAssertAlways(m) PAssertFunc(__FILE__,__LINE__,__CLASS__,(m)) 00605 00612 #define PAssertAlways2(c, m) PAssertFunc(__FILE__,__LINE__,(c),(m)) 00613 00614 #endif // P_USE_ASSERTS 00615 00616 00621 ostream & PGetErrorStream(); 00622 00626 void PSetErrorStream(ostream * strm ); 00627 00642 #define PError (PGetErrorStream()) 00643 00644 00645 00647 // Debug and tracing 00648 00649 #ifndef PTRACING 00650 #ifndef _DEBUG 00651 #define PTRACING 0 00652 #else 00653 #define PTRACING 1 00654 #endif 00655 #endif 00656 00661 class PTrace 00662 { 00663 public: 00665 enum Options { 00671 Blocks = 1, 00673 DateAndTime = 2, 00675 Timestamp = 4, 00677 Thread = 8, 00679 TraceLevel = 16, 00681 FileAndLine = 32, 00683 ThreadAddress = 64, 00685 AppendToFile = 128, 00688 GMTTime = 256, 00691 RotateDaily = 512, 00695 SystemLogStream = 32768 00696 }; 00697 00705 static void Initialise( 00706 unsigned level, 00707 const char * filename = NULL, 00708 unsigned options = Timestamp | Thread | Blocks 00709 ); 00710 00717 static void SetOptions(unsigned options ); 00718 00726 static void ClearOptions(unsigned options ); 00727 00732 static unsigned GetOptions(); 00733 00739 static void SetLevel(unsigned level ); 00740 00746 static unsigned GetLevel(); 00747 00752 static BOOL CanTrace(unsigned level ); 00753 00758 static void SetStream(ostream * out ); 00759 00775 static ostream & Begin( 00776 unsigned level, 00777 const char * fileName, 00778 int lineNum 00779 ); 00780 00797 static ostream & End(ostream & strm ); 00798 00799 00805 class Block { 00806 public: 00808 Block( 00809 const char * fileName, 00810 int lineNum, 00811 const char * traceName 00813 ); 00815 ~Block(); 00816 private: 00817 const char * file; 00818 int line; 00819 const char * name; 00820 }; 00821 }; 00822 00823 #if !PTRACING 00824 00825 #define PTRACE_PARAM(param) 00826 #define PTRACE_BLOCK(n) 00827 #define PTRACE_LINE() 00828 #define PTRACE(level, arg) 00829 #define PTRACE_IF(level, cond, args) 00830 00831 #else 00832 00833 /* Macro to conditionally declare a parameter to a function to avoid compiler 00834 warning due that parameter only being used in a PTRACE */ 00835 #define PTRACE_PARAM(param) param 00836 00843 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name) 00844 00848 #define PTRACE_LINE() \ 00849 if (!PTrace::CanTrace(1)) ; else \ 00850 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End 00851 00857 #define PTRACE(level, args) \ 00858 if (!PTrace::CanTrace(level)) ; else \ 00859 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End 00860 00868 #define PTRACE_IF(level, cond, args) \ 00869 if (!(PTrace::CanTrace(level) && (cond))) ; else \ 00870 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End 00871 00872 #endif 00873 00874 #if PMEMORY_CHECK 00875 00882 class PMemoryHeap { 00883 protected: 00885 PMemoryHeap(); 00886 00887 public: 00888 // Clear up the memory checking subsystem, dumping memory leaks. 00889 ~PMemoryHeap(); 00890 00897 static void * Allocate( 00898 size_t nSize, 00899 const char * file, 00900 int line, 00901 const char * className 00902 ); 00909 static void * Allocate( 00910 size_t count, 00911 size_t iSize, 00912 const char * file, 00913 int line 00914 ); 00915 00923 static void * Reallocate( 00924 void * ptr, 00925 size_t nSize, 00926 const char * file, 00927 int line 00928 ); 00929 00935 static void Deallocate( 00936 void * ptr, 00937 const char * className 00938 ); 00939 00942 enum Validation { 00943 Ok, Bad, Trashed 00944 }; 00952 static Validation Validate( 00953 void * ptr, 00954 const char * className, 00955 ostream * error 00956 ); 00957 00962 static BOOL ValidateHeap( 00963 ostream * error = NULL 00964 ); 00965 00971 static BOOL SetIgnoreAllocations( 00972 BOOL ignore 00973 ); 00974 00978 static void DumpStatistics(); 00982 static void DumpStatistics(ostream & strm ); 00983 00984 /* Get number of allocation. 00985 Each allocation is counted and if desired the next allocation request 00986 number may be obtained via this function. 00987 @return Allocation request number. 00988 */ 00989 static DWORD GetAllocationRequest(); 00990 00998 static void DumpObjectsSince( 00999 DWORD objectNumber 01000 ); 01001 01007 static void DumpObjectsSince( 01008 DWORD objectNumber, 01009 ostream & strm 01010 ); 01011 01017 static void SetAllocationBreakpoint( 01018 DWORD point 01019 ); 01020 01021 protected: 01022 void * InternalAllocate( 01023 size_t nSize, // Number of bytes to allocate. 01024 const char * file, // Source file name for allocating function. 01025 int line, // Source file line for allocating function. 01026 const char * className // Class name for allocating function. 01027 ); 01028 Validation InternalValidate( 01029 void * ptr, // Pointer to memory block to check 01030 const char * className, // Class name it should be. 01031 ostream * error // Stream to receive error message (may be NULL) 01032 ); 01033 void InternalDumpStatistics(ostream & strm); 01034 void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm); 01035 01036 class Wrapper { 01037 public: 01038 Wrapper(); 01039 ~Wrapper(); 01040 PMemoryHeap * operator->() const { return instance; } 01041 private: 01042 PMemoryHeap * instance; 01043 }; 01044 friend class Wrapper; 01045 01046 enum Flags { 01047 NoLeakPrint = 1 01048 }; 01049 01050 #pragma pack(1) 01051 struct Header { 01052 enum { 01053 // Assure that the Header struct is aligned to 8 byte boundary 01054 NumGuardBytes = 16 - (sizeof(Header *) + 01055 sizeof(Header *) + 01056 sizeof(const char *) + 01057 sizeof(const char *) + 01058 sizeof(size_t) + 01059 sizeof(DWORD) + 01060 sizeof(WORD) + 01061 sizeof(BYTE))%8 01062 }; 01063 01064 Header * prev; 01065 Header * next; 01066 const char * className; 01067 const char * fileName; 01068 size_t size; 01069 DWORD request; 01070 WORD line; 01071 BYTE flags; 01072 char guard[NumGuardBytes]; 01073 01074 static char GuardBytes[NumGuardBytes]; 01075 }; 01076 #pragma pack() 01077 01078 BOOL isDestroyed; 01079 01080 Header * listHead; 01081 Header * listTail; 01082 01083 static DWORD allocationBreakpoint; 01084 DWORD allocationRequest; 01085 DWORD firstRealObject; 01086 BYTE flags; 01087 01088 char allocFillChar; 01089 char freeFillChar; 01090 01091 DWORD currentMemoryUsage; 01092 DWORD peakMemoryUsage; 01093 DWORD currentObjects; 01094 DWORD peakObjects; 01095 DWORD totalObjects; 01096 01097 ostream * leakDumpStream; 01098 01099 #if defined(_WIN32) 01100 CRITICAL_SECTION mutex; 01101 #elif defined(P_PTHREADS) 01102 pthread_mutex_t mutex; 01103 #elif defined(P_VXWORKS) 01104 void * mutex; 01105 #endif 01106 }; 01107 01108 01113 inline void * runtime_malloc(size_t bytes ) { return malloc(bytes); } 01114 01119 inline void runtime_free(void * ptr ) { free(ptr); } 01120 01121 01128 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL) 01129 01136 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__) 01137 01144 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__) 01145 01146 01153 #define free(p) PMemoryHeap::Deallocate(p, NULL) 01154 01155 01162 #define cfree(p) PMemoryHeap::Deallocate(p, NULL) 01163 01164 01179 #define PNEW new (__FILE__, __LINE__) 01180 01181 #if !defined(_MSC_VER) || _MSC_VER<1200 01182 #define PSPECIAL_DELETE_FUNCTION 01183 #else 01184 #define PSPECIAL_DELETE_FUNCTION \ 01185 void operator delete(void * ptr, const char *, int) \ 01186 { PMemoryHeap::Deallocate(ptr, Class()); } \ 01187 void operator delete[](void * ptr, const char *, int) \ 01188 { PMemoryHeap::Deallocate(ptr, Class()); } 01189 #endif 01190 01191 #define PNEW_AND_DELETE_FUNCTIONS \ 01192 void * operator new(size_t nSize, const char * file, int line) \ 01193 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \ 01194 void * operator new(size_t nSize) \ 01195 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \ 01196 void operator delete(void * ptr) \ 01197 { PMemoryHeap::Deallocate(ptr, Class()); } \ 01198 void * operator new[](size_t nSize, const char * file, int line) \ 01199 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \ 01200 void * operator new[](size_t nSize) \ 01201 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \ 01202 void operator delete[](void * ptr) \ 01203 { PMemoryHeap::Deallocate(ptr, Class()); } \ 01204 PSPECIAL_DELETE_FUNCTION 01205 01206 01207 inline void * operator new(size_t nSize, const char * file, int line) 01208 { return PMemoryHeap::Allocate(nSize, file, line, NULL); } 01209 01210 inline void * operator new[](size_t nSize, const char * file, int line) 01211 { return PMemoryHeap::Allocate(nSize, file, line, NULL); } 01212 01213 #ifndef __GNUC__ 01214 void * operator new(size_t nSize); 01215 void * operator new[](size_t nSize); 01216 01217 void operator delete(void * ptr); 01218 void operator delete[](void * ptr); 01219 01220 #if defined(_MSC_VER) && _MSC_VER>=1200 01221 inline void operator delete(void * ptr, const char *, int) 01222 { PMemoryHeap::Deallocate(ptr, NULL); } 01223 01224 inline void operator delete[](void * ptr, const char *, int) 01225 { PMemoryHeap::Deallocate(ptr, NULL); } 01226 #endif 01227 #endif 01228 01229 01230 #else // PMEMORY_CHECK 01231 01232 #define PNEW new 01233 01234 #if defined(__GNUC__) || (defined(_WIN32_WCE) && defined(_X86_)) 01235 01236 #define PNEW_AND_DELETE_FUNCTIONS 01237 01238 #else 01239 01240 #define PNEW_AND_DELETE_FUNCTIONS \ 01241 void * operator new(size_t nSize) \ 01242 { return malloc(nSize); } \ 01243 void operator delete(void * ptr) \ 01244 { free(ptr); } \ 01245 void * operator new[](size_t nSize) \ 01246 { return malloc(nSize); } \ 01247 void operator delete[](void * ptr) \ 01248 { free(ptr); } 01249 01250 void * operator new(size_t nSize); 01251 void * operator new[](size_t nSize); 01252 01253 void operator delete(void * ptr); 01254 void operator delete[](void * ptr); 01255 01256 #endif 01257 01258 #define runtime_malloc(s) malloc(s) 01259 #define runtime_free(p) free(p) 01260 01261 #endif // PMEMORY_CHECK 01262 01263 01274 /* 01275 01276 ORIGINAL 01277 01278 #define PCLASSINFO(cls, par) \ 01279 public: \ 01280 static const char * Class() \ 01281 { return #cls; } \ 01282 virtual const char * GetClass(unsigned ancestor = 0) const \ 01283 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \ 01284 virtual BOOL IsClass(const char * clsName) const \ 01285 { return strcmp(clsName, cls::Class()) == 0; } \ 01286 virtual BOOL IsDescendant(const char * clsName) const \ 01287 { return strcmp(clsName, cls::Class()) == 0 || par::IsDescendant(clsName); } \ 01288 virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \ 01289 { return (Comparison)memcmp(this, &obj, sizeof(cls)); } 01290 */ 01291 01292 01293 #if P_HAS_TYPEINFO 01294 01295 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL) 01296 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str)) 01297 01298 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr)) 01299 01300 #if P_USE_ASSERTS 01301 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line) 01302 { if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; } 01303 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__) 01304 #else 01305 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr)) 01306 #endif 01307 01308 #include <typeinfo> 01309 01310 #define PCLASSNAME(cls) (#cls) 01311 01312 #define PBASECLASSINFO(cls, par) \ 01313 public: \ 01314 static inline const char * Class() \ 01315 { return PCLASSNAME(cls); } \ 01316 virtual BOOL InternalIsDescendant(const char * clsName) const \ 01317 { return strcmp(clsName, PCLASSNAME(cls)) == 0 || par::InternalIsDescendant(clsName); } \ 01318 01319 #else // P_HAS_TYPEINFO 01320 01321 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class())) 01322 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str)) 01323 01324 #define PRemoveConst(cls, ptr) ((cls*)(ptr)) 01325 01326 #if P_USE_ASSERTS 01327 template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line) 01328 { if (obj->InternalIsDescendant(BaseClass::Class()) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; } 01329 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__) 01330 #else 01331 #define PDownCast(cls, ptr) ((cls*)(ptr)) 01332 #endif 01333 01334 #define PBASECLASSINFO(cls, par) \ 01335 public: \ 01336 static const char * Class() \ 01337 { return #cls; } \ 01338 virtual BOOL InternalIsDescendant(const char * clsName) const \ 01339 { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \ 01340 01341 #endif // P_HAS_TYPEINFO 01342 01343 01344 #define PCLASSINFO(cls, par) \ 01345 PBASECLASSINFO(cls, par) \ 01346 virtual const char * GetClass(unsigned ancestor = 0) const \ 01347 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \ 01348 virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \ 01349 { return (Comparison)memcmp(this, &obj, sizeof(cls)); } \ 01350 01351 01359 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par) 01360 #ifdef DOC_PLUS_PLUS 01361 } Match previous opening brace in doc++ 01362 #endif 01363 01365 // The root of all evil ... umm classes 01366 01371 class PObject { 01372 01373 protected: 01377 PObject() { } 01378 01379 public: 01380 /* Destructor required to get the "virtual". A PObject really has nothing 01381 to destroy. 01382 */ 01383 virtual ~PObject() { } 01384 01397 static inline const char * Class() { return PCLASSNAME(PObject); } 01398 01411 virtual const char * GetClass(unsigned /*ancestor*/ = 0) const { return Class(); } 01412 01413 BOOL IsClass(const char * cls) const 01414 { return strcmp(cls, GetClass()) == 0; } 01415 01425 virtual BOOL InternalIsDescendant( 01426 const char * clsName // Ancestor class name to compare against. 01427 ) const 01428 { return IsClass(clsName); } 01429 01431 01437 enum Comparison { 01438 LessThan = -1, 01439 EqualTo = 0, 01440 GreaterThan = 1 01441 }; 01442 01454 virtual Comparison Compare( 01455 const PObject & obj // Object to compare against. 01456 ) const; 01457 01469 virtual Comparison CompareObjectMemoryDirect( 01470 const PObject & obj // Object to compare against. 01471 ) const; 01472 01478 bool operator==( 01479 const PObject & obj // Object to compare against. 01480 ) const { return Compare(obj) == EqualTo; } 01481 01487 bool operator!=( 01488 const PObject & obj // Object to compare against. 01489 ) const { return Compare(obj) != EqualTo; } 01490 01496 bool operator<( 01497 const PObject & obj // Object to compare against. 01498 ) const { return Compare(obj) == LessThan; } 01499 01505 bool operator>( 01506 const PObject & obj // Object to compare against. 01507 ) const { return Compare(obj) == GreaterThan; } 01508 01514 bool operator<=( 01515 const PObject & obj // Object to compare against. 01516 ) const { return Compare(obj) != GreaterThan; } 01517 01523 bool operator>=( 01524 const PObject & obj // Object to compare against. 01525 ) const { return Compare(obj) != LessThan; } 01527 01536 virtual void PrintOn( 01537 ostream &strm // Stream to print the object into. 01538 ) const; 01539 01546 virtual void ReadFrom( 01547 istream &strm // Stream to read the objects contents from. 01548 ); 01549 01550 01556 inline friend ostream & operator<<( 01557 ostream &strm, // Stream to print the object into. 01558 const PObject & obj // Object to print to the stream. 01559 ) { obj.PrintOn(strm); return strm; } 01560 01566 inline friend istream & operator>>( 01567 istream &strm, // Stream to read the objects contents from. 01568 PObject & obj // Object to read inormation into. 01569 ) { obj.ReadFrom(strm); return strm; } 01570 01571 01586 virtual PObject * Clone() const; 01587 01599 virtual PINDEX HashFunction() const; 01601 }; 01602 01604 // Platform independent types 01605 01606 // All these classes encapsulate primitive types such that they may be 01607 // transfered in a platform independent manner. In particular it is used to 01608 // do byte swapping for little endien and big endien processor architectures 01609 // as well as accommodating structure packing rules for memory structures. 01610 01611 #define PANSI_CHAR 1 01612 #define PLITTLE_ENDIAN 2 01613 #define PBIG_ENDIAN 3 01614 01615 01616 #if 0 01617 class PStandardType 01618 /* Encapsulate a standard 8 bit character into a portable format. This would 01619 rarely need to do translation, only if the target platform uses EBCDIC 01620 would it do anything. 01621 01622 The platform independent form here is always 8 bit ANSI. 01623 */ 01624 { 01625 public: 01626 PStandardType( 01627 type newVal // Value to initialise data in platform dependent form. 01628 ) { data = newVal; } 01629 /* Create a new instance of the platform independent type using platform 01630 dependent data, or platform independent streams. 01631 */ 01632 01633 operator type() { return data; } 01634 /* Get the platform dependent value for the type. 01635 01636 @return 01637 data for instance. 01638 */ 01639 01640 friend ostream & operator<<(ostream & strm, const PStandardType & val) 01641 { return strm << (type)val; } 01642 /* Output the platform dependent value for the type to the stream. 01643 01644 @return 01645 the stream output was made to. 01646 */ 01647 01648 friend istream & operator>>(istream & strm, PStandardType & val) 01649 { type data; strm >> data; val = PStandardType(data); return strm; } 01650 /* Input the platform dependent value for the type from the stream. 01651 01652 @return 01653 the stream input was made from. 01654 */ 01655 01656 01657 private: 01658 type data; 01659 }; 01660 #endif 01661 01662 01663 #define PI_SAME(name, type) \ 01664 struct name { \ 01665 name() { } \ 01666 name(type value) { data = value; } \ 01667 name(const name & value) { data = value.data; } \ 01668 name & operator =(type value) { data = value; return *this; } \ 01669 name & operator =(const name & value) { data = value.data; return *this; } \ 01670 operator type() const { return data; } \ 01671 friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \ 01672 friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \ 01673 private: type data; \ 01674 } 01675 01676 #define PI_LOOP(src, dst) \ 01677 BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \ 01678 while (s != (BYTE *)&src) *d++ = *--s; 01679 01680 #define PI_DIFF(name, type) \ 01681 struct name { \ 01682 name() { } \ 01683 name(type value) { operator=(value); } \ 01684 name(const name & value) { data = value.data; } \ 01685 name & operator =(type value) { PI_LOOP(value, data); return *this; } \ 01686 name & operator =(const name & value) { data = value.data; return *this; } \ 01687 operator type() const { type value; PI_LOOP(data, value); return value; } \ 01688 friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \ 01689 friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \ 01690 private: type data; \ 01691 } 01692 01693 #ifndef PCHAR8 01694 #define PCHAR8 PANSI_CHAR 01695 #endif 01696 01697 #if PCHAR8==PANSI_CHAR 01698 PI_SAME(PChar8, char); 01699 #endif 01700 01701 PI_SAME(PInt8, signed char); 01702 01703 PI_SAME(PUInt8, unsigned char); 01704 01705 #if PBYTE_ORDER==PLITTLE_ENDIAN 01706 PI_SAME(PInt16l, PInt16); 01707 #elif PBYTE_ORDER==PBIG_ENDIAN 01708 PI_DIFF(PInt16l, PInt16); 01709 #endif 01710 01711 #if PBYTE_ORDER==PLITTLE_ENDIAN 01712 PI_DIFF(PInt16b, PInt16); 01713 #elif PBYTE_ORDER==PBIG_ENDIAN 01714 PI_SAME(PInt16b, PInt16); 01715 #endif 01716 01717 #if PBYTE_ORDER==PLITTLE_ENDIAN 01718 PI_SAME(PUInt16l, WORD); 01719 #elif PBYTE_ORDER==PBIG_ENDIAN 01720 PI_DIFF(PUInt16l, WORD); 01721 #endif 01722 01723 #if PBYTE_ORDER==PLITTLE_ENDIAN 01724 PI_DIFF(PUInt16b, WORD); 01725 #elif PBYTE_ORDER==PBIG_ENDIAN 01726 PI_SAME(PUInt16b, WORD); 01727 #endif 01728 01729 #if PBYTE_ORDER==PLITTLE_ENDIAN 01730 PI_SAME(PInt32l, PInt32); 01731 #elif PBYTE_ORDER==PBIG_ENDIAN 01732 PI_DIFF(PInt32l, PInt32); 01733 #endif 01734 01735 #if PBYTE_ORDER==PLITTLE_ENDIAN 01736 PI_DIFF(PInt32b, PInt32); 01737 #elif PBYTE_ORDER==PBIG_ENDIAN 01738 PI_SAME(PInt32b, PInt32); 01739 #endif 01740 01741 #if PBYTE_ORDER==PLITTLE_ENDIAN 01742 PI_SAME(PUInt32l, DWORD); 01743 #elif PBYTE_ORDER==PBIG_ENDIAN 01744 PI_DIFF(PUInt32l, DWORD); 01745 #endif 01746 01747 #if PBYTE_ORDER==PLITTLE_ENDIAN 01748 PI_DIFF(PUInt32b, DWORD); 01749 #elif PBYTE_ORDER==PBIG_ENDIAN 01750 PI_SAME(PUInt32b, DWORD); 01751 #endif 01752 01753 #if PBYTE_ORDER==PLITTLE_ENDIAN 01754 PI_SAME(PInt64l, PInt64); 01755 #elif PBYTE_ORDER==PBIG_ENDIAN 01756 PI_DIFF(PInt64l, PInt64); 01757 #endif 01758 01759 #if PBYTE_ORDER==PLITTLE_ENDIAN 01760 PI_DIFF(PInt64b, PInt64); 01761 #elif PBYTE_ORDER==PBIG_ENDIAN 01762 PI_SAME(PInt64b, PInt64); 01763 #endif 01764 01765 #if PBYTE_ORDER==PLITTLE_ENDIAN 01766 PI_SAME(PUInt64l, PUInt64); 01767 #elif PBYTE_ORDER==PBIG_ENDIAN 01768 PI_DIFF(PUInt64l, PUInt64); 01769 #endif 01770 01771 #if PBYTE_ORDER==PLITTLE_ENDIAN 01772 PI_DIFF(PUInt64b, PUInt64); 01773 #elif PBYTE_ORDER==PBIG_ENDIAN 01774 PI_SAME(PUInt64b, PUInt64); 01775 #endif 01776 01777 #if PBYTE_ORDER==PLITTLE_ENDIAN 01778 PI_SAME(PFloat32l, float); 01779 #elif PBYTE_ORDER==PBIG_ENDIAN 01780 PI_DIFF(PFloat32l, float); 01781 #endif 01782 01783 #if PBYTE_ORDER==PLITTLE_ENDIAN 01784 PI_DIFF(PFloat32b, float); 01785 #elif PBYTE_ORDER==PBIG_ENDIAN 01786 PI_SAME(PFloat32b, float); 01787 #endif 01788 01789 #if PBYTE_ORDER==PLITTLE_ENDIAN 01790 PI_SAME(PFloat64l, double); 01791 #elif PBYTE_ORDER==PBIG_ENDIAN 01792 PI_DIFF(PFloat64l, double); 01793 #endif 01794 01795 #if PBYTE_ORDER==PLITTLE_ENDIAN 01796 PI_DIFF(PFloat64b, double); 01797 #elif PBYTE_ORDER==PBIG_ENDIAN 01798 PI_SAME(PFloat64b, double); 01799 #endif 01800 01801 #ifndef NO_LONG_DOUBLE // stupid OSX compiler 01802 #if PBYTE_ORDER==PLITTLE_ENDIAN 01803 PI_SAME(PFloat80l, long double); 01804 #elif PBYTE_ORDER==PBIG_ENDIAN 01805 PI_DIFF(PFloat80l, long double); 01806 #endif 01807 01808 #if PBYTE_ORDER==PLITTLE_ENDIAN 01809 PI_DIFF(PFloat80b, long double); 01810 #elif PBYTE_ORDER==PBIG_ENDIAN 01811 PI_SAME(PFloat80b, long double); 01812 #endif 01813 #endif 01814 01815 #undef PI_LOOP 01816 #undef PI_SAME 01817 #undef PI_DIFF 01818 01819 01821 // Miscellaneous 01822 01823 /*$MACRO PARRAYSIZE(array) 01824 This macro is used to calculate the number of array elements in a static 01825 array. 01826 */ 01827 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0]))) 01828 01829 /*$MACRO PMIN(v1, v2) 01830 This macro is used to calculate the minimum of two values. As this is a 01831 macro the expression in #v1# or #v2# is executed 01832 twice so extreme care should be made in its use. 01833 */ 01834 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2)) 01835 01836 /*$MACRO PMAX(v1, v2) 01837 This macro is used to calculate the maximum of two values. As this is a 01838 macro the expression in #v1# or #v2# is executed 01839 twice so extreme care should be made in its use. 01840 */ 01841 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2)) 01842 01843 /*$MACRO PABS(val) 01844 This macro is used to calculate an absolute value. As this is a macro the 01845 expression in #val# is executed twice so extreme care should be 01846 made in its use. 01847 */ 01848 #define PABS(v) ((v) < 0 ? -(v) : (v)) 01849 01850 #endif // _POBJECT_H 01851 01852 // End Of File ///////////////////////////////////////////////////////////////