object.h
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:87k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * object.h
  3.  *
  4.  * Mother of all ancestor classes.
  5.  *
  6.  * Portable Windows 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.  * $Log: object.h,v $
  30.  * Revision 1.62  2000/07/20 05:46:34  robertj
  31.  * Added runtime_malloc() function for cases where memory check code must be bypassed.
  32.  *
  33.  * Revision 1.61  2000/07/13 15:45:35  robertj
  34.  * Removed #define std that causes everyone so much grief!
  35.  *
  36.  * Revision 1.60  2000/06/26 11:17:19  robertj
  37.  * Nucleus++ port (incomplete).
  38.  *
  39.  * Revision 1.59  2000/02/29 12:26:14  robertj
  40.  * Added named threads to tracing, thanks to Dave Harvey
  41.  *
  42.  * Revision 1.58  2000/01/07 12:31:12  robertj
  43.  * Fixed 8 byte alignment on memory heap checking.
  44.  *
  45.  * Revision 1.57  2000/01/05 00:29:12  robertj
  46.  * Fixed alignment problems in memory checking debug functions.
  47.  *
  48.  * Revision 1.56  1999/11/30 00:22:54  robertj
  49.  * Updated documentation for doc++
  50.  *
  51.  * Revision 1.55  1999/11/01 00:10:27  robertj
  52.  * Added override of new functions for MSVC memory check code.
  53.  *
  54.  * Revision 1.54  1999/10/19 09:21:30  robertj
  55.  * Added functions to get current trace options and level.
  56.  *
  57.  * Revision 1.53  1999/09/13 13:15:06  robertj
  58.  * Changed PTRACE so will output to system log in PServiceProcess applications.
  59.  *
  60.  * Revision 1.52  1999/08/24 08:15:23  robertj
  61.  * Added missing operator on smart pointer to return the pointer!
  62.  *
  63.  * Revision 1.51  1999/08/24 06:54:36  robertj
  64.  * Cleaned up the smart pointer code (macros).
  65.  *
  66.  * Revision 1.50  1999/08/22 13:38:39  robertj
  67.  * Fixed termination hang up problem with memory check code under unix pthreads.
  68.  *
  69.  * Revision 1.49  1999/08/17 03:46:40  robertj
  70.  * Fixed usage of inlines in optimised version.
  71.  *
  72.  * Revision 1.48  1999/08/10 10:45:09  robertj
  73.  * Added mutex in memory check detection code.
  74.  *
  75.  * Revision 1.47  1999/07/18 15:08:24  robertj
  76.  * Fixed 64 bit compatibility
  77.  *
  78.  * Revision 1.46  1999/06/14 07:59:37  robertj
  79.  * Enhanced tracing again to add options to trace output (timestamps etc).
  80.  *
  81.  * Revision 1.45  1999/05/01 11:29:19  robertj
  82.  * Alpha linux port changes.
  83.  *
  84.  * Revision 1.44  1999/04/18 12:58:39  robertj
  85.  * MSVC 5 backward compatibility
  86.  *
  87.  * Revision 1.43  1999/03/09 10:30:17  robertj
  88.  * Fixed ability to have PMEMORY_CHECK on/off on both debug/release versions.
  89.  *
  90.  * Revision 1.42  1999/03/09 02:59:50  robertj
  91.  * Changed comments to doc++ compatible documentation.
  92.  *
  93.  * Revision 1.41  1999/02/23 07:11:26  robertj
  94.  * Improved trace facility adding trace levels and #define to remove all trace code.
  95.  *
  96.  * Revision 1.40  1999/02/22 10:48:14  robertj
  97.  * Fixed delete operator prototypes for MSVC6 and GNU compatibility.
  98.  *
  99.  * Revision 1.39  1999/02/19 11:33:02  robertj
  100.  * Fixed compatibility problems with GNU/MSVC6
  101.  *
  102.  * Revision 1.38  1999/02/16 08:12:22  robertj
  103.  * MSVC 6.0 compatibility changes.
  104.  *
  105.  * Revision 1.37  1999/01/07 03:35:35  robertj
  106.  * Added default for PCHAR8 to ANSI, removes need for compiler option.
  107.  *
  108.  * Revision 1.36  1998/12/15 09:00:29  robertj
  109.  * Fixed 8 byte alignment problem in memory leak check code for sparc.
  110.  *
  111.  * Revision 1.35  1998/11/03 00:57:19  robertj
  112.  * Added allocation breakpoint variable.
  113.  *
  114.  * Revision 1.34  1998/10/26 11:05:26  robertj
  115.  * Added raw free for things allocated within the runtime library.
  116.  *
  117.  * Revision 1.33  1998/10/18 14:26:55  robertj
  118.  * Improved tracing functions.
  119.  *
  120.  * Revision 1.32  1998/10/15 07:47:21  robertj
  121.  * Added ability to ignore G++lib memory leaks.
  122.  *
  123.  * Revision 1.31  1998/10/15 01:53:58  robertj
  124.  * GNU compatibility.
  125.  *
  126.  * Revision 1.30  1998/10/13 14:23:29  robertj
  127.  * Complete rewrite of memory leak detection.
  128.  *
  129.  * Revision 1.29  1998/09/23 06:20:57  robertj
  130.  * Added open source copyright license.
  131.  *
  132.  * Revision 1.28  1998/09/14 12:29:11  robertj
  133.  * Fixed memory leak dump under windows to not include static globals.
  134.  * Fixed problem with notifier declaration not allowing implementation inline after macro.
  135.  *
  136.  * Revision 1.27  1997/07/08 13:13:45  robertj
  137.  * DLL support.
  138.  *
  139.  * Revision 1.26  1997/04/27 05:50:11  robertj
  140.  * DLL support.
  141.  *
  142.  * Revision 1.25  1997/02/05 11:54:10  robertj
  143.  * Fixed problems with memory check and leak detection.
  144.  *
  145.  * Revision 1.24  1996/09/16 12:57:23  robertj
  146.  * DLL support
  147.  *
  148.  * Revision 1.23  1996/08/17 10:00:23  robertj
  149.  * Changes for Windows DLL support.
  150.  *
  151.  * Revision 1.22  1996/07/15 10:27:51  robertj
  152.  * Changed endian classes to be memory mapped.
  153.  *
  154.  * Revision 1.21  1996/05/09 12:14:48  robertj
  155.  * Fixed up 64 bit integer class for Mac platform.
  156.  *
  157.  * Revision 1.20  1996/02/24 14:19:29  robertj
  158.  * Fixed bug in endian independent integer code for memory transfers.
  159.  *
  160.  * Revision 1.19  1996/01/28 02:46:43  robertj
  161.  * Removal of MemoryPointer classes as usage didn't work for GNU.
  162.  * Added missing bit shift operators to 64 bit integer class.
  163.  *
  164.  * Revision 1.18  1996/01/23 13:14:32  robertj
  165.  * Added const version of PMemoryPointer.
  166.  * Added constructor to endian classes for the base type.
  167.  *
  168.  * Revision 1.17  1996/01/02 11:54:11  robertj
  169.  * Mac OS compatibility changes.
  170.  *
  171.  * Revision 1.16  1995/11/09 12:17:10  robertj
  172.  * Added platform independent base type access classes.
  173.  *
  174.  * Revision 1.15  1995/06/17 11:12:47  robertj
  175.  * Documentation update.
  176.  *
  177.  * Revision 1.14  1995/06/04 12:34:19  robertj
  178.  * Added trace functions.
  179.  *
  180.  * Revision 1.13  1995/04/25 12:04:35  robertj
  181.  * Fixed borland compatibility.
  182.  * Fixed function hiding ancestor virtuals.
  183.  *
  184.  * Revision 1.12  1995/03/14 12:41:54  robertj
  185.  * Updated documentation to use HTML codes.
  186.  *
  187.  * Revision 1.11  1995/03/12  04:40:55  robertj
  188.  * Changed standard error code for not open from file to channel.
  189.  *
  190.  * Revision 1.10  1995/02/19  04:19:14  robertj
  191.  * Added dynamically linked command processing.
  192.  *
  193.  * Revision 1.9  1995/02/05  00:48:07  robertj
  194.  * Fixed template version.
  195.  *
  196.  * Revision 1.8  1995/01/15  04:51:31  robertj
  197.  * Mac compatibility.
  198.  * Added levels of memory checking.
  199.  *
  200.  * Revision 1.7  1995/01/09  12:38:31  robertj
  201.  * Changed variable names around during documentation run.
  202.  * Fixed smart pointer comparison.
  203.  * Fixed serialisation stuff.
  204.  * Documentation.
  205.  *
  206.  * Revision 1.6  1995/01/03  09:39:06  robertj
  207.  * Put standard malloc style memory allocation etc into memory check system.
  208.  *
  209.  * Revision 1.5  1994/12/12  10:08:30  robertj
  210.  * Renamed PWrapper to PSmartPointer..
  211.  *
  212.  * Revision 1.4  1994/12/05  11:23:28  robertj
  213.  * Fixed PWrapper macros.
  214.  *
  215.  * Revision 1.3  1994/11/19  00:22:55  robertj
  216.  * Changed PInteger to be INT, ie standard type like BOOL/WORD etc.
  217.  * Moved null object check in notifier to construction rather than use.
  218.  * Added virtual to the callback function in notifier destination class.
  219.  *
  220.  * Revision 1.2  1994/11/03  09:25:30  robertj
  221.  * Made notifier destination object not to be descendent of PObject.
  222.  *
  223.  * Revision 1.1  1994/10/30  12:01:37  robertj
  224.  * Initial revision
  225.  *
  226.  */
  227. #ifdef __GNUC__
  228. #pragma interface
  229. #endif
  230. #include <stdio.h>
  231. #include <stdarg.h>
  232. #include <stdlib.h>
  233. #include <string.h>
  234. #ifdef __USE_STL__
  235. #include <string>
  236. #include <iomanip>
  237. #include <iostream>
  238. #include <strstream>
  239. #else
  240. #include <iostream.h>
  241. #ifndef __MWERKS__
  242. #include <iomanip.h>
  243. #endif
  244. #endif
  245. ///////////////////////////////////////////////////////////////////////////////
  246. // Disable inlines when debugging for faster compiles (the compiler doesn't
  247. // actually inline the function with debug on any way).
  248. #ifndef P_USE_INLINES
  249. #ifdef _DEBUG
  250. #define P_USE_INLINES 0
  251. #else
  252. #define P_USE_INLINES 1
  253. #endif
  254. #endif
  255. #if P_USE_INLINES
  256. #define PINLINE inline
  257. #else
  258. #define PINLINE
  259. #endif
  260. ///////////////////////////////////////////////////////////////////////////////
  261. // Declare the debugging support
  262. /// Standard assert messages for the PAssert macro.
  263. enum PStandardAssertMessage {
  264.   PLogicError,              // A logic error occurred.
  265.   POutOfMemory,             // A new or malloc failed.
  266.   PNullPointerReference,    // A reference was made through a NULL pointer.
  267.   PInvalidCast,             // An invalid cast to descendant is required.
  268.   PInvalidArrayIndex,       // An index into an array was negative.
  269.   PInvalidArrayElement,     // A NULL array element object was accessed.
  270.   PStackEmpty,              // A Pop() was made of a stack with no elements.
  271.   PUnimplementedFunction,   // Funtion is not implemented.
  272.   PInvalidParameter,        // Invalid parameter was passed to a function.
  273.   POperatingSystemError,    // Error was returned by Operating System.
  274.   PChannelNotOpen,          // Operation attempted when channel not open.
  275.   PUnsupportedFeature,      // Feature is not supported.
  276.   PInvalidWindow,           // Access through invalid window.
  277.   PMaxStandardAssertMessage
  278. };
  279. /** This macro is used to assert that a condition must be TRUE.
  280. If the condition is FALSE then an assert function is called with the source
  281. file and line number the macro was instantiated on, plus the message described
  282. by the #msg# parameter. This parameter may be either a standard value
  283. from the #PStandardAssertMessage# enum or a literal string.
  284. */
  285. #define PAssert(b, m) if(b);else PAssertFunc(__FILE__, __LINE__, (m))
  286. /** This macro is used to assert that an operating system call succeeds.
  287. If the condition is FALSE then an assert function is called with the source
  288. file and line number the macro was instantiated on, plus the message
  289. described by the #POperatingSystemError# value in the #PStandardAssertMessage#
  290. enum.
  291.  */
  292. #define PAssertOS(b) 
  293.               if(b);else PAssertFunc(__FILE__, __LINE__, POperatingSystemError)
  294. /** This macro is used to assert that a pointer must be non-null.
  295. If the pointer is NULL then an assert function is called with the source file
  296. and line number the macro was instantiated on, plus the message described by
  297. the PNullPointerReference value in the #PStandardAssertMessage# enum.
  298. Note that this evaluates the expression defined by #ptr# twice. To
  299. prevent incorrect behaviour with this, the macro will assume that the
  300. #ptr# parameter is an L-Value.
  301.  */
  302. #define PAssertNULL(p) ((&(p)&&(p)!=NULL)?(p):(PAssertFunc(__FILE__, 
  303.                                         __LINE__, PNullPointerReference), (p)))
  304. /** This macro is used to assert immediately.
  305. The assert function is called with the source file and line number the macro
  306. was instantiated on, plus the message described by the #msg# parameter. This
  307. parameter may be either a standard value from the #PStandardAssertMessage#
  308. enum or a literal string.
  309. */
  310. #define PAssertAlways(m) PAssertFunc(__FILE__, __LINE__, (m))
  311. void PAssertFunc(const char * file, int line, PStandardAssertMessage msg);
  312. void PAssertFunc(const char * file, int line, const char * msg);
  313. /** Get the stream being used for error output.
  314. This stream is used for all trace output using the various trace functions
  315. and macros.
  316. */
  317. ostream & PGetErrorStream();
  318. /** Set the stream to be used for error output.
  319. This stream is used for all error output using the #PError# macro.
  320. */
  321. void PSetErrorStream(ostream * strm /** New stream for error output */ );
  322. /** This macro is used to access the platform specific error output stream.
  323. This is to be used in preference to assuming #cerr# is always available. On
  324. Unix platforms this {bfis} #cerr# but for MS-Windows this is another stream
  325. that uses the OutputDebugString() Windows API function. Note that a MS-DOS or
  326. Windows NT console application would still use #cerr#.
  327. The #PError# stream would normally only be used for debugging information as
  328. a suitable display is not always available in windowed environments.
  329.    
  330. The macro is a wrapper for a global variable #PErrorStream# which is a pointer
  331. to an #ostream#. The variable is initialised to #cerr# for all but MS-Windows
  332. and NT GUI applications. An application could change this pointer to a
  333. #ofstream# variable of #PError# output is wished to be redirected to a file.
  334. */
  335. #define PError (PGetErrorStream())
  336. ///////////////////////////////////////////////////////////////////////////////
  337. // Debug and tracing
  338. #ifndef PTRACING
  339. #ifndef _DEBUG
  340. #define PTRACING 0
  341. #else
  342. #define PTRACING 1
  343. #endif
  344. #endif
  345. /**Class to encapsulate tracing functions.
  346.    This class does not require any instances and is only being used as a
  347.    method of grouping functions together in a name space.
  348.   */
  349. class PTrace
  350. {
  351. public:
  352.   /** Set the stream to be used for trace output.
  353.   This stream is used for all trace output using the various trace functions
  354.   and macros.
  355.   */
  356.   static void SetStream(ostream * out /** New output stream from trace. */ );
  357.   /// Options for trace output.
  358.   enum Options {
  359.     /**Include PTrace::Block constructs in output
  360.        If this is bit is clear, all PTrace::Block output is inhibited
  361.        regardless of the trace level. If set, the PTrace::Block may occur
  362.        provided the trace level is greater than zero.
  363.     */
  364.     Blocks = 1,
  365.     /// Include date and time in all output
  366.     DateAndTime = 2,
  367.     /// Include (millisecond) timestamp in all output
  368.     Timestamp = 4,
  369.     /// Include identifier for thread trace is made from in all output
  370.     Thread = 8,
  371.     /// Include trace level in all output
  372.     TraceLevel = 16,
  373.     /// Include the file and line for the trace call in all output
  374.     FileAndLine = 32,
  375.     /// Include thread object pointer address in all trace output
  376.     ThreadAddress = 64,
  377.     /** SystemLog flag for tracing within a PServiceProcess application. Must
  378.         be set in conjection with SetStream(new PSystemLog).
  379.       */
  380.     SystemLogStream = 32768
  381.   };
  382.   /** Set the trace options.
  383.   The PTRACE(), PTRACE_BLOCK() and PTRACE_LINE() macros output trace text that
  384.   may contain assorted values. These are defined by the Options enum.
  385.   Note this function OR's the bits included in the options parameter.
  386.   */
  387.   static void SetOptions(unsigned options /** New level for trace */ );
  388.   /** Clear the trace options.
  389.   The PTRACE(), PTRACE_BLOCK() and PTRACE_LINE() macros output trace text that
  390.   may contain assorted values. These are defined by the Options enum.
  391.   Note this function AND's the complement of the bits included in the options
  392.   parameter.
  393.   */
  394.   static void ClearOptions(unsigned options /** New level for trace */ );
  395.   /** Get the current trace options.
  396.   The PTRACE(), PTRACE_BLOCK() and PTRACE_LINE() macros output trace text that
  397.   may contain assorted values. These are defined by the Options enum.
  398.   */
  399.   static unsigned GetOptions();
  400.   /** Set the trace level.
  401.   The PTRACE() macro checks to see if its level is equal to or lower then the
  402.   level set by this function. If so then the trace text is output to the trace
  403.   stream.
  404.   */
  405.   static void SetLevel(unsigned level /** New level for trace */ );
  406.   /** Get the trace level.
  407.   The PTRACE() macro checks to see if its level is equal to or lower then the
  408.   level set by this function. If so then the trace text is output to the trace
  409.   stream.
  410.   */
  411.   static unsigned GetLevel();
  412.   /** Determine if the level may cause trace output.
  413.   This checks against the current global trace level set by #PSetTraceLevel#
  414.   for if the trace output may be emitted. This is used by the PTRACE macro.
  415.   */
  416.   static BOOL CanTrace(unsigned level /** Trace level to check */);
  417.   /** Begin a trace output.
  418.   If the trace stream output is used outside of the provided macros, it
  419.   should be noted that a mutex is obtained on the call to #PBeginTrace# which
  420.   will prevent any other threads from using the trace stream until the
  421.   #PEndTrace# function is called.
  422.   So a typical usage would be:
  423.   begin{verbatim}
  424.     ostream & s = PTrace::Begin(3, __FILE__, __LINE__);
  425.     s << "hello";
  426.     if (want_there)
  427.       s << " there";
  428.     s << '!' << PTrace::End();
  429.   end{verbatim}
  430.   */
  431.   static ostream & Begin(
  432.     unsigned level,         /// Log level for output
  433.     const char * fileName,  /// Filename of source file being traced
  434.     int lineNum             /// Line number of source file being traced.
  435.   );
  436.   /** End a trace output.
  437.   If the trace stream output is used outside of the provided macros, the
  438.   #PEndTrace# function must be used at the end of the section of trace
  439.   output. A mutex is obtained on the call to #PBeginTrace# which will prevent
  440.   any other threads from using the trace stream until the PEndTrace. The
  441.   #PEndTrace# is used in a similar manner to #::endl# or #::flush#.
  442.   So a typical usage would be:
  443.   begin{verbatim}
  444.     ostream & s = PTrace::Begin();
  445.     s << "hello";
  446.     if (want_there)
  447.       s << " there";
  448.     s << '!' << PTrace::End();
  449.   end{verbatim}
  450.   */
  451.   static ostream & End(ostream & strm /** Trace output stream being completed */);
  452.   /** Class to trace Execution blocks.
  453.   This class is used for tracing the entry and exit of program blocks. Upon
  454.   construction it outputs an entry trace message and on destruction outputs an
  455.   exit trace message. This is normally only used from in the PTRACE_BLOCK macro.
  456.   */
  457.   class Block {
  458.     public:
  459.       /** Output entry trace message. */
  460.       Block(
  461.         const char * fileName, /// Filename of source file being traced
  462.         int lineNum,           /// Line number of source file being traced.
  463.         const char * traceName
  464.           /// String to be output with trace, typically it is the function name.
  465.        );
  466.       /// Output exit trace message.
  467.       ~Block();
  468.     private:
  469.       const char * file;
  470.       int          line;
  471.       const char * name;
  472.   };
  473. };
  474. #if !PTRACING
  475. #define PTRACE_BLOCK(n)
  476. #define PTRACE_LINE()
  477. #define PTRACE(level, arg)
  478. #else
  479. /** Trace an execution block.
  480. This macro creates a trace variable for tracking the entry and exit of program
  481. blocks. It creates an instance of the PTraceBlock class that will output a
  482. trace message at the line PTRACE_BLOCK is called and then on exit from the
  483. scope it is defined in.
  484. */
  485. #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
  486. /** Trace the execution of a line.
  487. This macro outputs a trace of a source file line execution.
  488. */
  489. #define PTRACE_LINE() 
  490.     if (!PTrace::CanTrace(1)) ; else 
  491.       PTrace::Begin(1, __FILE__, __LINE__) << PTrace::End
  492. /** Output trace.
  493. This macro outputs a trace of any information needed, using standard stream
  494. output operators. The output is only made if the trace level set by the
  495. #PSetTraceLevel# function is greater than or equal to the #level# argument.
  496. */
  497. #define PTRACE(level, args) 
  498.     if (!PTrace::CanTrace(level)) ; else 
  499.       PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
  500. #endif
  501. #ifndef PMEMORY_CHECK
  502. #ifndef _DEBUG
  503. #define PMEMORY_CHECK 0
  504. #else
  505. #define PMEMORY_CHECK 1
  506. #endif
  507. #endif
  508. #if PMEMORY_CHECK
  509. /** Memory heap chacking class.
  510. This class implements the memory heap checking and validation functions. It
  511. maintains lists of allocated block so that memory leaks can be detected. It
  512. also initialises memory on allocation and deallocation to help catch errors
  513. involving the use of dangling pointers.
  514. */
  515. class PMemoryHeap {
  516.   protected:
  517.     /// Initialise the memory checking subsystem.
  518.     PMemoryHeap();
  519.   public:
  520.     // Clear up the memory checking subsystem, dumping memory leaks.
  521.     ~PMemoryHeap();
  522.     /** Allocate a memory block.
  523.        This allocates a new memory block and keeps track of it. The memory
  524.        block is filled with the value in the #allocFillChar# member variable
  525.        to help detect uninitialised structures.
  526.        @return pointer to newly allocated memory block.
  527.      */
  528.     static void * Allocate(
  529.       size_t nSize,           /// Number of bytes to allocate.
  530.       const char * file,      /// Source file name for allocating function.
  531.       int line,               /// Source file line for allocating function.
  532.       const char * className  /// Class name for allocating function.
  533.     );
  534.     /** Allocate a memory block.
  535.        This allocates a new memory block and keeps track of it. The memory
  536.        block is filled with the value in the #allocFillChar# member variable
  537.        to help detect uninitialised structures.
  538.        @return pointer to newly allocated memory block.
  539.      */
  540.     static void * Allocate(
  541.       size_t count,       /// Number of items to allocate.
  542.       size_t iSize,       /// Size in bytes of each item.
  543.       const char * file,  /// Source file name for allocating function.
  544.       int line            /// Source file line for allocating function.
  545.     );
  546.     /** Change the size of an allocated memory block.
  547.        This allocates a new memory block and keeps track of it. The memory
  548.        block is filled with the value in the #allocFillChar# member variable
  549.        to help detect uninitialised structures.
  550.       @return pointer to reallocated memory block. Note this may
  551.       {em not} be the same as the pointer passed into the function.
  552.      */
  553.     static void * Reallocate(
  554.       void * ptr,         /// Pointer to memory block to reallocate.
  555.       size_t nSize,       /// New number of bytes to allocate.
  556.       const char * file,  /// Source file name for allocating function.
  557.       int line            /// Source file line for allocating function.
  558.     );
  559.     /** Free a memory block.
  560.       The memory is deallocated, a warning is displayed if it was never
  561.       allocated. The block of memory is filled with the value in the
  562.       #freeFillChar# member variable.
  563.      */
  564.     static void Deallocate(
  565.       void * ptr,             /// Pointer to memory block to deallocate.
  566.       const char * className  /// Class name for deallocating function.
  567.     );
  568.     /** Validation result.
  569.      */
  570.     enum Validation {
  571.       Ok, Bad, Trashed
  572.     };
  573.     /** Validate the memory pointer.
  574.         The #ptr# parameter is validated as a currently allocated heap
  575.         variable.
  576.         @return Ok for pointer is in heap, Bad for pointer is not in the heap
  577.         or Trashed if the pointer is in the heap but has overwritten the guard
  578.         bytes before or after the actual data part of the memory block.
  579.      */
  580.     static Validation Validate(
  581.       void * ptr,             /// Pointer to memory block to check
  582.       const char * className, /// Class name it should be.
  583.       ostream * error         /// Stream to receive error message (may be NULL)
  584.     );
  585.     /** Ignore/Monitor allocations.
  586.        Set internal flag so that allocations are not included in the memory
  587.        leak check on program termination.
  588.      */
  589.     static void SetIgnoreAllocations(
  590.       BOOL ignore  /// New flag for allocation ignoring.
  591.     );
  592.     /** Get memory check system statistics.
  593.         Dump statistics output to the default stream.
  594.      */
  595.     static void DumpStatistics();
  596.     /** Get memory check system statistics.
  597.         Dump statistics output to the specified stream.
  598.      */
  599.     static void DumpStatistics(ostream & strm /** Stream to output to */);
  600.     /* Get number of allocation.
  601.       Each allocation is counted and if desired the next allocation request
  602.       number may be obtained via this function.
  603.       @return Allocation request number.
  604.      */
  605.     static DWORD GetAllocationRequest();
  606.     /** Dump allocated objects.
  607.        Dump ojects allocated and not deallocated since the specified object
  608.        number. This would be a value returned by the #GetAllocationRequest()#
  609.        function.
  610.        Output is to the default stream.
  611.      */
  612.     static void DumpObjectsSince(
  613.       DWORD objectNumber    /// Memory object to begin dump from.
  614.     );
  615.     /** Dump allocated objects.
  616.        Dump ojects allocated and not deallocated since the specified object
  617.        number. This would be a value returned by the #GetAllocationRequest()#
  618.        function.
  619.      */
  620.     static void DumpObjectsSince(
  621.       DWORD objectNumber,   /// Memory object to begin dump from.
  622.       ostream & strm        /// Stream to output dump
  623.     );
  624.     /** Set break point allocation number.
  625.       Set the allocation request number to cause an assert. This allows a
  626.       developer to cause a halt in a debugger on a certain allocation allowing
  627.       them to determine memory leaks allocation point.
  628.      */
  629.     static void SetAllocationBreakpoint(
  630.       DWORD point   /// Allocation number to stop at.
  631.     );
  632.   protected:
  633.     void * InternalAllocate(
  634.       size_t nSize,           // Number of bytes to allocate.
  635.       const char * file,      // Source file name for allocating function.
  636.       int line,               // Source file line for allocating function.
  637.       const char * className  // Class name for allocating function.
  638.     );
  639.     Validation InternalValidate(
  640.       void * ptr,             // Pointer to memory block to check
  641.       const char * className, // Class name it should be.
  642.       ostream * error         // Stream to receive error message (may be NULL)
  643.     );
  644.     void InternalDumpStatistics(ostream & strm);
  645.     void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
  646.     class Wrapper {
  647.       public:
  648.         Wrapper();
  649.         ~Wrapper();
  650.         PMemoryHeap * operator->() const { return instance; }
  651.       private:
  652.         PMemoryHeap * instance;
  653.     };
  654.     friend class Wrapper;
  655.     enum Flags {
  656.       NoLeakPrint = 1
  657.     };
  658. #pragma pack(1)
  659.     struct Header {
  660.       enum {
  661.         // Assure that the Header struct is aligned to 8 byte boundary
  662.         NumGuardBytes = 16 - (sizeof(Header *) +
  663.                               sizeof(Header *) +
  664.                               sizeof(const char *) +
  665.                               sizeof(const char *) +
  666.                               sizeof(size_t) +
  667.                               sizeof(DWORD) +
  668.                               sizeof(WORD) +
  669.                               sizeof(BYTE))%8
  670.       };
  671.       Header     * prev;
  672.       Header     * next;
  673.       const char * className;
  674.       const char * fileName;
  675.       size_t       size;
  676.       DWORD        request;
  677.       WORD         line;
  678.       BYTE         flags;
  679.       char         guard[NumGuardBytes];
  680.       static char GuardBytes[NumGuardBytes];
  681.     };
  682. #pragma pack()
  683.     BOOL isDestroyed;
  684.     Header * listHead;
  685.     Header * listTail;
  686.     static DWORD allocationBreakpoint;
  687.     DWORD allocationRequest;
  688.     DWORD firstRealObject;
  689.     BYTE  flags;
  690.     char  allocFillChar;
  691.     char  freeFillChar;
  692.     DWORD currentMemoryUsage;
  693.     DWORD peakMemoryUsage;
  694.     DWORD currentObjects;
  695.     DWORD peakObjects;
  696.     DWORD totalObjects;
  697.     ostream * leakDumpStream;
  698. #if defined(_WIN32)
  699.     CRITICAL_SECTION mutex;
  700. #elif defined(P_PTHREADS)
  701.     pthread_mutex_t mutex;
  702. #endif
  703. };
  704. /** Allocate memory for the run time library.
  705. This version of free is used for data that is not to be allocated using the
  706. memory check system, ie will be free'ed inside the C run time library.
  707. */
  708. inline void runtime_malloc(size_t bytes /** Size of block to allocate */ ) { malloc(bytes); }
  709. /** Free memory allocated by run time library.
  710. This version of free is used for data that is not allocated using the
  711. memory check system, ie was malloc'ed inside the C run time library.
  712. */
  713. inline void runtime_free(void * ptr /** Memory block to free */ ) { free(ptr); }
  714. /** Override of system call for memory check system.
  715. This macro is used to allocate memory via the memory check system selected
  716. with the #PMEMORY_CHECK# compile time option. It will include the source file
  717. and line into the memory allocation to allow the PMemoryHeap class to keep
  718. track of the memory block.
  719. */
  720. #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
  721. /** Override of system call for memory check system.
  722. This macro is used to allocate memory via the memory check system selected
  723. with the #PMEMORY_CHECK# compile time option. It will include the source file
  724. and line into the memory allocation to allow the PMemoryHeap class to keep
  725. track of the memory block.
  726. */
  727. #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
  728. /** Override of system call for memory check system.
  729. This macro is used to allocate memory via the memory check system selected
  730. with the #PMEMORY_CHECK# compile time option. It will include the source file
  731. and line into the memory allocation to allow the PMemoryHeap class to keep
  732. track of the memory block.
  733. */
  734. #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
  735. /** Override of system call for memory check system.
  736. This macro is used to deallocate memory via the memory check system selected
  737. with the #PMEMORY_CHECK# compile time option. It will include the source file
  738. and line into the memory allocation to allow the PMemoryHeap class to keep
  739. track of the memory block.
  740. */
  741. #define free(p) PMemoryHeap::Deallocate(p, NULL)
  742. /** Macro for overriding system default #new# operator.
  743. This macro is used to allocate memory via the memory check system selected
  744. with the PMEMORY_CHECK compile time option. It will include the source file
  745. and line into the memory allocation to allow the PMemoryHeap class to keep
  746. track of the memory block.
  747. This macro could be used instead of the system #new# operator. Or you can place
  748. the line
  749. begin{verbatim}
  750.   #define new PNEW
  751. end{verbatim}
  752. at the begining of the source file, after all declarations that use the
  753. PCLASSINFO macro.
  754. */
  755. #define PNEW  new (__FILE__, __LINE__)
  756. #if !defined(_MSC_VER) || _MSC_VER<1200
  757. #define PSPECIAL_DELETE_FUNCTION
  758. #else
  759. #define PSPECIAL_DELETE_FUNCTION 
  760.     void operator delete(void * ptr, const char *, int) 
  761.       { PMemoryHeap::Deallocate(ptr, Class()); } 
  762.     void operator delete[](void * ptr, const char *, int) 
  763.       { PMemoryHeap::Deallocate(ptr, Class()); }
  764. #endif
  765. #define PNEW_AND_DELETE_FUNCTIONS 
  766.     void * operator new(size_t nSize, const char * file, int line) 
  767.       { return PMemoryHeap::Allocate(nSize, file, line, Class()); } 
  768.     void * operator new(size_t nSize) 
  769.       { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } 
  770.     void operator delete(void * ptr) 
  771.       { PMemoryHeap::Deallocate(ptr, Class()); } 
  772.     void * operator new[](size_t nSize, const char * file, int line) 
  773.       { return PMemoryHeap::Allocate(nSize, file, line, Class()); } 
  774.     void * operator new[](size_t nSize) 
  775.       { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } 
  776.     void operator delete[](void * ptr) 
  777.       { PMemoryHeap::Deallocate(ptr, Class()); } 
  778.     PSPECIAL_DELETE_FUNCTION
  779. inline void * operator new(size_t nSize, const char * file, int line)
  780.   { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
  781. inline void * operator new[](size_t nSize, const char * file, int line)
  782.   { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
  783. #ifndef __GNUC__
  784. void * operator new(size_t nSize);
  785. void * operator new[](size_t nSize);
  786. void operator delete(void * ptr);
  787. void operator delete[](void * ptr);
  788. #if defined(_MSC_VER) && _MSC_VER>=1200
  789. inline void operator delete(void * ptr, const char *, int)
  790.   { PMemoryHeap::Deallocate(ptr, NULL); }
  791. inline void operator delete[](void * ptr, const char *, int)
  792.   { PMemoryHeap::Deallocate(ptr, NULL); }
  793. #endif
  794. #endif
  795. #else // _DEBUG
  796. #define PNEW new
  797. #define PNEW_AND_DELETE_FUNCTIONS
  798. #define runtime_malloc(s) malloc(s)
  799. #define runtime_free(p) free(p)
  800. #endif // _DEBUG
  801. /** Declare all the standard PWlib class information.
  802. This macro is used to provide the basic run-time typing capability needed
  803. by the library. All descendent classes from the #PObject# class require
  804. these functions for correct operation. Either use this macro or the
  805. #PDECLARE_CLASS# macro.
  806. The use of the #PDECLARE_CLASS# macro is no longer recommended for reasons
  807. of compatibility with documentation systems.
  808. */
  809. #define PCLASSINFO(cls, par) 
  810.   public: 
  811.     static const char * Class() 
  812.       { return #cls; } 
  813.     virtual const char * GetClass(unsigned ancestor = 0) const 
  814.       { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } 
  815.     virtual BOOL IsClass(const char * clsName) const 
  816.       { return strcmp(clsName, cls::Class()) == 0; } 
  817.     virtual BOOL IsDescendant(const char * clsName) const 
  818.       { return strcmp(clsName, cls::Class()) == 0 || 
  819.                                                par::IsDescendant(clsName); } 
  820.     virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const 
  821.       { return (Comparison)memcmp(this, &obj, sizeof(cls)); } 
  822.     PNEW_AND_DELETE_FUNCTIONS
  823. /** Declare a class with PWLib class information.
  824. This macro is used to declare a new class with a single public ancestor. It
  825. starts the class declaration and then uses the #PCLASSINFO# macro to
  826. get all the run-time type functions.
  827. The use of this macro is no longer recommended for reasons of compatibility
  828. with documentation systems.
  829. */
  830. #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
  831. #ifdef DOC_PLUS_PLUS
  832. } Match previous opening brace in doc++
  833. #endif
  834. class PSerialiser;
  835. class PUnSerialiser;
  836. ///////////////////////////////////////////////////////////////////////////////
  837. // The root of all evil ... umm classes
  838. /** Ultimate parent class for all objects in the class library.
  839. This provides functionality provided to all classes, eg run-time types,
  840. default comparison operations, simple stream I/O and serialisation support.
  841. */
  842. class PObject {
  843.   protected:
  844.     /** Constructor for PObject, make protected so cannot ever create one on
  845.        its own.
  846.      */
  847.     PObject() { }
  848.   public:
  849.     /* Destructor required to get the "virtual". A PObject really has nothing
  850.        to destroy.
  851.      */
  852.     virtual ~PObject() { }
  853.   /**@name Run Time Type functions */
  854.   //@{
  855.     /** Get the name of the class as a C string. This is a static function which
  856.        returns the type of a specific class. It is primarily used as an
  857.        argument to the #IsClass()# or #IsDescendant()# functions.
  858.        
  859.        When comparing class names, always use the #strcmp()#
  860.        function rather than comparing pointers. The pointers are not
  861.        necessarily the same over compilation units depending on the compiler,
  862.        platform etc.
  863.        The #PCLASSINFO# macro declares a version of this function for the
  864.        particular class.
  865.        @return pointer to C string literal.
  866.      */      
  867.     static const char * Class() { return "PObject"; }
  868.     /** Get the current dynamic type of the object instance.
  869.        When comparing class names, always use the #strcmp()#
  870.        function rather than comparing pointers. The pointers are not
  871.        necessarily the same over compilation units depending on the compiler,
  872.        platform etc.
  873.        The #PCLASSINFO# macro declares an override of this function for
  874.        the particular class. The user need not implement it.
  875.        @return pointer to C string literal.
  876.      */
  877.     virtual const char * GetClass(
  878.       unsigned ancestor = 0
  879.       /** Level of ancestor to get the class name for. A value of zero is the
  880.          instances class name, one is its ancestor, two for the ancestors
  881.          ancestor etc.
  882.        */
  883.     ) const;
  884.     /** Determine if the dynamic type of the current instance is of the
  885.        specified class. The class name is usually provided by the
  886.        #Class()# static function of the desired class.
  887.     
  888.        The #PCLASSINFO# macro declares an override of this function for
  889.        the particular class. The user need not implement it.
  890.        @return TRUE if object is of the class.
  891.      */
  892.     virtual BOOL IsClass(
  893.       const char * clsName    // Class name to compare against.
  894.     ) const;
  895.     /** Determine if the dynamic type of the current instance is a descendent of
  896.        the specified class. The class name is usually provided by the
  897.        #Class()# static function of the desired class.
  898.     
  899.        The #PCLASSINFO# macro declares an override of this function for
  900.        the particular class. The user need not implement it.
  901.        @return TRUE if object is descended from the class.
  902.      */
  903.     virtual BOOL IsDescendant(
  904.       const char * clsName    // Ancestor class name to compare against.
  905.     ) const;
  906.   //@}
  907.   /**@name Comparison functions */
  908.   //@{
  909.     /** Result of the comparison operation performed by the #Compare()#
  910.        function.
  911.       */
  912.     enum Comparison {
  913.       LessThan = -1,
  914.       EqualTo = 0,
  915.       GreaterThan = 1
  916.     };
  917.     /** Compare the two objects and return their relative rank. This function is
  918.        usually overridden by descendent classes to yield the ranking according
  919.        to the semantics of the object.
  920.        
  921.        The default function is to use the #CompareObjectMemoryDirect()#
  922.        function to do a byte wise memory comparison of the two objects.
  923.        @return
  924.        #LessThan#, #EqualTo# or #GreaterThan#
  925.        according to the relative rank of the objects.
  926.      */
  927.     virtual Comparison Compare(
  928.       const PObject & obj   // Object to compare against.
  929.     ) const;
  930.     
  931.     /** Determine the byte wise comparison of two objects. This is the default
  932.        comparison operation for objects that do not explicitly override the
  933.        #Compare()# function.
  934.     
  935.        The #PCLASSINFO# macro declares an override of this function for
  936.        the particular class. The user need not implement it.
  937.        @return
  938.        #LessThan#, #EqualTo# or #GreaterThan#
  939.        according to the result #memcpy()# function.
  940.      */
  941.     virtual Comparison CompareObjectMemoryDirect(
  942.       const PObject & obj   // Object to compare against.
  943.     ) const;
  944.     /** Compare the two objects.
  945.     
  946.        @return
  947.        TRUE if objects are equal.
  948.      */
  949.     BOOL operator==(
  950.       const PObject & obj   // Object to compare against.
  951.     ) const { return Compare(obj) == EqualTo; }
  952.     /** Compare the two objects.
  953.     
  954.        @return
  955.        TRUE if objects are not equal.
  956.      */
  957.     BOOL operator!=(
  958.       const PObject & obj   // Object to compare against.
  959.     ) const { return Compare(obj) != EqualTo; }
  960.     /** Compare the two objects.
  961.     
  962.        @return
  963.        TRUE if objects are less than.
  964.      */
  965.     BOOL operator<(
  966.       const PObject & obj   // Object to compare against.
  967.     ) const { return Compare(obj) == LessThan; }
  968.     /** Compare the two objects.
  969.     
  970.        @return
  971.        TRUE if objects are greater than.
  972.      */
  973.     BOOL operator>(
  974.       const PObject & obj   // Object to compare against.
  975.     ) const { return Compare(obj) == GreaterThan; }
  976.     /** Compare the two objects.
  977.     
  978.        @return
  979.        TRUE if objects are less than or equal.
  980.      */
  981.     BOOL operator<=(
  982.       const PObject & obj   // Object to compare against.
  983.     ) const { return Compare(obj) != GreaterThan; }
  984.     /** Compare the two objects.
  985.     
  986.        @return
  987.        TRUE if objects are greater than or equal.
  988.      */
  989.     BOOL operator>=(
  990.       const PObject & obj   // Object to compare against.
  991.     ) const { return Compare(obj) != LessThan; }
  992.   //@}
  993.   /**@name I/O functions */
  994.   //@{
  995.     /** Output the contents of the object to the stream. The exact output is
  996.        dependent on the exact semantics of the descendent class. This is
  997.        primarily used by the standard #operator<<# function.
  998.        The default behaviour is to print the class name.
  999.      */
  1000.     virtual void PrintOn(
  1001.       ostream &strm   // Stream to print the object into.
  1002.     ) const;
  1003.     /** Input the contents of the object from the stream. The exact input is
  1004.        dependent on the exact semantics of the descendent class. This is
  1005.        primarily used by the standard #operator>># function.
  1006.        The default behaviour is to do nothing.
  1007.      */
  1008.     virtual void ReadFrom(
  1009.       istream &strm   // Stream to read the objects contents from.
  1010.     );
  1011.     /** Global function for using the standard << operator on objects descended
  1012.        from PObject. This simply calls the objects #PrintOn()# function.
  1013.        
  1014.        @return the #strm# parameter.
  1015.      */
  1016.     inline friend ostream & operator<<(
  1017.       ostream &strm,       // Stream to print the object into.
  1018.       const PObject & obj  // Object to print to the stream.
  1019.     ) { obj.PrintOn(strm); return strm; }
  1020.     /** Global function for using the standard >> operator on objects descended
  1021.        from PObject. This simply calls the objects #ReadFrom()# function.
  1022.        @return the #strm# parameter.
  1023.      */
  1024.     inline friend istream & operator>>(
  1025.       istream &strm,   // Stream to read the objects contents from.
  1026.       PObject & obj    // Object to read inormation into.
  1027.     ) { obj.ReadFrom(strm); return strm; }
  1028.     /** This function is used to determine the size of the object and all other
  1029.        objects it contains. The actual size is dependent on the exact semantics
  1030.        of the descendent object. For example the #PString# class would
  1031.        return the length of the string plus one, while the #PList# class
  1032.        would return the sum of the sizes of all of the objects in the list
  1033.        plus the size of an integer for the number of objects.
  1034.        This in only required by the #PBinarySerialiser# class which
  1035.        serialises the objects into a binary file. The #PTextSerialiser#
  1036.        class which serialises into a text stream does not use this function.
  1037.        Note serialisation requires the use of the #PDECLARE_SERIAL# and
  1038.        #PIMPLEMENT_SERIAL# macros.
  1039.        @return size in bytes of object.
  1040.      */
  1041.     virtual PINDEX PreSerialise(
  1042.       PSerialiser & strm   // Serialiser stream to serialise object into.
  1043.     );
  1044.     /** Serialise the object into the specified stream. This is similar to the
  1045.        #PrintOn()# function that outputs the contents of the object to a
  1046.        stream, but where #PrintOn()# usually produces a human readable
  1047.        form of the object, this function outputs enough data so that it can be
  1048.        reconstructed by the #PUnSerialiser# class.
  1049.        
  1050.        When the user implements this function they will usually be doing it for
  1051.        one of either the text of binary output versions. In some circumstances,
  1052.        eg libraries, both need be supported so the #IsDscendent()#
  1053.        function should be used on the #strm# parameter to determine
  1054.        whether it is a #PBinarySerialiser# class or a
  1055.        #PTextSerialiser# class and do the appropriate output.
  1056.        To a large extent, if only the #<<# operator is used on the
  1057.        #PSerialiser# instance, the text and binary version can be made
  1058.        identical.
  1059.      */
  1060.     virtual void Serialise(
  1061.       PSerialiser & strm   // Serialiser stream to serialise object into.
  1062.     );
  1063.     /** Un-serialise the object from the specified stream. This is similar to
  1064.        the #ReadFrom()# function that inputs the contents of the object
  1065.        from a stream, but where #ReadFrom()# usually intrerprets a human
  1066.        readable form of the object, this function inputs enough data so that
  1067.        it can be reconstructed from the data provided by the #Serialise()#
  1068.        function.
  1069.        When the user implements this function they will usually be doing it for
  1070.        one of either the text of binary input versions. In some circumstances,
  1071.        eg libraries, both need be supported so the #IsDscendent()#
  1072.        function should be used on the #strm# parameter to determine
  1073.        whether it is a #PBinarySerialiser# class or a
  1074.        #PTextSerialiser# class and do the appropriate input.
  1075.        To a large extent, if only the >> operator is used on the
  1076.        #PUnSerialiser# instance, the text and binary version can be made
  1077.        identical.
  1078.      */
  1079.     virtual void UnSerialise(
  1080.       PUnSerialiser & strm   // Serialiser stream to serialise object into.
  1081.     );
  1082.   //@}
  1083.   /**@name Miscellaneous functions */
  1084.   //@{
  1085.     /** Create a copy of the class on the heap. The exact semantics of the
  1086.        descendent class determine what is required to make a duplicate of the
  1087.        instance. Not all classes can even {bf do} a clone operation.
  1088.        
  1089.        The main user of the clone function is the #PDictionary# class as
  1090.        it requires copies of the dictionary keys.
  1091.        The default behaviour is for this function to assert.
  1092.        @return
  1093.        pointer to new copy of the class instance.
  1094.      */
  1095.     virtual PObject * Clone() const;
  1096.     /** This function yields a hash value required by the #PDictionary#
  1097.        class. A descendent class that is required to be the key of a dictionary
  1098.        should override this function. The precise values returned is dependent
  1099.        on the semantics of the class. For example, the #PString# class
  1100.        overrides it to provide a hash function for distinguishing text strings.
  1101.        The default behaviour is to return the value zero.
  1102.        @return
  1103.        hash function value for class instance.
  1104.      */
  1105.     virtual PINDEX HashFunction() const;
  1106.   //@}
  1107. };
  1108. ///////////////////////////////////////////////////////////////////////////////
  1109. // Serialisation
  1110. class PUnSerialiser;
  1111. /** Registration class for persistent object serialisation/unserialisation.
  1112. This class is for registration of object classes that will be serialised and
  1113. un-serialised.
  1114. As objects are un-serialised, the objects need to be constructed. For the
  1115. #PUnSerialiser# instance to know what constructor to call, a
  1116. registration of functions that call the appropriate constructor.
  1117. The #PDECLARE_SERIAL# macro creates a single instance of this class to
  1118. register the class with the serialiser.
  1119. Even though this class implements a hash table it does {bf not} use the
  1120. standard #PHashTable# or #PDictionary# classes due to recursive
  1121. definition problems. Those classes need to register themselves with this
  1122. class before they can be used!
  1123. */
  1124. class PSerialRegistration {
  1125.   public:
  1126.     /** This type is a pointer to a function to create objects during the
  1127.        un-serialisation operation.
  1128.      */
  1129.     typedef PObject * (*CreatorFunction)(PUnSerialiser * serial);
  1130.     /** Create a serialiser class registration. This is unversally called by
  1131.        static member variables in the #PDECLARE_SERIAL# and
  1132.        #PIMPLEMENT_SERIAL# macros.
  1133.      */
  1134.     PSerialRegistration(
  1135.       const char * clsNam,    // Name of class to register.
  1136.       CreatorFunction func    // Constructor function for the class.
  1137.     );
  1138.     /** Get the creator function for the class name specified.
  1139.        @return function to construct objects.
  1140.      */
  1141.     static CreatorFunction GetCreator(
  1142.       const char * clsNam   // Name of class to get the creator function for.
  1143.     );
  1144.     // Constant for size of hash table.
  1145.     enum { HashTableSize = 41 };
  1146.   protected:
  1147.     /** Calculate the bucket for the hash table lookup.
  1148.       @return Has index for class.
  1149.      */
  1150.     static PINDEX HashFunction(
  1151.       const char * className    // Class name to calculate hash function for.
  1152.     );
  1153.     /// This serialiser registrations class
  1154.     const char * className;
  1155.     /** This serialiser registrations creator function - the function that will
  1156.        make a new object of the classes type and construct it with an instance
  1157.        of the #PSerialiser# class.
  1158.      */
  1159.     CreatorFunction creator;
  1160.     /// Pointer to next registration when a hash clash occurs.
  1161.     PSerialRegistration * clash;
  1162.     /// A static dictionary of class names to creator functions.
  1163.     static PSerialRegistration * creatorHashTable[HashTableSize];
  1164. };
  1165. /** This class allows the serialisation of objects to an output stream. This
  1166.    packages up objects so that they can be reconstructed by an instance of the
  1167.    #PUnSerialiser# class. The stream they are sent to can be any stream;
  1168.    file, string, pipe, socket etc.
  1169.    Serialisation can be done in two manners: binary or text. This depends on
  1170.    the serialiser instance that was constructed. Each objects
  1171.    #PObject::Serialise()# function is called and it is up to that
  1172.    function to output in binary or text.
  1173.    To a large extent, if only the << operator is used on the
  1174.    #PSerialser# instance, the text and binary versions of the
  1175.    #PObject::Serialise()# function can be made identical.
  1176.    This class is an abstract class and descendents of #PTextSerialiser# or
  1177.    #PBinarySerialiser# should be created.
  1178.  */
  1179. class PSerialiser : public PObject
  1180. {
  1181.   PCLASSINFO(PSerialiser, PObject);
  1182.   public:
  1183.     /// Construct a serialiser.
  1184.     PSerialiser(
  1185.       ostream & strm  // Stream to output serialisation to.
  1186.     );
  1187.     /// Output char to serial stream.
  1188.     virtual PSerialiser & operator<<(char) = 0;
  1189.     /// Output unsigned char to serial stream.
  1190.     virtual PSerialiser & operator<<(unsigned char) = 0;
  1191.     /// Output signed char to serial stream.
  1192.     virtual PSerialiser & operator<<(signed char) = 0;
  1193.     /// Output short to serial stream.
  1194.     virtual PSerialiser & operator<<(short) = 0;
  1195.     /// Output unsigned short to serial stream.
  1196.     virtual PSerialiser & operator<<(unsigned short) = 0;
  1197.     /// Output int to serial stream.
  1198.     virtual PSerialiser & operator<<(int) = 0;
  1199.     /// Output unsigned int to serial stream.
  1200.     virtual PSerialiser & operator<<(unsigned int) = 0;
  1201.     /// Output long to serial stream.
  1202.     virtual PSerialiser & operator<<(long) = 0;
  1203.     /// Output unsigned long to serial stream.
  1204.     virtual PSerialiser & operator<<(unsigned long) = 0;
  1205.     /// Output float to serial stream.
  1206.     virtual PSerialiser & operator<<(float) = 0;
  1207.     /// Output double to serial stream.
  1208.     virtual PSerialiser & operator<<(double) = 0;
  1209.     /// Output long double to serial stream.
  1210.     virtual PSerialiser & operator<<(long double) = 0;
  1211.     /// Output C string to serial stream.
  1212.     virtual PSerialiser & operator<<(const char *) = 0;
  1213.     /// Output C string to serial stream.
  1214.     virtual PSerialiser & operator<<(const unsigned char *) = 0;
  1215.     /// Output C string to serial stream.
  1216.     virtual PSerialiser & operator<<(const signed char *) = 0;
  1217.     /** Output the data to the serialiser object.
  1218.       When the operator is executed on a #PObject# descendent then that objects
  1219.       #PObject::Serialise()# function is called.
  1220.      */
  1221.     virtual PSerialiser & operator<<(PObject &);
  1222.   protected:
  1223.     /// Stream to output serial data to.
  1224.     ostream & stream;
  1225. };
  1226. /** This class allows the un-serialisation of objects from an input stream. This
  1227.    reconstruct objects that where packaged earlier by an instance of the
  1228.    #PSerialise# class. The stream they are received from can be any
  1229.    stream; file, string, pipe, socket etc.
  1230.    Serialisation can be done in two manners: binary or text. This depends on
  1231.    the serialiser instance that was constructed. Each objects
  1232.    #PObject::Serialise()# function is called and it is up to that
  1233.    function to output in binary or text.
  1234.    To a large extent, if only the #<<# operator is used on the
  1235.    #PSerialser# instance, the text and binary versions of the
  1236.    #PObject::Serialise()# function can be made identical.
  1237.    This class is an abstract class and descendents of #PTextSerialiser# or
  1238.    #PBinarySerialiser# should be created.
  1239.  */
  1240. class PUnSerialiser : public PObject
  1241. {
  1242.   PCLASSINFO(PUnSerialiser, PObject);
  1243.   public:
  1244.     /// Construct an un-serialiser.
  1245.     PUnSerialiser(
  1246.       istream & strm    // Stream to read the serialised objects from.
  1247.     );
  1248.     /// Input primitive from stream.
  1249.     virtual PUnSerialiser & operator>>(char &) = 0;
  1250.     /// Input primitive from stream.
  1251.     virtual PUnSerialiser & operator>>(unsigned char &) = 0;
  1252.     /// Input primitive from stream.
  1253.     virtual PUnSerialiser & operator>>(signed char &) = 0;
  1254.     /// Input primitive from stream.
  1255.     virtual PUnSerialiser & operator>>(short &) = 0;
  1256.     /// Input primitive from stream.
  1257.     virtual PUnSerialiser & operator>>(unsigned short &) = 0;
  1258.     /// Input primitive from stream.
  1259.     virtual PUnSerialiser & operator>>(int &) = 0;
  1260.     /// Input primitive from stream.
  1261.     virtual PUnSerialiser & operator>>(unsigned int &) = 0;
  1262.     /// Input primitive from stream.
  1263.     virtual PUnSerialiser & operator>>(long &) = 0;
  1264.     /// Input primitive from stream.
  1265.     virtual PUnSerialiser & operator>>(unsigned long &) = 0;
  1266.     /// Input primitive from stream.
  1267.     virtual PUnSerialiser & operator>>(float &) = 0;
  1268.     /// Input primitive from stream.
  1269.     virtual PUnSerialiser & operator>>(double &) = 0;
  1270.     /// Input primitive from stream.
  1271.     virtual PUnSerialiser & operator>>(long double &) = 0;
  1272.     /// Input primitive from stream.
  1273.     virtual PUnSerialiser & operator>>(char *) = 0;
  1274.     /// Input primitive from stream.
  1275.     virtual PUnSerialiser & operator>>(unsigned char *) = 0;
  1276.     /// Input primitive from stream.
  1277.     virtual PUnSerialiser & operator>>(signed char *) = 0;
  1278.     /** Input the data from the un-serialiser object.
  1279.       When the operator is executed on a #PObject# descendent then
  1280.       that objects #PObject::UnSerialise()# function is called.
  1281.      */
  1282.     virtual PUnSerialiser & operator>>(PObject &) = 0;
  1283.   protected:
  1284.     /// Stream the read un-serialiser data from.
  1285.     istream & stream;
  1286. };
  1287. /**Declare information in a class for serialisation of objects.
  1288.    This macro is used to declare functions required by the serialisation
  1289.    system. It is used in conjunction with the #PIMPLEMENT_SERIAL# macro.
  1290.    This declares the #PObject::PreSerialise()# and
  1291.    #PObject::Serialise()# functions which must be imeplemented by the
  1292.    user. The un-serialisation and registration is declared and implemented by
  1293.    these two functions automatically.
  1294.  */
  1295. #define PSERIALINFO(cls) 
  1296.   public: 
  1297.     virtual PINDEX PreSerialise(PSerialiser & strm); 
  1298.     virtual void Serialise(PSerialiser & serial); 
  1299.     virtual void UnSerialise(PUnSerialiser & serial); 
  1300.   protected: 
  1301.     cls(PUnSerialiser & serial); 
  1302.     static cls * UnSerialiseNew(PUnSerialiser & serial); 
  1303.   private: 
  1304.     PINDEX serialisedLength; 
  1305.     static PSerialRegistration pRegisterSerial; 
  1306. /**
  1307.    This macro is used to implement functions required by the serialisation
  1308.    system. It is used in conjunction with the #PDECLARE_SERIAL# macro.
  1309.  */
  1310. #define PIMPLEMENT_SERIAL(cls) 
  1311.   cls * cls::UnSerialiseNew(PUnSerialiser & serial) 
  1312.     { return new cls(serial); } 
  1313.   PSerialRegistration cls::pRegisterSerial(cls::Class(), cls::UnSerialise); 
  1314. /** This serialiser class serialises each object using ASCII text. This gives
  1315.   the highest level of portability for streams and platforms at the expense
  1316.   if larger amounts of data.
  1317.  */
  1318. class PTextSerialiser : public PSerialiser
  1319. {
  1320.   PCLASSINFO(PTextSerialiser, PSerialiser);
  1321.   public:
  1322.     /// Create a text serialiser.
  1323.     PTextSerialiser(
  1324.       ostream & strm,   // Stream to serialise to.
  1325.       PObject & data    // First object to serialise.
  1326.     );
  1327.     /// Output primitive to stream.
  1328.     PSerialiser & operator<<(char);
  1329.     /// Output primitive to stream.
  1330.     PSerialiser & operator<<(unsigned char);
  1331.     /// Output primitive to stream.
  1332.     PSerialiser & operator<<(signed char);
  1333.     /// Output primitive to stream.
  1334.     PSerialiser & operator<<(short);
  1335.     /// Output primitive to stream.
  1336.     PSerialiser & operator<<(unsigned short);
  1337.     /// Output primitive to stream.
  1338.     PSerialiser & operator<<(int);
  1339.     /// Output primitive to stream.
  1340.     PSerialiser & operator<<(unsigned int);
  1341.     /// Output primitive to stream.
  1342.     PSerialiser & operator<<(long);
  1343.     /// Output primitive to stream.
  1344.     PSerialiser & operator<<(unsigned long);
  1345.     /// Output primitive to stream.
  1346.     PSerialiser & operator<<(float);
  1347.     /// Output primitive to stream.
  1348.     PSerialiser & operator<<(double);
  1349.     /// Output primitive to stream.
  1350.     PSerialiser & operator<<(long double);
  1351.     /// Output primitive to stream.
  1352.     PSerialiser & operator<<(const char *);
  1353.     /// Output primitive to stream.
  1354.     PSerialiser & operator<<(const unsigned char *);
  1355.     /// Output primitive to stream.
  1356.     PSerialiser & operator<<(const signed char *);
  1357.     /** Output the data to the serialiser object.
  1358.       When the operator is executed on a #PObject# descendent then that objects
  1359.       #PObject::Serialise()# function is called.
  1360.      */
  1361.     virtual PSerialiser & operator<<(PObject & obj);
  1362. };
  1363. class PSortedStringList;
  1364. /** This serialiser class serialises each object using binary data. This gives
  1365.    the highest level data density at the expense of some portability and
  1366.    possibly the speed of execution.
  1367.    
  1368.    This is because two passes through the objects is made, the first to
  1369.    determine the classes and sizes and the second to actually output the data.
  1370.    A table of classes must also be output to set the correspondence between
  1371.    the class codes used in the output and the class names that are required by
  1372.    the unserialiser to construct instances of those classes.
  1373.  */
  1374. class PBinarySerialiser : public PSerialiser
  1375. {
  1376.   PCLASSINFO(PBinarySerialiser, PSerialiser);
  1377.   public:
  1378.     /// Create a binary serialiser.
  1379.     PBinarySerialiser(
  1380.       ostream & strm,   // Stream to serialise to.
  1381.       PObject & data    // First object to serialise.
  1382.     );
  1383.     /// Destroy the serialiser and its class table.
  1384.     ~PBinarySerialiser();
  1385.     /// Output primitive to stream.
  1386.     PSerialiser & operator<<(char);
  1387.     /// Output primitive to stream.
  1388.     PSerialiser & operator<<(unsigned char);
  1389.     /// Output primitive to stream.
  1390.     PSerialiser & operator<<(signed char);
  1391.     /// Output primitive to stream.
  1392.     PSerialiser & operator<<(short);
  1393.     /// Output primitive to stream.
  1394.     PSerialiser & operator<<(unsigned short);
  1395.     /// Output primitive to stream.
  1396.     PSerialiser & operator<<(int);
  1397.     /// Output primitive to stream.
  1398.     PSerialiser & operator<<(unsigned int);
  1399.     /// Output primitive to stream.
  1400.     PSerialiser & operator<<(long);
  1401.     /// Output primitive to stream.
  1402.     PSerialiser & operator<<(unsigned long);
  1403.     /// Output primitive to stream.
  1404.     PSerialiser & operator<<(float);
  1405.     /// Output primitive to stream.
  1406.     PSerialiser & operator<<(double);
  1407.     /// Output primitive to stream.
  1408.     PSerialiser & operator<<(long double);
  1409.     /// Output primitive to stream.
  1410.     PSerialiser & operator<<(const char *);
  1411.     /// Output primitive to stream.
  1412.     PSerialiser & operator<<(const unsigned char *);
  1413.     /// Output primitive to stream.
  1414.     PSerialiser & operator<<(const signed char *);
  1415.     /** Output the data to the serialiser object.
  1416.       When the operator is executed on a #PObject# descendent then that objects
  1417.       #PObject::Serialise()# function is called.
  1418.      */
  1419.     virtual PSerialiser & operator<<(PObject & obj);
  1420.   protected:
  1421.     /// List of classes used during serialisation.
  1422.     PSortedStringList * classesUsed;
  1423. };
  1424. /** This un-serialiser class reconstructs each object using ASCII text. This
  1425.    gives the highest level of portability for streams and platforms at the
  1426.    expense if larger amounts of data.
  1427.  */
  1428. class PTextUnSerialiser : public PUnSerialiser
  1429. {
  1430.   PCLASSINFO(PTextUnSerialiser, PUnSerialiser);
  1431.   public:
  1432.     /// Create a text un-serialiser.
  1433.     PTextUnSerialiser(
  1434.       istream & strm    // Stream to read serialised objects from.
  1435.     );
  1436.     /// Input primitive from stream.
  1437.     PUnSerialiser & operator>>(char &);
  1438.     /// Input primitive from stream.
  1439.     PUnSerialiser & operator>>(unsigned char &);
  1440.     /// Input primitive from stream.
  1441.     PUnSerialiser & operator>>(signed char &);
  1442.     /// Input primitive from stream.
  1443.     PUnSerialiser & operator>>(short &);
  1444.     /// Input primitive from stream.
  1445.     PUnSerialiser & operator>>(unsigned short &);
  1446.     /// Input primitive from stream.
  1447.     PUnSerialiser & operator>>(int &);
  1448.     /// Input primitive from stream.
  1449.     PUnSerialiser & operator>>(unsigned int &);
  1450.     /// Input primitive from stream.
  1451.     PUnSerialiser & operator>>(long &);
  1452.     /// Input primitive from stream.
  1453.     PUnSerialiser & operator>>(unsigned long &);
  1454.     /// Input primitive from stream.
  1455.     PUnSerialiser & operator>>(float &);
  1456.     /// Input primitive from stream.
  1457.     PUnSerialiser & operator>>(double &);
  1458.     /// Input primitive from stream.
  1459.     PUnSerialiser & operator>>(long double &);
  1460.     /// Input primitive from stream.
  1461.     PUnSerialiser & operator>>(char *);
  1462.     /// Input primitive from stream.
  1463.     PUnSerialiser & operator>>(unsigned char *);
  1464.     /// Input primitive from stream.
  1465.     PUnSerialiser & operator>>(signed char *);
  1466.     /** Input the data from the un-serialiser object.
  1467.       When the operator is executed on a #PObject# descendent then
  1468.       that objects #PObject::UnSerialise()# function is called.
  1469.      */
  1470.     PUnSerialiser & operator>>(PObject &);
  1471. };
  1472. class PStringArray;
  1473. /** This un-serialiser class reconstructs each object using binary data. This
  1474.    gives the highest level data density at the expense of some portability and
  1475.    possibly the speed of execution.
  1476.    
  1477.    A table of classes must also be output
  1478.    to set the correspondence between the class codes used in the output and
  1479.    the class names that are required by the unserialiser to construct instances
  1480.    of those classes.
  1481.  */
  1482. class PBinaryUnSerialiser : public PUnSerialiser
  1483. {
  1484.   PCLASSINFO(PBinaryUnSerialiser, PUnSerialiser);
  1485.   public:
  1486.     /// Create a binary un-serialiser.
  1487.     PBinaryUnSerialiser(
  1488.       istream & strm    // Stream to read serialised objects from.
  1489.     );
  1490.     /// Destroy the un-serialiser and its class table.
  1491.     ~PBinaryUnSerialiser();
  1492.     /// Input primitive from stream.
  1493.     PUnSerialiser & operator>>(char &);
  1494.     /// Input primitive from stream.
  1495.     PUnSerialiser & operator>>(unsigned char &);
  1496.     /// Input primitive from stream.
  1497.     PUnSerialiser & operator>>(signed char &);
  1498.     /// Input primitive from stream.
  1499.     PUnSerialiser & operator>>(short &);
  1500.     /// Input primitive from stream.
  1501.     PUnSerialiser & operator>>(unsigned short &);
  1502.     /// Input primitive from stream.
  1503.     PUnSerialiser & operator>>(int &);
  1504.     /// Input primitive from stream.
  1505.     PUnSerialiser & operator>>(unsigned int &);
  1506.     /// Input primitive from stream.
  1507.     PUnSerialiser & operator>>(long &);
  1508.     /// Input primitive from stream.
  1509.     PUnSerialiser & operator>>(unsigned long &);
  1510.     /// Input primitive from stream.
  1511.     PUnSerialiser & operator>>(float &);
  1512.     /// Input primitive from stream.
  1513.     PUnSerialiser & operator>>(double &);
  1514.     /// Input primitive from stream.
  1515.     PUnSerialiser & operator>>(long double &);
  1516.     /// Input primitive from stream.
  1517.     PUnSerialiser & operator>>(char *);
  1518.     /// Input primitive from stream.
  1519.     PUnSerialiser & operator>>(unsigned char *);
  1520.     /// Input primitive from stream.
  1521.     PUnSerialiser & operator>>(signed char *);
  1522.     /** Input the data from the un-serialiser object.
  1523.       When the operator is executed on a #PObject# descendent then
  1524.       that objects #PObject::UnSerialise()# function is called.
  1525.      */
  1526.     PUnSerialiser & operator>>(PObject &);
  1527.   protected:
  1528.     /// Class table used by the serialiser.
  1529.     PStringArray * classesUsed;
  1530. };
  1531. ///////////////////////////////////////////////////////////////////////////////
  1532. // "Smart" pointers.
  1533. /** This is the base class for objects that use the {it smart pointer} system.
  1534.    In conjunction with the #PSmartPointer# class, this class creates
  1535.    objects that can have the automatic deletion of the object instance when
  1536.    there are no more smart pointer instances pointing to it.
  1537.    A #PSmartObject# carries the reference count that the #PSmartPointer# 
  1538.    requires to determine if the pointer is needed any more and should be
  1539.    deleted.
  1540.  */
  1541. class PSmartObject : public PObject
  1542. {
  1543.   PCLASSINFO(PSmartObject, PObject);
  1544.   public:
  1545.     /** Construct a new smart object, subject to a #PSmartPointer# instance
  1546.        referencing it.
  1547.      */
  1548.     PSmartObject() { referenceCount = 1; }
  1549.   protected:
  1550.     /** Count of number of instances of #PSmartPointer# that currently
  1551.        reference the object instance.
  1552.      */
  1553.     unsigned referenceCount;
  1554.   friend class PSmartPointer;
  1555. };
  1556. /** This is the class for pointers to objects that use the {it smart pointer}
  1557.    system. In conjunction with the #PSmartObject# class, this class
  1558.    references objects that can have the automatic deletion of the object
  1559.    instance when there are no more smart pointer instances pointing to it.
  1560.    A PSmartPointer carries the pointer to a #PSmartObject# instance which
  1561.    contains a reference count. Assigning or copying instances of smart pointers
  1562.    will automatically increment and decrement the reference count. When the
  1563.    last instance that references a #PSmartObject# instance is destroyed or
  1564.    overwritten, the #PSmartObject# is deleted.
  1565.    A NULL value is possible for a smart pointer. It can be detected via the
  1566.    #IsNULL()# function.
  1567.  */
  1568. class PSmartPointer : public PObject
  1569. {
  1570.   PCLASSINFO(PSmartPointer, PObject);
  1571.   public:
  1572.   /**@name Construction */
  1573.   //@{
  1574.     /** Create a new smart pointer instance and have it point to the specified
  1575.        #PSmartObject# instance.
  1576.      */
  1577.     PSmartPointer(
  1578.       PSmartObject * obj = NULL   /// Smart object to point to.
  1579.     ) { object = obj; }
  1580.     /** Create a new smart pointer and point it at the data pointed to by the
  1581.        #ptr# parameter. The reference count for the object being
  1582.        pointed at is incremented.
  1583.      */
  1584.     PSmartPointer(
  1585.       const PSmartPointer & ptr  /// Smart pointer to make a copy of.
  1586.     );
  1587.     /** Destroy the smart pointer and decrement the reference count on the
  1588.        object being pointed to. If there are no more references then the
  1589.        object is deleted.
  1590.      */
  1591.     virtual ~PSmartPointer();
  1592.     /** Assign this pointer to the value specified in the #ptr#
  1593.        parameter.
  1594.        The previous object being pointed to has its reference count
  1595.        decremented as this will no longer point to it. If there are no more
  1596.        references then the object is deleted.
  1597.        The new object being pointed to after the assignment has its reference
  1598.        count incremented.
  1599.      */
  1600.     PSmartPointer & operator=(
  1601.       const PSmartPointer & ptr  /// Smart pointer to assign.
  1602.     );
  1603.   //@}
  1604.   /**@name Overrides from class PObject */
  1605.   //@{
  1606.     /** Determine the relative rank of the pointers. This is identical to
  1607.        determining the relative rank of the integer values represented by the
  1608.        memory pointers.
  1609.        @return
  1610.        #EqualTo# if objects point to the same object instance,
  1611.        otherwise #LessThan# and #GreaterThan# may be
  1612.        returned depending on the relative values of the memory pointers.
  1613.      */
  1614.     virtual Comparison Compare(
  1615.       const PObject & obj   // Other smart pointer to compare against.
  1616.     ) const;
  1617.   //@}
  1618.   /**@name Pointer access functions */
  1619.   //@{
  1620.     /** Determine if the smart pointer has been set to point to an actual
  1621.        object instance.
  1622.        @return
  1623.        TRUE if the pointer is NULL.
  1624.      */
  1625.     BOOL IsNULL() const { return object == NULL; }
  1626.     /** Get the current value if the internal smart object pointer.
  1627.        @return
  1628.        pointer to object instance.
  1629.      */
  1630.     PSmartObject * GetObject() const { return object; }
  1631.   //@}
  1632.   protected:
  1633.     // Member variables
  1634.     /// Object the smart pointer points to.
  1635.     PSmartObject * object;
  1636. };
  1637. /** This macro is used to declare a smart pointer class members.
  1638. The class #cls# is the smart pointer, descended from the #par# class, to the
  1639. #type# class.
  1640. The macro declares in the class the following functions:
  1641. begin{verbatim}
  1642.       PCLASSINFO(cls, par);
  1643.         Standard class info.
  1644.       type * operator->() const;
  1645.         Access to the members of the smart object in the smart pointer.
  1646.       type & operator*() const;
  1647.         Access to the value of the smart object in the smart pointer.
  1648. end{verbatim}
  1649. */
  1650. #define PSMART_POINTER_INFO(cls, par, type) 
  1651.   PCLASSINFO(cls, par) 
  1652.   public: 
  1653.     type * operator->() const 
  1654.       { return (type *)PAssertNULL(object); } 
  1655.     type & operator*() const 
  1656.       { return *(type *)PAssertNULL(object); } 
  1657.     operator type*() const 
  1658.       { return (type *)object; }
  1659. ///////////////////////////////////////////////////////////////////////////////
  1660. // General notification mechanism from one object to another
  1661. /** This class is the #PSmartObject# contents of the #PNotifier#
  1662.    class.
  1663.    This is an abstract class for which a descendent is declared for every
  1664.    function that may be called. The #PDECLARE_NOTIFIER# macro makes this
  1665.    declaration.
  1666.    The #PNotifier# and PNotifierFunction classes build a completely type
  1667.    safe mechanism for calling arbitrary member functions on classes. The
  1668.    "pointer to a member function" capability built into C++ makes the
  1669.    assumption that the function name exists in an ancestor class. If you wish
  1670.    to call a member function name that does {bf not} exist in any ancestor
  1671.    class, very type unsafe casting of the member functions must be made. Some
  1672.    compilers will even refuse to do it at all!
  1673.    To overcome this problem, as this mechanism is highly desirable for callback
  1674.    functions in the GUI part of the PWLib library, these classes and a macro
  1675.    are used to create all the classes and declarations to use polymorphism as
  1676.    the link between the caller, which has no knowledege of the function, and
  1677.    the receiver object and member function.
  1678.    This is most often used as the notification of actions being take by
  1679.    interactors in the PWLib library.
  1680.  */
  1681. class PNotifierFunction : public PSmartObject
  1682. {
  1683.   PCLASSINFO(PNotifierFunction, PSmartObject);
  1684.   public:
  1685.     /// Create a notification function instance.
  1686.     PNotifierFunction(
  1687.       void * obj    /// Object instance that the function will be called on.
  1688.     ) { object = PAssertNULL(obj); }
  1689.     /** Execute the call to the actual notification function on the object
  1690.        instance contained in this object.
  1691.      */
  1692.     virtual void Call(
  1693.       PObject & notifier,  /// Object that is making the notification.
  1694.       INT extra            /// Extra information that may be passed to function.
  1695.     ) const = 0;
  1696.   protected:
  1697.     // Member variables
  1698.     /** Object instance to receive the notification function call. */
  1699.     void * object;
  1700. };
  1701. /** This class is the #PSmartPointer# to the #PNotifierFunction#
  1702.    class.
  1703.    The PNotifier and #PNotifierFunction# classes build a completely type
  1704.    safe mechanism for calling arbitrary member functions on classes. The
  1705.    "pointer to a member function" capability built into C++ makes the
  1706.    assumption that the function name exists in an ancestor class. If you wish
  1707.    to call a member function name that does {bf not} exist in any ancestor
  1708.    class, very type unsafe casting of the member functions must be made. Some
  1709.    compilers will even refuse to do it at all!
  1710.    To overcome this problem, as this mechanism is highly desirable for callback
  1711.    functions in the GUI part of the PWLib library, these classes and a macro
  1712.    are used to create all the classes and declarations to use polymorphism as
  1713.    the link between the caller, which has no knowledege of the function, and
  1714.    the receiver object and member function.
  1715.    This is most often used as the notification of actions being take by
  1716.    interactors in the PWLib library.
  1717.  */
  1718. class PNotifier : public PSmartPointer
  1719. {
  1720.   PCLASSINFO(PNotifier, PSmartPointer);
  1721.   public:
  1722.     /** Create a new notification function smart pointer. */
  1723.     PNotifier(
  1724.       PNotifierFunction * func = NULL   /// Notifier function to call.
  1725.     ) : PSmartPointer(func) { }
  1726.     /**Execute the call to the actual notification function on the object
  1727.        instance contained in this object. This will make a polymorphic call to
  1728.        the function declared by the #PDECLARE_NOTIFIER# macro which in
  1729.        turn calls the required function in the destination object.
  1730.      */
  1731.     virtual void operator()(
  1732.       PObject & notifier,  /// Object that is making the notification.
  1733.       INT extra            /// Extra information that may be passed to function.
  1734.     ) const {((PNotifierFunction*)PAssertNULL(object))->Call(notifier,extra);}
  1735. };
  1736. /** Declare a notifier object class.
  1737.   This macro declares the descendent class of #PNotifierFunction# that
  1738.   will be used in instances of #PNotifier# created by the
  1739.   #PCREATE_NOTIFIER# or #PCREATE_NOTIFIER2# macros.
  1740.   The macro is expected to be used inside a class declaration. The class it
  1741.   declares will therefore be a nested class within the class being declared.
  1742.   The name of the new nested class is derived from the member function name
  1743.   which should guarentee the class names are unique.
  1744.   The #notifier# parameter is the class of the function that will be
  1745.   calling the notification function. The #notifiee# parameter is the
  1746.   class to which the called member function belongs. Finally the
  1747.   #func# parameter is the name of the member function to be
  1748.   declared.
  1749.   This macro will also declare the member function itself. This will be:
  1750. begin{verbatim}
  1751.       void func(notifier & n, INT extra)
  1752. end{verbatim}
  1753.   The implementation of the function is left for the user.
  1754.  */
  1755. #define PDECLARE_NOTIFIER(notifier, notifiee, func) 
  1756.   class func##_PNotifier : public PNotifierFunction { 
  1757.     public: 
  1758.       func##_PNotifier(notifiee * obj) : PNotifierFunction(obj) { } 
  1759.       virtual void Call(PObject & note, INT extra) const 
  1760.         { ((notifiee*)object)->func((notifier &)note, extra); } 
  1761.   }; 
  1762.   friend class func##_PNotifier; 
  1763.   virtual void func(notifier & note, INT extra)
  1764. /** Create a notifier object instance.
  1765.   This macro creates an instance of the particular #PNotifier# class using
  1766.   the #func# parameter as the member function to call.
  1767.   The #obj# parameter is the instance to call the function against.
  1768.   If the instance to be called is the current instance, ie #obj# is
  1769.   to #this# the the #PCREATE_NOTIFIER# macro should be used.
  1770.  */
  1771. #define PCREATE_NOTIFIER2(obj, func) PNotifier(new func##_PNotifier(obj))
  1772. /** Create a notifier object instance.
  1773.   This macro creates an instance of the particular #PNotifier# class using
  1774.   the #func# parameter as the member function to call.
  1775.   The #this# object is used as the instance to call the function
  1776.   against. The #PCREATE_NOTIFIER2# macro may be used if the instance to be
  1777.   called is not the current object instance.
  1778.  */
  1779. #define PCREATE_NOTIFIER(func) PCREATE_NOTIFIER2(this, func)
  1780. ///////////////////////////////////////////////////////////////////////////////
  1781. // Really big integer class for architectures without
  1782. #ifdef P_NEEDS_INT64
  1783. class PInt64__ {
  1784.   public:
  1785.     operator long()  const { return (long)low; }
  1786.     operator int()   const { return (int)low; }
  1787.     operator short() const { return (short)low; }
  1788.     operator char()  const { return (char)low; }
  1789.     operator unsigned long()  const { return (unsigned long)low; }
  1790.     operator unsigned int()   const { return (unsigned int)low; }
  1791.     operator unsigned short() const { return (unsigned short)low; }
  1792.     operator unsigned char()  const { return (unsigned char)low; }
  1793.   protected:
  1794.     PInt64__() { }
  1795.     PInt64__(unsigned long l) : low(l), high(0) { }
  1796.     PInt64__(unsigned long l, unsigned long h) : low(l), high(h) { }
  1797.     void operator=(const PInt64__ & v) { low = v.low; high = v.high; }
  1798.     void Inc() { if (++low == 0) ++high; }
  1799.     void Dec() { if (--low == 0) --high; }
  1800.     void Or (long v) { low |= v; }
  1801.     void And(long v) { low &= v; }
  1802.     void Xor(long v) { low ^= v; }
  1803.     void Add(const PInt64__ & v);
  1804.     void Sub(const PInt64__ & v);
  1805.     void Mul(const PInt64__ & v);
  1806.     void Div(const PInt64__ & v);
  1807.     void Mod(const PInt64__ & v);
  1808.     void Or (const PInt64__ & v) { low |= v.low; high |= v.high; }
  1809.     void And(const PInt64__ & v) { low &= v.low; high &= v.high; }
  1810.     void Xor(const PInt64__ & v) { low ^= v.low; high ^= v.high; }
  1811.     void ShiftLeft(int bits);
  1812.     void ShiftRight(int bits);
  1813.     BOOL Eq(unsigned long v) const { return low == v && high == 0; }
  1814.     BOOL Ne(unsigned long v) const { return low != v || high != 0; }
  1815.     BOOL Eq(const PInt64__ & v) const { return low == v.low && high == v.high; }
  1816.     BOOL Ne(const PInt64__ & v) const { return low != v.low || high != v.high; }
  1817.     unsigned long low, high;
  1818. };
  1819. #define DECL_OPS(cls, type) 
  1820.     const cls & operator=(type v) { PInt64__::operator=(cls(v)); return *this; } 
  1821.     cls operator+(type v) const { cls t = *this; t.Add(v); return t; } 
  1822.     cls operator-(type v) const { cls t = *this; t.Sub(v); return t; } 
  1823.     cls operator*(type v) const { cls t = *this; t.Mul(v); return t; } 
  1824.     cls operator/(type v) const { cls t = *this; t.Div(v); return t; } 
  1825.     cls operator%(type v) const { cls t = *this; t.Mod(v); return t; } 
  1826.     cls operator|(type v) const { cls t = *this; t.Or (v); return t; } 
  1827.     cls operator&(type v) const { cls t = *this; t.And(v); return t; } 
  1828.     cls operator^(type v) const { cls t = *this; t.Xor(v); return t; } 
  1829.     cls operator<<(type v) const { cls t = *this; t.ShiftLeft((int)v); return t; } 
  1830.     cls operator>>(type v) const { cls t = *this; t.ShiftRight((int)v); return t; } 
  1831.     const cls & operator+=(type v) { Add(v); return *this; } 
  1832.     const cls & operator-=(type v) { Sub(v); return *this; } 
  1833.     const cls & operator*=(type v) { Mul(v); return *this; } 
  1834.     const cls & operator/=(type v) { Div(v); return *this; } 
  1835.     const cls & operator|=(type v) { Or (v); return *this; } 
  1836.     const cls & operator&=(type v) { And(v); return *this; } 
  1837.     const cls & operator^=(type v) { Xor(v); return *this; } 
  1838.     const cls & operator<<=(type v) { ShiftLeft((int)v); return *this; } 
  1839.     const cls & operator>>=(type v) { ShiftRight((int)v); return *this; } 
  1840.     BOOL operator==(type v) const { return Eq(v); } 
  1841.     BOOL operator!=(type v) const { return Ne(v); } 
  1842.     BOOL operator< (type v) const { return Lt(v); } 
  1843.     BOOL operator> (type v) const { return Gt(v); } 
  1844.     BOOL operator>=(type v) const { return !Gt(v); } 
  1845.     BOOL operator<=(type v) const { return !Lt(v); } 
  1846. class PInt64 : public PInt64__ {
  1847.   public:
  1848.     PInt64() { }
  1849.     PInt64(long l) : PInt64__(l, l < 0 ? -1 : 0) { }
  1850.     PInt64(unsigned long l, long h) : PInt64__(l, h) { }
  1851.     PInt64(const PInt64__ & v) : PInt64__(v) { }
  1852.     PInt64 operator~() const { return PInt64(~low, ~high); }
  1853.     PInt64 operator-() const { return operator~()+1; }
  1854.     PInt64 operator++() { Inc(); return *this; }
  1855.     PInt64 operator--() { Dec(); return *this; }
  1856.     PInt64 operator++(int) { PInt64 t = *this; Inc(); return t; }
  1857.     PInt64 operator--(int) { PInt64 t = *this; Dec(); return t; }
  1858.     DECL_OPS(PInt64, char)
  1859.     DECL_OPS(PInt64, unsigned char)
  1860.     DECL_OPS(PInt64, short)
  1861.     DECL_OPS(PInt64, unsigned short)
  1862.     DECL_OPS(PInt64, int)
  1863.     DECL_OPS(PInt64, unsigned int)
  1864.     DECL_OPS(PInt64, long)
  1865.     DECL_OPS(PInt64, unsigned long)
  1866.     DECL_OPS(PInt64, const PInt64 &)
  1867.     friend ostream & operator<<(ostream &, const PInt64 &);
  1868.     friend istream & operator>>(istream &, PInt64 &);
  1869.   protected:
  1870.     void Add(long v) { Add(PInt64(v)); }
  1871.     void Sub(long v) { Sub(PInt64(v)); }
  1872.     void Mul(long v) { Mul(PInt64(v)); }
  1873.     void Div(long v) { Div(PInt64(v)); }
  1874.     void Mod(long v) { Mod(PInt64(v)); }
  1875.     BOOL Lt(long v) const { return Lt(PInt64(v)); }
  1876.     BOOL Gt(long v) const { return Gt(PInt64(v)); }
  1877.     BOOL Lt(const PInt64 &) const;
  1878.     BOOL Gt(const PInt64 &) const;
  1879. };
  1880. class PUInt64 : public PInt64__ {
  1881.   public:
  1882.     PUInt64() { }
  1883.     PUInt64(unsigned long l) : PInt64__(l, 0) { }
  1884.     PUInt64(unsigned long l, unsigned long h) : PInt64__(l, h) { }
  1885.     PUInt64(const PInt64__ & v) : PInt64__(v) { }
  1886.     PUInt64 operator~() const { return PUInt64(~low, ~high); }
  1887.     const PUInt64 & operator++() { Inc(); return *this; }
  1888.     const PUInt64 & operator--() { Dec(); return *this; }
  1889.     PUInt64 operator++(int) { PUInt64 t = *this; Inc(); return t; }
  1890.     PUInt64 operator--(int) { PUInt64 t = *this; Dec(); return t; }
  1891.     DECL_OPS(PUInt64, char)
  1892.     DECL_OPS(PUInt64, unsigned char)
  1893.     DECL_OPS(PUInt64, short)
  1894.     DECL_OPS(PUInt64, unsigned short)
  1895.     DECL_OPS(PUInt64, int)
  1896.     DECL_OPS(PUInt64, unsigned int)
  1897.     DECL_OPS(PUInt64, long)
  1898.     DECL_OPS(PUInt64, unsigned long)
  1899.     DECL_OPS(PUInt64, const PUInt64 &)
  1900.     friend ostream & operator<<(ostream &, const PUInt64 &);
  1901.     friend istream & operator>>(istream &, PUInt64 &);
  1902.   protected:
  1903.     void Add(long v) { Add(PUInt64(v)); }
  1904.     void Sub(long v) { Sub(PUInt64(v)); }
  1905.     void Mul(long v) { Mul(PUInt64(v)); }
  1906.     void Div(long v) { Div(PUInt64(v)); }
  1907.     void Mod(long v) { Mod(PUInt64(v)); }
  1908.     BOOL Lt(long v) const { return Lt(PUInt64(v)); }
  1909.     BOOL Gt(long v) const { return Gt(PUInt64(v)); }
  1910.     BOOL Lt(const PUInt64 &) const;
  1911.     BOOL Gt(const PUInt64 &) const;
  1912. };
  1913. #undef DECL_OPS
  1914. #endif
  1915. ///////////////////////////////////////////////////////////////////////////////
  1916. // Platform independent types
  1917. // All these classes encapsulate primitive types such that they may be
  1918. // transfered in a platform independent manner. In particular it is used to
  1919. // do byte swapping for little endien and big endien processor architectures
  1920. // as well as accommodating structure packing rules for memory structures.
  1921. #define PANSI_CHAR 1
  1922. #define PLITTLE_ENDIAN 2
  1923. #define PBIG_ENDIAN 3
  1924. #if 0
  1925. class PStandardType
  1926. /* Encapsulate a standard 8 bit character into a portable format. This would
  1927.    rarely need to do translation, only if the target platform uses EBCDIC
  1928.    would it do anything.
  1929.    The platform independent form here is always 8 bit ANSI.
  1930.  */
  1931. {
  1932.   public:
  1933.     PStandardType(
  1934.       type newVal   // Value to initialise data in platform dependent form.
  1935.     ) { data = newVal; }
  1936.     /* Create a new instance of the platform independent type using platform
  1937.        dependent data, or platform independent streams.
  1938.      */
  1939.     operator type() { return data; }
  1940.     /* Get the platform dependent value for the type.
  1941.        @return
  1942.        data for instance.
  1943.      */
  1944.     friend ostream & operator<<(ostream & strm, const PStandardType & val)
  1945.       { return strm << (type)val; }
  1946.     /* Output the platform dependent value for the type to the stream.
  1947.        @return
  1948.        the stream output was made to.
  1949.      */
  1950.     friend istream & operator>>(istream & strm, PStandardType & val)
  1951.       { type data; strm >> data; val = PStandardType(data); return strm; }
  1952.     /* Input the platform dependent value for the type from the stream.
  1953.        @return
  1954.        the stream input was made from.
  1955.      */
  1956.   private:
  1957.     type data;
  1958. };
  1959. #endif
  1960. #define PI_SAME(name, type) 
  1961.   struct name { 
  1962.     name() { } 
  1963.     name(type value) { data = value; } 
  1964.     name(const name & value) { data = value.data; } 
  1965.     name & operator =(type value) { data = value; return *this; } 
  1966.     name & operator =(const name & value) { data = value.data; return *this; } 
  1967.     operator type() const { return data; } 
  1968.     friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } 
  1969.     friend istream & operator>>(istream & s, name & v) { return s >> v.data; } 
  1970.     private: type data; 
  1971.   }
  1972. #define PI_LOOP(src, dst) 
  1973.     BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; 
  1974.     while (s != (BYTE *)&src) *d++ = *--s;
  1975. #define PI_DIFF(name, type) 
  1976.   struct name { 
  1977.     name() { } 
  1978.     name(type value) { operator=(value); } 
  1979.     name(const name & value) { data = value.data; } 
  1980.     name & operator =(type value) { PI_LOOP(value, data); return *this; } 
  1981.     name & operator =(const name & value) { data = value.data; return *this; } 
  1982.     operator type() const { type value; PI_LOOP(data, value); return value; } 
  1983.     friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } 
  1984.     friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } 
  1985.     private: type data; 
  1986.   }
  1987. #ifndef PCHAR8
  1988. #define PCHAR8 PANSI_CHAR
  1989. #endif
  1990. #if PCHAR8==PANSI_CHAR
  1991. PI_SAME(PChar8, char);
  1992. #endif
  1993. PI_SAME(PInt8, signed char);
  1994. PI_SAME(PUInt8, unsigned char);
  1995. #if PBYTE_ORDER==PLITTLE_ENDIAN
  1996. PI_SAME(PInt16l, PInt16);
  1997. #elif PBYTE_ORDER==PBIG_ENDIAN
  1998. PI_DIFF(PInt16l, PInt16);
  1999. #endif
  2000. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2001. PI_DIFF(PInt16b, PInt16);
  2002. #elif PBYTE_ORDER==PBIG_ENDIAN
  2003. PI_SAME(PInt16b, PInt16);
  2004. #endif
  2005. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2006. PI_SAME(PUInt16l, WORD);
  2007. #elif PBYTE_ORDER==PBIG_ENDIAN
  2008. PI_DIFF(PUInt16l, WORD);
  2009. #endif
  2010. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2011. PI_DIFF(PUInt16b, WORD);
  2012. #elif PBYTE_ORDER==PBIG_ENDIAN
  2013. PI_SAME(PUInt16b, WORD);
  2014. #endif
  2015. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2016. PI_SAME(PInt32l, PInt32);
  2017. #elif PBYTE_ORDER==PBIG_ENDIAN
  2018. PI_DIFF(PInt32l, PInt32);
  2019. #endif
  2020. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2021. PI_DIFF(PInt32b, PInt32);
  2022. #elif PBYTE_ORDER==PBIG_ENDIAN
  2023. PI_SAME(PInt32b, PInt32);
  2024. #endif
  2025. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2026. PI_SAME(PUInt32l, DWORD);
  2027. #elif PBYTE_ORDER==PBIG_ENDIAN
  2028. PI_DIFF(PUInt32l, DWORD);
  2029. #endif
  2030. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2031. PI_DIFF(PUInt32b, DWORD);
  2032. #elif PBYTE_ORDER==PBIG_ENDIAN
  2033. PI_SAME(PUInt32b, DWORD);
  2034. #endif
  2035. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2036. PI_SAME(PInt64l, PInt64);
  2037. #elif PBYTE_ORDER==PBIG_ENDIAN
  2038. PI_DIFF(PInt64l, PInt64);
  2039. #endif
  2040. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2041. PI_DIFF(PInt64b, PInt64);
  2042. #elif PBYTE_ORDER==PBIG_ENDIAN
  2043. PI_SAME(PInt64b, PInt64);
  2044. #endif
  2045. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2046. PI_SAME(PUInt64l, PUInt64);
  2047. #elif PBYTE_ORDER==PBIG_ENDIAN
  2048. PI_DIFF(PUInt64l, PUInt64);
  2049. #endif
  2050. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2051. PI_DIFF(PUInt64b, PUInt64);
  2052. #elif PBYTE_ORDER==PBIG_ENDIAN
  2053. PI_SAME(PUInt64b, PUInt64);
  2054. #endif
  2055. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2056. PI_SAME(PFloat32l, float);
  2057. #elif PBYTE_ORDER==PBIG_ENDIAN
  2058. PI_DIFF(PFloat32l, float);
  2059. #endif
  2060. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2061. PI_DIFF(PFloat32b, float);
  2062. #elif PBYTE_ORDER==PBIG_ENDIAN
  2063. PI_SAME(PFloat32b, float);
  2064. #endif
  2065. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2066. PI_SAME(PFloat64l, double);
  2067. #elif PBYTE_ORDER==PBIG_ENDIAN
  2068. PI_DIFF(PFloat64l, double);
  2069. #endif
  2070. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2071. PI_DIFF(PFloat64b, double);
  2072. #elif PBYTE_ORDER==PBIG_ENDIAN
  2073. PI_SAME(PFloat64b, double);
  2074. #endif
  2075. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2076. PI_SAME(PFloat80l, long double);
  2077. #elif PBYTE_ORDER==PBIG_ENDIAN
  2078. PI_DIFF(PFloat80l, long double);
  2079. #endif
  2080. #if PBYTE_ORDER==PLITTLE_ENDIAN
  2081. PI_DIFF(PFloat80b, long double);
  2082. #elif PBYTE_ORDER==PBIG_ENDIAN
  2083. PI_SAME(PFloat80b, long double);
  2084. #endif
  2085. #undef PI_LOOP
  2086. #undef PI_SAME
  2087. #undef PI_DIFF
  2088. ///////////////////////////////////////////////////////////////////////////////
  2089. // Miscellaneous
  2090. /*$MACRO PARRAYSIZE(array)
  2091.    This macro is used to calculate the number of array elements in a static
  2092.    array.
  2093.  */
  2094. #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
  2095. /*$MACRO PMIN(v1, v2)
  2096.    This macro is used to calculate the minimum of two values. As this is a
  2097.    macro the expression in #v1# or #v2# is executed
  2098.    twice so extreme care should be made in its use.
  2099.  */
  2100. #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
  2101. /*$MACRO PMAX(v1, v2)
  2102.    This macro is used to calculate the maximum of two values. As this is a
  2103.    macro the expression in #v1# or #v2# is executed
  2104.    twice so extreme care should be made in its use.
  2105.  */
  2106. #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
  2107. /*$MACRO PABS(val)
  2108.    This macro is used to calculate an absolute value. As this is a macro the
  2109.    expression in #val# is executed twice so extreme care should be
  2110.    made in its use.
  2111.  */
  2112. #define PABS(v) ((v) < 0 ? -(v) : (v))
  2113. // End Of File ///////////////////////////////////////////////////////////////