1 /*
2  * object.h
3  *
4  * Mother of all ancestor classes.
5  *
6  * Portable Tools Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 28201 $
30  * $Author: rjongbloed $
31  * $Date: 2012-08-14 21:30:31 -0500 (Tue, 14 Aug 2012) $
32  */
33 
34 #ifndef PTLIB_OBJECT_H
35 #define PTLIB_OBJECT_H
36 
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40 
41 #if defined(_WIN32) || defined(_WIN32_WCE)
42 #include "msos/ptlib/contain.h"
43 #else
44 #include "unix/ptlib/contain.h"
45 #endif
46 
47 #if defined(P_VXWORKS)
48 #include <private/stdiop.h>
49 #endif
50 
51 #include <stdio.h>
52 #include <stdarg.h>
53 #include <stdlib.h>
54 
55 #include <string.h>
56 
57 #include <string>
58 #include <iomanip>
59 #include <iostream>
60 #include <sstream>
61 #include <vector>
62 #include <list>
63 #include <map>
64 #include <algorithm>
65 
66 
67 #define P_REMOVE_VIRTUAL_INTERNAL_BASE(fn) __inline virtual struct ptlib_virtual_function_changed_or_removed ****** fn { return 0; }
68 
69 #if defined(_MSC_VER)
70   #if _MSC_VER < 1310
71     #define P_DEPRECATED
72     #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
73   #elif _MSC_VER < 1400
74     #define P_DEPRECATED __declspec(deprecated)
75     #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated) type fn body
76   #else
77     #define P_DEPRECATED __declspec(deprecated)
78     #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated("Virtual function signature changed or function deprecated")) type fn body
79   #endif
80 #elif defined(__GNUC__)
81   #if __GNUC__ < 4
82     #define P_DEPRECATED
83     #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
84   #else
85     #define P_DEPRECATED __attribute__((deprecated))
86     #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __attribute__((warn_unused_result)) __attribute__((deprecated)) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
87   #endif
88 #else
89     #define P_DEPRECATED
90     #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
91 #endif
92 
93 #define P_REMOVE_VIRTUAL_VOID(fn)       P_REMOVE_VIRTUAL_INTERNAL(void, fn, {})
94 #define P_REMOVE_VIRTUAL(type, fn, ret) P_REMOVE_VIRTUAL_INTERNAL(type, fn, { return ret; })
95 
96 
97 // P_USE_INTEGER_BOOL is the default and gives the old behaviour (it
98 // is also used for C translation units).
99 // without P_USE_INTEGER_BOOL, the ANSI C++ bool is used.
100 
101 #if defined(P_USE_INTEGER_BOOL) || !defined(__cplusplus)
102    typedef BOOL PBoolean;
103 #  define PTrue TRUE
104 #  define PFalse FALSE
105 #else
106    typedef bool PBoolean;
107 #  define PTrue true
108 #  define PFalse false
109 #endif
110 
111 
112 ///////////////////////////////////////////////////////////////////////////////
113 // Disable inlines when debugging for faster compiles (the compiler doesn't
114 // actually inline the function with debug on any way).
115 
116 #ifndef P_USE_INLINES
117 #ifdef _DEBUG
118 #define P_USE_INLINES 0
119 #else
120 #define P_USE_INLINES 0
121 #endif
122 #endif
123 
124 #if P_USE_INLINES
125 #define PINLINE inline
126 #else
127 #define PINLINE
128 #endif
129 
130 
131 ///////////////////////////////////////////////////////////////////////////////
132 // Declare the debugging support
133 
134 #ifndef P_USE_ASSERTS
135 #define P_USE_ASSERTS 1
136 #endif
137 
138 #if !P_USE_ASSERTS
139 
140 #define PAssert(b, m) (b)
141 #define PAssert2(b, c, m) (b)
142 #define PAssertOS(b) (b)
143 #define PAssertNULL(p) (p)
144 #define PAssertAlways(m) {}
145 #define PAssertAlways2(c, m) {}
146 
147 #else // P_USE_ASSERTS
148 
149 /// Standard assert messages for the PAssert macro.
150 enum PStandardAssertMessage {
151   PLogicError,              ///< A logic error occurred.
152   POutOfMemory,             ///< A new or malloc failed.
153   PNullPointerReference,    ///< A reference was made through a NULL pointer.
154   PInvalidCast,             ///< An invalid cast to descendant is required.
155   PInvalidArrayIndex,       ///< An index into an array was negative.
156   PInvalidArrayElement,     ///< A NULL array element object was accessed.
157   PStackEmpty,              ///< A Pop() was made of a stack with no elements.
158   PUnimplementedFunction,   ///< Funtion is not implemented.
159   PInvalidParameter,        ///< Invalid parameter was passed to a function.
160   POperatingSystemError,    ///< Error was returned by Operating System.
161   PChannelNotOpen,          ///< Operation attempted when channel not open.
162   PUnsupportedFeature,      ///< Feature is not supported.
163   PInvalidWindow,           ///< Access through invalid window.
164   PMaxStandardAssertMessage ///< Number of standard assert message.
165 };
166 
167 #define __CLASS__ NULL
168 
169 void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg);
170 void PAssertFunc(const char * file, int line, const char * className, const char * msg);
171 void PAssertFunc(const char * full_msg);
172 
PAssertFuncInline(bool b,const char * file,int line,const char * className,PStandardAssertMessage msg)173 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, PStandardAssertMessage msg)
174 {
175   if (!b)
176     PAssertFunc(file, line, className, msg);
177   return b;
178 }
PAssertFuncInline(bool b,const char * file,int line,const char * className,const char * msg)179 inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, const char * msg)
180 {
181   if (!b)
182     PAssertFunc(file, line, className, msg);
183   return b;
184 }
185 
186 /** This macro is used to assert that a condition must be true.
187 If the condition is false then an assert function is called with the source
188 file and line number the macro was instantiated on, plus the message described
189 by the <code>msg</code> parameter. This parameter may be either a standard value
190 from the <code>PStandardAssertMessage</code> enum or a literal string.
191 */
192 #define PAssert(b, msg) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(msg))
193 
194 /** This macro is used to assert that a condition must be true.
195 If the condition is false then an assert function is called with the source
196 file and line number the macro was instantiated on, plus the message described
197 by the <code>msg</code> parameter. This parameter may be either a standard value
198 from the <code>PStandardAssertMessage</code> enum or a literal string.
199 The <code>cls</code> parameter specifies the class name that the error occurred in
200 */
201 #define PAssert2(b, cls, msg) PAssertFuncInline((b), __FILE__,__LINE__,(cls),(msg))
202 
203 /** This macro is used to assert that an operating system call succeeds.
204 If the condition is false then an assert function is called with the source
205 file and line number the macro was instantiated on, plus the message
206 described by the <code>POperatingSystemError</code> value in the <code>PStandardAssertMessage</code>
207 enum.
208  */
209 #define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
210 
211 /** This macro is used to assert that a pointer must be non-null.
212 If the pointer is NULL then an assert function is called with the source file
213 and line number the macro was instantiated on, plus the message described by
214 the PNullPointerReference value in the <code>PStandardAssertMessage</code> enum.
215 
216 Note that this evaluates the expression defined by <code>ptr</code> twice. To
217 prevent incorrect behaviour with this, the macro will assume that the
218 <code>ptr</code> parameter is an L-Value.
219  */
220 #define PAssertNULL(ptr) (((ptr)!=NULL)?(ptr): \
221                      (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(ptr)))
222 
223 /** This macro is used to assert immediately.
224 The assert function is called with the source file and line number the macro
225 was instantiated on, plus the message described by the <code>msg</code> parameter. This
226 parameter may be either a standard value from the <code>PStandardAssertMessage</code>
227 enum or a literal string.
228 */
229 #define PAssertAlways(msg) PAssertFunc(__FILE__,__LINE__,__CLASS__,(msg))
230 
231 /** This macro is used to assert immediately.
232 The assert function is called with the source file and line number the macro
233 was instantiated on, plus the message described by the <code>msg</code> parameter. This
234 parameter may be either a standard value from the <code>PStandardAssertMessage</code>
235 enum or a literal string.
236 */
237 #define PAssertAlways2(cls, msg) PAssertFunc(__FILE__,__LINE__,(cls),(msg))
238 
239 #endif // P_USE_ASSERTS
240 
241 
242 /** Get the stream being used for error output.
243 This stream is used for all trace output using the various trace functions
244 and macros.
245 */
246 ostream & PGetErrorStream();
247 
248 /** Set the stream to be used for error output.
249 This stream is used for all error output using the <code>PError</code> macro.
250 */
251 void PSetErrorStream(ostream * strm /** New stream for error output */ );
252 
253 /** This macro is used to access the platform specific error output stream.
254 This is to be used in preference to assuming <code>cerr</code> is always available. On
255 Unix platforms this {\b is} <code>cerr</code> but for MS-Windows this is another stream
256 that uses the OutputDebugString() Windows API function. Note that a MS-DOS or
257 Windows NT console application would still use <code>cerr</code>.
258 
259 The <code>PError</code> stream would normally only be used for debugging information as
260 a suitable display is not always available in windowed environments.
261 
262 The macro is a wrapper for a global variable error stream. The internal variable
263 is initialised to <i>std::cerr</i> for all but MS-Windows and NT GUI applications.
264 An application could change this pointer to a <i>std::ofstream</i> variable of
265 #PError output is wished to be redirected to a file.
266 */
267 #define PError (PGetErrorStream())
268 
269 
270 
271 ///////////////////////////////////////////////////////////////////////////////
272 // Debug and tracing
273 
274 #ifndef PTRACING
275 #define PTRACING 1
276 #endif
277 
278 #if PTRACING
279 
280 /**Class to encapsulate tracing functions.
281    This class does not require any instances and is only being used as a
282    method of grouping functions together in a name space.
283 
284    There are a number of macros for supporting tracing. These will all
285    evaluate as empty in a "No Trace" build of the system:
286      - PTRACE()
287      - PTRACE_IF()
288      - PTRACE_PARAM()
289      - PTRACE_BLOCK()
290      - PTRACE_LINE()
291   */
292 class PTrace
293 {
294 public:
295   /// Options for trace output.
296   enum Options {
297     /**Include PTrace::Block constructs in output
298        If this is bit is clear, all PTrace::Block output is inhibited
299        regardless of the trace level. If set, the PTrace::Block may occur
300        provided the trace level is greater than zero.
301     */
302     Blocks = 1,
303     /// Include date and time in all output
304     DateAndTime = 2,
305     /// Include (millisecond) timestamp in all output
306     Timestamp = 4,
307     /// Include identifier for thread trace is made from in all output
308     Thread = 8,
309     /// Include trace level in all output
310     TraceLevel = 16,
311     /// Include the file and line for the trace call in all output
312     FileAndLine = 32,
313     /// Include thread object pointer address in all trace output
314     ThreadAddress = 64,
315     /// Append to log file rather than resetting every time
316     AppendToFile = 128,
317     /// Output timestamps in GMT time rather than local time
318     GMTTime = 256,
319     /// If set, log file will be rotated daily
320     RotateDaily = 512,
321     /// If set, log file will be rotated hourly
322     RotateHourly = 1024,
323     /// If set, log file will be rotated every minute
324     RotateMinutely = 2048,
325     /// Mask for all the rotate bits
326     RotateLogMask = RotateDaily + RotateHourly + RotateMinutely,
327     /** SystemLog flag for tracing within a PServiceProcess application. Must
328         be set in conjection with <code>#SetStream(new PSystemLog)</code>.
329       */
330     SystemLogStream = 32768
331   };
332 
333 
334   /**Set the most common trace options.
335      If \p filename is not NULL then a PTextFile is created and attached the
336      trace output stream. This object is never closed or deleted until the
337      termination of the program.
338 
339      There are several special values for \p filename:
340        <dl>
341        <dt>"stderr"      <dd>Output to standard error
342        <dt>"stdout"      <dd>Output to standard output
343        <dt>"DEBUGSTREAM" <dd>Output to debugger (Windows only)
344        </dl>
345      A trace output of the program name version and OS is written as well.
346     */
347   static void Initialise(
348     unsigned level,                               ///< Level for tracing
349     const char * filename = NULL,                 ///< Filename for log output
350     unsigned options = Timestamp | Thread | Blocks ///< #Options for tracing
351   );
352 
353   /**Set the most common trace options.
354      If \p filename is not NULL then a PTextFile is created and attached the
355      trace output stream. This object is never closed or deleted until the
356      termination of the program.
357 
358      If \p rolloverPatterm is not NULL it is used as the time format patterm
359      appended to filename if the #RotateDaily is set. Default is "yyyy_MM_dd".
360 
361      A trace output of the program name version and OS is written as well.
362     */
363   static void Initialise(
364     unsigned level,                                 ///< Level for tracing
365     const char * filename,                          ///< Filename for log output
366     const char * rolloverPattern,                   ///< Pattern for rolling over trace files
367     unsigned options = Timestamp | Thread | Blocks  ///< #Options for tracing
368   );
369 
370   /** Set the trace options.
371   The PTRACE(), PTRACE_BLOCK() and PTRACE_LINE() macros output trace text that
372   may contain assorted values. These are defined by the #Options enum.
373 
374   Note this function OR's the bits included in the options parameter.
375   */
376   static void SetOptions(
377     unsigned options ///< New option bits for tracing
378   );
379 
380   /** Clear the trace options.
381   The <code>PTRACE()</code>, <code>PTRACE_BLOCK()</code> and
382   <code>PTRACE_LINE()</code> macros output trace text that
383   may contain assorted values. These are defined by the #Options enum.
384 
385   Note this function AND's the complement of the bits included in the options
386   parameter.
387   */
388   static void ClearOptions(
389     unsigned options ///< Option bits to turn off
390   );
391 
392   /** Get the current trace options.
393   The <code>PTRACE()</code>, <code>PTRACE_BLOCK()</code> and
394   <code>PTRACE_LINE()</code> macros output trace text that
395   may contain assorted values. These are defined by the #Options enum.
396   */
397   static unsigned GetOptions();
398 
399   /** Set the trace level.
400   The <code>PTRACE()</code> macro checks to see if its level is equal to or lower then the
401   level set by this function. If so then the trace text is output to the trace
402   stream.
403   */
404   static void SetLevel(
405     unsigned level ///< New level for tracing
406   );
407 
408   /** Get the trace level.
409   The <code>PTRACE()</code> macro checks to see if its level is equal to or lower then the
410   level set by this function. If so then the trace text is output to the trace
411   stream.
412   */
413   static unsigned GetLevel();
414 
415   /** Determine if the level may cause trace output.
416   This checks against the current global trace level set by SetLevel()
417   for if the trace output may be emitted. This is used by the PTRACE() macro.
418   */
419   static PBoolean CanTrace(
420     unsigned level ///< Trace level to check
421   );
422 
423   /** Set the stream to be used for trace output.
424   This stream is used for all trace output using the various trace functions
425   and macros.
426   */
427   static void SetStream(
428     ostream * out ///< New output stream from trace.
429   );
430 
431   /** Begin a trace output.
432   If the trace stream output is used outside of the provided macros, it
433   should be noted that a mutex is obtained on the call to Begin() which
434   will prevent any other threads from using the trace stream until the
435   End() function is called.
436 
437   So a typical usage would be:
438   <pre><code>
439     ostream & s = PTrace::Begin(3, __FILE__, __LINE__);
440     s << "hello";
441     if (want_there)
442       s << " there";
443     s << '!' << PTrace::End;
444   </code></pre>
445   */
446   static ostream & Begin(
447     unsigned level,         ///< Log level for output
448     const char * fileName,  ///< Filename of source file being traced
449     int lineNum             ///< Line number of source file being traced.
450   );
451 
452   /** End a trace output.
453   If the trace stream output is used outside of the provided macros, the
454   End() function must be used at the end of the section of trace
455   output. A mutex is obtained on the call to Begin() which will prevent
456   any other threads from using the trace stream until the End(). The
457   End() is used in a similar manner to <code>std::endl</code> or
458   <code>std::flush</code>.
459 
460   So a typical usage would be:
461   <pre><code>
462     ostream & s = PTrace::Begin();
463     s << "hello";
464     if (want_there)
465       s << " there";
466     s << '!' << PTrace::End;
467   </code></pre>
468   */
469   static ostream & End(
470     ostream & strm ///< Trace output stream being completed
471   );
472 
473   /** Cleanup the trace system for a specific thread
474       When using thread local storage, this will delete the per-thread trace context
475     */
476   static void Cleanup();
477 
478   /** Class to trace Execution blocks.
479   This class is used for tracing the entry and exit of program blocks. Upon
480   construction it outputs an entry trace message and on destruction outputs an
481   exit trace message. This is normally only used from in the <code>PTRACE_BLOCK()</code> macro.
482   */
483   class Block {
484     public:
485       /** Output entry trace message. */
486       Block(
487         const char * fileName, ///< Filename of source file being traced
488         int lineNum,           ///< Line number of source file being traced.
489         const char * traceName
490           ///< String to be output with trace, typically it is the function name.
491        );
Block(const Block & obj)492       Block(const Block & obj)
493         : file(obj.file), line(obj.line), name(obj.name) { }
494       /// Output exit trace message.
495       ~Block();
496     private:
497       Block & operator=(const Block &)
498       { return *this; }
499       const char * file;
500       int          line;
501       const char * name;
502   };
503 };
504 
505 /* Macro to conditionally declare a parameter to a function to avoid compiler
506    warning due that parameter only being used in a <code>PTRACE()</code> */
507 #define PTRACE_PARAM(param) param
508 
509 /** Trace an execution block.
510 This macro creates a trace variable for tracking the entry and exit of program
511 blocks. It creates an instance of the PTraceBlock class that will output a
512 trace message at the line <code>PTRACE_BLOCK()</code> is called and then on exit from the
513 scope it is defined in.
514 */
515 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
516 
517 /** Trace the execution of a line.
518 This macro outputs a trace of a source file line execution.
519 */
520 #define PTRACE_LINE() \
521     if (PTrace::CanTrace(1)) \
522       PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End; \
523     else (void)0
524 
525 /** Output trace.
526 This macro outputs a trace of any information needed, using standard stream
527 output operators. The output is only made if the trace level set by the
528 SetLevel() function is greater than or equal to the \p level argument.
529 */
530 #define PTRACE(level, args) \
531     if (PTrace::CanTrace(level)) \
532       PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
533     else (void)0
534 
535 /** Output trace on condition.
536 This macro outputs a trace of any information needed, using standard stream
537 output operators. The output is only made if the trace level set by the
538 SetLevel() function is greater than or equal to the <code>level</code> argument
539 and the conditional is true. Note the conditional is only evaluated if the
540 trace level is sufficient.
541 */
542 #define PTRACE_IF(level, cond, args) \
543     if ((PTrace::CanTrace(level) && (cond))) \
544       PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
545     else (void)0
546 
547 #else // PTRACING
548 
549 #define PTRACE_PARAM(param)
550 #define PTRACE_BLOCK(n)
551 #define PTRACE_LINE()
552 #define PTRACE(level, arg)
553 #define PTRACE_IF(level, cond, args)
554 
555 #endif // PTRACING
556 
557 
558 
559 #if PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG) && !defined(_WIN32_WCE))
560 
561 #define PMEMORY_HEAP 1
562 
563 /** Memory heap checking class.
564 This class implements the memory heap checking and validation functions. It
565 maintains lists of allocated block so that memory leaks can be detected. It
566 also initialises memory on allocation and deallocation to help catch errors
567 involving the use of dangling pointers.
568 */
569 class PMemoryHeap {
570   public:
571     /// Initialise the memory checking subsystem.
572     PMemoryHeap();
573 
574     // Clear up the memory checking subsystem, dumping memory leaks.
575     ~PMemoryHeap();
576 
577     /** Allocate a memory block.
578        This allocates a new memory block and keeps track of it. The memory
579        block is filled with the value in the <code>allocFillChar</code> member variable
580        to help detect uninitialised structures.
581        @return pointer to newly allocated memory block.
582      */
583     static void * Allocate(
584       size_t nSize,           ///< Number of bytes to allocate.
585       const char * file,      ///< Source file name for allocating function.
586       int line,               ///< Source file line for allocating function.
587       const char * className  ///< Class name for allocating function.
588     );
589     /** Allocate a memory block.
590        This allocates a new memory block and keeps track of it. The memory
591        block is filled with the value in the <code>allocFillChar</code> member variable
592        to help detect uninitialised structures.
593        @return pointer to newly allocated memory block.
594      */
595     static void * Allocate(
596       size_t count,       ///< Number of items to allocate.
597       size_t iSize,       ///< Size in bytes of each item.
598       const char * file,  ///< Source file name for allocating function.
599       int line            ///< Source file line for allocating function.
600     );
601 
602     /** Change the size of an allocated memory block.
603        This allocates a new memory block and keeps track of it. The memory
604        block is filled with the value in the <code>allocFillChar</code> member variable
605        to help detect uninitialised structures.
606       @return pointer to reallocated memory block. Note this may
607       {\em not} be the same as the pointer passed into the function.
608      */
609     static void * Reallocate(
610       void * ptr,         ///< Pointer to memory block to reallocate.
611       size_t nSize,       ///< New number of bytes to allocate.
612       const char * file,  ///< Source file name for allocating function.
613       int line            ///< Source file line for allocating function.
614     );
615 
616     /** Free a memory block.
617       The memory is deallocated, a warning is displayed if it was never
618       allocated. The block of memory is filled with the value in the
619       <code>freeFillChar</code> member variable.
620      */
621     static void Deallocate(
622       void * ptr,             ///< Pointer to memory block to deallocate.
623       const char * className  ///< Class name for deallocating function.
624     );
625 
626     /** Validation result.
627      */
628     enum Validation {
629       Ok, Bad, Trashed
630     };
631     /** Validate the memory pointer.
632         The <code>ptr</code> parameter is validated as a currently allocated heap
633         variable.
634         @return Ok for pointer is in heap, Bad for pointer is not in the heap
635         or Trashed if the pointer is in the heap but has overwritten the guard
636         bytes before or after the actual data part of the memory block.
637      */
638     static Validation Validate(
639       const void * ptr,       ///< Pointer to memory block to check
640       const char * className, ///< Class name it should be.
641       ostream * error         ///< Stream to receive error message (may be NULL)
642     );
643 
644     /** Validate all objects in memory.
645        This effectively calls Validate() on every object in the heap.
646         @return true if every object in heap is Ok.
647      */
648     static PBoolean ValidateHeap(
649       ostream * error = NULL  ///< Stream to output, use default if NULL
650     );
651 
652     /** Ignore/Monitor allocations.
653        Set internal flag so that allocations are not included in the memory
654        leak check on program termination.
655        Returns the previous state.
656      */
657     static PBoolean SetIgnoreAllocations(
658       PBoolean ignore  ///< New flag for allocation ignoring.
659     );
660 
661     /** Get memory check system statistics.
662         Dump statistics output to the default stream.
663      */
664     static void DumpStatistics();
665     /** Get memory check system statistics.
666         Dump statistics output to the specified stream.
667      */
668     static void DumpStatistics(ostream & strm /** Stream to output to */);
669 
670 #if PMEMORY_CHECK
671     struct State {
672       DWORD allocationNumber;
673     };
674 #else
675 	typedef _CrtMemState State;
676 #endif
677 
678     /* Get memory state.
679       This returns a state that may be used to determine where to start dumping
680       objects from.
681      */
682     static void GetState(
683       State & state  ///< Memory state
684     );
685 
686     /** Dump allocated objects.
687        Dump ojects allocated and not deallocated since the specified object
688        number. This would be a value returned by the <code>GetAllocationRequest()</code>
689        function.
690 
691        Output is to the default stream.
692      */
693     static void DumpObjectsSince(
694       const State & when    ///< Memory state to begin dump from.
695     );
696 
697     /** Dump allocated objects.
698        Dump ojects allocated and not deallocated since the specified object
699        number. This would be a value returned by the <code>GetAllocationRequest()</code>
700        function.
701      */
702     static void DumpObjectsSince(
703       const State & when,   ///< Memory state to begin dump from.
704       ostream & strm        ///< Stream to output dump
705     );
706 
707     /** Set break point allocation number.
708       Set the allocation request number to cause an assert. This allows a
709       developer to cause a halt in a debugger on a certain allocation allowing
710       them to determine memory leaks allocation point.
711      */
712     static void SetAllocationBreakpoint(
713       DWORD point   ///< Allocation number to stop at.
714     );
715 
716 #if PMEMORY_CHECK
717 
718   protected:
719     void * InternalAllocate(
720       size_t nSize,           // Number of bytes to allocate.
721       const char * file,      // Source file name for allocating function.
722       int line,               // Source file line for allocating function.
723       const char * className  // Class name for allocating function.
724     );
725     Validation InternalValidate(
726       const void * ptr,       // Pointer to memory block to check
727       const char * className, // Class name it should be.
728       ostream * error         // Stream to receive error message (may be NULL)
729     );
730     void InternalDumpStatistics(ostream & strm);
731     void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
732 
733     class Wrapper {
734       public:
735         Wrapper();
736         ~Wrapper();
737         PMemoryHeap * operator->() const { return instance; }
738       private:
739         PMemoryHeap * instance;
740     };
741     friend class Wrapper;
742 
743     enum Flags {
744       NoLeakPrint = 1
745     };
746 
747 #pragma pack(1)
748     struct Header {
749       enum {
750         // Assure that the Header struct is aligned to 8 byte boundary
751         NumGuardBytes = 16 - (sizeof(Header *) +
752                               sizeof(Header *) +
753                               sizeof(const char *) +
754                               sizeof(const char *) +
755                               sizeof(size_t) +
756                               sizeof(DWORD) +
757                               sizeof(WORD) +
758                               sizeof(BYTE)
759 #if P_PTHREADS
760                               + sizeof(pthread_t)
761 #endif
762                               )%8
763       };
764 
765       Header     * prev;
766       Header     * next;
767       const char * className;
768       const char * fileName;
769       size_t       size;
770       DWORD        request;
771       WORD         line;
772       BYTE         flags;
773 #if P_PTHREADS
774       pthread_t    thread;
775 #endif
776       char         guard[NumGuardBytes];
777 
778       static char GuardBytes[NumGuardBytes];
779     };
780 #pragma pack()
781 
782     PBoolean isDestroyed;
783 
784     Header * listHead;
785     Header * listTail;
786 
787     static DWORD allocationBreakpoint;
788     DWORD allocationRequest;
789     DWORD firstRealObject;
790     BYTE  flags;
791 
792     char  allocFillChar;
793     char  freeFillChar;
794 
795     DWORD currentMemoryUsage;
796     DWORD peakMemoryUsage;
797     DWORD currentObjects;
798     DWORD peakObjects;
799     DWORD totalObjects;
800 
801     ostream * leakDumpStream;
802 
803 #if defined(_WIN32)
804     CRITICAL_SECTION mutex;
805 #elif defined(P_PTHREADS)
806     pthread_mutex_t mutex;
807 #elif defined(P_VXWORKS)
808     void * mutex;
809 #endif
810 
811 #else
812 
813 #define P_CLIENT_BLOCK (_CLIENT_BLOCK|(0x61<<16)) // This identifies a PObject derived class
814     _CrtMemState initialState;
815 
816 #endif // PMEMORY_CHECK
817 };
818 
819 
820 /** Allocate memory for the run time library.
821 This version of free is used for data that is not to be allocated using the
822 memory check system, ie will be free'ed inside the C run time library.
823 */
runtime_malloc(size_t bytes)824 inline void * runtime_malloc(size_t bytes /** Size of block to allocate */ ) { return malloc(bytes); }
825 
826 /** Free memory allocated by run time library.
827 This version of free is used for data that is not allocated using the
828 memory check system, ie was malloc'ed inside the C run time library.
829 */
runtime_free(void * ptr)830 inline void runtime_free(void * ptr /** Memory block to free */ ) { free(ptr); }
831 
832 
833 /** Override of system call for memory check system.
834 This macro is used to allocate memory via the memory check system selected
835 with the <code>PMEMORY_CHECK</code> compile time option. It will include the source file
836 and line into the memory allocation to allow the PMemoryHeap class to keep
837 track of the memory block.
838 */
839 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
840 
841 /** Override of system call for memory check system.
842 This macro is used to allocate memory via the memory check system selected
843 with the <code>PMEMORY_CHECK</code> compile time option. It will include the source file
844 and line into the memory allocation to allow the PMemoryHeap class to keep
845 track of the memory block.
846 */
847 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
848 
849 /** Override of system call for memory check system.
850 This macro is used to allocate memory via the memory check system selected
851 with the <code>PMEMORY_CHECK</code> compile time option. It will include the source file
852 and line into the memory allocation to allow the PMemoryHeap class to keep
853 track of the memory block.
854 */
855 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
856 
857 
858 /** Override of system call for memory check system.
859 This macro is used to deallocate memory via the memory check system selected
860 with the <code>PMEMORY_CHECK</code> compile time option. It will include the source file
861 and line into the memory allocation to allow the PMemoryHeap class to keep
862 track of the memory block.
863 */
864 #define free(p) PMemoryHeap::Deallocate(p, NULL)
865 
866 
867 /** Override of system call for memory check system.
868 This macro is used to deallocate memory via the memory check system selected
869 with the <code>PMEMORY_CHECK</code> compile time option. It will include the source file
870 and line into the memory allocation to allow the PMemoryHeap class to keep
871 track of the memory block.
872 */
873 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
874 
875 
876 /** Macro for overriding system default <code>new</code> operator.
877 This macro is used to allocate memory via the memory check system selected
878 with the PMEMORY_CHECK compile time option. It will include the source file
879 and line into the memory allocation to allow the PMemoryHeap class to keep
880 track of the memory block.
881 
882 This macro could be used instead of the system <code>new</code> operator. Or you can place
883 the line
884 <pre><code>
885   #define new PNEW
886 </code></pre>
887 at the begining of the source file, after all declarations that use the
888 <code>#PCLASSINFO</code> macro.
889 */
890 #define PNEW  new (__FILE__, __LINE__)
891 
892 #if !defined(_MSC_VER) || _MSC_VER<1200
893 #define PSPECIAL_DELETE_FUNCTION
894 #else
895 #define PSPECIAL_DELETE_FUNCTION \
896     void operator delete(void * ptr, const char *, int) \
897       { PMemoryHeap::Deallocate(ptr, Class()); } \
898     void operator delete[](void * ptr, const char *, int) \
899       { PMemoryHeap::Deallocate(ptr, Class()); }
900 #endif
901 
902 #define PNEW_AND_DELETE_FUNCTIONS \
903     void * operator new(size_t nSize, const char * file, int line) \
904       { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
905     void * operator new(size_t nSize) \
906       { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
907     void operator delete(void * ptr) \
908       { PMemoryHeap::Deallocate(ptr, Class()); } \
909     void * operator new(size_t, void * placement) \
910       { return placement; } \
911     void operator delete(void *, void *) \
912       { } \
913     void * operator new[](size_t nSize, const char * file, int line) \
914       { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
915     void * operator new[](size_t nSize) \
916       { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
917     void operator delete[](void * ptr) \
918       { PMemoryHeap::Deallocate(ptr, Class()); } \
919     PSPECIAL_DELETE_FUNCTION
920 
921 
new(size_t nSize,const char * file,int line)922 inline void * operator new(size_t nSize, const char * file, int line)
923   { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
924 
925 inline void * operator new[](size_t nSize, const char * file, int line)
926   { return PMemoryHeap::Allocate(nSize, file, line, NULL); }
927 
928 #ifndef __GNUC__
929 void * operator new(size_t nSize);
930 void * operator new[](size_t nSize);
931 
932 void operator delete(void * ptr);
933 void operator delete[](void * ptr);
934 
935 #if defined(_MSC_VER) && _MSC_VER>=1200
delete(void * ptr,const char *,int)936 inline void operator delete(void * ptr, const char *, int)
937   { PMemoryHeap::Deallocate(ptr, NULL); }
938 
939 inline void operator delete[](void * ptr, const char *, int)
940   { PMemoryHeap::Deallocate(ptr, NULL); }
941 #endif
942 #endif
943 
944 
945 class PMemoryHeapIgnoreAllocationsForScope {
946 public:
PMemoryHeapIgnoreAllocationsForScope()947   PMemoryHeapIgnoreAllocationsForScope() : previousIgnoreAllocations(PMemoryHeap::SetIgnoreAllocations(true)) { }
~PMemoryHeapIgnoreAllocationsForScope()948   ~PMemoryHeapIgnoreAllocationsForScope() { PMemoryHeap::SetIgnoreAllocations(previousIgnoreAllocations); }
949 private:
950   PBoolean previousIgnoreAllocations;
951 };
952 
953 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE PMemoryHeapIgnoreAllocationsForScope instance_PMemoryHeapIgnoreAllocationsForScope
954 
955 class PMemoryAllocationBreakpoint {
956 public:
PMemoryAllocationBreakpoint(DWORD point)957   PMemoryAllocationBreakpoint(DWORD point)
958   {
959     PMemoryHeap::SetAllocationBreakpoint(point);
960   }
961 };
962 
963 #define PMEMORY_ALLOCATION_BREAKPOINT(point) PMemoryAllocationBreakpoint PMemoryAllocationBreakpointInstance(point)
964 
965 
966 #else // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
967 
968 #define PMEMORY_HEAP 0
969 
970 #define PNEW new
971 
972 #define PNEW_AND_DELETE_FUNCTIONS
973 
974 #define runtime_malloc(s) malloc(s)
975 #define runtime_free(p) free(p)
976 
977 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE
978 #define PMEMORY_ALLOCATION_BREAKPOINT(point)
979 
980 #endif // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
981 
982 
983 
984 /*
985  *  Implement "construct on first use" paradigm
986  */
987 
988 template <class GnuAllocator, class Type>
989 struct PAllocatorTemplate
990 {
allocatePAllocatorTemplate991   Type * allocate(size_t v)
992   {
993     return GetAllocator().allocate(v);
994   }
995 
deallocatePAllocatorTemplate996   void deallocate(Type * p, size_t v)
997   {
998     GetAllocator().deallocate(p, v);
999   }
1000 
1001   private:
GetAllocatorPAllocatorTemplate1002     static GnuAllocator & GetAllocator()
1003     {
1004       static GnuAllocator instance;
1005       return instance;
1006     }
1007 };
1008 
1009 #define GCC_VERSION (__GNUC__ * 10000 \
1010                    + __GNUC_MINOR__ * 100 \
1011                    + __GNUC_PATCHLEVEL__)
1012 
1013 // Memory pooling allocators
1014 #if defined(__GNUC__) && (GCC_VERSION > 40000) && !defined(P_MINGW) && !defined(P_MACOSX) && !defined(_LIBCPP_VERSION)
1015 #include <ext/mt_allocator.h>
1016 template <class Type> struct PFixedPoolAllocator    : public PAllocatorTemplate<__gnu_cxx::__mt_alloc<Type>, Type> { };
1017 template <class Type> struct PVariablePoolAllocator : public PAllocatorTemplate<__gnu_cxx::__mt_alloc<Type>, Type> { };
1018 
1019 #else
1020 
1021 template <class Type> struct PFixedPoolAllocator    : public PAllocatorTemplate<std::allocator<Type>, Type> { };
1022 template <class Type> struct PVariablePoolAllocator : public PAllocatorTemplate<std::allocator<Type>, Type> { };
1023 #endif
1024 
1025 #define PDECLARE_POOL_ALLOCATOR() \
1026     void * operator new(size_t nSize); \
1027     void * operator new(size_t nSize, const char * file, int line); \
1028     void operator delete(void * ptr); \
1029     void operator delete(void * ptr, const char *, int)
1030 
1031 #define PDEFINE_POOL_ALLOCATOR(cls) \
1032   static PFixedPoolAllocator<cls> cls##_allocator; \
1033   void * cls::operator new(size_t)                           { return cls##_allocator.allocate(1);               } \
1034   void * cls::operator new(size_t, const char *, int)        { return cls##_allocator.allocate(1);               } \
1035   void   cls::operator delete(void * ptr)                    {        cls##_allocator.deallocate((cls *)ptr, 1); } \
1036   void   cls::operator delete(void * ptr, const char *, int) {        cls##_allocator.deallocate((cls *)ptr, 1); }
1037 
1038 
1039 /** Declare all the standard PTLib class information.
1040 This macro is used to provide the basic run-time typing capability needed
1041 by the library. All descendent classes from the <code>PObject</code> class require
1042 these functions for correct operation. Either use this macro or the
1043 <code>#PDECLARE_CLASS</code> macro.
1044 
1045 The use of the <code>#PDECLARE_CLASS</code> macro is no longer recommended for reasons
1046 of compatibility with documentation systems.
1047 */
1048 
1049 #define PCLASSINFO(cls, par) \
1050   public: \
1051     typedef cls P_thisClass; \
1052     static inline const char * Class() \
1053       { return #cls; } \
1054     virtual PBoolean InternalIsDescendant(const char * clsName) const \
1055       { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
1056     virtual const char * GetClass(unsigned ancestor = 0) const \
1057       { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
1058     virtual PObject::Comparison CompareObjectMemoryDirect(const PObject & obj) const \
1059       { return PObject::InternalCompareObjectMemoryDirect(this, dynamic_cast<const cls *>(&obj), sizeof(cls)); } \
1060     PNEW_AND_DELETE_FUNCTIONS
1061 
1062 
1063 #if P_HAS_TYPEINFO
1064 
1065 #define PIsDescendant(ptr, cls)    (dynamic_cast<const cls *>(ptr) != NULL)
1066 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
1067 
1068 #define PRemoveConst(cls, ptr)  (const_cast<cls*>(ptr))
1069 
1070 #if P_USE_ASSERTS
PAssertCast(BaseClass * obj,const char * file,int line)1071 template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line)
1072   { if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; }
1073 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
1074 #else
1075 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
1076 #endif
1077 
1078 #include <typeinfo>
1079 
1080 #else // P_HAS_TYPEINFO
1081 
1082 #define PIsDescendant(ptr, cls)    ((ptr)->InternalIsDescendant(cls::Class()))
1083 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
1084 
1085 #define PRemoveConst(cls, ptr)  ((cls*)(ptr))
1086 
1087 #if P_USE_ASSERTS
PAssertCast(PObject * obj,const char * file,int line)1088 template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line)
1089   { if (obj->InternalIsDescendant(BaseClass::Class())) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; }
1090 #define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
1091 #else
1092 #define PDownCast(cls, ptr) ((cls*)(ptr))
1093 #endif
1094 
1095 #endif // P_HAS_TYPEINFO
1096 
1097 
1098 /** Declare a class with PWLib class information.
1099 This macro is used to declare a new class with a single public ancestor. It
1100 starts the class declaration and then uses the <code>#PCLASSINFO</code> macro to
1101 get all the run-time type functions.
1102 
1103 The use of this macro is no longer recommended for reasons of compatibility
1104 with documentation systems.
1105 */
1106 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
1107 #ifdef DOC_PLUS_PLUS
1108 } Match previous opening brace in doc++
1109 #endif
1110 
1111 ///////////////////////////////////////////////////////////////////////////////
1112 // The root of all evil ... umm classes
1113 
1114 /** Ultimate parent class for all objects in the class library.
1115 This provides functionality provided to all classes, eg run-time types,
1116 default comparison operations, simple stream I/O and serialisation support.
1117 */
1118 class PObject {
1119 
1120   protected:
1121     /** Constructor for PObject, made protected so cannot ever create one on
1122        its own.
1123      */
1124     PObject() { }
1125 
1126   public:
1127     /* Destructor required to get the "virtual". A PObject really has nothing
1128        to destroy.
1129      */
1130     virtual ~PObject() { }
1131 
1132     /**@name Run Time Type functions */
1133   //@{
1134     /** Get the name of the class as a C string. This is a static function which
1135        returns the type of a specific class.
1136 
1137        When comparing class names, always use the <code>strcmp()</code>
1138        function rather than comparing pointers. The pointers are not
1139        necessarily the same over compilation units depending on the compiler,
1140        platform etc.
1141 
1142        @return pointer to C string literal.
1143      */
1144     static inline const char * Class()    { return "PObject"; }
1145 
1146     /** Get the current dynamic type of the object instance.
1147 
1148        When comparing class names, always use the <code>strcmp()</code>
1149        function rather than comparing pointers. The pointers are not
1150        necessarily the same over compilation units depending on the compiler,
1151        platform etc.
1152 
1153        The <code>#PCLASSINFO</code> macro declares an override of this function for
1154        the particular class. The user need not implement it.
1155 
1156        @return pointer to C string literal.
1157      */
1158     virtual const char * GetClass(unsigned ancestor = 0) const { return ancestor > 0 ? "" : Class(); }
1159 
1160     PBoolean IsClass(const char * cls) const
1161     { return strcmp(cls, GetClass()) == 0; }
1162 
1163     /** Determine if the dynamic type of the current instance is a descendent of
1164        the specified class. The class name is usually provided by the
1165        <code>Class()</code> static function of the desired class.
1166 
1167        The <code>#PCLASSINFO</code> macro declares an override of this function for
1168        the particular class. The user need not implement it.
1169 
1170        @return true if object is descended from the class.
1171      */
1172     virtual PBoolean InternalIsDescendant(
1173       const char * clsName    // Ancestor class name to compare against.
1174     ) const
1175     { return IsClass(clsName); }
1176 
1177   //@}
1178 
1179   /**@name Comparison functions */
1180   //@{
1181     /** Result of the comparison operation performed by the <code>Compare()</code>
1182        function.
1183       */
1184     enum Comparison {
1185       LessThan = -1,
1186       EqualTo = 0,
1187       GreaterThan = 1
1188     };
1189 
1190     /** Compare the two objects and return their relative rank. This function is
1191        usually overridden by descendent classes to yield the ranking according
1192        to the semantics of the object.
1193 
1194        The default function is to use the <code>CompareObjectMemoryDirect()</code>
1195        function to do a byte wise memory comparison of the two objects.
1196 
1197        @return
1198        <code>LessThan</code>, <code>EqualTo</code> or <code>GreaterThan</code>
1199        according to the relative rank of the objects.
1200      */
1201     virtual Comparison Compare(
1202       const PObject & obj   // Object to compare against.
1203     ) const;
1204 
1205     /** Determine the byte wise comparison of two objects. This is the default
1206        comparison operation for objects that do not explicitly override the
1207        <code>Compare()</code> function.
1208 
1209        The <code>#PCLASSINFO</code> macro declares an override of this function for
1210        the particular class. The user need not implement it.
1211 
1212        @return
1213        <code>LessThan</code>, <code>EqualTo</code> or <code>GreaterThan</code>
1214        according to the result <code>memcpy()</code> function.
1215      */
1216     virtual Comparison CompareObjectMemoryDirect(
1217       const PObject & obj   // Object to compare against.
1218     ) const;
1219 
1220     /// Internal function caled from CompareObjectMemoryDirect()
1221     static Comparison InternalCompareObjectMemoryDirect(
1222       const PObject * obj1,
1223       const PObject * obj2,
1224       PINDEX size
1225     );
1226 
1227     /** Compare the two objects.
1228 
1229        @return
1230        true if objects are equal.
1231      */
1232     bool operator==(
1233       const PObject & obj   // Object to compare against.
1234     ) const { return Compare(obj) == EqualTo; }
1235 
1236     /** Compare the two objects.
1237 
1238        @return
1239        true if objects are not equal.
1240      */
1241     bool operator!=(
1242       const PObject & obj   // Object to compare against.
1243     ) const { return Compare(obj) != EqualTo; }
1244 
1245     /** Compare the two objects.
1246 
1247        @return
1248        true if objects are less than.
1249      */
1250     bool operator<(
1251       const PObject & obj   // Object to compare against.
1252     ) const { return Compare(obj) == LessThan; }
1253 
1254     /** Compare the two objects.
1255 
1256        @return
1257        true if objects are greater than.
1258      */
1259     bool operator>(
1260       const PObject & obj   // Object to compare against.
1261     ) const { return Compare(obj) == GreaterThan; }
1262 
1263     /** Compare the two objects.
1264 
1265        @return
1266        true if objects are less than or equal.
1267      */
1268     bool operator<=(
1269       const PObject & obj   // Object to compare against.
1270     ) const { return Compare(obj) != GreaterThan; }
1271 
1272     /** Compare the two objects.
1273 
1274        @return
1275        true if objects are greater than or equal.
1276      */
1277     bool operator>=(
1278       const PObject & obj   // Object to compare against.
1279     ) const { return Compare(obj) != LessThan; }
1280   //@}
1281 
1282   /**@name I/O functions */
1283   //@{
1284     /** Output the contents of the object to the stream. The exact output is
1285        dependent on the exact semantics of the descendent class. This is
1286        primarily used by the standard <code>#operator<<</code> function.
1287 
1288        The default behaviour is to print the class name.
1289      */
1290     virtual void PrintOn(
1291       ostream &strm   // Stream to print the object into.
1292     ) const;
1293 
1294     /** Input the contents of the object from the stream. The exact input is
1295        dependent on the exact semantics of the descendent class. This is
1296        primarily used by the standard <code>#operator>></code> function.
1297 
1298        The default behaviour is to do nothing.
1299      */
1300     virtual void ReadFrom(
1301       istream &strm   // Stream to read the objects contents from.
1302     );
1303 
1304 
1305     /** Global function for using the standard << operator on objects descended
1306        from PObject. This simply calls the objects <code>PrintOn()</code> function.
1307 
1308        @return the \p strm parameter.
1309      */
1310     inline friend ostream & operator<<(
1311       ostream &strm,       ///< Stream to print the object into.
1312       const PObject & obj  ///< Object to print to the stream.
1313     ) { obj.PrintOn(strm); return strm; }
1314 
1315     /** Global function for using the standard >> operator on objects descended
1316        from PObject. This simply calls the objects <code>ReadFrom()</code> function.
1317 
1318        @return the \p strm parameter.
1319      */
1320     inline friend istream & operator>>(
1321       istream &strm,   ///< Stream to read the objects contents from.
1322       PObject & obj    ///< Object to read inormation into.
1323     ) { obj.ReadFrom(strm); return strm; }
1324 
1325 
1326   /**@name Miscellaneous functions */
1327   //@{
1328     /** Create a copy of the class on the heap. The exact semantics of the
1329        descendent class determine what is required to make a duplicate of the
1330        instance. Not all classes can even \b do a clone operation.
1331 
1332        The main user of the clone function is the <code>PDictionary</code> class as
1333        it requires copies of the dictionary keys.
1334 
1335        The default behaviour is for this function to assert.
1336 
1337        @return
1338        pointer to new copy of the class instance.
1339      */
1340     virtual PObject * Clone() const;
1341 
1342     /** This function yields a hash value required by the <code>PDictionary</code>
1343        class. A descendent class that is required to be the key of a dictionary
1344        should override this function. The precise values returned is dependent
1345        on the semantics of the class. For example, the <code>PString</code> class
1346        overrides it to provide a hash function for distinguishing text strings.
1347 
1348        The default behaviour is to return the value zero.
1349 
1350        @return
1351        hash function value for class instance.
1352      */
1353     virtual PINDEX HashFunction() const;
1354   //@}
1355 };
1356 
1357 ///////////////////////////////////////////////////////////////////////////////
1358 // Platform independent types
1359 
1360 // All these classes encapsulate primitive types such that they may be
1361 // transfered in a platform independent manner. In particular it is used to
1362 // do byte swapping for little endien and big endien processor architectures
1363 // as well as accommodating structure packing rules for memory structures.
1364 
1365 #define PANSI_CHAR 1
1366 #define PLITTLE_ENDIAN 2
1367 #define PBIG_ENDIAN 3
1368 
1369 
1370 template <typename type>
1371 struct PIntSameOrder {
1372   __inline PIntSameOrder()                            : data(0)              { }
1373   __inline PIntSameOrder(type value)                  : data(value)          { }
1374   __inline PIntSameOrder(const PIntSameOrder & value) : data(value.data)     { }
1375   __inline PIntSameOrder & operator=(type value)                             { data = value; return *this; }
1376   __inline PIntSameOrder & operator=(const PIntSameOrder & value)            { data = value.data; return *this; }
1377   __inline operator type() const                                             { return data; }
1378   __inline friend ostream & operator<<(ostream & s, const PIntSameOrder & v) { return s << v.data; }
1379   __inline friend istream & operator>>(istream & s, PIntSameOrder & v)       { return s >> v.data; }
1380 
1381   private:
1382     type data;
1383 };
1384 
1385 
1386 template <typename type>
1387 struct PIntReversedOrder {
1388   __inline PIntReversedOrder()                                : data(0)              { }
1389   __inline PIntReversedOrder(type value)                                             { ReverseBytes(value, data); }
1390   __inline PIntReversedOrder(const PIntReversedOrder & value) : data(value.data)     { }
1391   __inline PIntReversedOrder & operator=(type value)                                 { ReverseBytes(value, data); return *this; }
1392   __inline PIntReversedOrder & operator=(const PIntReversedOrder & value)            { data = value.data; return *this; }
1393   __inline operator type() const                                                     { type value; ReverseBytes(data, value); return value; }
1394   __inline friend ostream & operator<<(ostream & s, const PIntReversedOrder & value) { return s << (type)value; }
1395   __inline friend istream & operator>>(istream & s, PIntReversedOrder & v)           { type val; s >> val; v = val; return s; }
1396 
1397   private:
1398     type data;
1399 
1400   static __inline void ReverseBytes(const type & src, type & dst)
1401   {
1402     size_t s = sizeof(type)-1;
1403     for (size_t d = 0; d < sizeof(type); ++d,--s)
1404       ((BYTE *)&dst)[d] = ((const BYTE *)&src)[s];
1405   }
1406 };
1407 
1408 #ifndef PCHAR8
1409 #define PCHAR8 PANSI_CHAR
1410 #endif
1411 
1412 #if PCHAR8==PANSI_CHAR
1413 typedef PIntSameOrder<char> PChar8;
1414 #endif
1415 
1416 typedef PIntSameOrder<char> PInt8;
1417 
1418 typedef PIntSameOrder<unsigned char> PUInt8;
1419 
1420 #if PBYTE_ORDER==PLITTLE_ENDIAN
1421 typedef PIntSameOrder<PInt16> PInt16l;
1422 #elif PBYTE_ORDER==PBIG_ENDIAN
1423 typedef PIntReversedOrder<PInt16> PInt16l;
1424 #endif
1425 
1426 #if PBYTE_ORDER==PLITTLE_ENDIAN
1427 typedef PIntReversedOrder<PInt16> PInt16b;
1428 #elif PBYTE_ORDER==PBIG_ENDIAN
1429 typedef PIntSameOrder<PInt16> PInt16b;
1430 #endif
1431 
1432 #if PBYTE_ORDER==PLITTLE_ENDIAN
1433 typedef PIntSameOrder<WORD> PUInt16l;
1434 #elif PBYTE_ORDER==PBIG_ENDIAN
1435 typedef PIntReversedOrder<WORD> PUInt16l;
1436 #endif
1437 
1438 #if PBYTE_ORDER==PLITTLE_ENDIAN
1439 typedef PIntReversedOrder<WORD> PUInt16b;
1440 #elif PBYTE_ORDER==PBIG_ENDIAN
1441 typedef PIntSameOrder<WORD> PUInt16b;
1442 #endif
1443 
1444 #if PBYTE_ORDER==PLITTLE_ENDIAN
1445 typedef PIntSameOrder<PInt32> PInt32l;
1446 #elif PBYTE_ORDER==PBIG_ENDIAN
1447 typedef PIntReversedOrder<PInt32> PInt32l;
1448 #endif
1449 
1450 #if PBYTE_ORDER==PLITTLE_ENDIAN
1451 typedef PIntReversedOrder<PInt32> PInt32b;
1452 #elif PBYTE_ORDER==PBIG_ENDIAN
1453 typedef PIntSameOrder<PInt32> PInt32b;
1454 #endif
1455 
1456 #if PBYTE_ORDER==PLITTLE_ENDIAN
1457 typedef PIntSameOrder<DWORD> PUInt32l;
1458 #elif PBYTE_ORDER==PBIG_ENDIAN
1459 typedef PIntReversedOrder<DWORD> PUInt32l;
1460 #endif
1461 
1462 #if PBYTE_ORDER==PLITTLE_ENDIAN
1463 typedef PIntReversedOrder<DWORD> PUInt32b;
1464 #elif PBYTE_ORDER==PBIG_ENDIAN
1465 typedef PIntSameOrder<DWORD> PUInt32b;
1466 #endif
1467 
1468 #if PBYTE_ORDER==PLITTLE_ENDIAN
1469 typedef PIntSameOrder<PInt64> PInt64l;
1470 #elif PBYTE_ORDER==PBIG_ENDIAN
1471 typedef PIntReversedOrder<PInt64> PInt64l;
1472 #endif
1473 
1474 #if PBYTE_ORDER==PLITTLE_ENDIAN
1475 typedef PIntReversedOrder<PInt64> PInt64b;
1476 #elif PBYTE_ORDER==PBIG_ENDIAN
1477 typedef PIntSameOrder<PInt64> PInt64b;
1478 #endif
1479 
1480 #if PBYTE_ORDER==PLITTLE_ENDIAN
1481 typedef PIntSameOrder<PUInt64> PUInt64l;
1482 #elif PBYTE_ORDER==PBIG_ENDIAN
1483 typedef PIntReversedOrder<PUInt64> PUInt64l;
1484 #endif
1485 
1486 #if PBYTE_ORDER==PLITTLE_ENDIAN
1487 typedef PIntReversedOrder<PUInt64> PUInt64b;
1488 #elif PBYTE_ORDER==PBIG_ENDIAN
1489 typedef PIntSameOrder<PUInt64> PUInt64b;
1490 #endif
1491 
1492 #if PBYTE_ORDER==PLITTLE_ENDIAN
1493 typedef PIntSameOrder<float> PFloat32l;
1494 #elif PBYTE_ORDER==PBIG_ENDIAN
1495 typedef PIntReversedOrder<float> PFloat32l;
1496 #endif
1497 
1498 #if PBYTE_ORDER==PLITTLE_ENDIAN
1499 typedef PIntReversedOrder<float> PFloat32b;
1500 #elif PBYTE_ORDER==PBIG_ENDIAN
1501 typedef PIntSameOrder<float> PFloat32b;
1502 #endif
1503 
1504 #if PBYTE_ORDER==PLITTLE_ENDIAN
1505 typedef PIntSameOrder<double> PFloat64l;
1506 #elif PBYTE_ORDER==PBIG_ENDIAN
1507 typedef PIntReversedOrder<double> PFloat64l;
1508 #endif
1509 
1510 #if PBYTE_ORDER==PLITTLE_ENDIAN
1511 typedef PIntReversedOrder<double> PFloat64b;
1512 #elif PBYTE_ORDER==PBIG_ENDIAN
1513 typedef PIntSameOrder<double> PFloat64b;
1514 #endif
1515 
1516 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
1517 #if PBYTE_ORDER==PLITTLE_ENDIAN
1518 typedef PIntSameOrder<long double> PFloat80l;
1519 #elif PBYTE_ORDER==PBIG_ENDIAN
1520 typedef PIntReversedOrder<long double> PFloat80l;
1521 #endif
1522 
1523 #if PBYTE_ORDER==PLITTLE_ENDIAN
1524 typedef PIntReversedOrder<long double> PFloat80b;
1525 #elif PBYTE_ORDER==PBIG_ENDIAN
1526 typedef PIntSameOrder<long double> PFloat80b;
1527 #endif
1528 #endif
1529 
1530 
1531 ///////////////////////////////////////////////////////////////////////////////
1532 // Miscellaneous
1533 
1534 /*$MACRO PARRAYSIZE(array)
1535    This macro is used to calculate the number of array elements in a static
1536    array.
1537  */
1538 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
1539 
1540 /*$MACRO PMIN(v1, v2)
1541    This macro is used to calculate the minimum of two values. As this is a
1542    macro the expression in <code>v1</code> or <code>v2</code> is executed
1543    twice so extreme care should be made in its use.
1544  */
1545 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
1546 
1547 /*$MACRO PMAX(v1, v2)
1548    This macro is used to calculate the maximum of two values. As this is a
1549    macro the expression in <code>v1</code> or <code>v2</code> is executed
1550    twice so extreme care should be made in its use.
1551  */
1552 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
1553 
1554 /*$MACRO PABS(val)
1555    This macro is used to calculate an absolute value. As this is a macro the
1556    expression in <code>val</code> is executed twice so extreme care should be
1557    made in its use.
1558  */
1559 #define PABS(v) ((v) < 0 ? -(v) : (v))
1560 
1561 
1562 #endif // PTLIB_OBJECT_H
1563 
1564 
1565 // End Of File ///////////////////////////////////////////////////////////////
1566