⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ustring.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    }  }    return UString(p, end - p);}UString UString::from(long l){  UChar buf[20];  UChar *end = buf + 20;  UChar *p = end;    if (l == 0) {    *--p = '0';  } else if (l == LONG_MIN) {    char minBuf[20];    sprintf(minBuf, "%ld", LONG_MIN);    return UString(minBuf);  } else {    bool negative = false;    if (l < 0) {      negative = true;      l = -l;    }    while (l) {      *--p = (unsigned short)((l % 10) + '0');      l /= 10;    }    if (negative) {      *--p = '-';    }  }    return UString(p, end - p);}UString UString::from(double d){  char buf[80];  int decimalPoint;  int sign;    char *result = kjs_dtoa(d, 0, 0, &decimalPoint, &sign, NULL);  int length = strlen(result);    int i = 0;  if (sign) {    buf[i++] = '-';  }    if (decimalPoint <= 0 && decimalPoint > -6) {    buf[i++] = '0';    buf[i++] = '.';    for (int j = decimalPoint; j < 0; j++) {      buf[i++] = '0';    }    strcpy(buf + i, result);  } else if (decimalPoint <= 21 && decimalPoint > 0) {    if (length <= decimalPoint) {      strcpy(buf + i, result);      i += length;      for (int j = 0; j < decimalPoint - length; j++) {	buf[i++] = '0';      }      buf[i] = '\0';    } else {      strncpy(buf + i, result, decimalPoint);      i += decimalPoint;      buf[i++] = '.';      strcpy(buf + i, result + decimalPoint);    }  } else if (result[0] < '0' || result[0] > '9') {    strcpy(buf + i, result);  } else {    buf[i++] = result[0];    if (length > 1) {      buf[i++] = '.';      strcpy(buf + i, result + 1);      i += length - 1;    }        buf[i++] = 'e';    buf[i++] = (decimalPoint >= 0) ? '+' : '-';    // decimalPoint can't be more than 3 digits decimal given the    // nature of float representation    int exponential = decimalPoint - 1;    if (exponential < 0) {      exponential = exponential * -1;    }    if (exponential >= 100) {      buf[i++] = '0' + exponential / 100;    }    if (exponential >= 10) {      buf[i++] = '0' + (exponential % 100) / 10;    }    buf[i++] = '0' + exponential % 10;    buf[i++] = '\0';  }    kjs_freedtoa(result);    return UString(buf);}UString &UString::append(const UString &t){  int thisSize = size();  int thisOffset = rep->offset;  int tSize = t.size();  int length = thisSize + tSize;  // possible cases:  if (thisSize == 0) {    // this is empty    *this = t;  } else if (tSize == 0) {    // t is empty  } else if (!rep->baseString && rep->rc == 1) {    // this is direct and has refcount of 1 (so we can just alter it directly)    expandCapacity(thisOffset + length);    memcpy(const_cast<UChar *>(data() + thisSize), t.data(), tSize * sizeof(UChar));    rep->len = length;    rep->_hash = 0;  } else if (thisOffset + thisSize == usedCapacity()) {    // this reaches the end of the buffer - extend it    expandCapacity(length);    memcpy(const_cast<UChar *>(data() + thisSize), t.data(), tSize * sizeof(UChar));    Rep *newRep = Rep::create(rep, 0, length);    release();    rep = newRep;  } else {    // this is shared with someone using more capacity, gotta make a whole new string    int newCapacity = expandedSize(length, 0);    UChar *d = static_cast<UChar *>(malloc(sizeof(UChar) * newCapacity));    memcpy(d, data(), thisSize * sizeof(UChar));    memcpy(const_cast<UChar *>(d + thisSize), t.data(), tSize * sizeof(UChar));    release();    rep = Rep::create(d, length);    rep->capacity = newCapacity;  }  return *this;}UString &UString::append(const char *t){  int thisSize = size();  int thisOffset = rep->offset;  int tSize = strlen(t);  int length = thisSize + tSize;  // possible cases:  if (thisSize == 0) {    // this is empty    *this = t;  } else if (tSize == 0) {    // t is empty, we'll just return *this below.  } else if (!rep->baseString && rep->rc == 1) {    // this is direct and has refcount of 1 (so we can just alter it directly)    expandCapacity(thisOffset + length);    UChar *d = const_cast<UChar *>(data());    for (int i = 0; i < tSize; ++i)      d[thisSize+i] = t[i];    rep->len = length;    rep->_hash = 0;  } else if (thisOffset + thisSize == usedCapacity()) {    // this string reaches the end of the buffer - extend it    expandCapacity(thisOffset + length);    UChar *d = const_cast<UChar *>(data());    for (int i = 0; i < tSize; ++i)      d[thisSize+i] = t[i];    Rep *newRep = Rep::create(rep, 0, length);    release();    rep = newRep;  } else {    // this is shared with someone using more capacity, gotta make a whole new string    int newCapacity = expandedSize(length, 0);    UChar *d = static_cast<UChar *>(malloc(sizeof(UChar) * newCapacity));    memcpy(d, data(), thisSize * sizeof(UChar));    for (int i = 0; i < tSize; ++i)      d[thisSize+i] = t[i];    release();    rep = Rep::create(d, length);    rep->capacity = newCapacity;  }  return *this;}UString &UString::append(unsigned short c){  int thisOffset = rep->offset;  int length = size();  // possible cases:  if (length == 0) {    // this is empty - must make a new rep because we don't want to pollute the shared empty one     int newCapacity = expandedSize(1, 0);    UChar *d = static_cast<UChar *>(malloc(sizeof(UChar) * newCapacity));    d[0] = c;    release();    rep = Rep::create(d, 1);    rep->capacity = newCapacity;  } else if (!rep->baseString && rep->rc == 1) {    // this is direct and has refcount of 1 (so we can just alter it directly)    expandCapacity(thisOffset + length + 1);    UChar *d = const_cast<UChar *>(data());    d[length] = c;    rep->len = length + 1;    rep->_hash = 0;  } else if (thisOffset + length == usedCapacity()) {    // this reaches the end of the string - extend it and share    expandCapacity(thisOffset + length + 1);    UChar *d = const_cast<UChar *>(data());    d[length] = c;    Rep *newRep = Rep::create(rep, 0, length + 1);    release();    rep = newRep;  } else {    // this is shared with someone using more capacity, gotta make a whole new string    int newCapacity = expandedSize((length + 1), 0);    UChar *d = static_cast<UChar *>(malloc(sizeof(UChar) * newCapacity));    memcpy(d, data(), length * sizeof(UChar));    d[length] = c;    release();    rep = Rep::create(d, length);    rep->capacity = newCapacity;  }  return *this;}CString UString::cstring() const{  return ascii();}char *UString::ascii() const{  // Never make the buffer smaller than normalStatBufferSize.  // Thus we almost never need to reallocate.  int length = size();  int neededSize = length + 1;  if (neededSize < normalStatBufferSize) {    neededSize = normalStatBufferSize;  }  if (neededSize != statBufferSize) {    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 && !rep->baseString && rep->offset == 0 && rep->preCapacity == 0) {    d = rep->buf;    rep->_hash = 0;  } else {    release();    d = static_cast<UChar *>(malloc(sizeof(UChar) * 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 '\0';  return data()[pos];}UCharReference UString::operator[](int pos){  /* TODO: boundary check */  return UCharReference(this, pos);}double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const{  double d;  // 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;  // 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 ?      d = 1.0;      if (*c == '+')	c++;      else if (*c == '-') {	d = -1.0;	c++;      }      if (strncmp(c, "Infinity", 8) != 0)	return NaN;      d = d * Inf;      c += 8;    }  }  // allow trailing white space  while (isspace(*c))    c++;  // don't allow anything after - unless tolerant=true  if (!tolerateTrailingJunk && *c != '\0')    d = NaN;  return d;}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);}uint32_t UString::toUInt32(bool *ok) const{  double d = toDouble();  bool b = true;  if (isNaN(d) || d != static_cast<uint32_t>(d)) {    b = false;    d = 0;  }  if (ok)    *ok = b;  return static_cast<uint32_t>(d);}uint32_t 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->data();  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.  uint32_t 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{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -