📄 valuenostl.cpp
字号:
/****************License************************************************ * * Copyright 2000-2001. SpeechWorks International, Inc. * * Use of this software is subject to notices and obligations set forth * in the SpeechWorks Public License - Software Version 1.1 which is * included with this software. * * SpeechWorks is a registered trademark, and SpeechWorks Here, * DialogModules and the SpeechWorks logo are trademarks of SpeechWorks * International, Inc. in the United States and other countries. * *********************************************************************** * * Implementation of the complex VXIValue based types without using * the C++ Standard Template Library as defined in vxivalue.h: * VXIString, VXIMap, and VXIVector. * * See ValueSTL.cpp for the higher-performance and less complex STL * based implementation. * ***********************************************************************/#define VXIVALUE_EXPORTS#include "Value.hpp"#include <stdio.h>#include <string.h>#include <stdlib.h>/** * Abstractions for VXIchar */#define _UNICODE#ifdef _UNICODE#define VXIcharStrlen wcslen#define VXIcharStrcpy wcscpy#define VXIcharStrcmp wcscmp#else#define VXIcharStrlen strlen#define VXIcharStrcpy strcpy#define VXIcharStrcmp strcmp#endif/** * Real VXIString class */class VXIString : public VXIValue { public: // Constructor and destructor VXIString (const VXIchar *v) : VXIValue (VALUE_STRING), value(NULL), length(0) { if (( v ) && ( (value = new VXIchar [VXIcharStrlen (v) + 1]) != NULL )) { VXIcharStrcpy (value, v); length = VXIcharStrlen (v); } } VXIString (const VXIchar *v, VXIunsigned u) : VXIValue (VALUE_STRING), value(NULL), length(u) { if (( v ) && ( (value = new VXIchar [u + 1]) != NULL )) { for (unsigned int i = 0; i < u; ++i) value[i] = v[i]; value[u] = '\0'; } } virtual ~VXIString( ) { if ( value ) { delete [] value; value = NULL; } } // Get the length of the string VXIunsigned GetLength( ) const { return length; } // Get and set the value const VXIchar *GetValue( ) const { return value; } void SetValue (const VXIchar *v) { if ( value ) { delete [] value; value = NULL; length = 0; } if (( v ) && ( (value = new VXIchar [VXIcharStrlen (v) + 1]) != NULL )) { VXIcharStrcpy (value, v); length = VXIcharStrlen (v); } } // Comparison methods, equivalent to strcmp( ) int Compare (const VXIString &s) const { return VXIcharStrcmp (value, s.value); } int Compare (const VXIchar *s) const { return VXIcharStrcmp (value, s); } // Copy constructor and assignment operator VXIString (const VXIString &v) : VXIValue (VALUE_STRING), value(NULL) { if (( v.value ) && ( (value = new VXIchar [v.length + 1]) != NULL )) { for (unsigned int i = 0; i < v.length + 1; ++i) value[i] = v.value[i]; length = v.length; } } VXIString & operator= (const VXIString &v) { if ( this != &v ) { if ( value ) { delete [] value; value = NULL; length = 0; } if (( v.value ) && ( (value = new VXIchar [v.length + 1]) != NULL )) { for (unsigned int i = 0; i < v.length + 1; ++i) value[i] = v.value[i]; length = v.length; } } return *this; } // Overrides of comparison operators for VXIMapElement use virtual bool operator< (const VXIString &s) const { return (Compare (s) < 0 ? true : false); } virtual bool operator== (const VXIString &s) const { return (Compare (s) == 0 ? true : false); } virtual bool operator!= (const VXIString &s) const { return (Compare (s) != 0 ? true : false); } private: VXIchar *value; unsigned int length;};/** * Real VXIMap and supporting classes */class VXIElement { public: // Constructor and destructor VXIElement (const VXIchar *k, VXIValue *v) : key(k), value(v), next(NULL) { } VXIElement (const VXIString &k, VXIValue *v) : key(k), value(v), next(NULL) { } ~VXIElement( ) { value = NULL; } // Get the key and value const VXIString &GetKey( ) const { return key; } const VXIValue *GetValue( ) const { return value; } // Destroy the value void DestroyValue( ) { if ( value ) VXIValueDestroy (&value); } // Get and set the next element pointer VXIElement *GetNext( ) const { return next; } void SetNext (VXIElement *e) { next = e; } // Overrides of comparison operators for finding elements based on // the key name virtual bool operator< (const VXIElement &e) const { return key < e.key; } virtual bool operator== (const VXIElement &e) const { return key == e.key; } virtual bool operator!= (const VXIElement &e) const { return key != e.key; } private: // Stubs to prevent copy constructor and assignment operator use VXIElement (const VXIElement &e); VXIElement & operator= (const VXIElement &e); private: VXIString key; VXIValue *value; VXIElement *next;};class VXIMap : public VXIValue { public: // Constructor and destructor VXIMap( ) : VXIValue (VALUE_MAP), badState(false), size(0), head(NULL) { } virtual ~VXIMap( ); // Copy constructor VXIMap (const VXIMap &m); private: // Stub to prevent assignment operator use, use the copy constructor VXIMap & operator= (const VXIMap &m); public: bool badState; unsigned long size; VXIElement *head;};VXIMap::~VXIMap( ){ VXIElement *cur = head, *next; while (cur) { next = cur->GetNext( ); cur->DestroyValue( ); delete cur; cur = next; }}VXIMap::VXIMap (const VXIMap &m) : VXIValue (VALUE_MAP), badState(false), size(0), head(NULL){ VXIElement *src = m.head, *prev = NULL, *dest; while (src) { dest = new VXIElement (src->GetKey( ), VXIValueClone (src->GetValue( ))); if ( dest == NULL ) { badState = true; return; } else if (( dest->GetKey( ).GetLength( ) == 0 ) || ( dest->GetValue( ) == NULL )) { dest->DestroyValue( ); delete dest; badState = true; return; } if ( prev == NULL ) head = dest; else prev->SetNext (dest); prev = dest; src = src->GetNext( ); } size = m.size;}class VXIMapIterator { public: // Constructor and destructor VXIMapIterator(const VXIMap *o) : curElement(o->head) { } virtual ~VXIMapIterator( ) { } // Get the key and value at the iterator's position VXIvalueResult GetKeyValue (const VXIchar **key, const VXIValue **value) const { if ( curElement == NULL ) { *key = NULL; *value = NULL; return VXIvalue_RESULT_FAILURE; } *key = curElement->GetKey( ).GetValue( ); *value = curElement->GetValue( ); return VXIvalue_RESULT_SUCCESS; } // Increment the iterator VXIMapIterator &operator++(int) { if ( curElement != NULL ) curElement = curElement->GetNext( ); return *this; } private: const VXIElement *curElement;};/** * Real VXIVector and supporting classes */class VXIVector : public VXIValue { public: static const int GROW_SIZE; public: // Constructor and destructor VXIVector( ) : VXIValue (VALUE_VECTOR), badState(false), size(0), allocated(0), data(NULL) { } virtual ~VXIVector( ); // Copy constructor VXIVector (const VXIVector &v); // Add an element VXIvalueResult Add (VXIValue *v); private: // Stub to prevent assignment operator use, use the copy constructor VXIMap & operator= (const VXIMap &o); public: bool badState; unsigned long size; unsigned long allocated; VXIElement *data;};const int VXIVector::GROW_SIZE = 8;// Special new operator required by VXIVector, used to simply allow// us to allocate our own memory for the vector data storage, and// the matching deleteinline void *operator new (size_t, void *p) { return p; }inline void operator delete(void *, void *) { }VXIVector::~VXIVector( ){ if ( data ) { // Explicit destructor of each held item which does the standard // destruction of delete( ) but skips the memory free since we // provided the memory ourselves for (unsigned long i = 0; i < size; i++) { data[i].DestroyValue( ); data[i].~VXIElement( ); } // Now free the memory for the vector free (data); }}VXIVector::VXIVector (const VXIVector &v) : VXIValue (VALUE_VECTOR), badState(false), size(0), allocated(0), data(NULL){ if ( v.size > 0 ) { // Allocate just enough memory to store the vector we're copying, we're // making a guess that they will just hold onto this clone instead of // adding additional elements to it data = (VXIElement *) malloc (v.size * sizeof (VXIElement)); if ( data == NULL ) { badState = true; return; } allocated = v.size; // Now copy the elements while ( size < v.size ) { // Set the new element using a new operator with placement syntax // so it does the standard initialization of new( ) but skips the // allocation, instead using the memory we provide VXIElement *element = new (&data[size]) VXIElement (v.data[size].GetKey( ), VXIValueClone (v.data[size].GetValue( ))); size++; } }}VXIvalueResult VXIVector::Add (VXIValue *val){ // Reallocate memory for the vector if required if ( allocated <= size ) { VXIElement *ptr = (VXIElement *) realloc (data, (size + VXIVector::GROW_SIZE) * sizeof (VXIElement)); if ( ptr == NULL ) return VXIvalue_RESULT_OUT_OF_MEMORY; data = ptr; allocated = size + VXIVector::GROW_SIZE; } // Set the new element using a new operator with placement syntax // so it does the standard initialization of new( ) but skips the // allocation, instead using the memory we provide VXIElement *element = new (&data[size]) VXIElement (NULL, val); size++; return VXIvalue_RESULT_SUCCESS;}/** * Create a String from a null-terminated character array * * @param str NULL-terminated character array * @return String with the specified value on success, * NULL otherwise */VXIVALUE_API VXIString *VXIStringCreate(const VXIchar *str){ if ( str == NULL ) return NULL; // Allocate the string VXIString *s = new VXIString (str); if (( s != NULL ) && ( s->GetValue( ) == NULL )) { delete s; s = NULL; } return s;}/** * Create a String from a known-length character array * * @param str Character array (null characters may be embedded in the * array) * @param len Number of characters which will be copied. * @return String with the specified value on success, * NULL otherwise */VXIVALUE_API VXIString *VXIStringCreateN(const VXIchar *str, VXIunsigned len){ if ( str == NULL ) return NULL; // Allocate the string VXIString *s = new VXIString (str, len); if (( s != NULL ) && ( s->GetValue( ) == NULL )) { delete s; s = NULL; } return s;}/** * String destructor * * @param s String to destroy */VXIVALUE_API void VXIStringDestroy(VXIString **s){ if (( s ) && ( *s ) && ( (*s)->GetType( ) == VALUE_STRING )) { delete *s; *s = NULL; }}/** * String clone * * Note: functionally redundant with VXIValueClone( ), but provided to * reduce the need for C casts for this common operation * * @param s String to clone * @return Clone of the string on success, NULL otherwise */VXIVALUE_API VXIString *VXIStringClone(const VXIString *s){ if (( s == NULL ) || ( s->GetType( ) != VALUE_STRING )) return NULL; // Allocate the string VXIString *str = new VXIString (*s); if (( str != NULL ) && ( str->GetValue( ) == NULL )) { delete str; str = NULL; } return str;}/** * Set the value of a String from a null-terminated character array * * Note: this functionality is provided to allow defining interfaces * where the caller passes in a VXIString from VXIStringCreate( ) * (typically with an empty string as its value) with the interface * changing that value to return a string as output. This avoids * having to define interfaces where the client has to provide a * fixed length buffer (and thus worry about "buffer too small" errors * and complicated handling). * * @param s String to change the value of * @param str NULL-terminated character array * @return VXIvalue_RESULT_SUCCESS on success */VXIVALUE_API VXIvalueResult VXIStringSetValue(VXIString *s, const VXIchar *str){ if (( s == NULL ) || ( s->GetType( ) != VALUE_STRING ) || ( str == NULL )) return VXIvalue_RESULT_INVALID_ARGUMENT; s->SetValue (str); if ( s->GetValue( ) == NULL ) return VXIvalue_RESULT_OUT_OF_MEMORY; return VXIvalue_RESULT_SUCCESS;}/** * Get the value of a String * * @param s String to access * @param buf Character buffer to copy the value into as a * NULL-terminated character array. The buffer size must be * at least VXIStringLength() + 1. * @param len Size of the buffer, in characters * @return Pointer to buf on success, NULL on failure (most likely * buffer too small) */VXIVALUE_API VXIchar *VXIStringValue(const VXIString *s, VXIchar *buf, VXIunsigned len){ if (( s == NULL ) || ( s->GetType( ) != VALUE_STRING ) || ( buf == NULL )) return NULL; // Make sure the buffer is large enough if ( len < s->GetLength( ) + 1 ) return NULL; const VXIchar * str = s->GetValue(); unsigned int length = s->GetLength(); for (unsigned int i = 0; i < length; ++i) *(buf + i) = str[i]; *(buf + length) = '\0'; return buf;}/** * Get direct access to the NULL-terminated character value * * Note: the returned buffer must never be modified, and is only * provided for transient use (i.e. immediately logging it, comparing * it, etc. rather than storing or returning the pointer for longer * term access). * * @param s String to retrieve the data from * @return Pointer to the NULL-terminated character array retrieved */VXIVALUE_API const VXIchar* VXIStringCStr(const VXIString *s){ if (( s == NULL ) || ( s->GetType( ) != VALUE_STRING )) return NULL; return s->GetValue( );}/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -