UString UString::spliceSubstringsWithSeparators(const Range *substringRanges, int rangeCount, const UString *separators, int separatorCount) const
{
  int totalLength = 0;

  for (int i = 0; i < rangeCount; i++) {
    totalLength += substringRanges[i].length;
  }
  for (int i = 0; i < separatorCount; i++) {
    totalLength += separators[i].size();
  }

  UChar *buffer = static_cast<UChar *>(malloc(totalLength * sizeof(UChar)));

  int maxCount = MAX(rangeCount, separatorCount);
  int bufferPos = 0;
  for (int i = 0; i < maxCount; i++) {
    if (i < rangeCount) {
      memcpy(buffer + bufferPos, data() + substringRanges[i].position, substringRanges[i].length * sizeof(UChar));
      bufferPos += substringRanges[i].length;
    }
    if (i < separatorCount) {
      memcpy(buffer + bufferPos, separators[i].data(), separators[i].size() * sizeof(UChar));
      bufferPos += separators[i].size();
    }
  }

  UString::Rep *rep = UString::Rep::create(buffer, totalLength);
  UString result = UString(rep);
  rep->deref();

  return result;
}
Beispiel #2
0
void PropertyMap::clear()
{
    if (!_table) {
#if USE_SINGLE_ENTRY
        UString::Rep *key = _singleEntry.key;
        if (key) {
            key->deref();
            _singleEntry.key = 0;
        }
#endif
        return;
    }

    int size = _table->size;
    Entry *entries = _table->entries;
    for (int i = 0; i < size; i++) {
        UString::Rep *key = entries[i].key;
        if (isValid(key)) {
            key->deref();
            entries[i].key = 0;
            entries[i].value = 0;
        }
    }
    _table->keyCount = 0;
    _table->sentinelCount = 0;
}
EXPORT
void JSStringRelease(JSStringRef string)
{
    JSLock lock;
    UString::Rep* rep = toJS(string);
    rep->deref();
}
Beispiel #4
0
PropertyMap::~PropertyMap()
{
    if (!_table) {
#if USE_SINGLE_ENTRY
        UString::Rep *key = _singleEntry.key;
        if (key)
            key->deref();
#endif
        return;
    }
    
    int minimumKeysToProcess = _table->keyCount + _table->sentinelCount;
    Entry *entries = _table->entries;
    for (int i = 0; i < minimumKeysToProcess; i++) {
        UString::Rep *key = entries[i].key;
        if (key) {
            if (key != deletedSentinel())
                key->deref();
        } else
            ++minimumKeysToProcess;
    }
    fastFree(_table);
}
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;

  UString::Rep *newRep = Rep::create(rep, pos, len);
  UString result(newRep);
  newRep->deref();

  return result;
}
UString UString::substr(int pos, int len) const
{
  int s = size();

  if (pos < 0)
    pos = 0;
  else if (pos >= s)
    pos = s;
  if (len < 0)
    len = s;
  if (pos + len >= s)
    len = s - pos;

  if (pos == 0 && len == s)
    return *this;

  UString::Rep *newRep = Rep::create(rep, pos, len);
  UString result(newRep);
  newRep->deref();

  return result;
}
Beispiel #7
0
size_t Structure::remove(const Identifier& propertyName)
{
    ASSERT(!propertyName.isNull());

    checkConsistency();

    UString::Rep* rep = propertyName._ustring.rep();

    if (!m_propertyTable)
        return notFound;

#if DUMP_PROPERTYMAP_STATS
    ++numProbes;
    ++numRemoves;
#endif

    // Find the thing to remove.
    unsigned i = rep->computedHash();
    unsigned k = 0;
    unsigned entryIndex;
    UString::Rep* key = 0;
    while (1) {
        entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
        if (entryIndex == emptyEntryIndex)
            return notFound;

        key = m_propertyTable->entries()[entryIndex - 1].key;
        if (rep == key)
            break;

        if (k == 0) {
            k = 1 | doubleHash(rep->computedHash());
#if DUMP_PROPERTYMAP_STATS
            ++numCollisions;
#endif
        }

        i += k;

#if DUMP_PROPERTYMAP_STATS
        ++numRehashes;
#endif
    }

    // Replace this one element with the deleted sentinel. Also clear out
    // the entry so we can iterate all the entries as needed.
    m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = deletedSentinelIndex;

    size_t offset = m_propertyTable->entries()[entryIndex - 1].offset;

    key->deref();
    m_propertyTable->entries()[entryIndex - 1].key = 0;
    m_propertyTable->entries()[entryIndex - 1].attributes = 0;
    m_propertyTable->entries()[entryIndex - 1].offset = 0;

    if (!m_propertyTable->deletedOffsets)
        m_propertyTable->deletedOffsets = new Vector<unsigned>;
    m_propertyTable->deletedOffsets->append(offset);

    ASSERT(m_propertyTable->keyCount >= 1);
    --m_propertyTable->keyCount;
    ++m_propertyTable->deletedSentinelCount;

    if (m_propertyTable->deletedSentinelCount * 4 >= m_propertyTable->size)
        rehashPropertyMapHashTable();

    checkConsistency();
    return offset;
}
Beispiel #8
0
void PropertyMap::remove(const Identifier &name)
{
    assert(!name.isNull());
    
    checkConsistency();

    UString::Rep *rep = name._ustring.rep();

    UString::Rep *key;

    if (!_table) {
#if USE_SINGLE_ENTRY
        key = _singleEntry.key;
        if (rep == key) {
            key->deref();
            _singleEntry.key = 0;
            checkConsistency();
        }
#endif
        return;
    }

    // Find the thing to remove.
    unsigned h = rep->hash();
    int sizeMask = _table->sizeMask;
    Entry *entries = _table->entries;
    int i = h & sizeMask;
    int k = 0;
#if DUMP_STATISTICS
    ++numProbes;
    ++numRemoves;
    numCollisions += entries[i].key && entries[i].key != rep;
#endif
    while ((key = entries[i].key)) {
        if (rep == key)
            break;
        if (k == 0)
            k = 1 | (h % sizeMask);
        i = (i + k) & sizeMask;
#if DUMP_STATISTICS
        ++numRehashes;
#endif
    }
    if (!key)
        return;
    
    // Replace this one element with the deleted sentinel. Also set value to 0 and attributes to DontEnum
    // to help callers that iterate all keys not have to check for the sentinel.
    key->deref();
    key = deletedSentinel();
    entries[i].key = key;
    entries[i].value = 0;
    entries[i].attributes = DontEnum;
    assert(_table->keyCount >= 1);
    --_table->keyCount;
    ++_table->sentinelCount;
    
    if (_table->sentinelCount * 4 >= _table->size)
        rehash();

    checkConsistency();
}