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 unsigned int 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
00377 const_iterator end() const;
00378
00381 bool escape_q() const;
00382
00384 bool is_null() const;
00385
00387 void it_is_null();
00388
00390 size_type length() const;
00391
00397 size_type max_size() const { return size(); }
00398
00401 bool quote_q() const;
00402
00404 size_type size() const { return length(); }
00405
00408 void strip_leading_blanks(std::string& s) const
00409 {
00410 const char* pc = data();
00411 if (pc) {
00412 size_type n = length();
00413 while (n && (*pc == ' ')) {
00414 ++pc;
00415 --n;
00416 }
00417
00418 s.assign(pc, n);
00419 }
00420 else {
00421 s.clear();
00422 }
00423 }
00424
00432 void to_string(std::string& s) const;
00433
00435 mysql_type_info type() const
00436 {
00437 return buffer_ ? buffer_->type() : mysql_type_info::string_type;
00438 }
00439
00441 String& operator =(const std::string& rhs)
00442 {
00443 buffer_ = new SQLBuffer(rhs.data(),
00444 static_cast<size_type>(rhs.length()),
00445 mysql_type_info::string_type, false);
00446
00447 return *this;
00448 }
00449
00454 String& operator =(const char* str)
00455 {
00456 buffer_ = new SQLBuffer(str,
00457 static_cast<size_type>(strlen(str)),
00458 mysql_type_info::string_type, false);
00459
00460 return *this;
00461 }
00462
00468 String& operator =(const String& other)
00469 {
00470 buffer_ = other.buffer_;
00471
00472 return *this;
00473 }
00474
00479 char operator [](size_type pos) const;
00480
00482 operator const char*() const { return data(); }
00483
00485 operator signed char() const
00486 { return conv(static_cast<signed char>(0)); }
00487
00489 operator unsigned char() const
00490 { return conv(static_cast<unsigned char>(0)); }
00491
00493 operator int() const
00494 { return conv(static_cast<int>(0)); }
00495
00497 operator unsigned int() const
00498 { return conv(static_cast<unsigned int>(0)); }
00499
00501 operator short int() const
00502 { return conv(static_cast<short int>(0)); }
00503
00506 operator unsigned short int() const
00507 { return conv(static_cast<unsigned short int>(0)); }
00508
00510 operator long int() const
00511 { return conv(static_cast<long int>(0)); }
00512
00515 operator unsigned long int() const
00516 { return conv(static_cast<unsigned long int>(0)); }
00517
00518 #if !defined(NO_LONG_LONGS)
00521 operator longlong() const
00522 { return conv(static_cast<longlong>(0)); }
00523
00526 operator ulonglong() const
00527 { return conv(static_cast<ulonglong>(0)); }
00528 #endif
00529
00531 operator float() const
00532 { return conv(static_cast<float>(0)); }
00533
00535 operator double() const
00536 { return conv(static_cast<double>(0)); }
00537
00539 operator bool() const { return buffer_ ? atoi(c_str()) : false; }
00540
00542 operator Date() const { return buffer_ ? Date(*this) : Date(); }
00543
00545 operator DateTime() const
00546 { return buffer_ ? DateTime(*this) : DateTime(); }
00547
00549 operator Time() const { return buffer_ ? Time(*this) : Time(); }
00550
00554 template <class T, class B>
00555 operator Null<T, B>() const { return conv(Null<T, B>()); }
00556
00557 private:
00559 template <class Type>
00560 Type do_conv(const char* type_name) const
00561 {
00562 if (buffer_) {
00563 std::stringstream buf;
00564 buf.write(data(), length());
00565 buf.imbue(std::locale::classic());
00566 Type num = Type();
00567
00568 if (buf >> num) {
00569 char c;
00570 if (!(buf >> c)) {
00571
00572
00573 return num;
00574 }
00575
00576 if (c == '.' &&
00577 (typeid(Type) != typeid(float)) &&
00578 (typeid(Type) != typeid(double))) {
00579
00580
00581
00582
00583 c = '0';
00584 while (buf >> c && c == '0') ;
00585 if (buf.eof() && c == '0') {
00586 return num;
00587 }
00588 }
00589 }
00590 else if (buf.eof()) {
00591 return num;
00592 }
00593
00594 throw BadConversion(type_name, data(), 0, length());
00595 }
00596 else {
00597 return 0;
00598 }
00599 }
00600
00601 RefCountedBuffer buffer_;
00602
00603 friend class SQLTypeAdapter;
00604 };
00605
00606 MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& o,
00607 const String& in);
00608
00609
00610 #if !defined(MYSQLPP_NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
00611
00612
00613
00614
00615
00616 #define oprsw(opr, other, conv) \
00617 inline other operator opr (String x, other y) \
00618 { return static_cast<conv>(x) opr y; } \
00619 inline other operator opr (other x, String y) \
00620 { return x opr static_cast<conv>(y); }
00621
00622 #define operator_binary(other, conv) \
00623 oprsw(+, other, conv) \
00624 oprsw(-, other, conv) \
00625 oprsw(*, other, conv) \
00626 oprsw(/, other, conv)
00627
00628 #define operator_binary_int(other, conv) \
00629 operator_binary(other, conv) \
00630 oprsw(%, other, conv) \
00631 oprsw(&, other, conv) \
00632 oprsw(^, other, conv) \
00633 oprsw(|, other, conv) \
00634 oprsw(<<, other, conv) \
00635 oprsw(>>, other, conv)
00636
00637
00638 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
00639 # pragma warning(disable: 4244)
00640 #endif
00641
00642 operator_binary(float, double)
00643 operator_binary(double, double)
00644
00645 operator_binary_int(char, long int)
00646 operator_binary_int(int, long int)
00647 operator_binary_int(short int, long int)
00648 operator_binary_int(long int, long int)
00649
00650 operator_binary_int(unsigned char, unsigned long int)
00651 operator_binary_int(unsigned int, unsigned long int)
00652 operator_binary_int(unsigned short int, unsigned long int)
00653 operator_binary_int(unsigned long int, unsigned long int)
00654
00655 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
00656 # pragma warning(default: 4244)
00657 #endif
00658
00659 #if !defined(NO_LONG_LONGS)
00660 operator_binary_int(longlong, longlong)
00661 operator_binary_int(ulonglong, ulonglong)
00662 #endif // !defined(NO_LONG_LONGS)
00663 #endif // !defined(MYSQLPP_NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
00664
00665
00666 #if !defined(DOXYGEN_IGNORE)
00667
00668
00669
00675 template <> MYSQLPP_EXPORT bool String::conv(bool) const;
00676
00689 template <> MYSQLPP_EXPORT String String::conv(String) const;
00690
00692 template <> MYSQLPP_EXPORT std::string String::conv(std::string) const;
00693
00699 template <> MYSQLPP_EXPORT Date String::conv(Date) const;
00700
00706 template <> MYSQLPP_EXPORT DateTime String::conv(DateTime) const;
00707
00713 template <> MYSQLPP_EXPORT Time String::conv(Time) const;
00714
00715 #endif // !defined(DOXYGEN_IGNORE)
00716
00717 }
00718
00719 #endif // !defined(MYSQLPP_MYSTRING_H)