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 #if !defined(MYSQLPP_MYSTRING_H)
00030 #define MYSQLPP_MYSTRING_H
00031
00032 #include "common.h"
00033
00034 #include "datetime.h"
00035 #include "exceptions.h"
00036 #include "null.h"
00037 #include "sql_buffer.h"
00038
00039 #include <string>
00040 #include <sstream>
00041 #include <limits>
00042
00043 #include <stdlib.h>
00044 #include <string.h>
00045
00046 namespace mysqlpp {
00047
00048 #if !defined(DOXYGEN_IGNORE)
00049
00050
00051 namespace detail
00052 {
00053 template<typename T, bool is_signed = std::numeric_limits<T>::is_signed>
00054 struct conv_promotion;
00055
00056 template<>
00057 struct conv_promotion<float>
00058 {
00059 typedef double type;
00060 };
00061
00062 template<>
00063 struct conv_promotion<double>
00064 {
00065 typedef double type;
00066 };
00067
00068 # if !defined(NO_LONG_LONGS)
00069 template<>
00070 struct conv_promotion<unsigned long long>
00071 {
00072 typedef unsigned long long type;
00073 };
00074
00075 template<>
00076 struct conv_promotion<long long>
00077 {
00078 typedef long long type;
00079 };
00080 # endif
00081
00082
00083 template<>
00084 struct conv_promotion<char>
00085 {
00086 typedef long type;
00087 };
00088
00089
00090
00091 template<typename T>
00092 struct conv_promotion<T, true>
00093 {
00094 typedef long type;
00095 };
00096
00097 template<typename T>
00098 struct conv_promotion<T, false>
00099 {
00100 typedef unsigned long type;
00101 };
00102 }
00103
00104 class MYSQLPP_EXPORT SQLTypeAdapter;
00105 #endif // !defined(DOXYGEN_IGNORE)
00106
00138
00139 class MYSQLPP_EXPORT String
00140 {
00141 public:
00144 typedef const char value_type;
00145
00147 typedef size_t size_type;
00148
00150 typedef const char* const_iterator;
00151
00154 typedef const_iterator iterator;
00155
00156 #if !defined(DOXYGEN_IGNORE)
00157
00158 typedef int difference_type;
00159 typedef const char* const_pointer;
00160 typedef const_pointer pointer;
00161 #endif // !defined(DOXYGEN_IGNORE)
00162
00167 String() :
00168 buffer_()
00169 {
00170 }
00171
00179 String(const String& other) :
00180 buffer_(other.buffer_)
00181 {
00182 }
00183
00196 explicit String(const char* str, size_type len,
00197 mysql_type_info type = mysql_type_info::string_type,
00198 bool is_null = false) :
00199 buffer_(new SQLBuffer(str, len, type, is_null))
00200 {
00201 }
00202
00210 explicit String(const std::string& str,
00211 mysql_type_info type = mysql_type_info::string_type,
00212 bool is_null = false) :
00213 buffer_(new SQLBuffer(str.data(), static_cast<size_type>(str.length()),
00214 type, is_null))
00215 {
00216 }
00217
00225 explicit String(const char* str,
00226 mysql_type_info type = mysql_type_info::string_type,
00227 bool is_null = false) :
00228 buffer_(new SQLBuffer(str, static_cast<size_type>(strlen(str)),
00229 type, is_null))
00230 {
00231 }
00232
00234 ~String() { }
00235
00242 void assign(const char* str, size_type len,
00243 mysql_type_info type = mysql_type_info::string_type,
00244 bool is_null = false)
00245 {
00246 buffer_ = new SQLBuffer(str, len, type, is_null);
00247 }
00248
00255 void assign(const std::string& str,
00256 mysql_type_info type = mysql_type_info::string_type,
00257 bool is_null = false)
00258 {
00259 buffer_ = new SQLBuffer(str.data(),
00260 static_cast<size_type>(str.length()), type, is_null);
00261 }
00262
00269 void assign(const char* str,
00270 mysql_type_info type = mysql_type_info::string_type,
00271 bool is_null = false)
00272 {
00273 buffer_ = new SQLBuffer(str, static_cast<size_type>(strlen(str)),
00274 type, is_null);
00275 }
00276
00281 char at(size_type pos) const;
00282
00285 const_iterator begin() const { return data(); }
00286
00288 const char* c_str() const { return data(); }
00289
00290 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
00291
00292 # pragma warning(disable: 4244)
00293 #endif
00294
00297 template <class Type>
00298 Type conv(Type) const
00299 {
00300
00301
00302
00303 typedef typename detail::conv_promotion<Type>::type conv_type;
00304 return do_conv<conv_type>(typeid(Type).name());
00305 }
00306
00307 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
00308 # pragma warning(default: 4244)
00309 #endif
00310
00317 template <class T, class B>
00318 Null<T, B> conv(Null<T, B>) const
00319 {
00320 if (is_null()) {
00321 return Null<T, B>(null);
00322 }
00323 else {
00324 return Null<T, B>(conv(T()));
00325 }
00326 }
00327
00333 int compare(const String& other) const;
00334
00340 int compare(const std::string& other) const;
00341
00350 int compare(size_type pos, size_type num, std::string& other) const;
00351
00357 int compare(const char* other) const;
00358
00369 int compare(size_type pos, size_type num, const char* other) const;
00370
00373 const char* data() const;
00374
00376 bool empty() const { return size() == 0; }
00377
00380 const_iterator end() const;
00381
00384 bool escape_q() const;
00385
00387 bool is_null() const;
00388
00390 void it_is_null();
00391
00400 size_type length() const;
00401
00407 size_type max_size() const { return size(); }
00408
00411 bool quote_q() const;
00412
00417 size_type size() const { return length(); }
00418
00421 void strip_leading_blanks(std::string& s) const
00422 {
00423 const char* pc = data();
00424 if (pc) {
00425 size_type n = length();
00426 while (n && (*pc == ' ')) {
00427 ++pc;
00428 --n;
00429 }
00430
00431 s.assign(pc, n);
00432 }
00433 else {
00434 s.clear();
00435 }
00436 }
00437
00445 void to_string(std::string& s) const;
00446
00448 mysql_type_info type() const
00449 {
00450 return buffer_ ? buffer_->type() : mysql_type_info::string_type;
00451 }
00452
00454 String& operator =(const std::string& rhs)
00455 {
00456 buffer_ = new SQLBuffer(rhs.data(),
00457 static_cast<size_type>(rhs.length()),
00458 mysql_type_info::string_type, false);
00459
00460 return *this;
00461 }
00462
00467 String& operator =(const char* str)
00468 {
00469 buffer_ = new SQLBuffer(str,
00470 static_cast<size_type>(strlen(str)),
00471 mysql_type_info::string_type, false);
00472
00473 return *this;
00474 }
00475
00481 String& operator =(const String& other)
00482 {
00483 buffer_ = other.buffer_;
00484
00485 return *this;
00486 }
00487
00492 template <typename T>
00493 bool operator ==(const T& rhs) const
00494 {
00495 return compare(rhs) == 0;
00496 }
00497
00501 bool operator ==(const mysqlpp::null_type&) const
00502 {
00503 return is_null();
00504 }
00505
00510 template <typename T>
00511 bool operator !=(const T& rhs) const
00512 {
00513 return compare(rhs) != 0;
00514 }
00515
00519 bool operator !=(const mysqlpp::null_type&) const
00520 {
00521 return !is_null();
00522 }
00523
00530 char operator [](size_type pos) const { return at(pos); }
00531
00533 operator const char*() const { return data(); }
00534
00536 operator signed char() const
00537 { return conv(static_cast<signed char>(0)); }
00538
00540 operator unsigned char() const
00541 { return conv(static_cast<unsigned char>(0)); }
00542
00544 operator int() const
00545 { return conv(static_cast<int>(0)); }
00546
00548 operator unsigned int() const
00549 { return conv(static_cast<unsigned int>(0)); }
00550
00552 operator short int() const
00553 { return conv(static_cast<short int>(0)); }
00554
00557 operator unsigned short int() const
00558 { return conv(static_cast<unsigned short int>(0)); }
00559
00561 operator long int() const
00562 { return conv(static_cast<long int>(0)); }
00563
00566 operator unsigned long int() const
00567 { return conv(static_cast<unsigned long int>(0)); }
00568
00569 #if !defined(NO_LONG_LONGS)
00572 operator longlong() const
00573 { return conv(static_cast<longlong>(0)); }
00574
00577 operator ulonglong() const
00578 { return conv(static_cast<ulonglong>(0)); }
00579 #endif
00580
00582 operator float() const
00583 { return conv(static_cast<float>(0)); }
00584
00586 operator double() const
00587 { return conv(static_cast<double>(0)); }
00588
00590 operator bool() const { return buffer_ ? atoi(c_str()) : false; }
00591
00593 operator Date() const { return buffer_ ? Date(*this) : Date(); }
00594
00596 operator DateTime() const
00597 { return buffer_ ? DateTime(*this) : DateTime(); }
00598
00600 operator Time() const { return buffer_ ? Time(*this) : Time(); }
00601
00605 template <class T, class B>
00606 operator Null<T, B>() const { return conv(Null<T, B>()); }
00607
00608 private:
00610 template <class Type>
00611 Type do_conv(const char* type_name) const
00612 {
00613 if (buffer_) {
00614 std::stringstream buf;
00615 buf.write(data(), static_cast<std::streamsize>(length()));
00616 buf.imbue(std::locale::classic());
00617 Type num = Type();
00618
00619 if (buf >> num) {
00620 char c;
00621 if (!(buf >> c)) {
00622
00623
00624 return num;
00625 }
00626
00627 if (c == '.' &&
00628 (typeid(Type) != typeid(float)) &&
00629 (typeid(Type) != typeid(double))) {
00630
00631
00632
00633
00634 c = '0';
00635 while (buf >> c && c == '0') ;
00636 if (buf.eof() && c == '0') {
00637 return num;
00638 }
00639 }
00640 }
00641 else if (buf.eof()) {
00642 return num;
00643 }
00644
00645 throw BadConversion(type_name, data(), 0, length());
00646 }
00647 else {
00648 return 0;
00649 }
00650 }
00651
00652 RefCountedBuffer buffer_;
00653
00654 friend class SQLTypeAdapter;
00655 };
00656
00657 MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& o,
00658 const String& in);
00659
00660
00661 #if !defined(MYSQLPP_NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
00662
00663
00664
00665
00666
00667 #define oprsw(opr, other, conv) \
00668 inline other operator opr (String x, other y) \
00669 { return static_cast<conv>(x) opr y; } \
00670 inline other operator opr (other x, String y) \
00671 { return x opr static_cast<conv>(y); }
00672
00673 #define operator_binary(other, conv) \
00674 oprsw(+, other, conv) \
00675 oprsw(-, other, conv) \
00676 oprsw(*, other, conv) \
00677 oprsw(/, other, conv)
00678
00679 #define operator_binary_int(other, conv) \
00680 operator_binary(other, conv) \
00681 oprsw(%, other, conv) \
00682 oprsw(&, other, conv) \
00683 oprsw(^, other, conv) \
00684 oprsw(|, other, conv) \
00685 oprsw(<<, other, conv) \
00686 oprsw(>>, other, conv)
00687
00688
00689 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
00690 # pragma warning(disable: 4244)
00691 #endif
00692
00693 operator_binary(float, double)
00694 operator_binary(double, double)
00695
00696 operator_binary_int(char, long int)
00697 operator_binary_int(int, long int)
00698 operator_binary_int(short int, long int)
00699 operator_binary_int(long int, long int)
00700
00701 operator_binary_int(unsigned char, unsigned long int)
00702 operator_binary_int(unsigned int, unsigned long int)
00703 operator_binary_int(unsigned short int, unsigned long int)
00704 operator_binary_int(unsigned long int, unsigned long int)
00705
00706 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
00707 # pragma warning(default: 4244)
00708 #endif
00709
00710 #if !defined(NO_LONG_LONGS)
00711 operator_binary_int(longlong, longlong)
00712 operator_binary_int(ulonglong, ulonglong)
00713 #endif // !defined(NO_LONG_LONGS)
00714 #endif // !defined(MYSQLPP_NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
00715
00716
00717 #if !defined(DOXYGEN_IGNORE)
00718
00719
00720
00726 template <> MYSQLPP_EXPORT bool String::conv(bool) const;
00727
00740 template <> MYSQLPP_EXPORT String String::conv(String) const;
00741
00743 template <> MYSQLPP_EXPORT std::string String::conv(std::string) const;
00744
00750 template <> MYSQLPP_EXPORT Date String::conv(Date) const;
00751
00757 template <> MYSQLPP_EXPORT DateTime String::conv(DateTime) const;
00758
00764 template <> MYSQLPP_EXPORT Time String::conv(Time) const;
00765
00766 #endif // !defined(DOXYGEN_IGNORE)
00767
00768 }
00769
00770 #endif // !defined(MYSQLPP_MYSTRING_H)