Index: pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/persistent.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/persistent.hpp	(revision 4644)
+++ pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/persistent.hpp	(revision 4657)
@@ -334,4 +334,272 @@
 				      throw(Error);
 };
+
+
+/**
+ * Forward declaration of container_node_op.
+ */
+struct container_node_op;
+
+
+/**
+ * Internal data for ContainerNode. See ContainerNode implementation notes
+ * for more info.
+ */
+struct container_node_internal_data
+{
+    void	*doc;
+    void	*data1;
+    void	*data2;
+};
+
+/**
+ * A container node is a placeholder for storing other data elements, which
+ * could be boolean, number, string, array of strings, or another container.
+ * Each data in the container is basically a name/value pair, with a type
+ * internally associated with it so that written data can be read in the
+ * correct type. Data is read and written serially, hence the order of
+ * reading must be the same as the order of writing.
+ *
+ * Application can read data from it by using the various read methods, and
+ * write data to it using the various write methods. Alternatively, it
+ * may be more convenient to use the provided macros below to read and write
+ * the data, because these macros set the name automatically:
+ *	- NODE_READ_BOOL(node,item)
+ *	- NODE_READ_UNSIGNED(node,item)
+ *	- NODE_READ_INT(node,item)
+ *	- NODE_READ_FLOAT(node,item)
+ *	- NODE_READ_NUM_T(node,type,item)
+ *	- NODE_READ_STRING(node,item)
+ *	- NODE_READ_STRINGV(node,item)
+ *	- NODE_READ_OBJ(node,item)
+ *	- NODE_WRITE_BOOL(node,item)
+ *	- NODE_WRITE_UNSIGNED(node,item)
+ *	- NODE_WRITE_INT(node,item)
+ *	- NODE_WRITE_FLOAT(node,item)
+ *	- NODE_WRITE_NUM_T(node,type,item)
+ *	- NODE_WRITE_STRING(node,item)
+ *	- NODE_WRITE_STRINGV(node,item)
+ *	- NODE_WRITE_OBJ(node,item)
+ *
+ * Implementation notes:
+ *
+ * The ContainerNode class is subclass-able, but not in the usual C++ way.
+ * With the usual C++ inheritance, some methods will be made pure virtual
+ * and must be implemented by the actual class. However, doing so will
+ * require dynamic instantiation of the ContainerNode class, which means
+ * we will need to pass around the class as pointer, for example as the
+ * return value of readContainer() and writeNewContainer() methods. Then
+ * we will need to establish who needs or how to delete these objects, or
+ * use shared pointer mechanism, each of which is considered too inconvenient
+ * or complicated for the purpose.
+ *
+ * So hence we use C style "inheritance", where the methods are declared in
+ * container_node_op and the data in container_node_internal_data structures.
+ * An implementation of ContainerNode class will need to set up these members
+ * with values that makes sense to itself. The methods in container_node_op
+ * contains the pointer to the actual implementation of the operation, which
+ * would be specific according to the format of the document. The methods in
+ * this ContainerNode class are just thin wrappers which call the
+ * implementation in the container_node_op structure.
+ *
+ */
+class ContainerNode
+{
+public:
+    /**
+     * Determine if there is unread element. If yes, then app can use one of
+     * the readXxx() functions to read it.
+     */
+    bool		hasUnread() const;
+
+    /**
+     * Get the name of the next unread element.
+     */
+    string		unreadName() const throw(Error);
+
+    /**
+     * Read an integer value from the document and return the value.
+     * This will throw Error if the current element is not a number.
+     * The read position will be advanced to the next element.
+     *
+     * @param name	If specified, then the function will check if the
+     * 			name of the next element matches the specified
+     * 			name and throw Error if it doesn't match.
+     *
+     * @return		The value.
+     */
+    int			readInt(const string &name="") const throw(Error);
+
+    /**
+     * Read a number value from the document and return the value.
+     * This will throw Error if the current element is not a number.
+     * The read position will be advanced to the next element.
+     *
+     * @param name	If specified, then the function will check if the
+     * 			name of the next element matches the specified
+     * 			name and throw Error if it doesn't match.
+     *
+     * @return		The value.
+     */
+    float		readNumber(const string &name="") const throw(Error);
+
+    /**
+     * Read a boolean value from the container and return the value.
+     * This will throw Error if the current element is not a boolean.
+     * The read position will be advanced to the next element.
+     *
+     * @param name	If specified, then the function will check if the
+     * 			name of the next element matches the specified
+     * 			name and throw Error if it doesn't match.
+     *
+     * @return		The value.
+     */
+    bool		readBool(const string &name="") const throw(Error);
+
+    /**
+     * Read a string value from the container and return the value.
+     * This will throw Error if the current element is not a string.
+     * The read position will be advanced to the next element.
+     *
+     * @param name	If specified, then the function will check if the
+     * 			name of the next element matches the specified
+     * 			name and throw Error if it doesn't match.
+     *
+     * @return		The value.
+     */
+    string		readString(const string &name="") const throw(Error);
+
+    /**
+     * Read a string array from the container. This will throw Error
+     * if the current element is not a string array. The read position
+     * will be advanced to the next element.
+     *
+     * @param name	If specified, then the function will check if the
+     * 			name of the next element matches the specified
+     * 			name and throw Error if it doesn't match.
+     *
+     * @return		The value.
+     */
+    StringVector	readStringVector(const string &name="") const
+					 throw(Error);
+
+    /**
+     * Read the specified object from the container. This is equal to
+     * calling PersistentObject.readObject(ContainerNode);
+     *
+     * @param obj	The object to read.
+     */
+    void		readObject(PersistentObject &obj) const throw(Error);
+
+    /**
+     * Read a container from the container. This will throw Error if the
+     * current element is not a container. The read position will be advanced
+     * to the next element.
+     *
+     * @param name	If specified, then the function will check if the
+     * 			name of the next element matches the specified
+     * 			name and throw Error if it doesn't match.
+     *
+     * @return		Container object.
+     */
+    ContainerNode	readContainer(const string &name="") const
+				      throw(Error);
+
+    /**
+     * Read array container from the container. This will throw Error if the
+     * current element is not an array. The read position will be advanced
+     * to the next element.
+     *
+     * @param name	If specified, then the function will check if the
+     * 			name of the next element matches the specified
+     * 			name and throw Error if it doesn't match.
+     *
+     * @return		Container object.
+     */
+    ContainerNode	readArray(const string &name="") const
+				  throw(Error);
+
+    /**
+     * Write a number value to the container.
+     *
+     * @param name	The name for the value in the container.
+     * @param value	The value to be written.
+     */
+    void		writeNumber(const string &name,
+        		            float num) throw(Error);
+
+    /**
+     * Write a number value to the container.
+     *
+     * @param name	The name for the value in the container.
+     * @param value	The value to be written.
+     */
+    void		writeInt(const string &name,
+        		         int num) throw(Error);
+
+    /**
+     * Write a boolean value to the container.
+     *
+     * @param name	The name for the value in the container.
+     * @param value	The value to be written.
+     */
+    void		writeBool(const string &name,
+        		          bool value) throw(Error);
+
+    /**
+     * Write a string value to the container.
+     *
+     * @param name	The name for the value in the container.
+     * @param value	The value to be written.
+     */
+    void		writeString(const string &name,
+        		            const string &value) throw(Error);
+
+    /**
+     * Write string vector to the container.
+     *
+     * @param name	The name for the value in the container.
+     * @param array	The vector to be written.
+     */
+    void		writeStringVector(const string &name,
+        		                  const StringVector &value)
+					  throw(Error);
+
+    /**
+     * Write an object to the container. This is equal to calling
+     * PersistentObject.writeObject(ContainerNode);
+     *
+     * @param obj	The object to be written
+     */
+    void		writeObject(const PersistentObject &obj) throw(Error);
+
+    /**
+     * Create and write an empty Object node that can be used as parent
+     * for subsequent write operations.
+     *
+     * @param name	The name for the new container in the container.
+     *
+     * @return		A sub-container.
+     */
+    ContainerNode 	writeNewContainer(const string &name)
+					  throw(Error);
+
+    /**
+     * Create and write an empty array node that can be used as parent
+     * for subsequent write operations.
+     *
+     * @param name	The name for the array.
+     *
+     * @return		A sub-container.
+     */
+    ContainerNode 	writeNewArray(const string &name)
+				      throw(Error);
+
+public:
+    /* internal data */
+    container_node_op *op;
+    container_node_internal_data data;
+};
+
 
 /**
@@ -387,263 +655,4 @@
 };
 
-/**
- * Internal data for ContainerNode. See ContainerNode implementation notes
- * for more info.
- */
-struct container_node_internal_data
-{
-    void	*doc;
-    void	*data1;
-    void	*data2;
-};
-
-/**
- * A container node is a placeholder for storing other data elements, which
- * could be boolean, number, string, array of strings, or another container.
- * Each data in the container is basically a name/value pair, with a type
- * internally associated with it so that written data can be read in the
- * correct type. Data is read and written serially, hence the order of
- * reading must be the same as the order of writing.
- *
- * Application can read data from it by using the various read methods, and
- * write data to it using the various write methods. Alternatively, it
- * may be more convenient to use the provided macros below to read and write
- * the data, because these macros set the name automatically:
- *	- NODE_READ_BOOL(node,item)
- *	- NODE_READ_UNSIGNED(node,item)
- *	- NODE_READ_INT(node,item)
- *	- NODE_READ_FLOAT(node,item)
- *	- NODE_READ_NUM_T(node,type,item)
- *	- NODE_READ_STRING(node,item)
- *	- NODE_READ_STRINGV(node,item)
- *	- NODE_READ_OBJ(node,item)
- *	- NODE_WRITE_BOOL(node,item)
- *	- NODE_WRITE_UNSIGNED(node,item)
- *	- NODE_WRITE_INT(node,item)
- *	- NODE_WRITE_FLOAT(node,item)
- *	- NODE_WRITE_NUM_T(node,type,item)
- *	- NODE_WRITE_STRING(node,item)
- *	- NODE_WRITE_STRINGV(node,item)
- *	- NODE_WRITE_OBJ(node,item)
- *
- * Implementation notes:
- *
- * The ContainerNode class is subclass-able, but not in the usual C++ way.
- * With the usual C++ inheritance, some methods will be made pure virtual
- * and must be implemented by the actual class. However, doing so will
- * require dynamic instantiation of the ContainerNode class, which means
- * we will need to pass around the class as pointer, for example as the
- * return value of readContainer() and writeNewContainer() methods. Then
- * we will need to establish who needs or how to delete these objects, or
- * use shared pointer mechanism, each of which is considered too inconvenient
- * or complicated for the purpose.
- *
- * So hence we use C style "inheritance", where the methods are declared in
- * container_node_op and the data in container_node_internal_data structures.
- * An implementation of ContainerNode class will need to set up these members
- * with values that makes sense to itself. The methods in container_node_op
- * contains the pointer to the actual implementation of the operation, which
- * would be specific according to the format of the document. The methods in
- * this ContainerNode class are just thin wrappers which call the
- * implementation in the container_node_op structure.
- *
- */
-class ContainerNode
-{
-public:
-    /**
-     * Determine if there is unread element. If yes, then app can use one of
-     * the readXxx() functions to read it.
-     */
-    bool		hasUnread() const;
-
-    /**
-     * Get the name of the next unread element.
-     */
-    string		unreadName() const throw(Error);
-
-    /**
-     * Read an integer value from the document and return the value.
-     * This will throw Error if the current element is not a number.
-     * The read position will be advanced to the next element.
-     *
-     * @param name	If specified, then the function will check if the
-     * 			name of the next element matches the specified
-     * 			name and throw Error if it doesn't match.
-     *
-     * @return		The value.
-     */
-    int			readInt(const string &name="") const throw(Error);
-
-    /**
-     * Read a number value from the document and return the value.
-     * This will throw Error if the current element is not a number.
-     * The read position will be advanced to the next element.
-     *
-     * @param name	If specified, then the function will check if the
-     * 			name of the next element matches the specified
-     * 			name and throw Error if it doesn't match.
-     *
-     * @return		The value.
-     */
-    float		readNumber(const string &name="") const throw(Error);
-
-    /**
-     * Read a boolean value from the container and return the value.
-     * This will throw Error if the current element is not a boolean.
-     * The read position will be advanced to the next element.
-     *
-     * @param name	If specified, then the function will check if the
-     * 			name of the next element matches the specified
-     * 			name and throw Error if it doesn't match.
-     *
-     * @return		The value.
-     */
-    bool		readBool(const string &name="") const throw(Error);
-
-    /**
-     * Read a string value from the container and return the value.
-     * This will throw Error if the current element is not a string.
-     * The read position will be advanced to the next element.
-     *
-     * @param name	If specified, then the function will check if the
-     * 			name of the next element matches the specified
-     * 			name and throw Error if it doesn't match.
-     *
-     * @return		The value.
-     */
-    string		readString(const string &name="") const throw(Error);
-
-    /**
-     * Read a string array from the container. This will throw Error
-     * if the current element is not a string array. The read position
-     * will be advanced to the next element.
-     *
-     * @param name	If specified, then the function will check if the
-     * 			name of the next element matches the specified
-     * 			name and throw Error if it doesn't match.
-     *
-     * @return		The value.
-     */
-    StringVector	readStringVector(const string &name="") const
-					 throw(Error);
-
-    /**
-     * Read the specified object from the container. This is equal to
-     * calling PersistentObject.readObject(ContainerNode);
-     *
-     * @param obj	The object to read.
-     */
-    void		readObject(PersistentObject &obj) const throw(Error);
-
-    /**
-     * Read a container from the container. This will throw Error if the
-     * current element is not a container. The read position will be advanced
-     * to the next element.
-     *
-     * @param name	If specified, then the function will check if the
-     * 			name of the next element matches the specified
-     * 			name and throw Error if it doesn't match.
-     *
-     * @return		Container object.
-     */
-    ContainerNode	readContainer(const string &name="") const
-				      throw(Error);
-
-    /**
-     * Read array container from the container. This will throw Error if the
-     * current element is not an array. The read position will be advanced
-     * to the next element.
-     *
-     * @param name	If specified, then the function will check if the
-     * 			name of the next element matches the specified
-     * 			name and throw Error if it doesn't match.
-     *
-     * @return		Container object.
-     */
-    ContainerNode	readArray(const string &name="") const
-				  throw(Error);
-
-    /**
-     * Write a number value to the container.
-     *
-     * @param name	The name for the value in the container.
-     * @param value	The value to be written.
-     */
-    void		writeNumber(const string &name,
-        		            float num) throw(Error);
-
-    /**
-     * Write a number value to the container.
-     *
-     * @param name	The name for the value in the container.
-     * @param value	The value to be written.
-     */
-    void		writeInt(const string &name,
-        		         int num) throw(Error);
-
-    /**
-     * Write a boolean value to the container.
-     *
-     * @param name	The name for the value in the container.
-     * @param value	The value to be written.
-     */
-    void		writeBool(const string &name,
-        		          bool value) throw(Error);
-
-    /**
-     * Write a string value to the container.
-     *
-     * @param name	The name for the value in the container.
-     * @param value	The value to be written.
-     */
-    void		writeString(const string &name,
-        		            const string &value) throw(Error);
-
-    /**
-     * Write string vector to the container.
-     *
-     * @param name	The name for the value in the container.
-     * @param array	The vector to be written.
-     */
-    void		writeStringVector(const string &name,
-        		                  const StringVector &value)
-					  throw(Error);
-
-    /**
-     * Write an object to the container. This is equal to calling
-     * PersistentObject.writeObject(ContainerNode);
-     *
-     * @param obj	The object to be written
-     */
-    void		writeObject(const PersistentObject &obj) throw(Error);
-
-    /**
-     * Create and write an empty Object node that can be used as parent
-     * for subsequent write operations.
-     *
-     * @param name	The name for the new container in the container.
-     *
-     * @return		A sub-container.
-     */
-    ContainerNode 	writeNewContainer(const string &name)
-					  throw(Error);
-
-    /**
-     * Create and write an empty array node that can be used as parent
-     * for subsequent write operations.
-     *
-     * @param name	The name for the array.
-     *
-     * @return		A sub-container.
-     */
-    ContainerNode 	writeNewArray(const string &name)
-				      throw(Error);
-
-public:
-    /* internal data */
-    container_node_op *op;
-    container_node_internal_data data;
-};
 
 /*
@@ -660,7 +669,7 @@
 
 #define NODE_WRITE_BOOL(node,item)	node.writeBool(#item, item)
-#define NODE_WRITE_UNSIGNED(node,item)	node.writeNumber(#item, item)
-#define NODE_WRITE_INT(node,item)	node.writeNumber(#item, item)
-#define NODE_WRITE_NUM_T(node,T,item)	node.writeNumber(#item, (int)item)
+#define NODE_WRITE_UNSIGNED(node,item)	node.writeNumber(#item, (float)item)
+#define NODE_WRITE_INT(node,item)	node.writeNumber(#item, (float)item)
+#define NODE_WRITE_NUM_T(node,T,item)	node.writeNumber(#item, (float)item)
 #define NODE_WRITE_FLOAT(node,item)	node.writeNumber(#item, item)
 #define NODE_WRITE_STRING(node,item)	node.writeString(#item, item)
