Main Page | Modules | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

XML Library Functions
[Core Library]


Data Structures

struct  switch_xml
 A representation of an XML tree. More...

Defines

#define SWITCH_XML_BUFSIZE   1024
#define switch_xml_next(xml)   ((xml) ? xml->next : NULL)
 returns the next tag of the same name in the same section and depth or NULL \ if not found
#define switch_xml_name(xml)   ((xml) ? xml->name : NULL)
 returns the name of the given tag
#define switch_xml_txt(xml)   ((xml) ? xml->txt : "")
 returns the given tag's character content or empty string if none
#define switch_xml_new_d(name)   switch_xml_set_flag(switch_xml_new(strdup(name)), SWITCH_XML_NAMEM)
 wrapper for switch_xml_new() that strdup()s name
#define switch_xml_add_child_d(xml, name, off)   switch_xml_set_flag(switch_xml_add_child(xml, strdup(name), off), SWITCH_XML_NAMEM)
 wrapper for switch_xml_add_child() that strdup()s name
#define switch_xml_set_txt_d(xml, txt)   switch_xml_set_flag(switch_xml_set_txt(xml, strdup(txt)), SWITCH_XML_TXTM)
 wrapper for switch_xml_set_txt() that strdup()s txt \ sets the character content for the given tag and returns the tag
#define switch_xml_set_attr_d(xml, name, value)   switch_xml_set_attr(switch_xml_set_flag(xml, SWITCH_XML_DUP), strdup(name), strdup(switch_str_nil(value)))
 Wrapper for switch_xml_set_attr() that strdup()s name/value. Value cannot be NULL.
#define switch_xml_set_attr_d_buf(xml, name, value)   switch_xml_set_attr(switch_xml_set_flag(xml, SWITCH_XML_DUP), strdup(name), strdup(value))
#define switch_xml_move(xml, dest, off)   switch_xml_insert(switch_xml_cut(xml), dest, off)
 Moves an existing tag to become a subtag of dest at the given offset from \ the start of dest's character content. Returns the moved tag.
#define switch_xml_remove(xml)   switch_xml_free(switch_xml_cut(xml))
 removes a tag along with all its subtags

Enumerations

enum  switch_xml_flag_t { SWITCH_XML_ROOT = (1 << 0), SWITCH_XML_NAMEM = (1 << 1), SWITCH_XML_TXTM = (1 << 2), SWITCH_XML_DUP = (1 << 3) }

Functions

switch_xml_t switch_xml_parse_str (char *s, switch_size_t len)
 Given a string of xml data and its length, parses it and creates an switch_xml \ structure. For efficiency, modifies the data by adding null terminators \ and decoding ampersand sequences. If you don't want this, copy the data and \ pass in the copy. Returns NULL on failure.
switch_xml_t switch_xml_parse_fd (int fd)
 A wrapper for switch_xml_parse_str() that accepts a file descriptor. First \ attempts to mem map the file. Failing that, reads the file into memory. \ Returns NULL on failure.
switch_xml_t switch_xml_parse_file (const char *file)
 a wrapper for switch_xml_parse_fd() that accepts a file name
switch_xml_t switch_xml_parse_file_simple (const char *file)
switch_xml_t switch_xml_parse_fp (FILE *fp)
 Wrapper for switch_xml_parse_str() that accepts a file stream. Reads the entire \ stream into memory and then parses it. For xml files, use switch_xml_parse_file() \ or switch_xml_parse_fd().
switch_xml_t switch_xml_child (switch_xml_t xml, const char *name)
 returns the first child tag (one level deeper) with the given name or NULL \ if not found
switch_xml_t switch_xml_find_child (switch_xml_t node, const char *childname, const char *attrname, const char *value)
 find a child tag in a node called 'childname' with an attribute 'attrname' which equals 'value'
switch_xml_t switch_xml_idx (switch_xml_t xml, int idx)
 Returns the Nth tag with the same name in the same section at the same depth \ or NULL if not found. An index of 0 returns the tag given.
const char * switch_xml_attr (switch_xml_t xml, const char *attr)
 returns the value of the requested tag attribute, or NULL if not found
const char * switch_xml_attr_soft (switch_xml_t xml, const char *attr)
 returns the value of the requested tag attribute, or "" if not found
