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; }
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(); }
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; }
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; }
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(); }