www.pudn.com > EasySoap++-0.6.1.rar > SOAPArray.h
/* * EasySoap++ - A C++ library for SOAP (Simple Object Access Protocol) * Copyright (C) 2001 David Crowley; SciTegic, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: SOAPArray.h,v 1.3 2002/05/20 16:56:11 jgorlick Exp $ */ #ifndef __SOAPARRAY_H__ #define __SOAPARRAY_H__ #include#include #include BEGIN_EASYSOAP_NAMESPACE /** * Wrapper for 1-dimensional array of type T. * STL compatibility provided. */ template class SOAPArray { private: T* m_array; size_t m_allocated; size_t m_size; void _realloc(size_t s) { if (s > m_allocated) { const size_t minalloc = sp_maximum (8, 128/sizeof(T)); size_t toalloc = m_allocated; if (toalloc < minalloc) toalloc = minalloc; while (toalloc < s) toalloc *= 2; T* newarray = sp_alloc (toalloc); if (!newarray) throw SOAPMemoryException(); // Copy/construct new array from old array size_t i; for (i = 0; i < m_size; ++i) new (newarray + i) T(m_array[i]); // Initialize rest of new array for (i = m_size; i < toalloc; ++i) new (newarray + i) T(); s = m_size; Empty(); m_size = s; m_array = newarray; m_allocated = toalloc; } } public: typedef T* Iterator; typedef const T* ConstIterator; /** * constructor. * @param s initial size of array, default 0. */ SOAPArray(size_t s = 0) : m_array(0) , m_allocated(0) , m_size(0) { Resize(s); } /** * copy constructor. * @param x source array to copy. */ SOAPArray(const SOAPArray& x) : m_array(0) , m_allocated(0) , m_size(0) { Add(x.m_array, x.Size()); } /** * operator =. * @param x source array to copy. * @return this to enable chaining. */ SOAPArray & operator=(const SOAPArray & x) { Resize(x.Size()); for (size_t i = 0; i < x.Size(); ++i) m_array[i] = x[i]; return *this; } /** * destructor. */ ~SOAPArray() { Empty(); } /** * attach, copy and release source. * @param other source array to copy and release. */ void AttachTo(SOAPArray & other) { Empty(); m_allocated = other.m_allocated; m_array = other.m_array; m_size = other.m_size; other.m_allocated = 0; other.m_array = 0; other.m_size = 0; } /** * add allocation only. * @return newly allocated element. */ T& Add() { size_t len = Size(); Resize(len + 1); return m_array[len]; } /** * add. * @param val value of element to be allocated. * @return newly allocated element. */ template T& Add(const X& val) { size_t len = Size(); Resize(len + 1); return m_array[len] = val; } /** * add all elements from source array. * @param a source array. */ template void AddArray(const SOAPArray & a) { Add((const X*)a, a.Size()); } /** * add all elements from C source array. * @param vals C array of values. * @param numVals number of elements in C array of values. * @note vals need not be NULL-terminated. */ template void Add(const X* vals, size_t numVals) { size_t len = Size(); size_t newlen = Size() + numVals; Resize(newlen); T *work = m_array + len; for (size_t i = 0; i < numVals; ++i) *work++ = vals[i]; } /** * add a value at a specified index. * @param index offset for element to be allocated. * @param val value for element to be allocated. * @return value of newly allocated element. */ template T& AddAt(size_t index, const X &val) { Resize(Size() + 1); for (size_t i = Size() - 1; i > index; i--) m_array[i] = m_array[i - 1]; return m_array[index] = val; } /** * begin const iterator. * @return const iterator marking beginning of array. */ ConstIterator Begin() const { return m_array; } /** * end const interator. * @return const iterator marking ending of array. */ ConstIterator End() const { return m_array + Size(); } /** * begin iterator. * @return iterator marking beginning of array. */ Iterator Begin() { return m_array; } /** * end iterator. * @return iterator marking ending of array. */ Iterator End() { return m_array + Size(); } /** * empty, clear the array. * free all allocated elements, resize to initial allocation. */ void Empty() { for (size_t i = 0; i < m_allocated; ++i) m_array[i].~T(); sp_free(m_array); m_allocated = 0; m_size = 0; } /** * test for empty. * @return true if the array is empty. */ bool IsEmpty() const { return (Size() == 0); } /** * funtional cast to C array. * @return head of C array. */ T* Ptr() { return m_array; } /** * functional cast to const C array. * @return const head of C array. */ const T* Ptr() const { return m_array; } /** * cast to C array. * @return head of C array. */ operator T* () { return Ptr(); } /** * cast to const C array. * @return const head of C array. */ operator const T* () const { return Ptr(); } /** * add multiple items with a single value, similar to a malloc/memset. * @param numItems number of items to be allocated. * @param value value of items to be allocated. */ template void Assign(size_t numItems, const X &value) { Resize(numItems); for(size_t i = 0; i < Size(); i++) m_array[i] = value; } /** * remove element at index. * @param index offset for element to be removed. */ void RemoveAt(size_t index) { for(size_t i = index; i < Size() - 1; i++) m_array[i] = m_array[i + 1]; Resize(Size() - 1); } /** * current allocation size. * @return number of elements. */ size_t Size() const { return m_size; } /** * resize the array. * @param s requested allocation size. * @bug jgorlick>>leaks for s Size()) _realloc(s); m_size = s; } /** * get element at index. * @param index offset of element to be fetched. * @return element at index. */ T& GetAt(size_t index) { return m_array[index]; } /** * get const element at index. * @param index offset of element to be fetched. * @return const element at index. */ const T& GetAt(size_t index) const { return m_array[index]; } /** * operator [], treat like C array. * @param index offset of element to be fetched. * @return element at index. */ T& operator[](int index) { return m_array[index]; } /** * const operator [], treat like C array. * @param index offset of element to be fetched. * @return const element at index. */ const T& operator[](int index) const { return m_array[index]; } /** * operator [], treat like C array. * @param index offset of element to be fetched. * @return element at index. */ T& operator[](size_t index) { return m_array[index]; } /** * const operator [], treat like C array. * @param index offset of element to be fetched. * @return const element at index. */ const T& operator[](size_t index) const { return m_array[index]; } /** * operator ==. * @internal bool return, tests only exact equality, compare to string * operator ==, which returns int like strcmp indicating the * first element of difference and uses the sign to indicate * which string is alphabetically nearer to "A". * @param x array to be compared. * @return true if arrays are exactly equal. */ template bool operator==(const SOAPArray & x) const { if (m_size != x.m_size) return false; for (size_t i = 0; i < m_size; ++i) if (m_array[i] != x[i]) return false; return true; } /** * operator !=. * @param x array to be compared. * @return true if arrays are different, by size or by element. */ template bool operator!=(const SOAPArray & x) const { return !(*this == x); } // // For some STL compatibility typedef T* iterator; typedef const T* const_iterator; typedef T value_type; /** * STL compatibility, const begin. * @return const iterator marking beginning of array. */ const_iterator begin() const {return Begin();} /** * STL compatibility, const end. * @return const iterator marking ending of array. */ const_iterator end() const {return End();} /** * STL compatibility, begin. * @return iterator marking beginning of array. */ iterator begin() {return Begin();} /** * STL compatibility, end. * @return iterator marking ending of array. */ iterator end() {return End();} /** * STL compatibility, size. * Current allocation size. * @return const number of elements. */ size_t size() const {return Size();} /** * STL compatibility, resize. * Resize the array. * @param s requested allocation size. */ void resize(size_t s) {Resize(s);} }; /** * Wrapper for 2-dimension array of type T. */ template class SOAP2DArray { private: SOAPArray m_array; size_t m_rows; size_t m_cols; /** * @todo implement copy constructor. */ SOAP2DArray(const SOAP2DArray&); /** * @todo implement operator = */ SOAP2DArray& operator=(const SOAP2DArray&); public: /** * constructor. */ SOAP2DArray() { } /** * constructor. * @param rows number of rows. * @param cols number of columns. */ SOAP2DArray(size_t rows, size_t cols) { Resize(rows, cols); } /** * resize array. * @bug jgorlick>>original contents are overwritten during resize. * @param rows number of rows requested for allocation. * @param cols number of columns requested for allocation. */ void Resize(size_t rows, size_t cols) { m_rows = rows; m_cols = cols; m_array.Resize(m_rows * m_cols); } /** * accessor for rows. * @return const number of rows. */ size_t GetNumRows() const {return m_rows;} /** * accessor for columns. * @return const number of columns. */ size_t GetNumCols() const {return m_cols;} /** * operator []. * @param row offset of row to be fetched. * @return C array at row. * @note client MUST remain within underlying 2-dimensional array bounds. */ T* operator[](size_t row) { return m_array.Ptr() + (row * m_cols); } /** * const operator []. * @param row offset of row to be fetched. * @return const C array at row. * @note client MUST remain within underlying 2-dimensional array bounds. */ const T* operator[](size_t row) const { return m_array.Ptr() + (row * m_cols); } /** * operator ==. * @internal see internal for SOAPArray::operator== * @param other array to be compared. * @return true if arrays are exactly equal. */ bool operator==(const SOAP2DArray& other) { return GetNumRows() == other.GetNumRows() && GetNumCols() == other.GetNumCols() && m_array == other.m_array; } /** * operator !=. * @param other array to be compared. * @return true if arrays are different, by row, by column, * or by element. */ bool operator!=(const SOAP2DArray& other) { return !(*this == other); } // // For some STL compatibilty typedef T value_type; /** * STL compatibility, resize. * @param rows number of rows requested for allocation. * @param cols nubmer of columns requested for allocation. */ void resize(size_t rows, size_t cols) {Resize(rows, cols);} }; END_EASYSOAP_NAMESPACE #endif // __SOAPARRAY_H__