switch_xml_t switch_xml_get (switch_xml_t xml,...)
 Traverses the switch_xml sturcture to retrieve a specific subtag. Takes a \ variable length list of tag names and indexes. The argument list must be \ terminated by either an index of -1 or an empty string tag name. Example: \ title = switch_xml_get(library, "shelf", 0, "book", 2, "title", -1); \ This retrieves the title of the 3rd book on the 1st shelf of library. \ Returns NULL if not found.
char * switch_xml_toxml (switch_xml_t xml, switch_bool_t prn_header)
 Converts an switch_xml structure back to xml. Returns a string of xml data that \ must be freed.
char * switch_xml_toxml_buf (switch_xml_t xml, char *buf, switch_size_t buflen, switch_size_t offset, switch_bool_t prn_header)
 Converts an switch_xml structure back to xml using the buffer passed in the parameters.
const char ** switch_xml_pi (switch_xml_t xml, const char *target)
 returns a NULL terminated array of processing instructions for the given \ target
void switch_xml_free (switch_xml_t xml)
 frees the memory allocated for an switch_xml structure
void switch_xml_free_in_thread (switch_xml_t xml, int stacksize)
const char * switch_xml_error (switch_xml_t xml)
 returns parser error message or empty string if none
switch_xml_t switch_xml_new (const char *name)
 returns a new empty switch_xml structure with the given root tag name
switch_xml_t switch_xml_add_child (switch_xml_t xml, const char *name, switch_size_t off)
 Adds a child tag. off is the offset of the child tag relative to the start \ of the parent tag's character content. Returns the child tag.
switch_xml_t switch_xml_set_txt (switch_xml_t xml, const char *txt)
 sets the character content for the given tag and returns the tag
switch_xml_t switch_xml_set_attr (switch_xml_t xml, const char *name, const char *value)
 Sets the given tag attribute or adds a new attribute if not found. A value \ of NULL will remove the specified attribute.
switch_xml_t switch_xml_set_flag (switch_xml_t xml, switch_xml_flag_t flag)
 sets a flag for the given tag and returns the tag
switch_xml_t switch_xml_cut (switch_xml_t xml)
 removes a tag along with its subtags without freeing its memory
switch_xml_t switch_xml_insert (switch_xml_t xml, switch_xml_t dest, switch_size_t off)
 inserts an existing tag into an ezxml structure
switch_xml_t switch_xml_open_root (uint8_t reload, const char **err)
 open the Core xml root
switch_status_t switch_xml_init (switch_memory_pool_t *pool, const char **err)
 initilize the core XML backend
switch_status_t switch_xml_destroy (void)
switch_xml_t switch_xml_root (void)
 retrieve the core XML root node
switch_status_t switch_xml_locate (const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_xml_t *root, switch_xml_t *node, switch_event_t *params)
 locate an xml pointer in the core registry
switch_status_t switch_xml_locate_domain (const char *domain_name, switch_event_t *params, switch_xml_t *root, switch_xml_t *domain)
switch_status_t switch_xml_locate_user (const char *key, const char *user_name, const char *domain_name, const char *ip, switch_xml_t *root, switch_xml_t *domain, switch_xml_t *user, switch_event_t *params)
switch_xml_t switch_xml_open_cfg (const char *file_path, switch_xml_t *node, switch_event_t *params)
 open a config in the core registry
switch_status_t switch_xml_bind_search_function (switch_xml_search_function_t function, switch_xml_section_t sections, void *user_data)
 bind a search function to an external gateway
switch_status_t switch_xml_unbind_search_function (switch_xml_binding_t **binding)
switch_status_t switch_xml_unbind_search_function_ptr (switch_xml_search_function_t function)
switch_xml_section_t switch_xml_parse_section_string (const char *str)
 parse a string for a list of sections


Define Documentation

#define switch_xml_add_child_d xml,
name,
off   )     switch_xml_set_flag(switch_xml_add_child(xml, strdup(name), off), SWITCH_XML_NAMEM)
 

wrapper for switch_xml_add_child() that strdup()s name

Parameters:
xml the xml node
name the name of the child
off the offset

#define SWITCH_XML_BUFSIZE   1024
 

#define switch_xml_move xml,
dest,
off   )     switch_xml_insert(switch_xml_cut(xml), dest, off)
 

Moves an existing tag to become a subtag of dest at the given offset from \ the start of dest's character content. Returns the moved tag.

