Group PJSUA2_PERSISTENT

group PJSUA2_PERSISTENT

The persistent API provides functionality to read/write data from/to a document (string or file). The data can be simple data types such as boolean, number, string, and string arrays, or a user defined object. Currently the implementation supports reading and writing from/to JSON document, but the framework allows application to extend the API to support other document formats.

class PersistentObject
#include <persistent.hpp>

This is the abstract base class of objects that can be serialized to/from persistent document.

Subclassed by pj::AccountCallConfig, pj::AccountConfig, pj::AccountMediaConfig, pj::AccountMwiConfig, pj::AccountNatConfig, pj::AccountPresConfig, pj::AccountRegConfig, pj::AccountSipConfig, pj::AccountVideoConfig, pj::AuthCredInfo, pj::BuddyConfig, pj::EpConfig, pj::LogConfig, pj::MediaConfig, pj::RtcpFbConfig, pj::SrtpOpt, pj::TlsConfig, pj::TransportConfig, pj::UaConfig

Public Functions

inline virtual ~PersistentObject()

Virtual destructor

virtual void readObject(const ContainerNode &node) = 0

Read this object from a container node.

Parameters:

node – Container to read values from.

virtual void writeObject(ContainerNode &node) const = 0

Write this object to a container node.

Parameters:

node – Container to write values to.

class PersistentDocument
#include <persistent.hpp>

This a the abstract base class for a persistent document. A document is created either by loading from a string or a file, or by constructing it manually when writing data to it. The document then can be saved to either string or to a file. A document contains one root ContainerNode where all data are stored under.

Document is read and written serially, hence the order of reading must be the same as the order of writing. The PersistentDocument class provides API to read and write to the root node, but for more flexible operations application can use the ContainerNode methods instead. Indeed the read and write API in PersistentDocument is just a shorthand which calls the relevant methods in the ContainerNode. As a tip, normally application only uses the readObject() and writeObject() methods declared here to read/write top level objects, and use the macros that are explained in ContainerNode documentation to read/write more detailed data.

Subclassed by pj::JsonDocument

Public Functions

inline virtual ~PersistentDocument()

Virtual destructor

virtual void loadFile(const string &filename) = 0

Load this document from a file.

Parameters:

filename – The file name.

virtual void loadString(const string &input) = 0

Load this document from string.

Parameters:

input – The string.

virtual void saveFile(const string &filename) = 0

Write this document to a file.

Parameters:

filename – The file name.

virtual string saveString() = 0

Write this document to string.

Returns:

The string document.

virtual ContainerNode &getRootContainer() const = 0

Get the root container node for this document

Returns:

The root node.

bool hasUnread() const

Determine if there is unread element. If yes, then app can use one of the readXxx() functions to read it.

Returns:

True if there is.

string unreadName() const

Get the name of the next unread element. It will throw Error if there is no more element to read.

Returns:

The name of the next element .

int readInt(const string &name = "") const

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.

Parameters:

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.

Returns:

The value.

float readNumber(const string &name = "") const

Read a float 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.

Parameters:

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.

Returns:

The value.

bool readBool(const string &name = "") const

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.

Parameters:

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.

Returns:

The value.

string readString(const string &name = "") const

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.

Parameters:

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.

Returns:

The value.

StringVector readStringVector(const string &name = "") const

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.

Parameters:

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.

Returns:

The value.

void readObject(PersistentObject &obj) const

Read the specified object from the container. This is equal to calling PersistentObject.readObject(ContainerNode);

Parameters:

obj – The object to read.

ContainerNode readContainer(const string &name = "") const

Read a container from the container. This will throw Error if the current element is not an object. The read position will be advanced to the next element.

Parameters:

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.

Returns:

Container object.

ContainerNode readArray(const string &name = "") const

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.

Parameters:

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.

Returns:

Container object.

void writeNumber(const string &name, float num)

Write a number value to the container.

