object.h
Go to the documentation of this file.
/*
* object.h
*
* Mother of all ancestor classes.
*
* Portable Tools Library
*
* Copyright (c) 1993-1998 Equivalence Pty. Ltd.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Portable Windows Library.
*
* The Initial Developer of the Original Code is Equivalence Pty. Ltd.
*
* Portions are Copyright (C) 1993 Free Software Foundation, Inc.
* All Rights Reserved.
*
* Contributor(s): ______________________________________.
*
* $Revision: 28201 $
* $Author: rjongbloed $
* $Date: 2012-08-14 21:30:31 -0500 (Tue, 14 Aug 2012) $
*/
#ifndef PTLIB_OBJECT_H
#define PTLIB_OBJECT_H
#ifdef P_USE_PRAGMA
#pragma interface
#endif
#if defined(_WIN32) || defined(_WIN32_WCE)
#include "msos/ptlib/contain.h"
#else
#include "unix/ptlib/contain.h"
#endif
#if defined(P_VXWORKS)
#include <private/stdiop.h>
#endif
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>
#include <list>
#include <map>
#include <algorithm>
#define P_REMOVE_VIRTUAL_INTERNAL_BASE(fn) __inline virtual struct ptlib_virtual_function_changed_or_removed ****** fn { return 0; }
#if defined(_MSC_VER)
#if _MSC_VER < 1310
#define P_DEPRECATED
#define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
#elif _MSC_VER < 1400
#define P_DEPRECATED __declspec(deprecated)
#define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated) type fn body
#else
#define P_DEPRECATED __declspec(deprecated)
#define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated("Virtual function signature changed or function deprecated")) type fn body
#endif
#elif defined(__GNUC__)
#if __GNUC__ < 4
#define P_DEPRECATED
#define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
#else
#define P_DEPRECATED __attribute__((deprecated))
#define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __attribute__((warn_unused_result)) __attribute__((deprecated)) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
#endif
#else
#define P_DEPRECATED
#define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
#endif
#define P_REMOVE_VIRTUAL_VOID(fn) P_REMOVE_VIRTUAL_INTERNAL(void, fn, {})
#define P_REMOVE_VIRTUAL(type, fn, ret) P_REMOVE_VIRTUAL_INTERNAL(type, fn, { return ret; })
// P_USE_INTEGER_BOOL is the default and gives the old behaviour (it
// is also used for C translation units).
// without P_USE_INTEGER_BOOL, the ANSI C++ bool is used.
#if defined(P_USE_INTEGER_BOOL) || !defined(__cplusplus)
typedef BOOL PBoolean;
# define PTrue TRUE
# define PFalse FALSE
#else
typedef bool PBoolean;
# define PTrue true
# define PFalse false
#endif
// Disable inlines when debugging for faster compiles (the compiler doesn't
// actually inline the function with debug on any way).
#ifndef P_USE_INLINES
#ifdef _DEBUG
#define P_USE_INLINES 0
#else
#define P_USE_INLINES 0
#endif
#endif
#if P_USE_INLINES
#define PINLINE inline
#else
#define PINLINE
#endif
// Declare the debugging support
#ifndef P_USE_ASSERTS
#define P_USE_ASSERTS 1
#endif
#if !P_USE_ASSERTS
#define PAssert(b, m) (b)
#define PAssert2(b, c, m) (b)
#define PAssertOS(b) (b)
#define PAssertNULL(p) (p)
#define PAssertAlways(m) {}
#define PAssertAlways2(c, m) {}
#else // P_USE_ASSERTS
enum PStandardAssertMessage {
PLogicError,
POutOfMemory,
PNullPointerReference,
PInvalidCast,
PInvalidArrayIndex,
PInvalidArrayElement,
PStackEmpty,
PUnimplementedFunction,
PInvalidParameter,
POperatingSystemError,
PChannelNotOpen,
PUnsupportedFeature,
PInvalidWindow,
PMaxStandardAssertMessage
};
#define __CLASS__ NULL
void PAssertFunc(const char * file, int line, const char * className, PStandardAssertMessage msg);
void PAssertFunc(const char * file, int line, const char * className, const char * msg);
void PAssertFunc(const char * full_msg);
inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, PStandardAssertMessage msg)
{
if (!b)
PAssertFunc(file, line, className, msg);
return b;
}
inline bool PAssertFuncInline(bool b, const char * file, int line, const char * className, const char * msg)
{
if (!b)
PAssertFunc(file, line, className, msg);
return b;
}
#define PAssert(b, msg) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,(msg))
#define PAssert2(b, cls, msg) PAssertFuncInline((b), __FILE__,__LINE__,(cls),(msg))
#define PAssertOS(b) PAssertFuncInline((b), __FILE__,__LINE__,__CLASS__,POperatingSystemError)
#define PAssertNULL(ptr) (((ptr)!=NULL)?(ptr): \
(PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(ptr)))
#define PAssertAlways(msg) PAssertFunc(__FILE__,__LINE__,__CLASS__,(msg))
#define PAssertAlways2(cls, msg) PAssertFunc(__FILE__,__LINE__,(cls),(msg))
#endif // P_USE_ASSERTS
ostream & PGetErrorStream();
void PSetErrorStream(ostream * strm );
#define PError (PGetErrorStream())
// Debug and tracing
#ifndef PTRACING
#define PTRACING 1
#endif
#if PTRACING
class PTrace
{
public:
enum Options {
Blocks = 1,
DateAndTime = 2,
Timestamp = 4,
Thread = 8,
TraceLevel = 16,
FileAndLine = 32,
ThreadAddress = 64,
AppendToFile = 128,
GMTTime = 256,
RotateDaily = 512,
RotateHourly = 1024,
RotateMinutely = 2048,
RotateLogMask = RotateDaily + RotateHourly + RotateMinutely,
SystemLogStream = 32768
};
static void Initialise(
unsigned level,
const char * filename = NULL,
unsigned options = Timestamp | Thread | Blocks
);
static void Initialise(
unsigned level,
const char * filename,
const char * rolloverPattern,
unsigned options = Timestamp | Thread | Blocks
);
static void SetOptions(
unsigned options
);
static void ClearOptions(
unsigned options
);
static unsigned GetOptions();
static void SetLevel(
unsigned level
);
static unsigned GetLevel();
static PBoolean CanTrace(
unsigned level
);
static void SetStream(
ostream * out
);
static ostream & Begin(
unsigned level,
const char * fileName,
int lineNum
);
static ostream & End(
ostream & strm
);
static void Cleanup();
class Block {
public:
Block(
const char * fileName,
int lineNum,
const char * traceName
);
Block(const Block & obj)
: file(obj.file), line(obj.line), name(obj.name) { }
~Block();
private:
Block & operator=(const Block &)
{ return *this; }
const char * file;
int line;
const char * name;
};
};
/* Macro to conditionally declare a parameter to a function to avoid compiler
warning due that parameter only being used in a <code>PTRACE()</code> */
#define PTRACE_PARAM(param) param
#define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
#define PTRACE_LINE() \
if (PTrace::CanTrace(1)) \
PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End; \
else (void)0
#define PTRACE(level, args) \
if (PTrace::CanTrace(level)) \
PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
else (void)0
#define PTRACE_IF(level, cond, args) \
if ((PTrace::CanTrace(level) && (cond))) \
PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End; \
else (void)0
#else // PTRACING
#define PTRACE_PARAM(param)
#define PTRACE_BLOCK(n)
#define PTRACE_LINE()
#define PTRACE(level, arg)
#define PTRACE_IF(level, cond, args)
#endif // PTRACING
#if PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG) && !defined(_WIN32_WCE))
#define PMEMORY_HEAP 1
class PMemoryHeap {
public:
PMemoryHeap();
// Clear up the memory checking subsystem, dumping memory leaks.
~PMemoryHeap();
static void * Allocate(
size_t nSize,
const char * file,
int line,
const char * className
);
static void * Allocate(
size_t count,
size_t iSize,
const char * file,
int line
);
static void * Reallocate(
void * ptr,
size_t nSize,
const char * file,
int line
);
static void Deallocate(
void * ptr,
const char * className
);
enum Validation {
Ok, Bad, Trashed
};
static Validation Validate(
const void * ptr,
const char * className,
ostream * error
);
static PBoolean ValidateHeap(
ostream * error = NULL
);
static PBoolean SetIgnoreAllocations(
PBoolean ignore
);
static void DumpStatistics();
static void DumpStatistics(ostream & strm );
#if PMEMORY_CHECK
struct State {
DWORD allocationNumber;
};
#else
typedef _CrtMemState State;
#endif
/* Get memory state.
This returns a state that may be used to determine where to start dumping
objects from.
*/
static void GetState(
State & state
);
static void DumpObjectsSince(
const State & when
);
static void DumpObjectsSince(
const State & when,
ostream & strm
);
static void SetAllocationBreakpoint(
DWORD point
);
#if PMEMORY_CHECK
protected:
void * InternalAllocate(
size_t nSize, // Number of bytes to allocate.
const char * file, // Source file name for allocating function.
int line, // Source file line for allocating function.
const char * className // Class name for allocating function.
);
Validation InternalValidate(
const void * ptr, // Pointer to memory block to check
const char * className, // Class name it should be.
ostream * error // Stream to receive error message (may be NULL)
);
void InternalDumpStatistics(ostream & strm);
void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
class Wrapper {
public:
Wrapper();
~Wrapper();
PMemoryHeap * operator->() const { return instance; }
private:
PMemoryHeap * instance;
};
friend class Wrapper;
enum Flags {
NoLeakPrint = 1
};
#pragma pack(1)
struct Header {
enum {
// Assure that the Header struct is aligned to 8 byte boundary
NumGuardBytes = 16 - (sizeof(Header *) +
sizeof(Header *) +
sizeof(const char *) +
sizeof(const char *) +
sizeof(size_t) +
sizeof(DWORD) +
sizeof(WORD) +
sizeof(BYTE)
#if P_PTHREADS
+ sizeof(pthread_t)
#endif
)%8
};
Header * prev;
Header * next;
const char * className;
const char * fileName;
size_t size;
DWORD request;
WORD line;
BYTE flags;
#if P_PTHREADS
pthread_t thread;
#endif
char guard[NumGuardBytes];
static char GuardBytes[NumGuardBytes];
};
#pragma pack()
PBoolean isDestroyed;
Header * listHead;
Header * listTail;
static DWORD allocationBreakpoint;
DWORD allocationRequest;
DWORD firstRealObject;
BYTE flags;
char allocFillChar;
char freeFillChar;
DWORD currentMemoryUsage;
DWORD peakMemoryUsage;
DWORD currentObjects;
DWORD peakObjects;
DWORD totalObjects;
ostream * leakDumpStream;
#if defined(_WIN32)
CRITICAL_SECTION mutex;
#elif defined(P_PTHREADS)
pthread_mutex_t mutex;
#elif defined(P_VXWORKS)
void * mutex;
#endif
#else
#define P_CLIENT_BLOCK (_CLIENT_BLOCK|(0x61<<16)) // This identifies a PObject derived class
_CrtMemState initialState;
#endif // PMEMORY_CHECK
};
inline void * runtime_malloc(size_t bytes ) { return malloc(bytes); }
inline void runtime_free(void * ptr ) { free(ptr); }
#define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
#define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
#define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
#define free(p) PMemoryHeap::Deallocate(p, NULL)
#define cfree(p) PMemoryHeap::Deallocate(p, NULL)
#define PNEW new (__FILE__, __LINE__)
#if !defined(_MSC_VER) || _MSC_VER<1200
#define PSPECIAL_DELETE_FUNCTION
#else
#define PSPECIAL_DELETE_FUNCTION \
void operator delete(void * ptr, const char *, int) \
{ PMemoryHeap::Deallocate(ptr, Class()); } \
void operator delete[](void * ptr, const char *, int) \
{ PMemoryHeap::Deallocate(ptr, Class()); }
#endif
#define PNEW_AND_DELETE_FUNCTIONS \
void * operator new(size_t nSize, const char * file, int line) \
{ return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
void * operator new(size_t nSize) \
{ return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
void operator delete(void * ptr) \
{ PMemoryHeap::Deallocate(ptr, Class()); } \
void * operator new(size_t, void * placement) \
{ return placement; } \
void operator delete(void *, void *) \
{ } \
void * operator new[](size_t nSize, const char * file, int line) \
{ return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
void * operator new[](size_t nSize) \
{ return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
void operator delete[](void * ptr) \
{ PMemoryHeap::Deallocate(ptr, Class()); } \
PSPECIAL_DELETE_FUNCTION
inline void * operator new(size_t nSize, const char * file, int line)
{ return PMemoryHeap::Allocate(nSize, file, line, NULL); }
inline void * operator new[](size_t nSize, const char * file, int line)
{ return PMemoryHeap::Allocate(nSize, file, line, NULL); }
#ifndef __GNUC__
void * operator new(size_t nSize);
void * operator new[](size_t nSize);
void operator delete(void * ptr);
void operator delete[](void * ptr);
#if defined(_MSC_VER) && _MSC_VER>=1200
inline void operator delete(void * ptr, const char *, int)
{ PMemoryHeap::Deallocate(ptr, NULL); }
inline void operator delete[](void * ptr, const char *, int)
{ PMemoryHeap::Deallocate(ptr, NULL); }
#endif
#endif
class PMemoryHeapIgnoreAllocationsForScope {
public:
PMemoryHeapIgnoreAllocationsForScope() : previousIgnoreAllocations(PMemoryHeap::SetIgnoreAllocations(true)) { }
~PMemoryHeapIgnoreAllocationsForScope() { PMemoryHeap::SetIgnoreAllocations(previousIgnoreAllocations); }
private:
PBoolean previousIgnoreAllocations;
};
#define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE PMemoryHeapIgnoreAllocationsForScope instance_PMemoryHeapIgnoreAllocationsForScope
class PMemoryAllocationBreakpoint {
public:
PMemoryAllocationBreakpoint(DWORD point)
{
PMemoryHeap::SetAllocationBreakpoint(point);
}
};
#define PMEMORY_ALLOCATION_BREAKPOINT(point) PMemoryAllocationBreakpoint PMemoryAllocationBreakpointInstance(point)
#else // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
#define PMEMORY_HEAP 0
#define PNEW new
#define PNEW_AND_DELETE_FUNCTIONS
#define runtime_malloc(s) malloc(s)
#define runtime_free(p) free(p)
#define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE
#define PMEMORY_ALLOCATION_BREAKPOINT(point)
#endif // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
/*
* Implement "construct on first use" paradigm
*/
template <class GnuAllocator, class Type>
struct PAllocatorTemplate
{
Type * allocate(size_t v)
{
return GetAllocator().allocate(v);
}
void deallocate(Type * p, size_t v)
{
GetAllocator().deallocate(p, v);
}
private:
static GnuAllocator & GetAllocator()
{
static GnuAllocator instance;
return instance;
}
};
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
// Memory pooling allocators
#if defined(__GNUC__) && (GCC_VERSION > 40000) && !defined(P_MINGW) && !defined(P_MACOSX)
#include <ext/mt_allocator.h>
template <class Type> struct PFixedPoolAllocator : public PAllocatorTemplate<__gnu_cxx::__mt_alloc<Type>, Type> { };
template <class Type> struct PVariablePoolAllocator : public PAllocatorTemplate<__gnu_cxx::__mt_alloc<Type>, Type> { };
#else
template <class Type> struct PFixedPoolAllocator : public PAllocatorTemplate<std::allocator<Type>, Type> { };
template <class Type> struct PVariablePoolAllocator : public PAllocatorTemplate<std::allocator<Type>, Type> { };
#endif
#define PDECLARE_POOL_ALLOCATOR() \
void * operator new(size_t nSize); \
void * operator new(size_t nSize, const char * file, int line); \
void operator delete(void * ptr); \
void operator delete(void * ptr, const char *, int)
#define PDEFINE_POOL_ALLOCATOR(cls) \
static PFixedPoolAllocator<cls> cls##_allocator; \
void * cls::operator new(size_t) { return cls##_allocator.allocate(1); } \
void * cls::operator new(size_t, const char *, int) { return cls##_allocator.allocate(1); } \
void cls::operator delete(void * ptr) { cls##_allocator.deallocate((cls *)ptr, 1); } \
void cls::operator delete(void * ptr, const char *, int) { cls##_allocator.deallocate((cls *)ptr, 1); }
#define PCLASSINFO(cls, par) \
public: \
typedef cls P_thisClass; \
static inline const char * Class() \
{ return #cls; } \
virtual PBoolean InternalIsDescendant(const char * clsName) const \
{ return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
virtual const char * GetClass(unsigned ancestor = 0) const \
{ return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
virtual PObject::Comparison CompareObjectMemoryDirect(const PObject & obj) const \
{ return PObject::InternalCompareObjectMemoryDirect(this, dynamic_cast<const cls *>(&obj), sizeof(cls)); } \
PNEW_AND_DELETE_FUNCTIONS
#if P_HAS_TYPEINFO
#define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
#define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
#define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
#if P_USE_ASSERTS
template<class BaseClass> inline BaseClass * PAssertCast(BaseClass * obj, const char * file, int line)
{ if (obj == NULL) PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return obj; }
#define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
#else
#define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
#endif
#include <typeinfo>
#else // P_HAS_TYPEINFO
#define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class()))
#define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
#define PRemoveConst(cls, ptr) ((cls*)(ptr))
#if P_USE_ASSERTS
template<class BaseClass> inline BaseClass * PAssertCast(PObject * obj, const char * file, int line)
{ if (obj->InternalIsDescendant(BaseClass::Class())) return (BaseClass *)obj; PAssertFunc(file, line, BaseClass::Class(), PInvalidCast); return NULL; }
#define PDownCast(cls, ptr) PAssertCast<cls>((ptr),__FILE__,__LINE__)
#else
#define PDownCast(cls, ptr) ((cls*)(ptr))
#endif
#endif // P_HAS_TYPEINFO
#define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
#ifdef DOC_PLUS_PLUS
} Match previous opening brace in doc++
#endif
// The root of all evil ... umm classes
class PObject {
protected:
PObject() { }
public:
/* Destructor required to get the "virtual". A PObject really has nothing
to destroy.
*/
virtual ~PObject() { }
static inline const char * Class() { return "PObject"; }
virtual const char * GetClass(unsigned ancestor = 0) const { return ancestor > 0 ? "" : Class(); }
PBoolean IsClass(const char * cls) const
{ return strcmp(cls, GetClass()) == 0; }
virtual PBoolean InternalIsDescendant(
const char * clsName // Ancestor class name to compare against.
) const
{ return IsClass(clsName); }
enum Comparison {
LessThan = -1,
EqualTo = 0,
GreaterThan = 1
};
virtual Comparison Compare(
const PObject & obj // Object to compare against.
) const;
virtual Comparison CompareObjectMemoryDirect(
const PObject & obj // Object to compare against.
) const;
static Comparison InternalCompareObjectMemoryDirect(
const PObject * obj1,
const PObject * obj2,
PINDEX size
);
bool operator==(
const PObject & obj // Object to compare against.
) const { return Compare(obj) == EqualTo; }
bool operator!=(
const PObject & obj // Object to compare against.
) const { return Compare(obj) != EqualTo; }
bool operator<(
const PObject & obj // Object to compare against.
) const { return Compare(obj) == LessThan; }
bool operator>(
const PObject & obj // Object to compare against.
) const { return Compare(obj) == GreaterThan; }
bool operator<=(
const PObject & obj // Object to compare against.
) const { return Compare(obj) != GreaterThan; }
bool operator>=(
const PObject & obj // Object to compare against.
) const { return Compare(obj) != LessThan; }
virtual void PrintOn(
ostream &strm // Stream to print the object into.
) const;
virtual void ReadFrom(
istream &strm // Stream to read the objects contents from.
);
inline friend ostream & operator<<(
ostream &strm,
const PObject & obj
) { obj.PrintOn(strm); return strm; }
inline friend istream & operator>>(
istream &strm,
PObject & obj
) { obj.ReadFrom(strm); return strm; }
virtual PObject * Clone() const;
virtual PINDEX HashFunction() const;
};
// Platform independent types
// All these classes encapsulate primitive types such that they may be
// transfered in a platform independent manner. In particular it is used to
// do byte swapping for little endien and big endien processor architectures
// as well as accommodating structure packing rules for memory structures.
#define PANSI_CHAR 1
#define PLITTLE_ENDIAN 2
#define PBIG_ENDIAN 3
template <typename type>
struct PIntSameOrder {
__inline PIntSameOrder() : data(0) { }
__inline PIntSameOrder(type value) : data(value) { }
__inline PIntSameOrder(const PIntSameOrder & value) : data(value.data) { }
__inline PIntSameOrder & operator=(type value) { data = value; return *this; }
__inline PIntSameOrder & operator=(const PIntSameOrder & value) { data = value.data; return *this; }
__inline operator type() const { return data; }
__inline friend ostream & operator<<(ostream & s, const PIntSameOrder & v) { return s << v.data; }
__inline friend istream & operator>>(istream & s, PIntSameOrder & v) { return s >> v.data; }
private:
type data;
};
template <typename type>
struct PIntReversedOrder {
__inline PIntReversedOrder() : data(0) { }
__inline PIntReversedOrder(type value) { ReverseBytes(value, data); }
__inline PIntReversedOrder(const PIntReversedOrder & value) : data(value.data) { }
__inline PIntReversedOrder & operator=(type value) { ReverseBytes(value, data); return *this; }
__inline PIntReversedOrder & operator=(const PIntReversedOrder & value) { data = value.data; return *this; }
__inline operator type() const { type value; ReverseBytes(data, value); return value; }
__inline friend ostream & operator<<(ostream & s, const PIntReversedOrder & value) { return s << (type)value; }
__inline friend istream & operator>>(istream & s, PIntReversedOrder & v) { type val; s >> val; v = val; return s; }
private:
type data;
static __inline void ReverseBytes(const type & src, type & dst)
{
size_t s = sizeof(type)-1;
for (size_t d = 0; d < sizeof(type); ++d,--s)
((BYTE *)&dst)[d] = ((const BYTE *)&src)[s];
}
};
#ifndef PCHAR8
#define PCHAR8 PANSI_CHAR
#endif
#if PCHAR8==PANSI_CHAR
typedef PIntSameOrder<char> PChar8;
#endif
typedef PIntSameOrder<char> PInt8;
typedef PIntSameOrder<unsigned char> PUInt8;
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntSameOrder<PInt16> PInt16l;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntReversedOrder<PInt16> PInt16l;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntReversedOrder<PInt16> PInt16b;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntSameOrder<PInt16> PInt16b;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntSameOrder<WORD> PUInt16l;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntReversedOrder<WORD> PUInt16l;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntReversedOrder<WORD> PUInt16b;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntSameOrder<WORD> PUInt16b;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntSameOrder<PInt32> PInt32l;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntReversedOrder<PInt32> PInt32l;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntReversedOrder<PInt32> PInt32b;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntSameOrder<PInt32> PInt32b;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntSameOrder<DWORD> PUInt32l;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntReversedOrder<DWORD> PUInt32l;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntReversedOrder<DWORD> PUInt32b;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntSameOrder<DWORD> PUInt32b;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntSameOrder<PInt64> PInt64l;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntReversedOrder<PInt64> PInt64l;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntReversedOrder<PInt64> PInt64b;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntSameOrder<PInt64> PInt64b;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntSameOrder<PUInt64> PUInt64l;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntReversedOrder<PUInt64> PUInt64l;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntReversedOrder<PUInt64> PUInt64b;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntSameOrder<PUInt64> PUInt64b;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntSameOrder<float> PFloat32l;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntReversedOrder<float> PFloat32l;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntReversedOrder<float> PFloat32b;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntSameOrder<float> PFloat32b;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntSameOrder<double> PFloat64l;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntReversedOrder<double> PFloat64l;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntReversedOrder<double> PFloat64b;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntSameOrder<double> PFloat64b;
#endif
#ifndef NO_LONG_DOUBLE // stupid OSX compiler
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntSameOrder<long double> PFloat80l;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntReversedOrder<long double> PFloat80l;
#endif
#if PBYTE_ORDER==PLITTLE_ENDIAN
typedef PIntReversedOrder<long double> PFloat80b;
#elif PBYTE_ORDER==PBIG_ENDIAN
typedef PIntSameOrder<long double> PFloat80b;
#endif
#endif
// Miscellaneous
/*$MACRO PARRAYSIZE(array)
This macro is used to calculate the number of array elements in a static
array.
*/
#define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
/*$MACRO PMIN(v1, v2)
This macro is used to calculate the minimum of two values. As this is a
macro the expression in <code>v1</code> or <code>v2</code> is executed
twice so extreme care should be made in its use.
*/
#define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
/*$MACRO PMAX(v1, v2)
This macro is used to calculate the maximum of two values. As this is a
macro the expression in <code>v1</code> or <code>v2</code> is executed
twice so extreme care should be made in its use.
*/
#define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
/*$MACRO PABS(val)
This macro is used to calculate an absolute value. As this is a macro the
expression in <code>val</code> is executed twice so extreme care should be
made in its use.
*/
#define PABS(v) ((v) < 0 ? -(v) : (v))
#endif // PTLIB_OBJECT_H
// End Of File ///////////////////////////////////////////////////////////////
PTrace::Options
Options
Options for trace output.
Definition: object.h:296
PMemoryHeap
Memory heap checking class.
Definition: object.h:569
PUInt8
PIntSameOrder< unsigned char > PUInt8
Definition: object.h:1418
PTrace::DateAndTime
Include date and time in all output.
Definition: object.h:304
PMemoryHeap::Deallocate
static void Deallocate(void *ptr, const char *className)
Free a memory block.
PMemoryHeap::currentObjects
DWORD currentObjects
Definition: object.h:797
PIntReversedOrder::operator=
__inline PIntReversedOrder & operator=(const PIntReversedOrder &value)
Definition: object.h:1392
PMemoryHeap::flags
BYTE flags
Definition: object.h:790
PTrace::GetLevel
static unsigned GetLevel()
Get the trace level.
PObject::operator==
bool operator==(const PObject &obj) const
Compare the two objects.
Definition: object.h:1232
PTrace
Class to encapsulate tracing functions.
Definition: object.h:292
PIntSameOrder::operator<<
__inline friend ostream & operator<<(ostream &s, const PIntSameOrder &v)
Definition: object.h:1378
PIntReversedOrder
Definition: object.h:1387
PMemoryHeap::Allocate
static void * Allocate(size_t nSize, const char *file, int line, const char *className)
Allocate a memory block.
PMaxStandardAssertMessage
Number of standard assert message.
Definition: object.h:164
PIntSameOrder::operator=
__inline PIntSameOrder & operator=(type value)
Definition: object.h:1375
PMemoryHeap::Wrapper::operator->
PMemoryHeap * operator->() const
Definition: object.h:737
PObject::IsClass
PBoolean IsClass(const char *cls) const
Definition: object.h:1160
PMemoryHeap::firstRealObject
DWORD firstRealObject
Definition: object.h:789
PObject::operator!=
bool operator!=(const PObject &obj) const
Compare the two objects.
Definition: object.h:1241
PMemoryHeapIgnoreAllocationsForScope::PMemoryHeapIgnoreAllocationsForScope
PMemoryHeapIgnoreAllocationsForScope()
Definition: object.h:947
PMemoryHeap::currentMemoryUsage
DWORD currentMemoryUsage
Definition: object.h:795
PMemoryHeap::SetAllocationBreakpoint
static void SetAllocationBreakpoint(DWORD point)
Set break point allocation number.
PMemoryHeap::SetIgnoreAllocations
static PBoolean SetIgnoreAllocations(PBoolean ignore)
Ignore/Monitor allocations.
PMemoryHeap::Flags
Flags
Definition: object.h:743
PIntReversedOrder::operator<<
__inline friend ostream & operator<<(ostream &s, const PIntReversedOrder &value)
Definition: object.h:1394
PIntSameOrder::operator=
__inline PIntSameOrder & operator=(const PIntSameOrder &value)
Definition: object.h:1376
PObject::Comparison
Comparison
Result of the comparison operation performed by the Compare() function.
Definition: object.h:1184
PMemoryHeap::leakDumpStream
ostream * leakDumpStream
Definition: object.h:801
PStandardAssertMessage
PStandardAssertMessage
Standard assert messages for the PAssert macro.
Definition: object.h:150
POutOfMemory
A new or malloc failed.
Definition: object.h:152
PIntSameOrder::operator>>
__inline friend istream & operator>>(istream &s, PIntSameOrder &v)
Definition: object.h:1379
PStackEmpty
A Pop() was made of a stack with no elements.
Definition: object.h:157
PMemoryHeap::peakMemoryUsage
DWORD peakMemoryUsage
Definition: object.h:796
PGetErrorStream
ostream & PGetErrorStream()
Get the stream being used for error output.
PVariablePoolAllocator
Definition: object.h:1022
PTrace::Initialise
static void Initialise(unsigned level, const char *filename=NULL, unsigned options=Timestamp|Thread|Blocks)
Set the most common trace options.
PMemoryHeap::allocationRequest
DWORD allocationRequest
Definition: object.h:788
PTrace::SetOptions
static void SetOptions(unsigned options)
Set the trace options.
PMemoryHeap::isDestroyed
PBoolean isDestroyed
Definition: object.h:782
runtime_free
void runtime_free(void *ptr)
Free memory allocated by run time library.
Definition: object.h:830
PrintOn
virtual void PrintOn(ostream &strm) const
Print the array.
PTrace::End
static ostream & End(ostream &strm)
End a trace output.
PMemoryHeap::freeFillChar
char freeFillChar
Definition: object.h:793
PAssertCast
BaseClass * PAssertCast(BaseClass *obj, const char *file, int line)
Definition: object.h:1071
PObject::ReadFrom
virtual void ReadFrom(istream &strm)
Input the contents of the object from the stream.
PInvalidArrayIndex
An index into an array was negative.
Definition: object.h:155
PMemoryHeap::Header::fileName
const char * fileName
Definition: object.h:768
PNullPointerReference
A reference was made through a NULL pointer.
Definition: object.h:153
PAssertFuncInline
bool PAssertFuncInline(bool b, const char *file, int line, const char *className, PStandardAssertMessage msg)
Definition: object.h:173
PMemoryHeap::allocationBreakpoint
static DWORD allocationBreakpoint
Definition: object.h:787
PObject::InternalIsDescendant
virtual PBoolean InternalIsDescendant(const char *clsName) const
Determine if the dynamic type of the current instance is a descendent of the specified class...
Definition: object.h:1172
PObject::~PObject
virtual ~PObject()
Definition: object.h:1130
PIntReversedOrder::PIntReversedOrder
__inline PIntReversedOrder()
Definition: object.h:1388
PChar8
PIntSameOrder< char > PChar8
Definition: object.h:1413
PChannelNotOpen
Operation attempted when channel not open.
Definition: object.h:161
PObject::PrintOn
virtual void PrintOn(ostream &strm) const
Output the contents of the object to the stream.
PIntSameOrder
Definition: object.h:1371
PObject::PObject
PObject()
Constructor for PObject, made protected so cannot ever create one on its own.
Definition: object.h:1124
runtime_malloc
void * runtime_malloc(size_t bytes)
Allocate memory for the run time library.
Definition: object.h:824
PBoolean
BOOL PBoolean
Definition: object.h:102
PAllocatorTemplate
Definition: object.h:989
PInvalidWindow
Access through invalid window.
Definition: object.h:163
PTrace::Blocks
Include PTrace::Block constructs in output If this is bit is clear, all PTrace::Block output is inhib...
Definition: object.h:302
PMemoryHeapIgnoreAllocationsForScope
Definition: object.h:945
PMemoryAllocationBreakpoint
Definition: object.h:955
PMemoryHeap::Header
Definition: object.h:748
PObject::operator<
bool operator<(const PObject &obj) const
Compare the two objects.
Definition: object.h:1250
PMemoryHeap::peakObjects
DWORD peakObjects
Definition: object.h:798
PTrace::RotateHourly
If set, log file will be rotated hourly.
Definition: object.h:322
PTrace::Begin
static ostream & Begin(unsigned level, const char *fileName, int lineNum)
Begin a trace output.
free
#define free(p)
Override of system call for memory check system.
Definition: object.h:864
PTrace::ClearOptions
static void ClearOptions(unsigned options)
Clear the trace options.
PIntReversedOrder::PIntReversedOrder
__inline PIntReversedOrder(const PIntReversedOrder &value)
Definition: object.h:1390
PObject::operator<<
friend ostream & operator<<(ostream &strm, const PObject &obj)
Global function for using the standard << operator on objects descended from PObject.
Definition: object.h:1310
PTrace::Cleanup
static void Cleanup()
Cleanup the trace system for a specific thread When using thread local storage, this will delete the ...
PMemoryHeap::Header::className
const char * className
Definition: object.h:767
PIntSameOrder::PIntSameOrder
__inline PIntSameOrder(type value)
Definition: object.h:1373
PIntReversedOrder::operator>>
__inline friend istream & operator>>(istream &s, PIntReversedOrder &v)
Definition: object.h:1395
PIntReversedOrder::operator=
__inline PIntReversedOrder & operator=(type value)
Definition: object.h:1391
PAllocatorTemplate::deallocate
void deallocate(Type *p, size_t v)
Definition: object.h:996
PMemoryHeap::Header::line
WORD line
Definition: object.h:771
PTrace::Block::Block
Block(const Block &obj)
Definition: object.h:492
PMemoryHeap::Wrapper
Definition: object.h:733
PTrace::RotateDaily
If set, log file will be rotated daily.
Definition: object.h:320
PUnsupportedFeature
Feature is not supported.
Definition: object.h:162
PTrace::Block::~Block
~Block()
Output exit trace message.
PMemoryHeap::Header::size
size_t size
Definition: object.h:769
PMemoryHeap::Header::flags
BYTE flags
Definition: object.h:772
PObject::operator>=
bool operator>=(const PObject &obj) const
Compare the two objects.
Definition: object.h:1277
PMemoryHeap::listHead
Header * listHead
Definition: object.h:784
PTrace::Timestamp
Include (millisecond) timestamp in all output.
Definition: object.h:306
PInvalidCast
An invalid cast to descendant is required.
Definition: object.h:154
PTrace::FileAndLine
Include the file and line for the trace call in all output.
Definition: object.h:312
PMemoryHeap::allocFillChar
char allocFillChar
Definition: object.h:792
malloc
#define malloc(s)
Override of system call for memory check system.
Definition: object.h:839
PTrace::AppendToFile
Append to log file rather than resetting every time.
Definition: object.h:316
PTrace::ThreadAddress
Include thread object pointer address in all trace output.
Definition: object.h:314
PMemoryHeap::listTail
Header * listTail
Definition: object.h:785
PObject::operator>>
friend istream & operator>>(istream &strm, PObject &obj)
Global function for using the standard >> operator on objects descended from PObject.
Definition: object.h:1320
PTrace::GetOptions
static unsigned GetOptions()
Get the current trace options.
POperatingSystemError
Error was returned by Operating System.
Definition: object.h:160
PMemoryHeapIgnoreAllocationsForScope::~PMemoryHeapIgnoreAllocationsForScope
~PMemoryHeapIgnoreAllocationsForScope()
Definition: object.h:948
PIntSameOrder::PIntSameOrder
__inline PIntSameOrder(const PIntSameOrder &value)
Definition: object.h:1374
PInvalidParameter
Invalid parameter was passed to a function.
Definition: object.h:159
PUnimplementedFunction
Funtion is not implemented.
Definition: object.h:158
PTrace::Thread
Include identifier for thread trace is made from in all output.
Definition: object.h:308
PAllocatorTemplate::allocate
Type * allocate(size_t v)
Definition: object.h:991
PMemoryHeap::State::allocationNumber
DWORD allocationNumber
Definition: object.h:672
PTrace::Block::Block
Block(const char *fileName, int lineNum, const char *traceName)
Output entry trace message.
PTrace::TraceLevel
Include trace level in all output.
Definition: object.h:310
PSetErrorStream
void PSetErrorStream(ostream *strm)
Set the stream to be used for error output.
PFixedPoolAllocator
Definition: object.h:1021
PTrace::SystemLogStream
SystemLog flag for tracing within a PServiceProcess application.
Definition: object.h:330
PInvalidArrayElement
A NULL array element object was accessed.
Definition: object.h:156
PAssertFunc
void PAssertFunc(const char *file, int line, const char *className, PStandardAssertMessage msg)
PIntSameOrder::PIntSameOrder
__inline PIntSameOrder()
Definition: object.h:1372
PObject::GetClass
virtual const char * GetClass(unsigned ancestor=0) const
Get the current dynamic type of the object instance.
Definition: object.h:1158
PIntReversedOrder::PIntReversedOrder
__inline PIntReversedOrder(type value)
Definition: object.h:1389
PInt8
PIntSameOrder< char > PInt8
Definition: object.h:1416
PTrace::Block
Class to trace Execution blocks.
Definition: object.h:483
PTrace::SetLevel
static void SetLevel(unsigned level)
Set the trace level.
PMemoryAllocationBreakpoint::PMemoryAllocationBreakpoint
PMemoryAllocationBreakpoint(DWORD point)
Definition: object.h:957
PObject::operator>
bool operator>(const PObject &obj) const
Compare the two objects.
Definition: object.h:1259
PMemoryHeap::Header::next
Header * next
Definition: object.h:766
PTrace::SetStream
static void SetStream(ostream *out)
Set the stream to be used for trace output.
PObject::Class
static const char * Class()
Get the name of the class as a C string.
Definition: object.h:1144
PObject
Ultimate parent class for all objects in the class library.
Definition: object.h:1118
PMemoryHeap::Header::prev
Header * prev
Definition: object.h:765
PLogicError
A logic error occurred.
Definition: object.h:151
PObject::operator<=
bool operator<=(const PObject &obj) const
Compare the two objects.
Definition: object.h:1268
PTrace::GMTTime
Output timestamps in GMT time rather than local time.
Definition: object.h:318
PMemoryHeap::State
Definition: object.h:671
PTrace::RotateLogMask
Mask for all the rotate bits.
Definition: object.h:326
PMemoryHeap::Validation
Validation
Validation result.
Definition: object.h:628
PTrace::RotateMinutely
If set, log file will be rotated every minute.
Definition: object.h:324
ReadFrom
virtual void ReadFrom(istream &strm)
Read the array.
PTrace::CanTrace
static PBoolean CanTrace(unsigned level)
Determine if the level may cause trace output.
PMemoryHeap::Header::request
DWORD request
Definition: object.h:770
PMemoryHeap::totalObjects
DWORD totalObjects
Definition: object.h:799