it_bus/soap_enc_array_t.h

00001 #ifndef _IT_BUS_SOAP_ENC_ARRAY_T_H_
00002 #define _IT_BUS_SOAP_ENC_ARRAY_T_H_
00003 
00004 // @Copyright 2004 IONA Technologies, Plc. All Rights Reserved.
00005 //
00006 
00007 #include <it_cal/cal.h>
00008 #include <it_bus/qname.h>
00009 #include <it_bus/soap_enc_array.h>
00010 #include <it_bus/element_list_t.h>
00011 #include <it_bus/complex_type_reader.h>
00012 #include <it_bus/complex_type_writer.h>
00013 
00014 namespace IT_Bus
00015 {
00016     class SoapEncArrayCoordinate : public ArrayCoordinate
00017     {
00018       public:
00019         SoapEncArrayCoordinate(
00020             size_t dimensions,
00021             const size_t coords[]
00022         ) :
00023             m_dimensions(dimensions)
00024         {
00025             size_t* p = new size_t[m_dimensions];
00026             memcpy(p, coords, sizeof(size_t) * m_dimensions);
00027             m_coords.reset(p);
00028         }
00029 
00030         SoapEncArrayCoordinate(
00031             const SoapEncArrayCoordinate& rhs
00032         ) :
00033             m_dimensions(rhs.m_dimensions)
00034         {
00035             m_coords.reset(new size_t[m_dimensions]);
00036             for (size_t idx = 0; idx < m_dimensions; idx++)
00037             {
00038                 m_coords[idx] = rhs[idx];
00039             }
00040         }
00041 
00042         SoapEncArrayCoordinate(
00043             size_t dimensions
00044         ) :
00045             m_dimensions(dimensions)
00046         {
00047             size_t* p = new size_t[m_dimensions];
00048             memset(p, 0, sizeof(size_t) * m_dimensions);
00049             m_coords.reset(p);
00050         }
00051 
00052         SoapEncArrayCoordinate&
00053         operator=(
00054             const ArrayCoordinate& rhs
00055         )
00056         {
00057             if (this != &rhs)
00058             {
00059                 size_t sz = rhs.get_number_dimensions();
00060                 if (m_dimensions != sz)
00061                 {
00062                     m_dimensions = sz;
00063                     m_coords.reset(new size_t[m_dimensions]);
00064                 }
00065                 for (size_t i = 0; i < sz; ++i)
00066                 {
00067                     m_coords[i] = rhs[i];
00068                 }
00069             }
00070             return *this;
00071         }
00072 
00073         virtual const size_t
00074         get_number_dimensions() const
00075         {
00076             return m_dimensions;
00077         }
00078 
00079         virtual const size_t&
00080         operator[] (
00081             size_t idx
00082         ) const
00083         {
00084             return m_coords[idx];
00085         }
00086 
00087         virtual size_t&
00088         operator[] (
00089             size_t idx
00090         )
00091         {
00092             return m_coords[idx];
00093         }
00094 
00095       protected:
00096         IT_AutoArrayPtr<size_t> m_coords;
00097         size_t                  m_dimensions;
00098     };
00099 
00100 
00101     template<typename T>
00102     class SoapEncArrayT : public SoapEncArray
00103     {
00104 
00105         typedef SoapEncArrayT<T> ThisType;
00106 
00107       public:
00108 
00109         SoapEncArrayT(size_t dimensions)
00110          : m_data(IT_Bus::QName::ITEM_QNAME, size_t(0), size_t(-1)),
00111            m_array_extents(dimensions)
00112         {
00113             m_defined_elements = new unsigned char[1];
00114             m_defined_elements[0] = 0;
00115         }
00116 
00117         SoapEncArrayT(size_t dimensions, const size_t extents[])
00118          :  m_data(IT_Bus::QName::ITEM_QNAME, size_t(0), size_t(-1)),
00119             m_array_extents(dimensions, extents)
00120         {
00121             m_defined_elements = 0;
00122             set_extents(m_array_extents);
00123         }
00124 
00125         SoapEncArrayT(const IT_Bus::SoapEncArrayCoordinate & array_extents)
00126          :  m_data(IT_Bus::QName::ITEM_QNAME, size_t(0), size_t(-1)),
00127             m_array_extents(array_extents)
00128         {
00129             m_defined_elements = 0;
00130             set_extents(array_extents);
00131         }
00132 
00133         SoapEncArrayT(const SoapEncArrayT<T> & rhs)
00134          :  m_data(IT_Bus::QName::ITEM_QNAME, size_t(0), size_t(-1)),
00135             m_array_extents(rhs.m_array_extents)
00136         {
00137             m_data.set_size(0);
00138             m_defined_elements = 0;
00139             set_extents(rhs.get_extents());
00140 
00141             size_t idx;
00142             for (idx = 0; idx < m_data.get_size(); idx++)
00143             {
00144                 m_data[idx] = rhs.m_data[idx];
00145             }
00146 
00147             for (idx = 0; idx < ((m_data.get_size() >> 3) + 1); idx++)
00148             {
00149                 m_defined_elements[idx] = rhs.m_defined_elements[idx];
00150             }
00151         }
00152 
00153         virtual ~SoapEncArrayT()
00154         {
00155             delete [] m_defined_elements;
00156         }
00157 
00158         virtual void
00159         read(
00160             const QName& name,
00161             ComplexTypeReader& reader
00162         ) IT_THROW_DECL((IT_Bus::DeserializationException))
00163         {
00164             reader.read_soap_enc_array(name, *this);
00165         }
00166 
00167         virtual void
00168         write(
00169             const QName& name,
00170             ComplexTypeWriter& writer
00171         ) const IT_THROW_DECL((IT_Bus::SerializationException))
00172         {
00173             writer.write_soap_enc_array(name, *this);
00174         }
00175 
00176         const size_t
00177         get_offset(
00178             const ArrayCoordinate & position
00179         ) const
00180         {
00181             size_t offset = position[0];
00182             for (size_t idx = 1; idx < m_array_extents.get_number_dimensions(); idx++)
00183             {
00184                 offset *= m_array_extents[idx];
00185                 offset += position[idx];
00186             }
00187             return offset;
00188         }
00189 
00190         const size_t
00191         get_offset(
00192             const String & coords
00193         ) const
00194         {
00195             SoapEncArrayCoordinate coordinate(m_array_extents.get_number_dimensions());
00196 
00197             String dimensions = coords.substr(1, coords.length() - 2);
00198 
00199             unsigned int comma_count = 0;
00200             String tmp_string = dimensions;
00201 
00202             size_t start = 0;
00203             size_t end = dimensions.find(',', start);
00204             while (end != String::npos)
00205             {
00206                 comma_count++;
00207                 start = end + 1;
00208                 end = dimensions.find(',', start);
00209             }
00210 
00211             size_t idx = 0;
00212             start = 0;
00213             end = dimensions.find(',', start);
00214             while (end != String::npos)
00215             {
00216                 coordinate[idx] = atoi(dimensions.substr(start, end - start).c_str());
00217                 idx++;
00218                 start = end + 1;
00219                 end = dimensions.find(',', start);
00220             }
00221             coordinate[idx] = atoi(dimensions.substr(start).c_str());
00222 
00223             return get_offset(coordinate);
00224         }
00225 
00226 
00227         const T &
00228         operator[](
00229             size_t offset
00230         ) const
00231         {
00232             return m_data[offset];
00233         }
00234 
00235         T &
00236         operator[](
00237             size_t offset
00238         )
00239         {
00240             unsigned char mask = (unsigned char) (offset & 7);
00241             mask = ((unsigned char)1) << mask;
00242 
00243             *(m_defined_elements + (offset >> 3)) |= mask;
00244 
00245             return m_data[offset];
00246         }
00247 
00248 
00249         const T &
00250         operator[](
00251             int offset
00252         ) const
00253         {
00254             return m_data[offset];
00255         }
00256 
00257         T &
00258         operator[](
00259             int offset
00260         )
00261         {
00262             unsigned char mask = (unsigned char) (offset & 7);
00263             mask = ((unsigned char)1) << mask;
00264 
00265             *(m_defined_elements + (offset >> 3)) |= mask;
00266 
00267             return m_data[offset];
00268         }
00269 
00270         const T &
00271         operator[](
00272             const ArrayCoordinate & position
00273         ) const
00274         {
00275             return m_data[get_offset(position)];
00276         }
00277 
00278         T &
00279         operator[](
00280             const ArrayCoordinate & position
00281         )
00282         {
00283             size_t offset = get_offset(position);
00284 
00285             unsigned char mask = (unsigned char) (offset & 7);
00286             mask = ((unsigned char)1) << mask;
00287 
00288             *(m_defined_elements + (offset >> 3)) |= mask;
00289 
00290             return m_data[offset];
00291         }
00292 
00293         const T &
00294         operator[](
00295             const IT_Bus::SoapEncArrayCoordinate & position
00296         ) const
00297         {
00298             return m_data[get_offset(position)];
00299         }
00300 
00301         T &
00302         operator[](
00303             const IT_Bus::SoapEncArrayCoordinate & position
00304         )
00305         {
00306             size_t offset = get_offset(position);
00307 
00308             unsigned char mask = (unsigned char) (offset & 7);
00309             mask = ((unsigned char)1) << mask;
00310 
00311             *(m_defined_elements + (offset >> 3)) |= mask;
00312 
00313             return m_data[offset];
00314         }
00315 
00316         const T &
00317         operator[](
00318             const size_t coords[]
00319         ) const
00320         {
00321             IT_Bus::SoapEncArrayCoordinate position(m_array_extents.get_number_dimensions(),coords);
00322             return m_data[get_offset(position)];
00323         }
00324 
00325         T &
00326         operator[](
00327             const size_t coords[]
00328         )
00329         {
00330             IT_Bus::SoapEncArrayCoordinate position(m_array_extents.get_number_dimensions(),coords);
00331             size_t offset = get_offset(position);
00332 
00333             unsigned char mask = (unsigned char) (offset & 7);
00334             mask = ((unsigned char)1) << mask;
00335 
00336             *(m_defined_elements + (offset >> 3)) |= mask;
00337 
00338             return m_data[offset];
00339         }
00340 
00341         const T &
00342         operator[](
00343             const String & position
00344         ) const
00345         {
00346             return m_data[get_offset(position)];
00347         }
00348 
00349         T &
00350         operator[](
00351             const String & position
00352         )
00353         {
00354             size_t offset = get_offset(position);
00355 
00356             unsigned char mask = (unsigned char) (offset & 7);
00357             mask = ((unsigned char)1) << mask;
00358 
00359             *(m_defined_elements + (offset >> 3)) |= mask;
00360 
00361             return m_data[offset];
00362         }
00363 
00364 
00365         virtual void
00366         write_position(
00367             ArrayCoordinate & position,
00368             ComplexTypeWriter & writer
00369         ) const IT_THROW_DECL((SerializationException))
00370         {
00371             writer.write(QName::ITEM_QNAME, (*this)[position]);
00372         }
00373 
00374         virtual void
00375         read_position(
00376             ComplexTypeReader & reader,
00377             ArrayCoordinate & position
00378         ) IT_THROW_DECL((DeserializationException)) 
00379         {
00380             size_t offset = get_offset(position);
00381             T & item = m_data[offset];
00382 
00383             reader.read(QName::ITEM_QNAME, item);
00384             unsigned char mask = (unsigned char) (offset & 7);
00385             mask = ((unsigned char)1) << mask;
00386 
00387             offset >>= 3;
00388             *(m_defined_elements + offset) |= mask;
00389         }
00390 
00391         virtual void
00392         write_contents(
00393             ComplexTypeWriter & writer
00394         ) const IT_THROW_DECL((SerializationException))
00395         {
00396             writer.write_element_list(m_data.get_item_name(), m_data);
00397         }
00398         
00399         virtual void
00400         read_contents(
00401             ComplexTypeReader & reader
00402         ) IT_THROW_DECL((DeserializationException))
00403         {
00404             reader.read_element_list(m_data.get_item_name(), m_data);
00405         }
00406 
00407         virtual bool
00408         is_empty(
00409             const ArrayCoordinate & position
00410         ) const
00411         {
00412             size_t offset = get_offset(position);
00413 
00414             unsigned char mask = (unsigned char) (offset & 7);
00415             mask = ((unsigned char)1) << mask;
00416 
00417             offset >>= 3;
00418             return ((*(m_defined_elements + offset) & mask) == 0);
00419         }
00420 
00421 
00422         virtual bool
00423         is_empty(
00424             const IT_Bus::SoapEncArrayCoordinate & position
00425         ) const
00426         {
00427             return is_empty(IT_STATIC_CAST(const ArrayCoordinate &, position));
00428         }
00429 
00430         virtual bool
00431         is_empty(
00432             const size_t coords[]
00433         ) const
00434         {
00435             IT_Bus::SoapEncArrayCoordinate position(m_array_extents.get_number_dimensions(),coords);
00436             return is_empty(IT_STATIC_CAST(const ArrayCoordinate &, position));
00437         }
00438 
00439 
00440         virtual void
00441         set_empty(
00442             const ArrayCoordinate & position
00443         )
00444         {
00445             size_t offset = get_offset(position);
00446 
00447             unsigned char mask = (unsigned char) (offset & 7);
00448             mask = ((unsigned char)1) << mask;
00449             mask = !mask;
00450 
00451             offset >>= 3;
00452             *(m_defined_elements + offset) &= mask;
00453         }
00454 
00455         virtual void
00456         set_empty(
00457             const IT_Bus::SoapEncArrayCoordinate & position
00458         )
00459         {
00460             set_empty(IT_STATIC_CAST(const ArrayCoordinate &, position));
00461         }
00462 
00463         virtual void
00464         set_empty(
00465             const size_t coords[]
00466         )
00467         {
00468             IT_Bus::SoapEncArrayCoordinate position(m_array_extents.get_number_dimensions(),coords);
00469             set_empty(IT_STATIC_CAST(const ArrayCoordinate &, position));
00470         }
00471 
00472         virtual const ArrayCoordinate &
00473         get_extents() const
00474         {
00475             return m_array_extents;
00476         }
00477 
00478         virtual void
00479         set_extents(
00480             const ArrayCoordinate & extents
00481         )
00482         {
00483             m_data.set_size(0);
00484             delete [] m_defined_elements;
00485 
00486             size_t raw_size = extents[0];
00487             for (size_t idx = 1; idx < m_array_extents.get_number_dimensions(); idx++)
00488             {
00489                 raw_size *= extents[idx];
00490             }
00491 
00492             if (raw_size != 0)
00493             {
00494                 m_data.set_size(raw_size);
00495                 m_defined_elements = new unsigned char[(raw_size >> 3) + 1];
00496                 memset(m_defined_elements, 0, (raw_size >> 3) + 1);
00497             }
00498             else
00499             {
00500                 m_data.set_size(0);
00501                 m_defined_elements = new unsigned char[1];
00502                 m_defined_elements[0] = 0;
00503             }
00504             m_array_extents = extents;
00505         }
00506 
00507         SoapEncArrayT<T> &
00508         operator=(
00509             const SoapEncArrayT<T> & rhs
00510         )
00511         {
00512             set_extents(rhs.m_array_extents);
00513             size_t idx;
00514             for (idx = 0; idx < m_data.get_size(); idx++)
00515             {
00516                 m_data[idx] = rhs.m_data[idx];
00517             }
00518 
00519             for (idx = 0; idx < ((m_data.get_size() >> 3) + 1); idx++)
00520             {
00521                 m_defined_elements[idx] = rhs.m_defined_elements[idx];
00522             }
00523             return * this;
00524         }
00525 
00526         AnyType &
00527         operator= (
00528             const AnyType & assign
00529         )
00530         {
00531             const ThisType & rhs = IT_DYNAMIC_CAST(const ThisType &, assign);
00532             *this = rhs;
00533 
00534             return *this;
00535         }
00536 
00537         const ElementList &
00538         get_element_list() const
00539         {
00540             return m_data;
00541         }
00542 
00543         ElementList &
00544         get_element_list()
00545         {
00546             return m_data;
00547         }
00548 
00549       protected:
00550 
00551         IT_Bus::ElementListT<T>  m_data;
00552 
00553         unsigned char * m_defined_elements;
00554         SoapEncArrayCoordinate m_array_extents;
00555     };
00556 }
00557 
00558 #endif  

Generated on Thu Sep 7 11:39:05 2006 for Artix by  doxygen 1.4.7