ustring.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 978 行 · 第 1/2 页
CPP
978 行
delete [] statBuffer; statBuffer = new char [neededSize]; statBufferSize = neededSize; } const UChar *p = data(); char *q = statBuffer; const UChar *limit = p + length; while (p != limit) { *q = p->uc; ++p; ++q; } *q = '\0'; return statBuffer;}#ifdef KJS_DEBUG_MEMvoid UString::globalClear(){ delete [] statBuffer; statBuffer = 0; statBufferSize = 0;}#endifUString &UString::operator=(const char *c){ int l = c ? strlen(c) : 0; UChar *d; if (rep->rc == 1 && l <= rep->capacity) { d = rep->dat; rep->_hash = 0; } else { release(); d = allocateChars(l); rep = Rep::create(d, l); } for (int i = 0; i < l; i++) d[i].uc = c[i]; return *this;}UString &UString::operator=(const UString &str){ str.rep->ref(); release(); rep = str.rep; return *this;}bool UString::is8Bit() const{ const UChar *u = data(); const UChar *limit = u + size(); while (u < limit) { if (u->uc > 0xFF) return false; ++u; } return true;}UChar UString::operator[](int pos) const{ if (pos >= size()) return UChar::null; return ((UChar *)data())[pos];}UCharReference UString::operator[](int pos){ /* TODO: boundary check */ return UCharReference(this, pos);}static int skipInfString(const char *start){ const char *c = start; if (*c == '+' || *c == '-') c++; if (!strncmp(c,"Infinity",8)) return c+8-start; while (*c >= '0' && *c <= '9') c++; const char * const at_dot = c; if (*c == '.') c++; while (*c >= '0' && *c <= '9') c++; // don't accept a single dot as a number if (c - at_dot == 1 && *at_dot == '.') return at_dot-start; if (*c != 'e') return c-start; c++; if (*c == '+' || *c == '-') c++; while (*c >= '0' && *c <= '9') c++; return c-start;}double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const{ double d; double sign = 1; // FIXME: If tolerateTrailingJunk is true, then we want to tolerate non-8-bit junk // after the number, so is8Bit is too strict a check. if (!is8Bit()) return NaN; const char *c = ascii(); // skip leading white space while (isspace(*c)) c++; // empty string ? if (*c == '\0') return tolerateEmptyString ? 0.0 : NaN; if (*c == '-') { sign = -1; c++; } else if (*c == '+') { sign = 1; c++; } // hex number ? if (*c == '0' && (*(c+1) == 'x' || *(c+1) == 'X')) { c++; d = 0.0; while (*(++c)) { if (*c >= '0' && *c <= '9') d = d * 16.0 + *c - '0'; else if ((*c >= 'A' && *c <= 'F') || (*c >= 'a' && *c <= 'f')) d = d * 16.0 + (*c & 0xdf) - 'A' + 10.0; else break; } } else { // regular number ? char *end; d = kjs_strtod(c, &end); if ((d != 0.0 || end != c) && d != HUGE_VAL && d != -HUGE_VAL) { c = end; } else { // infinity ? int count = skipInfString(c); if (count == 0) return NaN; d = Inf; c += count; } } // allow trailing white space while (isspace(*c)) c++; // don't allow anything after - unless tolerant=true if (!tolerateTrailingJunk && *c != '\0') return NaN; return d*sign;}double UString::toDouble(bool tolerateTrailingJunk) const{ return toDouble(tolerateTrailingJunk, true);}double UString::toDouble() const{ return toDouble(false, true);}unsigned long UString::toULong(bool *ok, bool tolerateEmptyString) const{ double d = toDouble(false, tolerateEmptyString); bool b = true; if (isNaN(d) || d != static_cast<unsigned long>(d)) { b = false; d = 0; } if (ok) *ok = b; return static_cast<unsigned long>(d);}unsigned long UString::toULong(bool *ok) const{ return toULong(ok, true);}UString UString::toLower() const{ UString u = *this; for (int i = 0; i < size(); i++) u[i] = u[i].toLower(); return u;}UString UString::toUpper() const{ UString u = *this; for (int i = 0; i < size(); i++) u[i] = u[i].toUpper(); return u;}unsigned int UString::toUInt32(bool *ok) const{ double d = toDouble(); bool b = true; if (isNaN(d) || d != static_cast<unsigned>(d)) { b = false; d = 0; } if (ok) *ok = b; return static_cast<unsigned>(d);}unsigned int UString::toStrictUInt32(bool *ok) const{ if (ok) *ok = false; // Empty string is not OK. int len = rep->len; if (len == 0) return 0; const UChar *p = rep->dat; unsigned short c = p->unicode(); // If the first digit is 0, only 0 itself is OK. if (c == '0') { if (len == 1 && ok) *ok = true; return 0; } // Convert to UInt32, checking for overflow. unsigned int i = 0; while (1) { // Process character, turning it into a digit. if (c < '0' || c > '9') return 0; const unsigned d = c - '0'; // Multiply by 10, checking for overflow out of 32 bits. if (i > 0xFFFFFFFFU / 10) return 0; i *= 10; // Add in the digit, checking for overflow out of 32 bits. const unsigned max = 0xFFFFFFFFU - d; if (i > max) return 0; i += d; // Handle end of string. if (--len == 0) { if (ok) *ok = true; return i; } // Get next character. c = (++p)->unicode(); }}// Rule from ECMA 15.2 about what an array index is.// Must exactly match string form of an unsigned integer, and be less than 2^32 - 1.unsigned UString::toArrayIndex(bool *ok) const{ unsigned i = toStrictUInt32(ok); if (i >= 0xFFFFFFFFU && ok) *ok = false; return i;}int UString::find(const UString &f, int pos) const{ int sz = size(); int fsz = f.size(); if (sz < fsz) return -1; if (pos < 0) pos = 0; if (fsz == 0) return pos; const UChar *end = data() + sz - fsz; long fsizeminusone = (fsz - 1) * sizeof(UChar); const UChar *fdata = f.data(); unsigned short fchar = fdata->uc; ++fdata; for (const UChar *c = data() + pos; c <= end; c++) if (c->uc == fchar && !memcmp(c + 1, fdata, fsizeminusone)) return (c-data()); return -1;}int UString::find(UChar ch, int pos) const{ if (pos < 0) pos = 0; const UChar *end = data() + size(); for (const UChar *c = data() + pos; c < end; c++) if (*c == ch) return (c-data()); return -1;}int UString::rfind(const UString &f, int pos) const{ int sz = size(); int fsz = f.size(); if (sz < fsz) return -1; if (pos < 0) pos = 0; if (pos > sz - fsz) pos = sz - fsz; if (fsz == 0) return pos; long fsizeminusone = (fsz - 1) * sizeof(UChar); const UChar *fdata = f.data(); for (const UChar *c = data() + pos; c >= data(); c--) { if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone)) return (c-data()); } return -1;}int UString::rfind(UChar ch, int pos) const{ if (isEmpty()) return -1; if (pos + 1 >= size()) pos = size() - 1; for (const UChar *c = data() + pos; c >= data(); c--) { if (*c == ch) return (c-data()); } return -1;}UString UString::substr(int pos, int len) const{ if (pos < 0) pos = 0; else if (pos >= (int) size()) pos = size(); if (len < 0) len = size(); if (pos + len >= (int) size()) len = size() - pos; UChar *tmp = allocateChars(len); memcpy(tmp, data()+pos, len * sizeof(UChar)); UString result(tmp, len); delete [] tmp; return result;}void UString::attach(Rep *r){ rep = r; rep->ref();}void UString::detach(){ if (rep->rc > 1) { int l = size(); UChar *n = allocateChars(l); memcpy(n, data(), l * sizeof(UChar)); release(); rep = Rep::create(n, l); }}void UString::release(){ rep->deref();}bool KJS::operator==(const UString& s1, const UString& s2){ if (s1.rep->len != s2.rep->len) return false;#ifndef NDEBUG if ((s1.isNull() && s2.isEmpty() && !s2.isNull()) || (s2.isNull() && s1.isEmpty() && !s1.isNull())) fprintf(stderr, "KJS warning: comparison between empty and null string\n");#endif return (memcmp(s1.rep->dat, s2.rep->dat, s1.rep->len * sizeof(UChar)) == 0);}bool KJS::operator==(const UString& s1, const char *s2){ if (s2 == 0) { return s1.isEmpty(); } const UChar *u = s1.data(); const UChar *uend = u + s1.size(); while (u != uend && *s2) { if (u->uc != (unsigned char)*s2) return false; s2++; u++; } return u == uend && *s2 == 0;}bool KJS::operator<(const UString& s1, const UString& s2){ const int l1 = s1.size(); const int l2 = s2.size(); const int lmin = l1 < l2 ? l1 : l2; const UChar *c1 = s1.data(); const UChar *c2 = s2.data(); int l = 0; while (l < lmin && *c1 == *c2) { c1++; c2++; l++; } if (l < lmin) return (c1->uc < c2->uc); return (l1 < l2);}int KJS::compare(const UString& s1, const UString& s2){ const int l1 = s1.size(); const int l2 = s2.size(); const int lmin = l1 < l2 ? l1 : l2; const UChar *c1 = s1.data(); const UChar *c2 = s2.data(); int l = 0; while (l < lmin && *c1 == *c2) { c1++; c2++; l++; } if (l < lmin) return (c1->uc > c2->uc) ? 1 : -1; if (l1 == l2) { return 0; } return (l1 < l2) ? 1 : -1;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?