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
00046 #ifndef OPENRJ_INCL_OPENRJ_CPP_H_RECORD
00047 #define OPENRJ_INCL_OPENRJ_CPP_H_RECORD
00048
00049
00050
00051
00052
00053 #ifndef OPENRJ_DOCUMENTATION_SKIP_SECTION
00054 # define OPENRJ_VER_OPENRJ_CPP_H_RECORD_MAJOR 1
00055 # define OPENRJ_VER_OPENRJ_CPP_H_RECORD_MINOR 7
00056 # define OPENRJ_VER_OPENRJ_CPP_H_RECORD_REVISION 4
00057 # define OPENRJ_VER_OPENRJ_CPP_H_RECORD_EDIT 22
00058 #endif
00059
00060
00061
00062
00063
00064 #include <openrj/cpp/openrj.hpp>
00065 #include <openrj/cpp/field.hpp>
00066
00067 #include <stlsoft/stlsoft.h>
00068 #include <stlsoft/memory/auto_buffer.hpp>
00069 #ifdef __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00070 # include <stlsoft/meta/is_integral_type.hpp>
00071 # include <stlsoft/meta/select_first_type_if.hpp>
00072 # include <stlsoft/meta/yesno.hpp>
00073 #endif
00074
00075 #include <stdio.h>
00076 #include <algorithm>
00077 #include <stdexcept>
00078
00079
00080
00081
00082
00083 namespace openrj
00084 {
00085 namespace cpp
00086 {
00087
00088
00089
00090
00091
00093 class Record
00094 {
00095 private:
00096 friend class DatabaseBase;
00097
00098 Record(ORJRecord const &record)
00099 : m_record(&record)
00100 {}
00101 public:
00103 Record()
00104 : m_record(NULL)
00105 {}
00107 Record(Record const &rhs)
00108 : m_record(rhs.m_record)
00109 {}
00110
00112 Record &operator =(Record const &rhs)
00113 {
00114 m_record = rhs.m_record;
00115
00116 return *this;
00117 }
00118
00119 public:
00121 String GetComment() const
00122 {
00123 openrj_assert(NULL != m_record);
00124
00125 ORJStringA const *comment;
00126
00127 return (ORJ_RC_SUCCESS == ORJ_Record_GetCommentA(m_record, &comment)) ? String(comment->ptr, comment->len) : String();
00128 }
00129
00131 size_t GetNumFields() const
00132 {
00133 openrj_assert(NULL != m_record);
00134
00135 return ORJ_Record_GetNumFieldsA(m_record);
00136 }
00137
00154 const Field operator [](size_t index) const
00155 {
00156 openrj_assert(index <= GetNumFields());
00157
00158 ORJFieldA const *field;
00159
00160 if(ORJ_RC_SUCCESS != ORJ_Record_GetFieldA(m_record, index, &field))
00161 {
00162 field = NULL;
00163 }
00164
00165 return Field(field);
00166 }
00167
00172 bool has_field_with_name(char const *name, ORJField const **pfield = NULL) const
00173 {
00174 ORJField const *const begin = &m_record->fields[0];
00175 ORJField const *const end = &m_record->fields[m_record->numFields];
00176 ORJField const *it = ::std::find_if(begin, end, match_name(name));
00177
00178 if(NULL != pfield)
00179 {
00180 *pfield = (it == end) ? NULL : it;
00181 }
00182
00183 return (it != end);
00184 }
00185
00186 bool HasField(char const *name) const
00187 {
00188 return NULL != ORJ_Record_FindFieldByNameA(m_record, name, NULL);
00189 }
00190
00191 bool HasField(char const *name, char const *value) const
00192 {
00193 return NULL != ORJ_Record_FindFieldByNameA(m_record, name, value);
00194 }
00195
00196 bool HasFieldWithValue(char const *value) const
00197 {
00198 return NULL != ORJ_Record_FindFieldByNameA(m_record, NULL, value);
00199 }
00200
00201 #if !defined(ORJ_NO_EXCEPTIONS)
00219 String operator [](char const *name) const
00220 {
00221 openrj_assert(NULL != name);
00222
00223 ORJField const *begin = &m_record->fields[0];
00224 ORJField const *end = &m_record->fields[m_record->numFields];
00225 ORJField const *it = ::std::find_if(begin, end, match_name(name));
00226
00227 if(it == end)
00228 {
00229 const size_t nameLen = ::strlen(name);
00230 static const char fmt[] = "Field \"%s\" not found";
00231 stlsoft::auto_buffer<char> buff(nameLen + stlsoft_num_elements(fmt));
00232
00233 throw ::std::out_of_range((0 == buff.size()) ? "Field not found" : (::sprintf(&buff[0], fmt, name), buff.data()));
00234 }
00235
00236 return String(it->value.ptr, it->value.len);
00237 }
00238
00239
00240 # if defined(__STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT) && \
00241 !defined(STLSOFT_COMPILER_IS_BORLAND)
00242 template <typename S>
00243 String subscript_operator_(S const &name, stlsoft::no_type) const
00244 {
00245 return operator [](::stlsoft::c_str_ptr(name));
00246 }
00247
00248 template <typename I>
00249 Field subscript_operator_(I const &index, stlsoft::yes_type) const
00250 {
00251 return operator [](static_cast<size_t>(index));
00252 }
00253
00259 template <typename S>
00260 typename stlsoft::select_first_type_if<Field, String, stlsoft::is_integral_type<S>::value>::type operator [](S const &name) const
00261 {
00262 typedef typename stlsoft::is_integral_type<S>::type yesno_type;
00263
00264 return subscript_operator_(name, yesno_type());
00265 }
00266 # else
00272 # if !defined(STLSOFT_COMPILER_IS_MSVC) || \
00273 _MSC_VER >= 1200
00274 template <typename S>
00275 typename String operator [](S const &name) const
00276 {
00277 return operator [](::stlsoft::c_str_ptr(name));
00278 }
00279 # endif
00280
00281 # ifndef OPENRJ_DOCUMENTATION_SKIP_SECTION
00282 const Field operator [](int index) const
00283 {
00284 return operator [](static_cast<size_t>(index));
00285 }
00286
00287
00288
00289
00290 # endif
00291 # endif
00292 #endif
00293
00294
00295 private:
00296 struct match_name
00297 {
00298 public:
00299 match_name(char const *name)
00300 : m_name(name)
00301 {}
00302
00303 public:
00304 bool operator ()(ORJField const &field) const
00305 {
00306 return 0 == strcmp(m_name, field.name.ptr);
00307 }
00308
00309 private:
00310 char const *m_name;
00311 };
00312
00313
00314 private:
00315 ORJRecord const *m_record;
00316 };
00317
00318
00319
00320
00321
00322 }
00323 }
00324
00325
00326
00327 #endif
00328
00329