00001 #ifndef _IT_BUS_SOAP_ENC_ARRAY_T_H_
00002 #define _IT_BUS_SOAP_ENC_ARRAY_T_H_
00003
00004
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 ) throw((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 throw((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 throw((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 ) throw((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 throw((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 ) throw((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