ValueSTL.cpp
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:24k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /****************License************************************************
  2.  * Vocalocity OpenVXI
  3.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  18.  * registered trademarks of Vocalocity, Inc. 
  19.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  20.  * by Vocalocity.
  21.  ***********************************************************************/
  22. #define VXIVALUE_EXPORTS
  23. #include "Value.hpp"
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. // STL headers
  27. #include <string>
  28. #include <map>
  29. #include <vector>
  30. #include <algorithm>
  31. // Definition of string to use, based on VXIchar choice
  32. #define STL_STRING  std::basic_string<VXIchar>
  33. #define STRNCPY     wcsncpy
  34. /**
  35.  * Real VXIString class
  36.  */
  37. class VXIString : public VXIValue {
  38.  public:
  39.   // Constructor and destructor
  40.   VXIString (const STL_STRING &v) : VXIValue (VALUE_STRING), value(v) { }
  41.   VXIString (const VXIchar * v, VXIunsigned u)
  42.     : VXIValue (VALUE_STRING), value(v, u) { }
  43.   virtual ~VXIString( ) { }
  44.   // Get the length of the string
  45.   VXIunsigned GetLength( ) const { return value.length( ); }
  46.   // Get and set the value
  47.   const STL_STRING &GetValue( ) const { return value; }
  48.   void SetValue (const STL_STRING &v) { value = v; }
  49.  private:
  50.   STL_STRING  value;
  51. };
  52. /**
  53.  * Real VXIMap and supporting classes
  54.  */
  55. class VXIMap : public VXIValue {
  56.  public:
  57.   // Constructor and destructor
  58.   VXIMap( ) : VXIValue (VALUE_MAP), container( ) { }
  59.   virtual ~VXIMap( );
  60.   // Copy constructor
  61.   VXIMap (const VXIMap &m);
  62.  public:
  63.   typedef std::map<STL_STRING, VXIValue *> MAP;
  64.   MAP container;
  65. };
  66. VXIMap::~VXIMap( )
  67. {
  68.   // Must manually deep destroy values
  69.   MAP::iterator vi;
  70.   for (vi = container.begin( ); vi != container.end( ); vi++)
  71.     delete (*vi).second;
  72. }
  73. VXIMap::VXIMap (const VXIMap &m) : VXIValue (VALUE_MAP), container()
  74. {
  75.   // Must manually deep copy values
  76.   MAP::const_iterator vi;
  77.   for (vi = m.container.begin( ); vi != m.container.end( ); vi++) {
  78.     VXIValue *v = VXIValueClone ((*vi).second);
  79.     if ( v ) {
  80.       MAP::value_type element ((*vi).first, v);
  81.       container.insert (element);
  82.     } else {
  83.       return;
  84.     }
  85.   }
  86. }
  87. class VXIMapIterator {
  88.  public:
  89.   // Constructor and destructor
  90.   VXIMapIterator(const VXIMap *m) : 
  91.     map(m), mapIterator(m->container.begin( )) { }
  92.   virtual ~VXIMapIterator( ) { }
  93.   // Get the key and value at the iterator's position
  94.   VXIvalueResult GetKeyValue (const VXIchar **key, 
  95.       const VXIValue **value) const {
  96.     if ( mapIterator == map->container.end( ) ) {
  97.       *key = NULL;
  98.       *value = NULL;
  99.       return VXIvalue_RESULT_FAILURE;
  100.     }
  101.     *key = (*mapIterator).first.c_str( );
  102.     *value = (*mapIterator).second;
  103.     return VXIvalue_RESULT_SUCCESS;
  104.   }
  105.   // Increment the iterator
  106.   VXIMapIterator &operator++(int) { 
  107.     if ( mapIterator != map->container.end( ) )
  108.       mapIterator++; 
  109.     return *this; }
  110.  private:
  111.   const VXIMap *map;
  112.   VXIMap::MAP::const_iterator mapIterator;
  113. };
  114. /**
  115.  * Real VXIVector and supporting classes
  116.  */
  117. class VXIVector : public VXIValue {
  118.  public:
  119.   // Constructor and destructor
  120.   VXIVector( ) : VXIValue (VALUE_VECTOR), container( ) { }
  121.   virtual ~VXIVector( );
  122.   // Copy constructor
  123.   VXIVector (const VXIVector &v);
  124.  public:
  125.   typedef std::vector<VXIValue *> VECTOR;
  126.   VECTOR container;
  127. };
  128. VXIVector::~VXIVector( )
  129. {
  130.   // Must manually deep destroy values
  131.   VECTOR::iterator vi;
  132.   for (vi = container.begin( ); vi != container.end( ); vi++)
  133.     delete *vi;
  134. }
  135. VXIVector::VXIVector (const VXIVector &v) : VXIValue(VALUE_VECTOR), container()
  136. {
  137.   // Must manually deep copy values
  138.   VECTOR::const_iterator vi;
  139.   for (vi = v.container.begin( ); vi != v.container.end( ); vi++) {
  140.     VXIValue *v = VXIValueClone (*vi);
  141.     if ( v ) {
  142.       container.push_back(v);
  143.     } else {
  144.       return;
  145.     }
  146.   }
  147. }
  148. /**
  149.  * Create a String from a null-terminated character array
  150.  *
  151.  * @param   str   NULL-terminated character array
  152.  * @return        String with the specified value on success, 
  153.  *                NULL otherwise
  154.  */
  155. VXIVALUE_API VXIString *VXIStringCreate(const VXIchar *str)
  156. {
  157.   if ( str == NULL )
  158.     return NULL;
  159.   return new VXIString (str);
  160. }
  161. /**
  162.  * Create a String from a known-length character array
  163.  *
  164.  * @param   str   Character array (null characters may be embedded in 
  165.  *                the array)
  166.  * @param   len   Number of characters which will be copied.
  167.  * @return        String with the specified value on success, 
  168.  *                NULL otherwise
  169.  */
  170. VXIVALUE_API VXIString *VXIStringCreateN(const VXIchar *str, VXIunsigned len)
  171. {
  172.   if ( str == NULL )
  173.     return NULL;
  174.   return new VXIString (str, len);
  175. }
  176. /**
  177.  * String destructor
  178.  *
  179.  * @param   s   String to destroy
  180.  */
  181. VXIVALUE_API void VXIStringDestroy(VXIString **s)
  182. {
  183.   if (( s ) && ( *s ) && ( (*s)->GetType( ) == VALUE_STRING )) {
  184.     delete *s;
  185.     *s = NULL;
  186.   }
  187. }
  188. /**
  189.  * String clone
  190.  *
  191.  * Note: functionally redundant with VXIValueClone( ), but provided to
  192.  * reduce the need for C casts for this common operation
  193.  *
  194.  * @param    s   String to clone
  195.  * @return       Clone of the string on success, NULL otherwise
  196.  */
  197. VXIVALUE_API VXIString *VXIStringClone(const VXIString *s)
  198. {
  199.   if (( s == NULL ) || ( s->GetType( ) != VALUE_STRING ))
  200.     return NULL;
  201.   return new VXIString (*s);
  202. }
  203. /**
  204.  * Set the value of a String from a null-terminated character array
  205.  *
  206.  * Note: this functionality is provided to allow defining interfaces
  207.  * where the caller passes in a VXIString from VXIStringCreate( )
  208.  * (typically with an empty string as its value) with the interface
  209.  * changing that value to return a string as output. This avoids
  210.  * having to define interfaces where the client has to provide a
  211.  * fixed length buffer (and thus worry about "buffer too small" errors
  212.  * and complicated handling).
  213.  *
  214.  * @param   s     String to change the value of
  215.  * @param   str   NULL-terminated character array
  216.  * @return        VXIvalue_RESULT_SUCCESS on success 
  217.  */
  218. VXIVALUE_API VXIvalueResult VXIStringSetValue(VXIString      *s, 
  219.       const VXIchar  *str)
  220. {
  221.   if (( s == NULL ) || ( s->GetType( ) != VALUE_STRING ) || 
  222.       ( str == NULL ))
  223.     return VXIvalue_RESULT_INVALID_ARGUMENT;
  224.   s->SetValue (str);
  225.   return VXIvalue_RESULT_SUCCESS;
  226. }
  227. /**
  228.  * Get the value of a String
  229.  *
  230.  * @param   s     String to access
  231.  * @param   buf   Character buffer to copy the value into as a
  232.  *                NULL-terminated character array.  The buffer size must be
  233.  *                at least VXIStringLength() + 1.
  234.  * @param   len   Size of the buffer, in characters
  235.  * @return        Pointer to buf on success, NULL on failure (most likely
  236.  *                buffer too small) 
  237.  */
  238. VXIVALUE_API VXIchar *VXIStringValue(const VXIString  *s, 
  239.      VXIchar          *buf, 
  240.      VXIunsigned       len)
  241. {
  242.   if (( s == NULL ) || ( s->GetType( ) != VALUE_STRING ) || 
  243.       ( buf == NULL ))
  244.     return NULL;
  245.   // Make sure the buffer is large enough
  246.   if ( len < s->GetLength( ) + 1 ) return NULL;
  247.   const STL_STRING & str = s->GetValue();
  248.   unsigned int length = s->GetLength();
  249.   for (unsigned int i = 0; i < length; ++i)
  250.     *(buf + i) = str[i];
  251.   *(buf + length) = L'';
  252.   return buf;
  253. }
  254. /**
  255.  * Get direct access to the NULL-terminated character value
  256.  *
  257.  * Note: the returned buffer must never be modified, and is only
  258.  * provided for transient use (i.e. immediately logging it, comparing
  259.  * it, etc. rather than storing or returning the pointer for longer
  260.  * term access).
  261.  *
  262.  * @param   s   String to retrieve the data from
  263.  * @return      Pointer to the NULL-terminated character array retrieved
  264.  */
  265. VXIVALUE_API const VXIchar* VXIStringCStr(const VXIString *s)
  266. {
  267.   if (( s == NULL ) || ( s->GetType( ) != VALUE_STRING ))
  268.     return NULL;
  269.   return s->GetValue( ).c_str( );
  270. }
  271. /**
  272.  * Get the number of characters in a String's value
  273.  *
  274.  * Note: Add one byte for the NULL terminator when using this to determine
  275.  * the length of the array required for a VXIStringValue( ) call.
  276.  *
  277.  * @param   s   String to access
  278.  * @return      Length of the string, in characters
  279.  */
  280. VXIVALUE_API VXIunsigned VXIStringLength(const VXIString *s)
  281. {
  282.   if (( s == NULL ) || ( s->GetType( ) != VALUE_STRING ))
  283.     return 0;
  284.   return s->GetLength( );
  285. }
  286. /**
  287.  * Compares two Strings
  288.  *
  289.  * @param   s1   First String to compare
  290.  * @param   s2   Second String to compare
  291.  * @return       Returns a value that is less than, equal to, or greater
  292.  *               than zero depending on whether s1 is lexicographically
  293.  *               less than, equal to, or greater than s2
  294.  */
  295. VXIVALUE_API VXIint VXIStringCompare(const VXIString *s1, 
  296.      const VXIString *s2)
  297. {
  298.   if (( s1 == NULL ) || ( s1->GetType( ) != VALUE_STRING ))
  299.     return -1;
  300.   if (( s2 == NULL ) || ( s2->GetType( ) != VALUE_STRING ))
  301.     return 1;
  302.   return s1->GetValue( ).compare (s2->GetValue( ));
  303. }
  304. /**
  305.  * Compares a String to a NULL-terminated character array
  306.  *
  307.  * @param   str   String to compare
  308.  * @param   buf   NULL-terminated character array to compare
  309.  * @return        Returns a value that is less than, equal to, or greater
  310.  *                than zero depending on whether str is lexicographically
  311.  *                less than, equal to, or greater than buf
  312.  */
  313. VXIVALUE_API VXIint VXIStringCompareC(const VXIString *str, 
  314.       const VXIchar   *buf)
  315. {
  316.   if (( str == NULL ) || ( str->GetType( ) != VALUE_STRING ))
  317.     return -1;
  318.   if ( buf == NULL )
  319.     return 1;
  320.   return str->GetValue( ).compare (buf);
  321. }
  322. /**
  323.  * Create an empty Map
  324.  *
  325.  * @return   New map on success, NULL otherwise
  326.  */
  327. VXIVALUE_API VXIMap *VXIMapCreate(void)
  328. {
  329.   return new VXIMap;
  330. }
  331. /**
  332.  * Clear the content of the map and return an empty Map
  333.  *
  334.  * @return   None
  335.  */
  336. VXIVALUE_API void VXIMapClear(VXIMap *m)
  337. {
  338.   if ( m  && ( m->GetType( ) == VALUE_MAP )) {
  339.     // Must manually deep destroy values
  340.     VXIMap::MAP::iterator vi;
  341.     for (vi = m->container.begin( ); vi != m->container.end( ); vi++)
  342.       delete (*vi).second;
  343.     m->container.clear();
  344.   }
  345. }
  346. /**
  347.  * Map destructor
  348.  *
  349.  * Note: this recursively destroys all the values contained within the
  350.  * Map, including all the values of Maps and Vectors stored
  351.  * within this map. However, for Ptr values the user is
  352.  * responsible for freeing the held memory if appropriate.
  353.  *
  354.  * @param m   Map to destroy 
  355.  */
  356. VXIVALUE_API void VXIMapDestroy(VXIMap **m)
  357. {
  358.   if (( m ) && ( *m ) && ( (*m)->GetType( ) == VALUE_MAP )) {
  359.     delete *m;
  360.     *m = NULL;
  361.   }
  362. }
  363. /**
  364.  * Map clone
  365.  *
  366.  * Recursively copies all values contained within the map,
  367.  * including all the values of Maps and Vectors stored within this
  368.  * map.
  369.  *
  370.  * Note: functionally redundant with VXIValueClone( ), but provided to
  371.  * reduce the need for C casts for this common operation
  372.  *
  373.  * @param    m   Map to clone
  374.  * @return       Clone of the Map on success, NULL otherwise 
  375.  */
  376. VXIVALUE_API VXIMap *VXIMapClone(const VXIMap *m)
  377. {
  378.   if (( m == NULL ) || ( m->GetType( ) != VALUE_MAP ))
  379.     return NULL;
  380.   return new VXIMap (*m);
  381. }
  382. /**
  383.  * Set a named property on an Map
  384.  *
  385.  * The value can be an Map so a tree can be constructed.
  386.  *
  387.  * If the property already exists, the existing value is first
  388.  * destroyed using VXIValueDestroy( ) (thus recursively deleting held
  389.  * values within it if it is an Map or Vector), then does the
  390.  * set operation with the new value.
  391.  *
  392.  * @param   m     Map to access
  393.  * @param   key   NULL terminated property name
  394.  * @param   val   Value to set the property to, ownership is passed
  395.  *                to the Map (a simple pointer copy is done), so on
  396.  *                success the user must not delete, modify, or otherwise
  397.  *                use this. Also be careful to not add a Map as a
  398.  *                property of itself (directly or indirectly), otherwise
  399.  *                infinite loops may occur on access or deletion.
  400.  * @return        VXIvalue_RESULT_SUCCESS on success
  401.  */
  402. VXIVALUE_API VXIvalueResult VXIMapSetProperty(VXIMap         *m, 
  403.       const VXIchar  *key,
  404.       VXIValue       *val)
  405. {
  406.   if (( m == NULL ) || ( m->GetType( ) != VALUE_MAP ) ||
  407.       ( key == NULL ) || ( key[0] == 0 ) || ( val == NULL ))
  408.     return VXIvalue_RESULT_INVALID_ARGUMENT;
  409.   // Destroy any existing element with that key
  410.   VXIMap::MAP::iterator vi = m->container.find (key);
  411.   if ( vi != m->container.end( ) ) {
  412.     delete (*vi).second;
  413.     m->container.erase (vi);
  414.   }
  415.   // Insert the new element
  416.   VXIMap::MAP::value_type element (key, val);
  417.   std::pair<VXIMap::MAP::iterator, bool> rc = m->container.insert (element);
  418.   if ( rc.second != true )
  419.     return VXIvalue_RESULT_OUT_OF_MEMORY;
  420.   return VXIvalue_RESULT_SUCCESS;
  421. }
  422. /**
  423.  * Get a named property from an Map
  424.  *
  425.  * The property value is returned for read-only access and is
  426.  * invalidated if the Map is modified. The client must clone it if
  427.  * they wish to perform modifications or wish to retain the value even
  428.  * afer modifying this Map.
  429.  *
  430.  * @param   m     Map to access
  431.  * @param   key   NULL terminated property name
  432.  * @return        On success the value of the property for read-only 
  433.  *                access (invalidated if the Map is modified), NULL
  434.  *                if the property was never set or was deleted 
  435.  */
  436. VXIVALUE_API const VXIValue *VXIMapGetProperty(const VXIMap    *m, 
  437.        const VXIchar   *key)
  438. {
  439.   if (( m == NULL ) || ( m->GetType( ) != VALUE_MAP ) || 
  440.       ( key == NULL ) || ( key[0] == 0 ))
  441.     return NULL;
  442.   // Find the element with that key
  443.   VXIMap::MAP::const_iterator vi = m->container.find (key);
  444.   if ( vi != m->container.end( ) )
  445.     return (*vi).second;
  446.   return NULL;
  447. }
  448. /**
  449.  * Delete a named property from an Map
  450.  *
  451.  * This does a VXIValueDestroy( ) on the value for the named property
  452.  * (thus recursively deleting held values within it if it is an Map
  453.  * or Vector). However, for Ptr properties the user is responsible for
  454.  * freeing the held memory if appropriate.
  455.  *
  456.  * @param   m     Map to access
  457.  * @param   key   NULL terminated property name
  458.  * @return        VXIvalue_RESULT_SUCCESS on success 
  459.  */
  460. VXIVALUE_API VXIvalueResult VXIMapDeleteProperty(VXIMap         *m, 
  461.  const VXIchar  *key)
  462. {
  463.   if (( m == NULL ) || ( m->GetType( ) != VALUE_MAP ) || 
  464.       ( key == NULL ) || ( key[0] == 0 ))
  465.     return VXIvalue_RESULT_INVALID_ARGUMENT;
  466.   // Destroy any existing element with that key
  467.   VXIMap::MAP::iterator vi = m->container.find (key);
  468.   if ( vi == m->container.end( ) )
  469.     return VXIvalue_RESULT_FAILURE;
  470.   delete (*vi).second;
  471.   m->container.erase (vi);
  472.   return VXIvalue_RESULT_SUCCESS;
  473. }
  474. /**
  475.  * Return the number of properties for an Map
  476.  *
  477.  * Note: this only returns the number of properties that are direct
  478.  * children of the Map, it does not include the number of properties
  479.  * held in Maps and Vectors stored within this map.
  480.  *
  481.  * @param   m   Map to access
  482.  * @return      Number of properties stored in the Map
  483.  */
  484. VXIVALUE_API VXIunsigned VXIMapNumProperties(const VXIMap *m)
  485. {
  486.   if (( m == NULL ) || ( m->GetType( ) != VALUE_MAP ))
  487.     return 0;
  488.   return m->container.size( );
  489. }
  490. /**
  491.  * Get the first property of an Map and an iterator
  492.  *
  493.  * Note: this is used to traverse all the properties within an map,
  494.  * there is no guarantee on what order the properties will be
  495.  * returned. The iterator must be eventually freed with
  496.  * VXIMapIteratorDestroy( ), and is invalidated if the Map is
  497.  * modified in any way.
  498.  *
  499.  * @param   m      Map to access
  500.  * @param   key    Set to point at the property name for read-only 
  501.  *                 access (must not be modified)                 
  502.  * @param   value  Set to point at the property value for read-only 
  503.  *                 access (must not be modified)
  504.  * @return         Pointer to an iterator that may be used to get
  505.  *                 additional properties via VXIMapGetNextProperty( ),
  506.  *                 or NULL on failure (typically no properties in the map)
  507.  */
  508. VXIVALUE_API 
  509. VXIMapIterator *VXIMapGetFirstProperty(const VXIMap     *m,
  510.        const VXIchar   **key,
  511.        const VXIValue  **value)
  512. {
  513.   if (( m == NULL ) || ( m->GetType( ) != VALUE_MAP ) ||
  514.       ( m->container.size( ) == 0 ) || ( key == NULL ) || ( value == NULL ))
  515.     return NULL;
  516.   // Allocate an iterator map
  517.   VXIMapIterator *it = new VXIMapIterator (m);
  518.   if ( it == NULL )
  519.     return NULL;
  520.   
  521.   // Get the first property
  522.   it->GetKeyValue (key, value);
  523.   return it;
  524. }
  525. /**
  526.  * Get the next property of an Map based on an iterator
  527.  *
  528.  * Note: this is used to traverse all the properties within an map,
  529.  * there is no gaurantee on what order the properties will be
  530.  * returned.
  531.  *
  532.  * @param   it     Iterator used to access the map as obtained
  533.  *                 from VXIMapGetFirstProperty( ), this operation
  534.  *                 will advance the iterator to the next property on
  535.  *                 success
  536.  * @param   key    Set to point at the property name for read-only 
  537.  *                 access (must not be modified, invalidated if the
  538.  *                 Map is modified)                 
  539.  * @param   value  Set to point at the property value for read-only 
  540.  *                 access (must not be modified, invalidated if the
  541.  *                 Map is modified)
  542.  * @return         VXIvalue_RESULT_SUCCESS on success (property name 
  543.  *                 and value returned, iterator advanced), 
  544.  *                 VXIvalue_RESULT_FAILURE if there are no more properties
  545.  *                 to read, or a VXIvalueResult error code for severe errors
  546.  */
  547. VXIVALUE_API VXIvalueResult VXIMapGetNextProperty(VXIMapIterator  *it,
  548.   const VXIchar  **key,
  549.   const VXIValue **value)
  550. {
  551.   if (( it == NULL ) || ( key == NULL ) || ( value == NULL ))
  552.     return VXIvalue_RESULT_INVALID_ARGUMENT;
  553.   (*it)++;
  554.   return it->GetKeyValue (key, value);
  555. }
  556. /**
  557.  * Destroy an iterator
  558.  *
  559.  * @param   it     Iterator to destroy as obtained from 
  560.  *                 VXIMapGetFirstProperty( )
  561.  */
  562. VXIVALUE_API void VXIMapIteratorDestroy(VXIMapIterator **it)
  563. {
  564.   if (( it ) && ( *it )) {
  565.     delete *it;
  566.     *it = NULL;
  567.   }
  568. }
  569. /**
  570.  * Create an empty Vector
  571.  *
  572.  * @return   New vector on success, NULL otherwise
  573.  */
  574. VXIVALUE_API VXIVector *VXIVectorCreate(void)
  575. {
  576.   return new VXIVector;
  577. }
  578. /**
  579.  * Vector destructor
  580.  *
  581.  * Note: this recursively destroys all the values contained within the
  582.  * Vector, including all the values of Vectors stored within this
  583.  * vector. However, for Ptr values the user is responsible for
  584.  * freeing the held memory if appropriate.
  585.  *
  586.  * @param   v   Vector to destroy 
  587.  */
  588. VXIVALUE_API void VXIVectorDestroy(VXIVector **v)
  589. {
  590.   if (( v ) && ( *v ) && ( (*v)->GetType( ) == VALUE_VECTOR )) {
  591.     delete *v;
  592.     *v = NULL;
  593.   }
  594. }
  595. /**
  596.  * Vector clone
  597.  *
  598.  * Recursively copies all values contained within the vector,
  599.  * including all the values of Vectors and Maps stored within this
  600.  * vector.
  601.  *
  602.  * Note: functionally redundant with VXIValueClone( ), but provided to
  603.  * reduce the need for C casts for this common operation
  604.  *
  605.  * @param    v   Vector to clone
  606.  * @return Clone of the Vector on success, NULL otherwise */
  607. VXIVALUE_API VXIVector *VXIVectorClone(const VXIVector *v)
  608. {
  609.   if (( v == NULL ) || ( v->GetType( ) != VALUE_VECTOR ))
  610.     return NULL;
  611.   return new VXIVector (*v);
  612. }
  613. /**
  614.  * Adds an element to the end of the Vector
  615.  *
  616.  * The value can be a Vector so frames can be implemented.
  617.  *
  618.  * @param   v    Vector to access
  619.  * @param   val  Value to append to the vector, ownership is passed
  620.  *               to the Vector (a simple pointer copy is done), so on
  621.  *               success the user must not delete, modify, or otherwise
  622.  *               use this. Also be careful to not add a Vector as a
  623.  *               element of itself (directly or indirectly), otherwise
  624.  *               infinite loops may occur on access or deletion.
  625.  * @return       VXIvalue_RESULT_SUCCESS on success
  626.  */
  627. VXIVALUE_API VXIvalueResult VXIVectorAddElement(VXIVector      *v, 
  628. VXIValue       *val)
  629. {
  630.   if (( v == NULL ) || ( v->GetType( ) != VALUE_VECTOR ) || 
  631.       ( val == NULL ))
  632.     return VXIvalue_RESULT_INVALID_ARGUMENT;
  633.   // Insert the new element
  634.   v->container.push_back (val);
  635.   return VXIvalue_RESULT_SUCCESS;
  636. }
  637. /**
  638.  * Set an indexed vector element
  639.  *
  640.  * Overwrites the specified element with the new value. The existing
  641.  * value is first destroyed using VXIValueDestroy( ) (thus recursively
  642.  * deleting held values within it if it is an Map or Vector), then
  643.  * does the set operation with the new value.
  644.  *
  645.  * The value can be a Vector so frames can be implemented.
  646.  *
  647.  * @param   v     Vector to access
  648.  * @param   n     Element index to set, it is an error to pass a
  649.  *                index that is greater then the number of values
  650.  *                currently in the vector
  651.  * @param   val   Value to set the element to, ownership is passed
  652.  *                to the Vector (a simple pointer copy is done), so on
  653.  *                success the user must not delete, modify, or otherwise
  654.  *                use this. Also be careful to not add a Vector as a
  655.  *                element of itself (directly or indirectly), otherwise
  656.  *                infinite loops may occur on access or deletion.
  657.  * @return        VXIvalue_RESULT_SUCCESS on success
  658.  */
  659. VXIVALUE_API VXIvalueResult VXIVectorSetElement(VXIVector      *v, 
  660. VXIunsigned     n, 
  661. VXIValue       *val)
  662. {
  663.   if (( v == NULL ) || ( v->GetType( ) != VALUE_VECTOR ) || 
  664.       ( val == NULL ) || ( n >= v->container.size( ) ))
  665.     return VXIvalue_RESULT_INVALID_ARGUMENT;
  666.   // Set the element
  667.   delete v->container[n];
  668.   v->container[n] = val;
  669.   return VXIvalue_RESULT_SUCCESS;
  670. }
  671. /**
  672.  * Get an indexed vector element
  673.  *
  674.  * The element value is returned for read-only access and is
  675.  * invalidated if the Vector is modified. The client must clone it if
  676.  * they wish to perform modifications or wish to retain the value even
  677.  * after modifying this Vector.
  678.  *
  679.  * @param   v     Vector to access
  680.  * @param   n     Element index to set, it is an error to pass a
  681.  *                index that is greater or equal to then the number of values
  682.  *                currently in the vector (i.e. range is 0 to length-1)
  683.  * @return        On success the value of the property for read-only 
  684.  *                access (invalidated if the Vector is modified), NULL
  685.  *                on error 
  686.  */
  687. VXIVALUE_API const VXIValue *VXIVectorGetElement(const VXIVector *v, 
  688.  VXIunsigned      n)
  689. {
  690.   if (( v == NULL ) || ( v->GetType( ) != VALUE_VECTOR ) ||
  691.       ( n >= v->container.size( ) ))
  692.     return NULL;
  693.   return v->container[n];
  694. }
  695. /**
  696.  * Return number of elements in a Vector
  697.  *
  698.  * This computes only the length of the Vector, elements within
  699.  * Vectors and Maps within it are not counted.
  700.  *
  701.  * @param   v    Vector to access
  702.  * @return       Number of elements stored in the Vector
  703.  */
  704. VXIVALUE_API VXIunsigned VXIVectorLength(const VXIVector *v)
  705. {
  706.   if (( v == NULL ) || ( v->GetType( ) != VALUE_VECTOR ))
  707.     return 0;
  708.   return v->container.size( );
  709. }