diff --git a/qse/include/qse/cmn/StrBase.hpp b/qse/include/qse/cmn/StrBase.hpp index c52dd415..33887921 100644 --- a/qse/include/qse/cmn/StrBase.hpp +++ b/qse/include/qse/cmn/StrBase.hpp @@ -310,6 +310,20 @@ protected: this->ref_item (); } + void force_size (qse_size_t size) const + { + // for internal use only. + QSE_ASSERT (size < this->getCapacity()); + this->_item->size = size; + } + + qse_size_t round_capacity (qse_size_t n) + { + if (n == 0) n = 1; + return (n + (qse_size_t)DEFAULT_CAPACITY - 1) & + ~((qse_size_t)DEFAULT_CAPACITY - (qse_size_t)1); + } + public: qse_size_t getSize () const @@ -357,12 +371,12 @@ public: bool operator== (const CHAR_TYPE* str) const { - return this->_opset.compare (this->_item->buffer, this->_item_size, str) == 0; + return this->_opset.compare (this->_item->buffer, this->_item->size, str) == 0; } bool operator!= (const CHAR_TYPE* str) const { - return this->_opset.compare (this->_item->buffer, this->_item_size, str) != 0; + return this->_opset.compare (this->_item->buffer, this->_item->size, str) != 0; } // i don't want the caller to be able to change the character @@ -425,7 +439,7 @@ public: StringItem* t; if (new_size > this->_item->capacity) - t = this->_item->copy (this->getMmgr(), this->adjust_new_capacity(new_size)); + t = this->_item->copy (this->getMmgr(), this->adjust_desired_capacity(new_size)); else t = this->_item->copy (this->getMmgr()); @@ -435,7 +449,7 @@ public: } else if (new_size > this->_item->capacity) { - StringItem* t = this->_item->copy (this->getMmgr(), this->adjust_new_capacity(new_size)); + StringItem* t = this->_item->copy (this->getMmgr(), this->adjust_desired_capacity(new_size)); old_item = this->_item; this->_item = t; this->ref_item ();; @@ -539,82 +553,6 @@ public: return *this; } -#if 0 - void appendFormat (const CHAR_TYPE* fmt, ...) - { - /* - int n; - if (this->_item->isShared()) - { - StringItem* t = this->_item->copy (); - this->_item->deref (); this->_item = t; this->_item->ref (); - } - qse_va_start (ap, fmt); - while ((n = SelfType::opset.vsprintf (&this->_item->buffer[this->_item->size], this->_item->capacity - this->_item->size, fmt, ap)) <= -1) - { - this->_item->growBy (calc_new_inc_for_growth (0)); - qse_va_end (ap); - qse_va_start (ap, fmt); - } - qse_va_end (ap); - this->_item->size += n; - */ - qse_va_list ap; - qse_va_start (ap, fmt); - this->appendFormat (fmt, ap); - qse_va_end (ap); - } - - void appendFormat (const CHAR_TYPE* fmt, qse_va_list ap) - { - int n; - qse_va_list save_ap; - - if (this->_item->isShared()) this->possess_data (); - - qse_size_t n = this->_opset.format (QSE_NULL, 0, fmt, ap); - if (n == (qse_size_t)-1) - { - // there's conversion error. - ???? - } - - qse_va_copy (save_ap, ap); - while ((n = this->_opset.format (&this->_item->buffer[this->_item->size], this->_item->capacity - this->_item->size, fmt, ap)) <= -1) - { - this->_item->growBy (calc_new_inc_for_growth (0)); - qse_va_copy (ap, save_ap); - } - - this->_item->size += n; - } -#endif - -#if 0 - int format (const CHAR_TYPE* fmt, va_list ap) - { - int n; - qse_va_list save_ap; - - QSE_VA_COPY (save_ap, ap); - qse_size_t n = this->_opset.format (QSE_NULL, 0, fmt, ap); - if (n == (qse_size_t)-1) - { - // there's conversion error. - return -1; - } - - if (n > this->getCapacity()) this->possess_data (n); - else if (this->_item->isShared()) this->possess_data (); - - QSE_VA_COPY (ap, save_ap); - this->_opset.format (this->_item->buffer, this->_item->capacity + 1, fmt, ap); - - this->_item->size = n; - return 0; - } -#endif - void update (const CHAR_TYPE* str, qse_size_t size) { this->clear (); @@ -1000,15 +938,9 @@ protected: OPSET _opset; RESIZER _resizer; -private: - qse_size_t round_capacity (qse_size_t n) - { - if (n == 0) n = 1; - return (n + (qse_size_t)DEFAULT_CAPACITY - 1) & - ~((qse_size_t)DEFAULT_CAPACITY - (qse_size_t)1); - } - qse_size_t adjust_new_capacity (qse_size_t new_desired_capacity) +private: + qse_size_t adjust_desired_capacity (qse_size_t new_desired_capacity) { qse_size_t new_capacity = this->_resizer(this->_item->capacity, new_desired_capacity, this->getGrowthPolicy()); new_capacity = this->round_capacity(new_capacity); diff --git a/qse/include/qse/cmn/String.hpp b/qse/include/qse/cmn/String.hpp index b05aa839..471426ca 100644 --- a/qse/include/qse/cmn/String.hpp +++ b/qse/include/qse/cmn/String.hpp @@ -176,8 +176,8 @@ struct MbStringOpset } }; -// It's a pain to inherit StrBase<>. i do this not to have various va_xxx calls -// in the header file of StrBase. +// It's a pain to inherit StrBase<> as it has many constructors. +// i do this to hide various va_xxx calls from the header file of StrBase. class WcString: public StrBase { @@ -194,12 +194,12 @@ public: WcString (Mmgr* mmgr, const qse_wchar_t* str, qse_size_t size): ParentType(mmgr, str, size) {} WcString (qse_wchar_t c, qse_size_t size): ParentType(c, size) {} WcString (Mmgr* mmgr, qse_wchar_t c, qse_size_t size): ParentType(mmgr, c, size) {} - WcString (const WcString& str): ParentType(str) {} WcString& operator= (const WcString& str) { ParentType::operator=(str); return *this; } WcString& operator= (const qse_wchar_t* str) { ParentType::operator=(str); return *this; } WcString& operator= (const qse_wchar_t c) { ParentType::operator=(c); return *this; } + //using ParentType::operator=; int format (const qse_wchar_t* fmt, ...); int formatv (const qse_wchar_t* fmt, va_list ap); @@ -220,12 +220,12 @@ public: MbString (Mmgr* mmgr, const qse_mchar_t* str, qse_size_t size): ParentType(mmgr, str, size) {} MbString (qse_mchar_t c, qse_size_t size): ParentType(c, size) {} MbString (Mmgr* mmgr, qse_mchar_t c, qse_size_t size): ParentType(mmgr, c, size) {} - MbString (const MbString& str): ParentType(str) {} MbString& operator= (const MbString& str) { ParentType::operator=(str); return *this; } MbString& operator= (const qse_mchar_t* str) { ParentType::operator=(str); return *this; } MbString& operator= (const qse_mchar_t c) { ParentType::operator=(c); return *this; } + //using ParentType::operator=; int format (const qse_mchar_t* fmt, ...); int formatv (const qse_mchar_t* fmt, va_list ap); diff --git a/qse/lib/cmn/fmt-out.h b/qse/lib/cmn/fmt-out.h index 1b75c2b2..53ddca68 100644 --- a/qse/lib/cmn/fmt-out.h +++ b/qse/lib/cmn/fmt-out.h @@ -383,7 +383,7 @@ reswitch: lowercase_c: ach = QSE_SIZEOF(char_t) < QSE_SIZEOF(int)? va_arg(ap, int): va_arg(ap, char_t); - print_lowercase_c: + print_lowercase_c: /* precision 0 doesn't kill the letter */ width--; if (!(flagc & FLAGC_LEFTADJ) && width > 0) @@ -645,7 +645,7 @@ reswitch: if (flagc & FLAGC_STAR1) fltfmt.ptr[fmtlen++] = QSE_T('*'); else if (flagc & FLAGC_WIDTH) { - fmtlen += qse_fmtuintmaxtombs ( + fmtlen += qse_fmtuintmaxtombs ( &fltfmt.ptr[fmtlen], fltfmt.capa - fmtlen, width, 10, -1, QSE_MT('\0'), QSE_NULL); } @@ -653,7 +653,7 @@ reswitch: if (flagc & FLAGC_STAR2) fltfmt.ptr[fmtlen++] = QSE_T('*'); else if (flagc & FLAGC_PRECISION) { - fmtlen += qse_fmtuintmaxtombs ( + fmtlen += qse_fmtuintmaxtombs ( &fltfmt.ptr[fmtlen], fltfmt.capa - fmtlen, precision, 10, -1, QSE_MT('\0'), QSE_NULL); } @@ -668,7 +668,7 @@ reswitch: fltfmt.ptr[fmtlen++] = ch; fltfmt.ptr[fmtlen] = QSE_MT('\0'); - #if defined(HAVE_SNPRINTF) + #if defined(HAVE_SNPRINTF) /* nothing special here */ #else /* best effort to avoid buffer overflow when no snprintf is available. @@ -782,7 +782,7 @@ handle_nosign: num = va_arg (ap, unsigned long long int); #endif else if (lm_flag & (LF_L | LF_LD)) - num = va_arg (ap, long int); + num = va_arg (ap, unsigned long int); else if (lm_flag & LF_H) num = (unsigned short int)va_arg (ap, int); else if (lm_flag & LF_C) @@ -802,7 +802,7 @@ handle_sign: * This is just a work-around for it */ int i; for (i = 0, num = 0; i < QSE_SIZEOF(qse_intmax_t) / QSE_SIZEOF(qse_size_t); i++) - { + { #if defined(QSE_ENDIAN_BIG) num = num << (8 * QSE_SIZEOF(qse_size_t)) | (va_arg (ap, qse_size_t)); #else diff --git a/qse/samples/cmn/str02.cpp b/qse/samples/cmn/str02.cpp index be9f2e3c..2ffaf937 100644 --- a/qse/samples/cmn/str02.cpp +++ b/qse/samples/cmn/str02.cpp @@ -1,6 +1,7 @@ #include #include #include +#include void t1 () @@ -84,16 +85,48 @@ void t1 () } +#include void t2() { QSE::MbString x(QSE_MT("this is a string")); - qse_printf (QSE_T("x: [%hs] %d %d\n"), x.getBuffer(), (int)x.getCapacity(), (int)x.getLength()); - x.format (QSE_MT("what is this %d %d"), 10, 20); - qse_printf (QSE_T("x: [%hs] %d %d\n"), x.getBuffer(), (int)x.getCapacity(), (int)x.getLength()); + QSE::MbString z(QSE_MT("this is a string")); + qse_printf (QSE_T("x: [%hs] capa=%d len=%d\n"), x.getBuffer(), (int)x.getCapacity(), (int)x.getLength()); + QSE::MbString y(x); + y.format (QSE_MT("what is this %u %u fuck i don't like [%hs] 01234567890123456789 [%lu] [%ld]"), (int)10, (int)20, QSE_MT("what is what"), (unsigned long)QSE_TYPE_MAX(unsigned long), (long)QSE_TYPE_MAX(long)); + qse_printf (QSE_T("y: [%hs] capa=%d len=%d\n"), y.getBuffer(), (int)y.getCapacity(), (int)y.getLength()); + + qse_size_t zl = z.getLength(); + z.append (QSE_MT("is this good how do you do 0123456789 abcdefghijklmnopqrstuvwxyz AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBVVVVVVVVVVVVVVVVVVVVVVDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD?")); + qse_printf (QSE_T("z: [%hs] capa=%d len=%d\n"), z.getBuffer(), (int)z.getCapacity(), (int)z.getLength()); + QSE_ASSERT (z.getCapacity() > x.getCapacity()); + + z.remove (zl, z.getLength() - zl); + QSE_ASSERT (z.getCapacity() > x.getCapacity()); + QSE_ASSERT (z.getLength() == x.getLength()); + + QSE_ASSERT (x == x.getBuffer()); + QSE_ASSERT (x != y.getBuffer()); + QSE_ASSERT (y == y.getBuffer()); + QSE_ASSERT (y != x.getBuffer()); + + QSE_ASSERT (x != y); + QSE_ASSERT (y == y); + QSE_ASSERT (x == z); + QSE_ASSERT (x.getBuffer() != z.getBuffer()); + + z.compact (); + QSE_ASSERT (z.getCapacity() == z.getLength()); + QSE_ASSERT (z.getLength() == x.getLength()); + + qse_printf (QSE_T("z: [%hs] capa=%d len=%d\n"), z.getBuffer(), (int)z.getCapacity(), (int)z.getLength()); + + z.format (QSE_MT("hello %p world"), z.getBuffer()); + qse_printf (QSE_T("z: [%hs] capa=%d len=%d\n"), z.getBuffer(), (int)z.getCapacity(), (int)z.getLength()); } int main () { + setlocale (LC_ALL, ""); qse_openstdsios (); t1 ();