00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00048 #ifndef OPENRJ_INCL_OPENRJ_STL_HPP_DATABASE
00049 #define OPENRJ_INCL_OPENRJ_STL_HPP_DATABASE
00050
00051
00052
00053
00054
00055 #ifndef OPENRJ_DOCUMENTATION_SKIP_SECTION
00056 # define OPENRJ_VER_OPENRJ_STL_HPP_DATABASE_MAJOR 1
00057 # define OPENRJ_VER_OPENRJ_STL_HPP_DATABASE_MINOR 7
00058 # define OPENRJ_VER_OPENRJ_STL_HPP_DATABASE_REVISION 7
00059 # define OPENRJ_VER_OPENRJ_STL_HPP_DATABASE_EDIT 39
00060 #endif
00061
00062
00063
00064
00065
00066 #include <openrj/openrj.h>
00067 #include <openrj/openrj_assert.h>
00068
00069 #include <openrj/stl/openrj.hpp>
00070 #include <openrj/stl/field.hpp>
00071 #include <openrj/stl/record.hpp>
00072
00073 #if defined(ORJ_NO_EXCEPTIONS)
00074 # error The Open-RJ STL mapping is not compilable in the absence of exception
00075 #endif
00076
00077 #include <iterator>
00078
00079 #include <stlsoft/iterators/indirect_reverse_iterator.hpp>
00080 #include <stlsoft/iterator.hpp>
00081 #include <stlsoft/proxy_iterator.hpp>
00082
00083
00084
00085
00086
00087 #ifdef __BORLANDC__
00088 # pragma warn -8027
00089 #endif
00090
00091
00092
00093
00094
00095 #if defined(__BORLANDC__) || \
00096 defined(__COMO__x) || \
00097 ( defined(__DMC__) && \
00098 __DMC__ < 0x0843)|| \
00099 ( defined(__GNUC__) && \
00100 ( __GNUC__ < 3) || \
00101 ( __GNUC__ == 3 && \
00102 __GNUC_MINOR__ < 2)) || \
00103 ( defined(_MSC_VER) && \
00104 ( _MSC_VER < 1200 || \
00105 _MSC_VER == 1300))
00106 # define OPENRJ_STL_DATABASE_NO_FIELD_ITERATORS
00107 #endif
00108
00109
00110
00111
00112
00113 namespace openrj
00114 {
00115
00116 namespace stl
00117 {
00118
00119
00120
00121
00122
00125 class database_base
00126 {
00127 private:
00128 struct proxy_traits_type
00129 {
00130 static field make_value(ORJField const &field_)
00131 {
00132 return field(&field_);
00133 }
00134 };
00135 protected:
00137 typedef database_base class_type;
00138 public:
00140 typedef record value_type;
00142 #ifdef OPENRJ_STL_ITERATOR_HOLDS_VALUE
00143 typedef value_type const &const_reference;
00144 #else
00145 typedef value_type const const_reference;
00146 #endif
00148 typedef value_type const *const_pointer;
00150 typedef ptrdiff_t difference_type;
00152 typedef size_t size_type;
00153 #ifndef OPENRJ_STL_DATABASE_NO_FIELD_ITERATORS
00154
00155
00156
00157
00159 typedef stlsoft::proxy_iterator<const ORJField
00160 , field
00161 , proxy_traits_type
00162 , std::random_access_iterator_tag
00163 , field
00164 > const_field_iterator;
00165
00166 # if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00168 typedef stlsoft_ns_qual(const_reverse_iterator_base)< const_field_iterator
00169 , field
00170 , field
00171 , void
00172 , difference_type
00173 > const_reverse_field_iterator;
00174 # endif
00175 #endif
00177 typedef size_t distance_type;
00178
00179 #ifndef OPENRJ_DOCUMENTATION_SKIP_SECTION
00180 public:
00182 class const_iterator;
00183 #endif
00184
00185 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00187 # if 0
00188 typedef stlsoft_ns_qual(const_reverse_iterator_base)< const_iterator
00189 , value_type
00190 , value_type
00191 , void
00192 , difference_type
00193 > const_reverse_iterator;
00194 # else
00195
00196
00197
00198 typedef stlsoft_ns_qual(indirect_reverse_iterator)< const_iterator
00199 , value_type
00200 , value_type
00201 , void
00202 , difference_type
00203 , std::random_access_iterator_tag
00204 > const_reverse_iterator;
00205 # endif
00206 #endif
00207
00208 protected:
00209 explicit database_base(ORJDatabase const *database);
00210 public:
00212 ~database_base();
00213
00214 public:
00216 size_t num_lines() const;
00218 size_t num_fields() const;
00220 size_t num_records() const;
00222 size_t size() const;
00223
00224 public:
00229 const record operator [](size_t index) const;
00230
00231 public:
00235 const_iterator begin() const;
00239 const_iterator end() const;
00240
00241 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00245 const_reverse_iterator rbegin() const;
00249 const_reverse_iterator rend() const;
00250 #endif
00251
00252 #ifndef OPENRJ_STL_DATABASE_NO_FIELD_ITERATORS
00253 const_field_iterator fields_begin() const;
00254 const_field_iterator fields_end() const;
00255 # if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00256 const_reverse_field_iterator fields_rbegin() const;
00257 const_reverse_field_iterator fields_rend() const;
00258 # endif
00259 #endif
00260
00261
00262 private:
00263 ORJDatabase const *m_database;
00264
00265
00266 private:
00267 database_base(class_type const &);
00268 class_type const &operator =(class_type const &);
00269 };
00270
00271 #ifndef OPENRJ_NO_FILE_HANDLING
00273 class file_database
00274 : public database_base
00275 {
00276 private:
00277 typedef database_base parent_class_type;
00278 public:
00279 typedef file_database class_type;
00280
00281 public:
00287 explicit file_database(char const *jarName, unsigned flags = 0);
00293 template <typename S>
00294 explicit file_database(S const &jarName, unsigned flags = 0)
00295 : parent_class_type(create_database_(::stlsoft::c_str_ptr(jarName), flags))
00296 {}
00297
00298
00299 private:
00300 static ORJDatabase const *create_database_(char const *jarName, unsigned flags);
00301
00302
00303 private:
00304 file_database(class_type const &);
00305 class_type const &operator =(class_type const &);
00306 };
00307
00308 typedef file_database database;
00309 #endif
00310
00312 class memory_database
00313 : public database_base
00314 {
00315 private:
00316 typedef database_base parent_class_type;
00317 public:
00318 typedef memory_database class_type;
00319
00320 public:
00327 explicit memory_database(char const *contents, size_t cbContents, unsigned flags = 0);
00333 template <typename S>
00334 explicit memory_database(S const &contents, unsigned flags = 0)
00335 : parent_class_type(create_database_(::stlsoft::c_str_data(contents), ::stlsoft::c_str_len(contents), flags))
00336 {}
00337 #ifdef __STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT
00343 template <size_t N>
00344 explicit memory_database(const char (&contents)[N], unsigned flags = 0)
00345 : parent_class_type(create_database_(&contents[0], N, flags))
00346 {}
00347 #endif
00348
00349
00350 private:
00351 static ORJDatabase const *create_database_(char const *contents, size_t cbContents, unsigned flags);
00352
00353
00354 private:
00355 memory_database(class_type const &);
00356 class_type const &operator =(class_type const &);
00357 };
00358
00360 class database_base::const_iterator
00361 : public stlsoft::iterator_base<std::random_access_iterator_tag, const database_base::value_type, database_base::distance_type, database_base::const_pointer, database_base::const_reference>
00362 {
00363 public:
00364 typedef database_base::value_type value_type;
00365 typedef database_base::distance_type distance_type;
00366 typedef database_base::difference_type difference_type;
00367
00368 private:
00369 friend class database_base;
00370
00371 const_iterator(ORJRecordA const *record);
00372 public:
00373 const_iterator();
00374 const_iterator(const_iterator const &rhs);
00375
00376 const_iterator &operator =(const_iterator const &rhs);
00377
00378 public:
00379 #ifdef OPENRJ_STL_ITERATOR_HOLDS_VALUE
00380 const_reference operator *() const;
00381 #else
00382 value_type operator *() const;
00383 #endif
00384 const_iterator &operator ++();
00385 const_iterator operator ++(int);
00386 const_iterator &operator --();
00387 const_iterator operator --(int);
00388
00389 public:
00390 const_iterator operator -(difference_type d) const;
00391 difference_type operator -(const_iterator const &rhs) const;
00392
00393 public:
00394 bool equal(const_iterator const &rhs) const;
00395
00396 #if defined(__BORLANDC__) || \
00397 defined(__DMC__)
00398 bool operator ==(const_iterator const &rhs) const;
00399 bool operator !=(const_iterator const &rhs) const;
00400 #endif
00401
00402 private:
00403 ORJRecordA const *m_record;
00404 #ifdef OPENRJ_STL_ITERATOR_HOLDS_VALUE
00405 mutable value_type m_value;
00406 #endif
00407 };
00408
00409
00410
00411
00412
00413 #if !defined(__BORLANDC__) && \
00414 !defined(__DMC__)
00415 inline bool operator ==(database_base::const_iterator const &lhs, database_base::const_iterator const &rhs)
00416 {
00417 return lhs.equal(rhs);
00418 }
00419
00420 inline bool operator !=(database_base::const_iterator const &lhs, database_base::const_iterator const &rhs)
00421 {
00422 return !lhs.equal(rhs);
00423 }
00424 #endif
00425
00426
00427
00428
00429
00430
00431
00432 inline database_base::const_iterator::const_iterator(ORJRecordA const *record)
00433 : m_record(record)
00434 {}
00435
00436 inline database_base::const_iterator::const_iterator()
00437 : m_record(NULL)
00438 {}
00439
00440 inline database_base::const_iterator::const_iterator(database_base::const_iterator const &rhs)
00441 : m_record(rhs.m_record)
00442 {}
00443
00444 inline database_base::const_iterator &database_base::const_iterator::operator =(database_base::const_iterator const &rhs)
00445 {
00446 m_record = rhs.m_record;
00447
00448 return *this;
00449 }
00450
00451 #ifdef OPENRJ_STL_ITERATOR_HOLDS_VALUE
00452 inline database_base::const_reference database_base::const_iterator::operator *() const
00453 {
00454 m_value = value_type(m_record);
00455
00456 return m_value;
00457 }
00458 #else
00459 inline database_base::value_type database_base::const_iterator::operator *() const
00460 {
00461 return record(m_record);
00462 }
00463 #endif
00464
00465 inline database_base::const_iterator &database_base::const_iterator::operator ++()
00466 {
00467 ++m_record;
00468
00469 return *this;
00470 }
00471
00472 inline database_base::const_iterator database_base::const_iterator::operator ++(int)
00473 {
00474 const_iterator ret(*this);
00475
00476 operator ++();
00477
00478 return ret;
00479 }
00480
00481 inline database_base::const_iterator &database_base::const_iterator::operator --()
00482 {
00483 --m_record;
00484
00485 return *this;
00486 }
00487
00488 inline database_base::const_iterator database_base::const_iterator::operator --(int)
00489 {
00490 const_iterator ret(*this);
00491
00492 operator --();
00493
00494 return ret;
00495 }
00496
00497 inline database_base::const_iterator database_base::const_iterator::operator -(database_base::const_iterator::difference_type d) const
00498 {
00499 return const_iterator(&m_record[-d]);
00500 }
00501
00502 inline database_base::difference_type database_base::const_iterator::operator -(database_base::const_iterator const &rhs) const
00503 {
00504 return &rhs.m_record[0] - &m_record[0];
00505 }
00506
00507 inline bool database_base::const_iterator::equal(database_base::const_iterator const &rhs) const
00508 {
00509 return rhs.m_record == m_record;
00510 }
00511
00512 #if defined(__BORLANDC__) || \
00513 defined(__DMC__)
00514 inline bool database_base::const_iterator::operator ==(database_base::const_iterator const &rhs) const
00515 {
00516 return equal(rhs);
00517 }
00518
00519 inline bool database_base::const_iterator::operator !=(database_base::const_iterator const &rhs) const
00520 {
00521 return !equal(rhs);
00522 }
00523 #endif
00524
00525
00526
00527 #ifndef OPENRJ_NO_FILE_HANDLING
00528 inline ORJDatabase const *file_database::create_database_(char const *jarName, unsigned flags)
00529 {
00530 ORJDatabase const *database;
00531 ORJError error;
00532 ORJRC rc = ORJ_ReadDatabase(jarName, NULL, flags, &database, &error);
00533
00534 if(ORJ_RC_SUCCESS != rc)
00535 {
00536 throw database_exception(rc, error);
00537 }
00538
00539 return database;
00540 }
00541
00542 inline file_database::file_database(char const *jarName, unsigned flags )
00543 : parent_class_type(create_database_(jarName, flags))
00544 {}
00545 #endif
00546
00547
00548
00549 inline ORJDatabase const *memory_database::create_database_(char const *contents, size_t cbContents, unsigned flags)
00550 {
00551 ORJDatabase const *database;
00552 ORJError error;
00553 ORJRC rc = ORJ_CreateDatabaseFromMemory(contents, cbContents, NULL, flags, &database, &error);
00554
00555 if(ORJ_RC_SUCCESS != rc)
00556 {
00557 throw database_exception(rc, error);
00558 }
00559
00560 return database;
00561 }
00562
00563 inline memory_database::memory_database(char const *contents, size_t cbContents, unsigned flags)
00564 : parent_class_type(create_database_(contents, cbContents, flags))
00565 {}
00566
00567
00568
00569 inline database_base::database_base(ORJDatabase const *database)
00570 : m_database(database)
00571 {
00572 stlsoft_message_assert("Initialisng database_base with NULL database", NULL != m_database);
00573 }
00574
00575 inline database_base::~database_base()
00576 {
00577 ORJ_FreeDatabase(m_database);
00578 }
00579
00580 inline size_t database_base::num_lines() const
00581 {
00582 openrj_assert(NULL != m_database);
00583
00584 return m_database->numLines;
00585 }
00586
00587 inline size_t database_base::num_fields() const
00588 {
00589 openrj_assert(NULL != m_database);
00590
00591 return m_database->numFields;
00592 }
00593
00594 inline size_t database_base::num_records() const
00595 {
00596 openrj_assert(NULL != m_database);
00597
00598 return m_database->numRecords;
00599 }
00600
00601 inline size_t database_base::size() const
00602 {
00603 return num_records();
00604 }
00605
00606 inline const record database_base::operator [](size_t index) const
00607 {
00608 openrj_assert(index <= num_records());
00609
00610 return record(&m_database->records[index]);
00611 }
00612
00613 inline database_base::const_iterator database_base::begin() const
00614 {
00615 openrj_assert(NULL != m_database);
00616
00617 return &m_database->records[0];
00618 }
00619
00620 inline database_base::const_iterator database_base::end() const
00621 {
00622 openrj_assert(NULL != m_database);
00623
00624 return &m_database->records[m_database->numRecords];
00625 }
00626
00627 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00628 inline database_base::const_reverse_iterator database_base::rbegin() const
00629 {
00630 return const_reverse_iterator(end());
00631 }
00632
00633 inline database_base::const_reverse_iterator database_base::rend() const
00634 {
00635 return const_reverse_iterator(begin());
00636 }
00637 #endif
00638
00639 #ifndef OPENRJ_STL_DATABASE_NO_FIELD_ITERATORS
00640 inline database_base::const_field_iterator database_base::fields_begin() const
00641 {
00642 openrj_assert(NULL != m_database);
00643
00644 return const_field_iterator(&m_database->fields[0], &m_database->fields[m_database->numFields]);
00645 }
00646
00647 inline database_base::const_field_iterator database_base::fields_end() const
00648 {
00649 openrj_assert(NULL != m_database);
00650
00651 return const_field_iterator(&m_database->fields[m_database->numFields], &m_database->fields[m_database->numFields]);
00652 }
00653
00654 # if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00655 inline database_base::const_reverse_field_iterator database_base::fields_rbegin() const
00656 {
00657 return const_reverse_field_iterator(fields_end());
00658 }
00659
00660 inline database_base::const_reverse_field_iterator database_base::fields_rend() const
00661 {
00662 return const_reverse_field_iterator(fields_begin());
00663 }
00664 # endif
00665 #endif
00666
00667
00668
00669
00670
00671 }
00672 }
00673
00674
00675
00676 #endif
00677
00678