#define switch_xml_name xml   )     ((xml) ? xml->name : NULL)
 

returns the name of the given tag

Parameters:
xml the xml node
Returns:
the name

#define switch_xml_new_d name   )     switch_xml_set_flag(switch_xml_new(strdup(name)), SWITCH_XML_NAMEM)
 

wrapper for switch_xml_new() that strdup()s name

Parameters:
name the name of the root
Returns:
an xml node or NULL

#define switch_xml_next xml   )     ((xml) ? xml->next : NULL)
 

returns the next tag of the same name in the same section and depth or NULL \ if not found

Parameters:
xml an xml node
Returns:
an xml node or NULL

#define switch_xml_remove xml   )     switch_xml_free(switch_xml_cut(xml))
 

removes a tag along with all its subtags

#define switch_xml_set_attr_d xml,
name,
value   )     switch_xml_set_attr(switch_xml_set_flag(xml, SWITCH_XML_DUP), strdup(name), strdup(switch_str_nil(value)))
 

Wrapper for switch_xml_set_attr() that strdup()s name/value. Value cannot be NULL.

Parameters:
xml the xml node
name the attribute name
value the attribute value
Returns:
an xml node or NULL

#define switch_xml_set_attr_d_buf xml,
name,
value   )     switch_xml_set_attr(switch_xml_set_flag(xml, SWITCH_XML_DUP), strdup(name), strdup(value))
 

#define switch_xml_set_txt_d xml,
txt   )     switch_xml_set_flag(switch_xml_set_txt(xml, strdup(txt)), SWITCH_XML_TXTM)
 

wrapper for switch_xml_set_txt() that strdup()s txt \ sets the character content for the given tag and returns the tag

Parameters:
xml the xml node
txt the text
Returns:
an xml node or NULL

#define switch_xml_txt xml   )     ((xml) ? xml->txt : "")
 

returns the given tag's character content or empty string if none

Parameters:
xml the xml node
Returns:
the content


Enumeration Type Documentation

enum switch_xml_flag_t
 

Enumeration values:
SWITCH_XML_ROOT 
SWITCH_XML_NAMEM 
SWITCH_XML_TXTM 
SWITCH_XML_DUP 
00068                      {
00069         SWITCH_XML_ROOT = (1 << 0),     // root
00070         SWITCH_XML_NAMEM = (1 << 1),    // name is malloced
00071         SWITCH_XML_TXTM = (1 << 2),     // txt is malloced
00072         SWITCH_XML_DUP = (1 << 3)       // attribute name and value are strduped
00073 } switch_xml_flag_t;


Function Documentation

switch_xml_t switch_xml_add_child switch_xml_t  xml,
const char *  name,
switch_size_t  off
 

Adds a child tag. off is the offset of the child tag relative to the start \ of the parent tag's character content. Returns the child tag.

Parameters:
xml the xml node
name the name of the tag
off the offset
Returns:
an xml node or NULL
02065 {
02066         switch_xml_t child;
02067 
02068         if (!xml)
02069                 return NULL;
02070         child = (switch_xml_t) memset(malloc(sizeof(struct switch_xml)), '\0', sizeof(struct switch_xml));
02071         child->name = (char *) name;
02072         child->attr = SWITCH_XML_NIL;
02073         child->off = off;
02074         child->parent = xml;
02075         child->txt = (char *)"";
02076 
02077         return switch_xml_insert(child, xml, off);
02078 }

Here is the call graph for this function:

const char* switch_xml_attr switch_xml_t  xml,
const char *  attr
 

returns the value of the requested tag attribute, or NULL if not found

Parameters:
xml the xml node
attr the attribute
Returns:
the value
00304 {
00305         int i = 0, j = 1;
00306         switch_xml_root_t root = (switch_xml_root_t) xml;
00307 
00308         if (!xml || !xml->attr)
00309                 return NULL;
00310         while (xml->attr[i] && strcmp(attr, xml->attr[i]))
00311                 i += 2;
00312         if (xml->attr[i])
00313                 return xml->attr[i + 1];        // found attribute
00314 
00315         while (root->xml.parent)
00316                 root = (switch_xml_root_t) root->xml.parent;    // root tag
00317         for (i = 0; root->attr[i] && strcmp(xml->name, root->attr[i][0]); i++);
00318         if (!root->attr[i])
00319                 return NULL;                    // no matching default attributes
00320         while (root->attr[i][j] && strcmp(attr, root->attr[i][j]))
00321                 j += 3;
00322         return (root->attr[i][j]) ? root->attr[i][j + 1] : NULL;        // found default
00323 }

