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 + -
显示快捷键?