Parameters:
  • name – The name for the value in the container.

  • num – The value to be written.

void writeInt(const string &name, int num)

Write a number value to the container.

Parameters:
  • name – The name for the value in the container.

  • num – The value to be written.

void writeBool(const string &name, bool value)

Write a boolean value to the container.

Parameters:
  • name – The name for the value in the container.

  • value – The value to be written.

void writeString(const string &name, const string &value)

Write a string value to the container.

Parameters:
  • name – The name for the value in the container.

  • value – The value to be written.

void writeStringVector(const string &name, const StringVector &arr)

Write string vector to the container.

Parameters:
  • name – The name for the value in the container.

  • arr – The vector to be written.

void writeObject(const PersistentObject &obj)

Write an object to the container. This is equal to calling PersistentObject.writeObject(ContainerNode);

Parameters:

obj – The object to be written

ContainerNode writeNewContainer(const string &name)

Create and write an empty Object node that can be used as parent for subsequent write operations.

Parameters:

name – The name for the new container in the container.

Returns:

A sub-container.

ContainerNode writeNewArray(const string &name)

Create and write an empty array node that can be used as parent for subsequent write operations.

Parameters:

name – The name for the array.

Returns:

A sub-container.

struct container_node_internal_data
#include <persistent.hpp>

Internal data for ContainerNode. See ContainerNode implementation notes for more info.

Public Members

void *doc

The document.

void *data1

Internal data 1

void *data2

Internal data 2

class ContainerNode
#include <persistent.hpp>

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.

Public Functions

bool hasUnread() const

Determine if there is unread element. If yes, then app can use one of the readXxx() functions to read it.

string unreadName() const

Get the name of the next unread element.

int readInt(const string &name = "") const

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.

Parameters:

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.

Returns:

The value.

float readNumber(const string &name = "") const

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.

Parameters:

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.

Returns:

The value.

bool readBool(const string &name = "") const

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.

Parameters:

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.

Returns:

The value.

string readString(const string &name = "") const

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.

Parameters:

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.

Returns:

The value.

StringVector readStringVector(const string &name = "") const

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.

Parameters:

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.

Returns:

The value.

void readObject(PersistentObject &obj) const

Read the specified object from the container. This is equal to calling PersistentObject.readObject(ContainerNode);

Parameters:

obj – The object to read.

ContainerNode readContainer(const string &name = "") const

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.

Parameters:

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.

Returns:

Container object.

ContainerNode readArray(const string &name = "") const

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.

Parameters:

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.

Returns:

Container object.

void writeNumber(const string &name, float num)

Write a number value to the container.

Parameters:
  • name – The name for the value in the container.

  • num – The value to be written.

void writeInt(const string &name, int num)

Write a number value to the container.

Parameters:
  • name – The name for the value in the container.

  • num – The value to be written.

void writeBool(const string &name, bool value)

Write a boolean value to the container.

Parameters:
  • name – The name for the value in the container.

  • value – The value to be written.

void writeString(const string &name, const string &value)

Write a string value to the container.

Parameters:
  • name – The name for the value in the container.

  • value – The value to be written.

void writeStringVector(const string &name, const StringVector &arr)

Write string vector to the container.

Parameters:
  • name – The name for the value in the container.

  • arr – The vector to be written.

void writeObject(const PersistentObject &obj)

Write an object to the container. This is equal to calling PersistentObject.writeObject(ContainerNode);

Parameters:

obj – The object to be written

ContainerNode writeNewContainer(const string &name)

Create and write an empty Object node that can be used as parent for subsequent write operations.

Parameters:

name – The name for the new container in the container.

Returns:

A sub-container.

ContainerNode writeNewArray(const string &name)

Create and write an empty array node that can be used as parent for subsequent write operations.

Parameters:

name – The name for the array.

Returns:

A sub-container.

Public Members

container_node_op *op

Method table.

container_node_internal_data data

Internal data