const char* switch_xml_attr_soft switch_xml_t  xml,
const char *  attr
 

returns the value of the requested tag attribute, or "" if not found

Parameters:
xml the xml node
attr the attribute
Returns:
the value
00296 {
00297         const char *ret = switch_xml_attr(xml, attr);
00298 
00299         return ret ? ret : "";
00300 }

Here is the call graph for this function:

switch_status_t switch_xml_bind_search_function switch_xml_search_function_t  function,
switch_xml_section_t  sections,
void *  user_data
 

bind a search function to an external gateway

Parameters:
function the search function to bind
sections a bitmask of sections you wil service
user_data a pointer to private data to be used during the callback
Returns:
SWITCH_STATUS_SUCCESS if successful
Note:
gateway functions will be executed in the order they were binded until a success is found else the root registry will be used
00233 {
00234         switch_xml_binding_t *binding = NULL, *ptr = NULL;
00235         assert(function != NULL);
00236 
00237         if (!(binding = (switch_xml_binding_t *) switch_core_alloc(XML_MEMORY_POOL, sizeof(*binding)))) {
00238                 return SWITCH_STATUS_MEMERR;
00239         }
00240 
00241         binding->function = function;
00242         binding->sections = sections;
00243         binding->user_data = user_data;
00244 
00245         switch_thread_rwlock_wrlock(B_RWLOCK);
00246         for (ptr = BINDINGS; ptr && ptr->next; ptr = ptr->next);
00247 
00248         if (ptr) {
00249                 ptr->next = binding;
00250         } else {
00251                 BINDINGS = binding;
00252         }
00253         switch_thread_rwlock_unlock(B_RWLOCK);
00254 
00255         return SWITCH_STATUS_SUCCESS;
00256 }

Here is the call graph for this function:

switch_xml_t switch_xml_child switch_xml_t  xml,
const char *  name
 

returns the first child tag (one level deeper) with the given name or NULL \ if not found

Parameters:
xml an xml node
name the name of the child tag
Returns:
an xml node or NULL
00278 {
00279         xml = (xml) ? xml->child : NULL;
00280         while (xml && strcmp(name, xml->name))
00281                 xml = xml->sibling;
00282         return xml;
00283 }

switch_xml_t switch_xml_cut switch_xml_t  xml  ) 
 

removes a tag along with its subtags without freeing its memory

Parameters:
xml the xml node
02159 {
02160         switch_xml_t cur;
02161 
02162         if (!xml)
02163                 return NULL;                    // nothing to do
02164         if (xml->next)
02165                 xml->next->sibling = xml->sibling;      // patch sibling list
02166 
02167         if (xml->parent) {                      // not root tag
02168                 cur = xml->parent->child;       // find head of subtag list
02169                 if (cur == xml)
02170                         xml->parent->child = xml->ordered;      // first subtag
02171                 else {                                  // not first subtag
02172                         while (cur->ordered != xml)
02173                                 cur = cur->ordered;
02174                         cur->ordered = cur->ordered->ordered;   // patch ordered list
02175 
02176                         cur = xml->parent->child;       // go back to head of subtag list
02177                         if (strcmp(cur->name, xml->name)) {     // not in first sibling list
02178                                 while (strcmp(cur->sibling->name, xml->name))
02179                                         cur = cur->sibling;
02180                                 if (cur->sibling == xml) {      // first of a sibling list
02181                                         cur->sibling = (xml->next) ? xml->next : cur->sibling->sibling;
02182                                 } else
02183                                         cur = cur->sibling;     // not first of a sibling list
02184                         }
02185 
02186                         while (cur->next && cur->next != xml)
02187                                 cur = cur->next;
02188                         if (cur->next)
02189                                 cur->next = cur->next->next;    // patch next list
02190                 }
02191         }
02192         xml->ordered = xml->sibling = xml->next = NULL; // prevent switch_xml_free() from clobbering ordered list
02193         return xml;
02194 }

switch_status_t switch_xml_destroy void   ) 
 

