34 #ifndef PTLIB_OBJECT_H
35 #define PTLIB_OBJECT_H
42 #include "msos/ptlib/platform.h"
44 #include "unix/ptlib/platform.h"
78 #define P_REMOVE_VIRTUAL_INTERNAL_BASE(fn) __inline virtual struct ptlib_virtual_function_changed_or_removed ****** fn { return 0; }
83 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
85 #define P_DEPRECATED __declspec(deprecated)
86 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated) type fn body
88 #define P_DEPRECATED __declspec(deprecated)
89 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __inline virtual __declspec(deprecated("Virtual function signature changed or function deprecated")) type fn body
91 #elif defined(__GNUC__)
94 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
96 #define P_DEPRECATED __attribute__((deprecated))
97 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) __attribute__((warn_unused_result)) __attribute__((deprecated)) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
101 #define P_REMOVE_VIRTUAL_INTERNAL(type, fn, body) P_REMOVE_VIRTUAL_INTERNAL_BASE(fn)
104 #define P_REMOVE_VIRTUAL_VOID(fn) P_REMOVE_VIRTUAL_INTERNAL(void, fn, {})
105 #define P_REMOVE_VIRTUAL(type, fn, ret) P_REMOVE_VIRTUAL_INTERNAL(type, fn, { return ret; })
109 #define P_PUSH_MSVC_WARNINGS(warnings) __pragma(warning(push)) __pragma(warning(disable:warnings))
110 #define P_POP_MSVC_WARNINGS() __pragma(warning(pop))
112 #define P_PUSH_MSVC_WARNINGS(warnings)
113 #define P_POP_MSVC_WARNINGS()
115 #define P_DISABLE_MSVC_WARNINGS(warnings, statement) P_PUSH_MSVC_WARNINGS(warnings) statement P_POP_MSVC_WARNINGS()
137 #ifndef P_USE_INLINES
139 #define P_USE_INLINES 0
141 #define P_USE_INLINES 0
146 #define PINLINE __inline
156 #define PARG_COUNT(...) PARG_COUNT_PART1(PARG_COUNT_PART2(__VA_ARGS__,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
157 #define PARG_COUNT_PART1(arg) arg
158 #define PARG_COUNT_PART2(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,N,...) N
161 #define P_STRINGISE(v) P_STRINGISE_PART2(v)
162 #define P_STRINGIZE(v) P_STRINGISE_PART2(v)
163 #define P_STRINGISE_PART2(v) #v
176 #define P_DECLARE_ENUM_EX(name, countName, firstName, firstValue, ...) \
177 enum name { firstName = firstValue, Begin##name = firstName, __VA_ARGS__, End##name, countName = End##name-Begin##name }; \
178 friend __inline name operator++(name & e ) { PAssert(e < End##name, PInvalidParameter); return e = (name)(e+1); } \
179 friend __inline name operator++(name & e, int) { PAssert(e < End##name, PInvalidParameter); name o=e; e = (name)(e+1); return o; } \
180 friend __inline name operator--(name & e ) { PAssert(e >= Begin##name, PInvalidParameter); return e = (name)(e-1); } \
181 friend __inline name operator--(name & e, int) { PAssert(e >= Begin##name, PInvalidParameter); name o=e; e = (name)(e-1); return o; } \
182 static __inline name name##FromInt(int v) { return (name)(v < Begin##name ? Begin##name : v >= End##name ? (End##name-1) : v); }
195 #define P_DECLARE_ENUM(name, first, ...) P_DECLARE_ENUM_EX(name, Num##name, first, 0, __VA_ARGS__)
197 extern void PPrintEnum(std::ostream & strm,
int e,
int begin,
int end,
char const *
const * names);
198 extern int PReadEnum(std::istream & strm,
int begin,
int end,
char const *
const * names,
bool matchCase =
true);
199 extern int PParseEnum(
const char * str,
int begin,
int end,
char const *
const * names,
bool matchCase =
true);
201 #define P_ENUM_NAMES_PART1(narg, args)P_ENUM_NAMES_PART2(narg, args)
202 #define P_ENUM_NAMES_PART2(narg, args) P_ENUM_NAMES_ARG_##narg args
203 #define P_ENUM_NAMES_ARG_1(_1 )#_1
204 #define P_ENUM_NAMES_ARG_2(_1,_2 )#_1,#_2
205 #define P_ENUM_NAMES_ARG_3(_1,_2,_3 )#_1,#_2,#_3
206 #define P_ENUM_NAMES_ARG_4(_1,_2,_3,_4 )#_1,#_2,#_3,#_4
207 #define P_ENUM_NAMES_ARG_5(_1,_2,_3,_4,_5 )#_1,#_2,#_3,#_4,#_5
208 #define P_ENUM_NAMES_ARG_6(_1,_2,_3,_4,_5,_6 )#_1,#_2,#_3,#_4,#_5,#_6
209 #define P_ENUM_NAMES_ARG_7(_1,_2,_3,_4,_5,_6,_7 )#_1,#_2,#_3,#_4,#_5,#_6,#_7
210 #define P_ENUM_NAMES_ARG_8(_1,_2,_3,_4,_5,_6,_7,_8 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8
211 #define P_ENUM_NAMES_ARG_9(_1,_2,_3,_4,_5,_6,_7,_8,_9 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9
212 #define P_ENUM_NAMES_ARG_10(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10
213 #define P_ENUM_NAMES_ARG_11(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11
214 #define P_ENUM_NAMES_ARG_12(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12
215 #define P_ENUM_NAMES_ARG_13(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13
216 #define P_ENUM_NAMES_ARG_14(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14
217 #define P_ENUM_NAMES_ARG_15(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15
218 #define P_ENUM_NAMES_ARG_16(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16
219 #define P_ENUM_NAMES_ARG_17(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17
220 #define P_ENUM_NAMES_ARG_18(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18
221 #define P_ENUM_NAMES_ARG_19(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19
222 #define P_ENUM_NAMES_ARG_20(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20
223 #define P_ENUM_NAMES_ARG_21(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21
224 #define P_ENUM_NAMES_ARG_22(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22
225 #define P_ENUM_NAMES_ARG_23(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23
226 #define P_ENUM_NAMES_ARG_24(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24
227 #define P_ENUM_NAMES_ARG_25(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25
228 #define P_ENUM_NAMES_ARG_26(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26
229 #define P_ENUM_NAMES_ARG_27(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27
230 #define P_ENUM_NAMES_ARG_28(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28
231 #define P_ENUM_NAMES_ARG_29(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29
232 #define P_ENUM_NAMES_ARG_30(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30
233 #define P_ENUM_NAMES_ARG_31(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31
234 #define P_ENUM_NAMES_ARG_32(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32
235 #define P_ENUM_NAMES_ARG_33(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33
236 #define P_ENUM_NAMES_ARG_34(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34
237 #define P_ENUM_NAMES_ARG_35(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34,#_35
238 #define P_ENUM_NAMES_ARG_36(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34,#_35,#_36
239 #define P_ENUM_NAMES_ARG_37(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34,#_35,#_36,#_37
240 #define P_ENUM_NAMES_ARG_38(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34,#_35,#_36,#_37,#_38
241 #define P_ENUM_NAMES_ARG_39(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39 )#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34,#_35,#_36,#_37,#_38,#_39
242 #define P_ENUM_NAMES_ARG_40(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40)#_1,#_2,#_3,#_4,#_5,#_6,#_7,#_8,#_9,#_10,#_11,#_12,#_13,#_14,#_15,#_16,#_17,#_18,#_19,#_20,#_21,#_22,#_23,#_24,#_25,#_26,#_27,#_28,#_29,#_30,#_31,#_32,#_33,#_34,#_35,#_36,#_37,#_38,#_39,#_40
250 #define P_DECLARE_ENUM_NAMES(name, ...) \
251 struct PEnumNames_##name { \
252 static char const * const * Names() { static char const * const Strings[] = { __VA_ARGS__ }; return Strings; } \
254 friend __inline std::ostream & operator<<(std::ostream & strm, name e) \
255 { PPrintEnum(strm, e, Begin##name, End##name, PEnumNames_##name::Names()); return strm; } \
256 friend __inline std::istream & operator>>(std::istream & strm, name & e) \
257 { e = (name)PReadEnum(strm, Begin##name, End##name, PEnumNames_##name::Names()); return strm; } \
258 static __inline const char * name##ToString(name e) { return e >= Begin##name && e < End##name ? PAssertNULL(PEnumNames_##name::Names()[e-Begin##name]) : ""; } \
259 static __inline name name##FromString(const char * str, bool matchCase = true) { return (name)PParseEnum(str, Begin##name, End##name, PEnumNames_##name::Names(), matchCase); }
265 #define P_DECLARE_STREAMABLE_ENUM_EX(name, countName, firstName, firstValue, ...) \
266 P_DECLARE_ENUM_EX(name, countName, firstName, firstValue, __VA_ARGS__) \
267 P_DECLARE_ENUM_NAMES(name, #firstName, P_ENUM_NAMES_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__)))
273 #define P_DECLARE_STREAMABLE_ENUM(name, first, ...) P_DECLARE_STREAMABLE_ENUM_EX(name, Num##name, first, 0, __VA_ARGS__)
279 #ifndef P_USE_ASSERTS
280 #define P_USE_ASSERTS 1
285 #define PAssert(b, m) (b)
286 #define PAssert2(b, c, m) (b)
287 #define PAssertOS(b) (b)
288 #define PAssertNULL(p) (p)
289 #define PAssertAlways(m) {}
290 #define PAssertAlways2(c, m) {}
292 #else // P_USE_ASSERTS
312 #define __CLASS__ NULL
315 bool PAssertFunc(
const char * file,
int line,
const char * className,
const char * msg);
325 #define PAssert(b, msg) ((b)?true:PAssertFunc(__FILE__,__LINE__,__CLASS__,(msg)))
334 #define PAssert2(b, cls, msg) ((b)?true:PAssertFunc(__FILE__,__LINE__,(cls),(msg)))
342 #define PAssertOS(b) ((b)?true:PAssertFunc(__FILE__,__LINE__,__CLASS__,POperatingSystemError))
353 #define PAssertNULL(ptr) (((ptr)!=NULL)?(ptr): \
354 (PAssertFunc(__FILE__,__LINE__, __CLASS__, PNullPointerReference),(ptr)))
362 #define PAssertAlways(msg) PAssertFunc(__FILE__,__LINE__,__CLASS__,(msg))
370 #define PAssertAlways2(cls, msg) PAssertFunc(__FILE__,__LINE__,(cls),(msg))
372 #endif // P_USE_ASSERTS
400 #define PError (PGetErrorStream())
437 DateAndTime = 0x0002,
441 FileAndLine = 0x0020,
442 ThreadAddress = 0x0040,
443 AppendToFile = 0x0080,
445 RotateDaily = 0x0200,
446 RotateHourly = 0x0400,
447 RotateMinutely = 0x0800,
448 RotateLogMask = RotateDaily + RotateHourly + RotateMinutely,
450 ObjectInstance = 0x1000,
451 ContextIdentifier = 0x2000,
452 SystemLogStream = 0x8000,
455 HasFilePermissions = 0x8000000,
456 FilePermissionMask = 0x7ff0000,
458 FilePermissionShift = 16
462 #define PTRACE_ARGLIST_OPT_HELP \
463 "use +X or -X to add/remove option where X is one of:\r" \
464 " block PTrace::Block constructs in output\r" \
465 " time time since prgram start\r" \
466 " date date and time\r" \
467 " gmt Date/time is in UTC\r" \
468 " thread thread name and identifier\r" \
469 " level log level\r" \
470 " file source file name and line number\r" \
471 " object PObject pointer\r" \
472 " context context identifier\r" \
473 " daily rotate output file daily\r" \
474 " hour rotate output file hourly\r" \
475 " minute rotate output file every minute\r" \
476 " append append to output file, otherwise overwrites\r" \
477 " <perm> file permission similar to unix chmod, but starts\r" \
478 " with +/- and only has one combination at a time,\r" \
479 " e.g. +uw is user write, +or is other read, etc"
481 #define PTRACE_ARG_TRACE "trace"
482 #define PTRACE_ARG_LEVEL "trace-level"
483 #define PTRACE_ARG_OUTPUT "output"
484 #define PTRACE_ARG_ROLLOVER "trace-rollover"
485 #define PTRACE_ARG_OPTION "trace-option"
487 #define PTRACE_ARGLIST_EXT(t,l,o,r,O) \
488 t"-"PTRACE_ARG_TRACE". Trace enable (use multiple times for more detail).\n" \
489 l"-"PTRACE_ARG_LEVEL": Specify trace detail level.\n" \
490 o"-"PTRACE_ARG_OUTPUT": Specify filename for trace output\rMay be special value such as \"stderr\" dependent on platform.\n" \
491 r"-"PTRACE_ARG_ROLLOVER": Specify trace file rollover file name pattern.\n" \
492 O"-"PTRACE_ARG_OPTION": Specify trace option(s),\r" PTRACE_ARGLIST_OPT_HELP "\n"
494 #define PTRACE_ARGLIST PTRACE_ARGLIST_EXT("t","","o","","")
496 #define PTRACE_INITIALISE(...) PTrace::Initialise(__VA_ARGS__)
501 static void Initialise(
507 Timestamp | Thread | Blocks,
546 static void Initialise(
548 const char * filename = NULL,
549 unsigned options = Timestamp | Thread | Blocks,
550 const char * rolloverPattern = NULL
554 static void Initialise(
556 const char * filename,
557 const char * rolloverPattern,
558 unsigned options = Timestamp | Thread | Blocks
559 ) {
Initialise(level, filename, options, rolloverPattern); }
567 static void SetOptions(
579 static void ClearOptions(
588 static unsigned GetOptions();
595 static void SetLevel(
604 static unsigned GetLevel();
618 static void SetStream(
624 static ostream * GetStream();
628 static ostream & PrintInfo(
648 static ostream & Begin(
650 const char * fileName,
652 const PObject * instance = NULL,
653 const char * module = NULL
656 static ostream & Begin(
658 const char * fileName,
662 const char * defModule
663 ) {
return Begin(level, fileName, lineNum, instance, module != NULL ? module : defModule); }
665 static ostream & Begin(
667 const char * fileName,
672 ) {
return Begin(level, fileName, lineNum, instance != NULL ? instance : defInstance, module); }
691 static ostream & End(
704 const char * fileName,
706 const char * traceName
710 : file(obj.file), line(obj.line), name(obj.name) { }
721 static void WalkStack(
723 PThreadIdentifier
id = PNullThreadIdentifier
729 static unsigned GetNextContextIdentifier();
735 #define PTRACE_PARAM(...) __VA_ARGS__
743 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
748 #define PTRACE_LINE() \
749 if (PTrace::CanTrace(1)) \
750 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End; \
755 #define PTRACE_INTERNAL(level, condition, args, ...) \
756 if (PTrace::CanTrace(level) condition) \
757 PTrace::Begin(level, __FILE__, __LINE__, __VA_ARGS__) << args << PTrace::End; \
760 #define PTRACE_NO_CONDITION
763 #define PTRACE_PART1(narg, args) PTRACE_PART2(narg, args)
764 #define PTRACE_PART2(narg, args) PTRACE_ARG_##narg args
766 #define PTRACE_ARG_4(level, object, module, args) \
767 PTRACE_INTERNAL(level, PTRACE_NO_CONDITION, args, object, module)
769 #define PTRACE_ARG_3(level, objectOrModule, args) \
770 PTRACE_INTERNAL(level, PTRACE_NO_CONDITION, args, objectOrModule, PTraceObjectInstance(objectOrModule), PTraceModule())
772 #define PTRACE_ARG_2(level, args) \
773 PTRACE_INTERNAL(level, PTRACE_NO_CONDITION, args, PTraceObjectInstance(), PTraceModule())
776 #define PTRACE_IF_PART1(narg, args) PTRACE_IF_PART2(narg, args)
777 #define PTRACE_IF_PART2(narg, args) PTRACE_IF_ARG_##narg args
779 #define PTRACE_IF_ARG_5(level, condition, object, module, args) \
780 PTRACE_INTERNAL(level, && (condition), args, object, module)
782 #define PTRACE_IF_ARG_4(level, condition, objectOrModule, args) \
783 PTRACE_INTERNAL(level, && (condition), args, objectOrModule, PTraceObjectInstance(objectOrModule), PTraceModule())
785 #define PTRACE_IF_ARG_3(level, condition, args) \
786 PTRACE_INTERNAL(level, && (condition), args, PTraceObjectInstance(), PTraceModule())
789 #define PTRACE_BEGIN_PART1(narg, args) PTRACE_BEGIN_PART2(narg, args)
790 #define PTRACE_BEGIN_PART2(narg, args) PTRACE_BEGIN_ARG_##narg args
792 #define PTRACE_BEGIN_ARG_3(level, object, module) \
793 PTrace::Begin(level, __FILE__, __LINE__, object, module)
795 #define PTRACE_BEGIN_ARG_2(level, objectOrModule) \
796 PTrace::Begin(level, __FILE__, __LINE__, objectOrModule, PTraceObjectInstance(objectOrModule), PTraceModule())
798 #define PTRACE_BEGIN_ARG_1(level) \
799 PTrace::Begin(level, __FILE__, __LINE__, PTraceObjectInstance(), PTraceModule())
803 #define PTRACE2(level, object, args) \
804 PTRACE_INTERNAL(level, PTRACE_NO_CONDITION, args, object, PTraceModule())
805 #define PTRACE_IF2(level, condition, object, args) \
806 PTRACE_INTERNAL(level, && (condition), args, object, PTraceModule())
833 #define PTRACE(...) PTRACE_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__))
847 #define PTRACE_IF(...) PTRACE_IF_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__))
858 #define PTRACE_BEGIN(...) PTRACE_BEGIN_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__))
873 #define PTRACE_CONTEXT_ID_NEW() SetTraceContextIdentifier(PTrace::GetNextContextIdentifier())
874 #define PTRACE_CONTEXT_ID_SET(to, from) (to).SetTraceContextIdentifier(from)
875 #define PTRACE_CONTEXT_ID_FROM(obj) SetTraceContextIdentifier(obj)
876 #define PTRACE_CONTEXT_ID_TO(obj) GetTraceContextIdentifier(obj)
881 class PThread * m_currentThread;
882 unsigned m_savedContextIdentifier;
889 #define PTRACE_CONTEXT_ID_PUSH_THREAD(obj) PTraceSaveContextIdentifier praceSavedContextIdentifier(obj)
891 #endif // PTRACING==2
894 #define P_DECLARE_TRACED_ENUM P_DECLARE_STREAMABLE_ENUM
895 #define P_DECLARE_TRACED_ENUM_EX P_DECLARE_STREAMABLE_ENUM_EX
899 #ifndef PTRACE_ARGLIST_EXT
900 #define PTRACE_ARGLIST_EXT(...) ""
903 #ifndef PTRACE_ARGLIST
904 #define PTRACE_ARGLIST ""
907 #ifndef PTRACE_INITIALISE
908 #define PTRACE_INITIALISE(...)
912 #define PTRACE_PARAM(...)
916 #define PTRACE_BLOCK(n)
920 #define PTRACE_LINE()
928 #define PTRACE_IF(...)
932 #define PTRACE_BEGIN(...)
936 #define PTRACE2(level, obj, arg)
940 #define PTRACE_IF2(level, cond, obj, args)
943 #ifndef PTRACE_CONTEXT_ID_NEW
944 #define PTRACE_CONTEXT_ID_NEW()
947 #ifndef PTRACE_CONTEXT_ID_SET
948 #define PTRACE_CONTEXT_ID_SET(to, from)
951 #ifndef PTRACE_CONTEXT_ID_FROM
952 #define PTRACE_CONTEXT_ID_FROM(obj)
955 #ifndef PTRACE_CONTEXT_ID_TO
956 #define PTRACE_CONTEXT_ID_TO(obj)
959 #ifndef PTRACE_CONTEXT_ID_PUSH_THREAD
960 #define PTRACE_CONTEXT_ID_PUSH_THREAD(obj)
963 #ifndef P_DECLARE_TRACED_ENUM
964 #define P_DECLARE_TRACED_ENUM P_DECLARE_ENUM
967 #ifndef P_DECLARE_TRACED_ENUM_EX
968 #define P_DECLARE_TRACED_ENUM_EX P_DECLARE_ENUM_EX
972 #if PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG) && !defined(_WIN32_WCE))
974 #define PMEMORY_HEAP 1
997 static void * Allocate(
1001 const char * className
1009 static void * Allocate(
1023 static void * Reallocate(
1035 static void Deallocate(
1037 const char * className
1052 static Validation Validate(
1054 const char * className,
1063 ostream * error = NULL
1071 static PBoolean SetIgnoreAllocations(
1078 static void DumpStatistics();
1082 static void DumpStatistics(ostream & strm );
1089 typedef _CrtMemState
State;
1096 static void GetState(
1107 static void DumpObjectsSince(
1116 static void DumpObjectsSince(
1126 static void SetAllocationBreakpoint(
1133 void * InternalAllocate(
1137 const char * className
1141 const char * className,
1144 void InternalDumpStatistics(ostream & strm);
1145 void InternalDumpObjectsSince(DWORD objectNumber, ostream & strm);
1167 sizeof(
const char *) +
1168 sizeof(
const char *) +
1173 sizeof(PThreadIdentifier)
1186 char guard[NumGuardBytes];
1188 static char GuardBytes[NumGuardBytes];
1214 CRITICAL_SECTION mutex;
1215 #elif defined(P_PTHREADS)
1216 pthread_mutex_t mutex;
1217 #elif defined(P_VXWORKS)
1223 static void CreateInstance();
1224 #define P_CLIENT_BLOCK (_CLIENT_BLOCK|(0x61<<16)) // This identifies a PObject derived class
1225 _CrtMemState initialState;
1227 #endif // PMEMORY_CHECK
1250 #define malloc(s) PMemoryHeap::Allocate(s, __FILE__, __LINE__, NULL)
1258 #define calloc(n,s) PMemoryHeap::Allocate(n, s, __FILE__, __LINE__)
1266 #define realloc(p,s) PMemoryHeap::Reallocate(p, s, __FILE__, __LINE__)
1275 #define free(p) PMemoryHeap::Deallocate(p, NULL)
1284 #define cfree(p) PMemoryHeap::Deallocate(p, NULL)
1301 #define PNEW new (__FILE__, __LINE__)
1303 #if !defined(_MSC_VER) || _MSC_VER<1200
1304 #define PSPECIAL_DELETE_FUNCTION
1306 #define PSPECIAL_DELETE_FUNCTION \
1307 void operator delete(void * ptr, const char *, int) \
1308 { PMemoryHeap::Deallocate(ptr, Class()); } \
1309 void operator delete[](void * ptr, const char *, int) \
1310 { PMemoryHeap::Deallocate(ptr, Class()); }
1313 #define PNEW_AND_DELETE_FUNCTIONS \
1314 void * operator new(size_t nSize, const char * file, int line) \
1315 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
1316 void * operator new(size_t nSize) \
1317 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
1318 void operator delete(void * ptr) \
1319 { PMemoryHeap::Deallocate(ptr, Class()); } \
1320 void * operator new(size_t, void * placement) \
1321 { return placement; } \
1322 void operator delete(void *, void *) \
1324 void * operator new[](size_t nSize, const char * file, int line) \
1325 { return PMemoryHeap::Allocate(nSize, file, line, Class()); } \
1326 void * operator new[](size_t nSize) \
1327 { return PMemoryHeap::Allocate(nSize, NULL, 0, Class()); } \
1328 void operator delete[](void * ptr) \
1329 { PMemoryHeap::Deallocate(ptr, Class()); } \
1330 PSPECIAL_DELETE_FUNCTION
1333 inline void *
operator new(
size_t nSize,
const char * file,
int line)
1336 inline void *
operator new[](
size_t nSize,
const char * file,
int line)
1340 void *
operator new(
size_t nSize);
1341 void *
operator new[](
size_t nSize);
1343 void operator delete(
void * ptr);
1344 void operator delete[](
void * ptr);
1346 #if defined(_MSC_VER) && _MSC_VER>=1200
1347 inline void operator delete(
void * ptr,
const char *, int)
1350 inline void operator delete[](
void * ptr,
const char *, int)
1361 PBoolean previousIgnoreAllocations;
1364 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE PMemoryHeapIgnoreAllocationsForScope instance_PMemoryHeapIgnoreAllocationsForScope
1374 #define PMEMORY_ALLOCATION_BREAKPOINT(point) PMemoryAllocationBreakpoint PMemoryAllocationBreakpointInstance(point)
1377 #else // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
1379 #define PMEMORY_HEAP 0
1383 #define PNEW_AND_DELETE_FUNCTIONS
1385 #define runtime_malloc(s) malloc(s)
1386 #define runtime_free(p) free(p)
1388 #define PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE
1389 #define PMEMORY_ALLOCATION_BREAKPOINT(point)
1391 #endif // PMEMORY_CHECK || (defined(_MSC_VER) && defined(_DEBUG))
1407 template <
class Type,
typename GuardType =
unsigned>
1415 static Type * s_pointer;
1416 static GuardType s_guard;
1424 static Type s_instance;
1425 s_pointer = &s_instance;
1427 m_instance = s_pointer;
1431 Type & operator* ()
const {
return *m_instance; }
1440 #include <ext/mt_allocator.h>
1446 template <
bool _Thread>
1447 struct PMemoryPool :
public __gnu_cxx::__pool<_Thread>
1450 : __gnu_cxx::__pool<_Thread>()
1454 PMemoryPool(
const __gnu_cxx::__pool_base::_Tune& t)
1455 : __gnu_cxx::__pool<_Thread>(t)
1462 template <
class Type>
1463 struct PCommonPool :
public __gnu_cxx::__common_pool_policy<PMemoryPool, true>
1469 template <
class Type,
class Pool = PCommonPool<Type> >
1474 #if P_GNU_ALLOCATOR==1
1475 template <
class Type>
1480 #include <ext/bitmap_allocator.h>
1481 template <
class Type>
1489 template <
class Type,
class Pool =
void>
1494 template <
class Type>
1501 #define PDECLARE_POOL_ALLOCATOR() \
1502 void * operator new(size_t nSize); \
1503 void * operator new(size_t nSize, const char * file, int line); \
1504 void operator delete(void * ptr); \
1505 void operator delete(void * ptr, const char *, int)
1507 #define PDEFINE_POOL_ALLOCATOR(cls) \
1508 void * cls::operator new(size_t) { return PFixedPoolAllocator<cls>()->allocate(1); } \
1509 void * cls::operator new(size_t, const char *, int) { return PFixedPoolAllocator<cls>()->allocate(1); } \
1510 void cls::operator delete(void * ptr) { PFixedPoolAllocator<cls>()->deallocate((cls *)ptr, 1); } \
1511 void cls::operator delete(void * ptr, const char *, int) { PFixedPoolAllocator<cls>()->deallocate((cls *)ptr, 1); }
1525 #define PCLASSINFO(cls, par) \
1527 typedef cls P_thisClass; \
1528 static inline const char * Class() \
1530 virtual PBoolean InternalIsDescendant(const char * clsName) const \
1531 { return strcmp(clsName, this->Class()) == 0 || par::InternalIsDescendant(clsName); } \
1532 virtual const char * GetClass(unsigned ancestor = 0) const \
1533 { return ancestor > 0 ? par::GetClass(ancestor-1) : this->Class(); } \
1534 virtual PObject::Comparison CompareObjectMemoryDirect(const PObject & obj) const \
1535 { return PObject::InternalCompareObjectMemoryDirect(this, dynamic_cast<const cls *>(&obj), sizeof(cls)); } \
1536 PNEW_AND_DELETE_FUNCTIONS
1539 #define PCLASSINFO_WITH_CLONE(cls, par) \
1540 PCLASSINFO(cls, par) \
1541 virtual PObject * Clone() const { return new cls(*this); }
1544 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
1545 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
1547 #define PRemoveConst(cls, ptr) (const_cast<cls*>(ptr))
1550 template<
class BaseClass>
inline BaseClass *
PAssertCast(BaseClass * obj,
const char * file,
int line)
1552 #define PDownCast(cls, ptr) PAssertCast<cls>(dynamic_cast<cls*>(ptr),__FILE__,__LINE__)
1554 #define PDownCast(cls, ptr) (dynamic_cast<cls*>(ptr))
1566 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
1567 #ifdef DOC_PLUS_PLUS
1568 } Match previous opening brace in doc++
1591 #endif // PTRACING==2
1619 static inline const char *
Class() {
return "PObject"; }
1633 virtual const char *
GetClass(
unsigned ancestor = 0)
const {
return ancestor > 0 ?
"" : this->
Class(); }
1636 {
return strcmp(cls,
GetClass()) == 0; }
1648 const char * clsName
1791 ) { obj.
PrintOn(strm);
return strm; }
1801 ) { obj.
ReadFrom(strm);
return strm; }
1822 template <
class CLS>
1826 CLS * obj =
dynamic_cast<CLS *
>(clone);
1856 #define PANSI_CHAR 1
1857 #define PLITTLE_ENDIAN 2
1858 #define PBIG_ENDIAN 3
1861 template <
typename type>
1868 __inline
operator type()
const {
return data; }
1877 template <
typename type>
1884 __inline
operator type()
const { type value; ReverseBytes(data, value);
return value; }
1891 static __inline
void ReverseBytes(
const type & src, type & dst)
1893 size_t s =
sizeof(type)-1;
1894 for (
size_t d = 0; d <
sizeof(type); ++d,--s)
1895 ((BYTE *)&dst)[d] = ((
const BYTE *)&src)[s];
1900 #define PCHAR8 PANSI_CHAR
1903 #if PCHAR8==PANSI_CHAR
1911 #if PBYTE_ORDER==PLITTLE_ENDIAN
1913 #elif PBYTE_ORDER==PBIG_ENDIAN
1917 #if PBYTE_ORDER==PLITTLE_ENDIAN
1919 #elif PBYTE_ORDER==PBIG_ENDIAN
1923 #if PBYTE_ORDER==PLITTLE_ENDIAN
1925 #elif PBYTE_ORDER==PBIG_ENDIAN
1929 #if PBYTE_ORDER==PLITTLE_ENDIAN
1931 #elif PBYTE_ORDER==PBIG_ENDIAN
1935 #if PBYTE_ORDER==PLITTLE_ENDIAN
1937 #elif PBYTE_ORDER==PBIG_ENDIAN
1941 #if PBYTE_ORDER==PLITTLE_ENDIAN
1943 #elif PBYTE_ORDER==PBIG_ENDIAN
1947 #if PBYTE_ORDER==PLITTLE_ENDIAN
1949 #elif PBYTE_ORDER==PBIG_ENDIAN
1953 #if PBYTE_ORDER==PLITTLE_ENDIAN
1955 #elif PBYTE_ORDER==PBIG_ENDIAN
1959 #if PBYTE_ORDER==PLITTLE_ENDIAN
1961 #elif PBYTE_ORDER==PBIG_ENDIAN
1965 #if PBYTE_ORDER==PLITTLE_ENDIAN
1967 #elif PBYTE_ORDER==PBIG_ENDIAN
1971 #if PBYTE_ORDER==PLITTLE_ENDIAN
1973 #elif PBYTE_ORDER==PBIG_ENDIAN
1977 #if PBYTE_ORDER==PLITTLE_ENDIAN
1979 #elif PBYTE_ORDER==PBIG_ENDIAN
1983 #if PBYTE_ORDER==PLITTLE_ENDIAN
1985 #elif PBYTE_ORDER==PBIG_ENDIAN
1989 #if PBYTE_ORDER==PLITTLE_ENDIAN
1991 #elif PBYTE_ORDER==PBIG_ENDIAN
1995 #if PBYTE_ORDER==PLITTLE_ENDIAN
1997 #elif PBYTE_ORDER==PBIG_ENDIAN
2001 #if PBYTE_ORDER==PLITTLE_ENDIAN
2003 #elif PBYTE_ORDER==PBIG_ENDIAN
2007 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
2008 #if PBYTE_ORDER==PLITTLE_ENDIAN
2010 #elif PBYTE_ORDER==PBIG_ENDIAN
2014 #if PBYTE_ORDER==PLITTLE_ENDIAN
2016 #elif PBYTE_ORDER==PBIG_ENDIAN
2023 #if defined(_MSC_VER)
2024 #define P_ALIGN_FIELD(fieldType,fieldName,alignment) fieldType __declspec(align(alignment)) fieldName
2025 #elif defined(__GNUC__)
2026 #define P_ALIGN_FIELD(fieldType,fieldName,alignment) fieldType fieldName __attribute__ ((aligned(alignment)))
2038 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
2044 #define PMIN(v1, v2) std::min(v1, v2)
2050 #define PMAX(v1, v2) std::max(v1, v2)
2056 #define PABS(v) std::abs(v)
2059 #endif // PTLIB_OBJECT_H