01655 {
01656         if (MAIN_XML_ROOT) {
01657                 switch_xml_t xml = MAIN_XML_ROOT;
01658                 MAIN_XML_ROOT = NULL;
01659                 switch_xml_free(xml);
01660                 return SWITCH_STATUS_SUCCESS;
01661         }
01662 
01663         return SWITCH_STATUS_FALSE;
01664 }

Here is the call graph for this function:

const char* switch_xml_error switch_xml_t  xml  ) 
 

returns parser error message or empty string if none

Parameters:
xml the xml node
Returns:
the error string or nothing
02000 {
02001         while (xml && xml->parent)
02002                 xml = xml->parent;              // find root tag
02003         return (xml) ? ((switch_xml_root_t) xml)->err : "";
02004 }

switch_xml_t switch_xml_find_child switch_xml_t  node,
const char *  childname,
const char *  attrname,
const char *  value
 

find a child tag in a node called 'childname' with an attribute 'attrname' which equals 'value'

Parameters:
node the xml node
childname the child tag name
attrname the attribute name
value the value
Returns:
an xml node or NULL
00259 {
00260         switch_xml_t p = NULL;
00261 
00262         if (!(childname && attrname && value)) {
00263                 return node;
00264         }
00265 
00266         for (p = switch_xml_child(node, childname); p; p = p->next) {
00267                 const char *aname = switch_xml_attr(p, attrname);
00268                 if (aname && value && !strcasecmp(aname, value)) {
00269                         break;
00270                 }
00271         }
00272 
00273         return p;
00274 }

Here is the call graph for this function:

void switch_xml_free switch_xml_t  xml  ) 
 

frees the memory allocated for an switch_xml structure

Parameters:
xml the xml node
Note:
in the case of the root node the readlock will be lifted
01923 {
01924         switch_xml_root_t root = (switch_xml_root_t) xml;
01925         int i, j;
01926         char **a, *s;
01927 
01928 
01929         if (!xml)
01930                 return;
01931 
01932         if (switch_test_flag(xml, SWITCH_XML_ROOT)) {
01933                 switch_mutex_lock(XML_COUNT_LOCK);
01934                 if (lock_count > 0) {
01935                         switch_thread_rwlock_unlock(RWLOCK);
01936                         lock_count--;
01937                 }
01938                 switch_mutex_unlock(XML_COUNT_LOCK);
01939         }
01940 
01941         if (xml == MAIN_XML_ROOT) {
01942                 return;
01943         }
01944 
01945         if (xml->free_path) {
01946                 if (!switch_stristr("freeswitch.xml.fsxml", xml->free_path)) {
01947                         if (unlink(xml->free_path) != 0) {
01948                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "failed to delete file [%s]\n", xml->free_path);
01949                         }
01950                 }
01951                 switch_safe_free(xml->free_path);
01952         }
01953 
01954         switch_xml_free(xml->child);
01955         switch_xml_free(xml->ordered);
01956 
01957         if (!xml->parent) {                     // free root tag allocations
01958                 for (i = 10; root->ent[i]; i += 2)      // 0 - 9 are default entities (<>&"')
01959                         if ((s = root->ent[i + 1]) < root->s || s > root->e)
01960                                 free(s);
01961                 free(root->ent);                // free list of general entities
01962 
01963                 for (i = 0; (a = root->attr[i]); i++) {
01964                         for (j = 1; a[j++]; j += 2)     // free malloced attribute values
01965                                 if (a[j] && (a[j] < root->s || a[j] > root->e))
01966                                         free(a[j]);
01967                         free(a);
01968                 }
01969                 if (root->attr[0])
01970                         free(root->attr);       // free default attribute list
01971 
01972                 for (i = 0; root->pi[i]; i++) {
01973                         for (j = 1; root->pi[i][j]; j++);
01974                         free(root->pi[i][j + 1]);
01975                         free(root->pi[i]);
01976                 }
01977                 if (root->pi[0])
01978                         free(root->pi);         // free processing instructions
01979 
01980                 if (root->dynamic == 1)
01981                         free(root->m);          // malloced xml data
01982 #ifdef HAVE_MMAP
01983                 else if (root->len)
01984                         munmap(root->m, root->len);     // mem mapped xml data
01985 #endif // HAVE_MMAP
01986                 if (root->u)
01987                         free(root->u);          // utf8 conversion
01988         }
01989 
01990         switch_xml_free_attr(xml->attr);        // tag attributes
01991         if ((xml->flags & SWITCH_XML_TXTM))
01992                 free(xml->txt);                 // character content
01993         if ((xml->flags & SWITCH_XML_NAMEM))
01994                 free(xml->name);                // tag name
01995         free(xml);
01996 }

Here is the call graph for this function:

void switch_xml_free_in_thread switch_xml_t  xml,
int  stacksize
 

01550 {
01551         switch_thread_t *thread;
01552     switch_threadattr_t *thd_attr;
01553         switch_memory_pool_t *pool = NULL;
01554         struct destroy_xml *dx;
01555 
01556         switch_core_new_memory_pool(&pool);
01557 
01558         switch_threadattr_create(&thd_attr, pool);
01559     switch_threadattr_detach_set(thd_attr, 1);
01560         // TBD figure out how much space we need by looking at the xml_t when stacksize == 0
01561     switch_threadattr_stacksize_set(thd_attr, stacksize);
01562 
01563         dx = switch_core_alloc(pool, sizeof(*dx));
01564         dx->pool = pool;
01565         dx->xml = xml;
01566 
01567         switch_thread_create(&thread, thd_attr, destroy_thread, dx, pool);
01568 
01569 }

Here is the call graph for this function:

switch_xml_t switch_xml_get switch_xml_t  xml,
  ...
 

Traverses the switch_xml sturcture to retrieve a specific subtag. Takes a \ variable length list of tag names and indexes. The argument list must be \ terminated by either an index of -1 or an empty string tag name. Example: \ title = switch_xml_get(library, "shelf", 0, "book", 2, "title", -1); \ This retrieves the title of the 3rd book on the 1st shelf of library. \ Returns NULL if not found.

Parameters:
xml the xml node
Returns:
an xml node or NULL
00345 {
00346         va_list ap;
00347         switch_xml_t r;
00348 
00349         va_start(ap, xml);
00350         r = switch_xml_vget(xml, ap);
00351         va_end(ap);
00352         return r;
00353 }

switch_xml_t switch_xml_idx switch_xml_t  xml,
int  idx
 

Returns the Nth tag with the same name in the same section at the same depth \ or NULL if not found. An index of 0 returns the tag given.

Parameters:
xml the xml node
idx the index
Returns:
an xml node or NULL
00288 {
00289         for (; xml && idx; idx--)
00290                 xml = xml->next;
00291         return xml;
00292 }

switch_status_t switch_xml_init switch_memory_pool_t pool,
const char **  err
 

initilize the core XML backend

Parameters:
pool a memory pool to use
err a pointer to set error strings
Returns:
SWITCH_STATUS_SUCCESS if successful
01634 {
01635         switch_xml_t xml;
01636         XML_MEMORY_POOL = pool;
01637         *err = "Success";
01638 
01639         switch_mutex_init(&XML_LOCK, SWITCH_MUTEX_NESTED, XML_MEMORY_POOL);
01640         switch_mutex_init(&XML_COUNT_LOCK, SWITCH_MUTEX_NESTED, XML_MEMORY_POOL);
01641         switch_thread_rwlock_create(&RWLOCK, XML_MEMORY_POOL);
01642         switch_thread_rwlock_create(&B_RWLOCK, XML_MEMORY_POOL);
01643 
01644         assert(pool != NULL);
01645 
01646         if ((xml = switch_xml_open_root(FALSE, err))) {
01647                 switch_xml_free(xml);
01648                 return SWITCH_STATUS_SUCCESS;
01649         } else {
01650                 return SWITCH_STATUS_FALSE;
01651         }
01652 }

Here is the call graph for this function:

switch_xml_t switch_xml_insert switch_xml_t  xml,
switch_xml_t  dest,
switch_size_t  off
 

inserts an existing tag into an ezxml structure

02024 {
02025         switch_xml_t cur, prev, head;
02026 
02027         xml->next = xml->sibling = xml->ordered = NULL;
02028         xml->off = off;
02029         xml->parent = dest;
02030 
02031         if ((head = dest->child)) {     // already have sub tags
02032                 if (head->off <= off) { // not first subtag
02033                         for (cur = head; cur->ordered && cur->ordered->off <= off; cur = cur->ordered);
02034                         xml->ordered = cur->ordered;
02035                         cur->ordered = xml;
02036                 } else {                                // first subtag
02037                         xml->ordered = head;
02038                         dest->child = xml;
02039                 }
02040 
02041                 for (cur = head, prev = NULL; cur && strcmp(cur->name, xml->name); prev = cur, cur = cur->sibling);     // find tag type
02042                 if (cur && cur->off <= off) {   // not first of type
02043                         while (cur->next && cur->next->off <= off)
02044                                 cur = cur->next;
02045                         xml->next = cur->next;
02046                         cur->next = xml;
02047                 } else {                                // first tag of this type
02048                         if (prev && cur)
02049                                 prev->sibling = cur->sibling;   // remove old first
02050                         xml->next = cur;        // old first tag is now next
02051                         for (cur = head, prev = NULL; cur && cur->off <= off; prev = cur, cur = cur->sibling);  // new sibling insert point
02052                         xml->sibling = cur;
02053                         if (prev)
02054                                 prev->sibling = xml;
02055                 }
02056         } else
02057                 dest->child = xml;              // only sub tag
02058 
02059         return xml;
02060 }

switch_status_t switch_xml_locate const char *  section,
const char *  tag_name,
const char *  key_name,
const char *  key_value,
switch_xml_t root,
switch_xml_t node,
switch_event_t params
 

locate an xml pointer in the core registry

Parameters:
section the section to look in
tag_name the type of tag in that section
key_name the name of the key
key_value the value of the key
root a pointer to point at the root node
node a pointer to the requested node
params optional URL formatted params to pass to external gateways
Returns:
SWITCH_STATUS_SUCCESS if successful root and node will be assigned
01362 {
01363         switch_xml_t conf = NULL;
01364         switch_xml_t tag = NULL;
01365         switch_xml_t xml = NULL;
01366         switch_xml_binding_t *binding;
01367         uint8_t loops = 0;
01368 
01369         switch_thread_rwlock_rdlock(B_RWLOCK);
01370 
01371         for (binding = BINDINGS; binding; binding = binding->next) {
01372                 switch_xml_section_t sections = switch_xml_parse_section_string(section);
01373 
01374                 if (binding->sections && !(sections & binding->sections)) {
01375                         continue;
01376                 }
01377 
01378                 if ((xml = binding->function(section, tag_name, key_name, key_value, params, binding->user_data))) {
01379                         const char *err = NULL;
01380 
01381                         err = switch_xml_error(xml);
01382                         if (switch_strlen_zero(err)) {
01383                                 if ((conf = switch_xml_find_child(xml, "section", "name", "result"))) {
01384                                         switch_xml_t p;
01385                                         const char *aname;
01386 
01387                                         if ((p = switch_xml_child(conf, "result"))) {
01388                                                 aname = switch_xml_attr(p, "status");
01389                                                 if (aname && !strcasecmp(aname, "not found")) {
01390                                                         switch_xml_free(xml);
01391                                                         xml = NULL;
01392                                                         continue;
01393                                                 }
01394                                         }
01395                                 }
01396                                 break;
01397                         } else {
01398                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error[%s]\n", err);
01399                                 switch_xml_free(xml);
01400                                 xml = NULL;
01401                         }
01402                 }
01403         }
01404         switch_thread_rwlock_unlock(B_RWLOCK);
01405 
01406         for (;;) {
01407                 if (!xml) {
01408                         if (!(xml = switch_xml_root())) {
01409                                 *node = NULL;
01410                                 *root = NULL;
01411                                 return SWITCH_STATUS_FALSE;
01412                         }
01413                 }
01414 
01415                 if ((conf = switch_xml_find_child(xml, "section", "name", section)) && (tag = switch_xml_find_child(conf, tag_name, key_name, key_value))) {
01416                         *node = tag;
01417                         *root = xml;
01418                         return SWITCH_STATUS_SUCCESS;
01419                 } else {
01420                         switch_xml_free(xml);
01421                         xml = NULL;
01422                         *node = NULL;
01423                         *root = NULL;
01424                         if (loops++ > 1) {
01425                                 break;
01426                         }
01427                 }
01428         }
01429 
01430         return SWITCH_STATUS_FALSE;
01431 }

Here is the call graph for this function:

switch_status_t switch_xml_locate_domain const char *  domain_name,
switch_event_t params,
switch_xml_t root,
switch_xml_t domain
 

01434 {
01435         switch_event_t *my_params = NULL;
01436         switch_status_t status;
01437         *domain = NULL;
01438 
01439         if (!params) {
01440                 switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS);
01441                 switch_assert(my_params);
01442                 switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain_name);
01443                 params = my_params;
01444         }
01445 
01446         status = switch_xml_locate("directory", "domain", "name", domain_name, root, domain, params);
01447         if (my_params) {
01448                 switch_event_destroy(&my_params);
01449         }
01450         return status;
01451 }

Here is the call graph for this function:

switch_status_t switch_xml_locate_user const char *  key,
const char *  user_name,
const char *  domain_name,
const char *  ip,
switch_xml_t root,
switch_xml_t domain,
switch_xml_t user,
switch_event_t params
 

01461 {
01462         switch_status_t status = SWITCH_STATUS_FALSE;
01463         switch_event_t *my_params = NULL;
01464 
01465         *root = NULL;
01466         *user = NULL;
01467         *domain = NULL;
01468 
01469         if (!params) {
01470                 switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS);
01471                 switch_assert(my_params);
01472                 params = my_params;
01473         }
01474 
01475         switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "key", key);
01476 
01477         if (user_name) {
01478                 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "user", user_name);
01479         }
01480 
01481         if (domain_name) {
01482                 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain_name);
01483         }
01484 
01485         if (ip) {
01486                 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "ip", ip);
01487         }
01488         
01489         if ((status = switch_xml_locate_domain(domain_name, params, root, domain)) != SWITCH_STATUS_SUCCESS) {
01490                 goto end;
01491         }
01492         
01493         status = SWITCH_STATUS_FALSE;
01494 
01495         if (ip) {
01496                 if ((*user = switch_xml_find_child(*domain, "user", "ip", ip))) {
01497                         status = SWITCH_STATUS_SUCCESS;
01498                         goto end;
01499                 }
01500         } 
01501 
01502         if (user_name) {
01503                 if (params != my_params && switch_event_get_header(params, (char *) "mailbox")) {
01504                         if ((*user = switch_xml_find_child(*domain, "user", "mailbox", user_name))) {
01505                                 status = SWITCH_STATUS_SUCCESS;
01506                                 goto end;
01507                         }
01508                 }
01509 
01510                 if ((*user = switch_xml_find_child(*domain, "user", key, user_name))) {
01511                         status = SWITCH_STATUS_SUCCESS;
01512                         goto end;
01513                 }
01514         }
01515 
01516  end:
01517 
01518         if (my_params) {
01519                 switch_event_destroy(&my_params);
01520         }
01521 
01522         return status;
01523 }

Here is the call graph for this function:

switch_xml_t switch_xml_new const char *  name  ) 
 

returns a new empty switch_xml structure with the given root tag name

Parameters:
name the name of the new root tag
02008 {
02009         static const char *ent[] = { "lt;", "&#60;", "gt;", "&#62;", "quot;", "&#34;",
02010                 "apos;", "&#39;", "amp;", "&#38;", NULL
02011         };
02012         switch_xml_root_t root = (switch_xml_root_t) memset(malloc(sizeof(struct switch_xml_root)),
02013                                                                                                                 '\0', sizeof(struct switch_xml_root));
02014         root->xml.name = (char *) name;
02015         root->cur = &root->xml;
02016         strcpy(root->err, root->xml.txt = (char *)"");
02017         root->ent = (char **)memcpy(malloc(sizeof(ent)), ent, sizeof(ent));
02018         root->attr = root->pi = (char ***) (root->xml.attr = SWITCH_XML_NIL);
02019         return &root->xml;
02020 }

Here is the call graph for this function:

switch_xml_t switch_xml_open_cfg const char *  file_path,
switch_xml_t node,
switch_event_t params
 

open a config in the core registry

Parameters:
file_path the name of the config section e.g. modules.conf
node a pointer to point to the node if it is found
params optional URL formatted params to pass to external gateways
Returns:
the root xml node associated with the current request or NULL
01667 {
01668         switch_xml_t xml = NULL, cfg = NULL;
01669 
01670         *node = NULL;
01671 
01672         assert(MAIN_XML_ROOT != NULL);
01673 
01674         if (switch_xml_locate("configuration",