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

📄 property_map.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    _table->entries[i].value = value;    _table->entries[i].attributes = attributes;    _table->entries[i].index = index;}void PropertyMap::expand(){    checkConsistency();        Table *oldTable = _table;    int oldTableSize = oldTable ? oldTable->size : 0;    int oldTableKeyCount = oldTable ? oldTable->keyCount : 0;        int newTableSize = oldTableSize ? oldTableSize * 2 : 16;    _table = (Table *)calloc(1, sizeof(Table) + (newTableSize - 1) * sizeof(Entry) );    _table->size = newTableSize;    _table->sizeMask = newTableSize - 1;    _table->keyCount = oldTableKeyCount;#if USE_SINGLE_ENTRY    UString::Rep *key = _singleEntry.key;    if (key) {        insert(key, _singleEntry.value, _singleEntry.attributes, 0);        _singleEntry.key = 0;	// update the count, because single entries don't count towards	// the table key count	++_table->keyCount;	assert(_table->keyCount == 1);    }#endif        int lastIndexUsed = 0;    for (int i = 0; i != oldTableSize; ++i) {        Entry &entry = oldTable->entries[i];        UString::Rep *key = entry.key;        if (key) {            // Don't copy deleted-element sentinels.            if (key == &UString::Rep::null)                key->deref();            else {                int index = entry.index;                lastIndexUsed = MAX(index, lastIndexUsed);                insert(key, entry.value, entry.attributes, index);            }        }    }    _table->lastIndexUsed = lastIndexUsed;    free(oldTable);    checkConsistency();}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 i = h & _table->sizeMask;    int k = 0;#if DUMP_STATISTICS    ++numProbes;    ++numRemoves;    numCollisions += _table->entries[i].key && _table->entries[i].key != rep;#endif    while ((key = _table->entries[i].key)) {        if (rep == key)            break;        if (k == 0)            k = 1 | (h % _table->sizeMask);        i = (i + k) & _table->sizeMask;#if DUMP_STATISTICS        ++numRehashes;#endif    }    if (!key)        return;        // Replace this one element with the deleted sentinel,    // &UString::Rep::null; 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 = &UString::Rep::null;    key->ref();    _table->entries[i].key = key;    _table->entries[i].value = 0;    _table->entries[i].attributes = DontEnum;    assert(_table->keyCount >= 1);    --_table->keyCount;        checkConsistency();}void PropertyMap::mark() const{    if (!_table) {#if USE_SINGLE_ENTRY        if (_singleEntry.key) {            ValueImp *v = _singleEntry.value;            if (!v->marked())                v->mark();        }#endif        return;    }    for (int i = 0; i != _table->size; ++i) {        UString::Rep *key = _table->entries[i].key;        if (key) {            ValueImp *v = _table->entries[i].value;            // Check v against 0 to handle deleted elements            // without comparing key to UString::Rep::null.            if (v && !v->marked())                v->mark();        }    }}static int comparePropertyMapEntryIndices(const void *a, const void *b){    int ia = static_cast<PropertyMapHashTableEntry * const *>(a)[0]->index;    int ib = static_cast<PropertyMapHashTableEntry * const *>(b)[0]->index;    if (ia < ib)        return -1;    if (ia > ib)        return +1;    return 0;}void PropertyMap::addEnumerablesToReferenceList(ReferenceList &list, const Object &base) const{    if (!_table) {#if USE_SINGLE_ENTRY        UString::Rep *key = _singleEntry.key;        if (key && !(_singleEntry.attributes & DontEnum))            list.append(Reference(base, Identifier(key)));#endif        return;    }    // Allocate a buffer to use to sort the keys.    Entry *fixedSizeBuffer[smallMapThreshold];    Entry **sortedEnumerables;    if (_table->keyCount <= smallMapThreshold)        sortedEnumerables = fixedSizeBuffer;    else        sortedEnumerables = new Entry *[_table->keyCount];    // Get pointers to the enumerable entries in the buffer.    Entry **p = sortedEnumerables;    for (int i = 0; i != _table->size; ++i) {        Entry *e = &_table->entries[i];        if (e->key && !(e->attributes & DontEnum))            *p++ = e;    }    // Sort the entries by index.    qsort(sortedEnumerables, p - sortedEnumerables, sizeof(sortedEnumerables[0]), comparePropertyMapEntryIndices);    // Put the keys of the sorted entries into the reference list.    Entry **q = sortedEnumerables;    while (q != p)        list.append(Reference(base, Identifier((*q++)->key)));    // Deallocate the buffer.    if (sortedEnumerables != fixedSizeBuffer)        delete [] sortedEnumerables;}void PropertyMap::addSparseArrayPropertiesToReferenceList(ReferenceList &list, const Object &base) const{    if (!_table) {#if USE_SINGLE_ENTRY        UString::Rep *key = _singleEntry.key;        if (key) {            UString k(key);            bool fitsInUInt32;            k.toUInt32(&fitsInUInt32);            if (fitsInUInt32)                list.append(Reference(base, Identifier(key)));        }#endif        return;    }    for (int i = 0; i != _table->size; ++i) {        UString::Rep *key = _table->entries[i].key;        if (key && key != &UString::Rep::null)        {            UString k(key);            bool fitsInUInt32;            k.toUInt32(&fitsInUInt32);            if (fitsInUInt32)                list.append(Reference(base, Identifier(key)));        }    }}void PropertyMap::save(SavedProperties &p) const{    int count = 0;    if (!_table) {#if USE_SINGLE_ENTRY        if (_singleEntry.key && !(_singleEntry.attributes & (ReadOnly | Function)))            ++count;#endif    } else {        for (int i = 0; i != _table->size; ++i)            if (_table->entries[i].key && !(_table->entries[i].attributes & (ReadOnly | Function)))                ++count;    }    delete [] p._properties;    p._count = count;    if (count == 0) {        p._properties = 0;        return;    }        p._properties = new SavedProperty [count];        SavedProperty *prop = p._properties;        if (!_table) {#if USE_SINGLE_ENTRY        if (_singleEntry.key && !(_singleEntry.attributes & (ReadOnly | Function))) {            prop->key = Identifier(_singleEntry.key);            prop->value = Value(_singleEntry.value);            prop->attributes = _singleEntry.attributes;            ++prop;        }#endif    } else {        // Save in the right order so we don't lose the order.        // Another possibility would be to save the indices.        // Allocate a buffer to use to sort the keys.        Entry *fixedSizeBuffer[smallMapThreshold];        Entry **sortedEntries;        if (count <= smallMapThreshold)            sortedEntries = fixedSizeBuffer;        else            sortedEntries = new Entry *[count];        // Get pointers to the entries in the buffer.        Entry **p = sortedEntries;        for (int i = 0; i != _table->size; ++i) {            Entry *e = &_table->entries[i];            if (e->key && !(e->attributes & (ReadOnly | Function)))                *p++ = e;        }        assert(p - sortedEntries == count);        // Sort the entries by index.        qsort(sortedEntries, p - sortedEntries, sizeof(sortedEntries[0]), comparePropertyMapEntryIndices);        // Put the sorted entries into the saved properties list.        Entry **q = sortedEntries;        while (q != p) {            Entry *e = *q++;            prop->key = Identifier(e->key);            prop->value = Value(e->value);            prop->attributes = e->attributes;            ++prop;        }        // Deallocate the buffer.        if (sortedEntries != fixedSizeBuffer)            delete [] sortedEntries;    }}void PropertyMap::restore(const SavedProperties &p){    for (int i = 0; i != p._count; ++i)        put(p._properties[i].key, p._properties[i].value.imp(), p._properties[i].attributes);}#if DO_CONSISTENCY_CHECKvoid PropertyMap::checkConsistency(){    if (!_table)        return;    int count = 0;    for (int j = 0; j != _table->size; ++j) {        UString::Rep *rep = _table->entries[j].key;        if (!rep || rep == &UString::Rep::null)            continue;        unsigned h = rep->hash();        int i = h & _table->sizeMask;	int k = 0;        while (UString::Rep *key = _table->entries[i].key) {            if (rep == key)                break;	    if (k == 0)		k = 1 | (h % _table->sizeMask);	    i = (i + k) & _table->sizeMask;        }        assert(i == j);        count++;    }    assert(count == _table->keyCount);    assert(_table->size >= 16);    assert(_table->sizeMask);    assert(_table->size == _table->sizeMask + 1);}#endif // DO_CONSISTENCY_CHECK} // namespace KJS

⌨️ 快捷键说明

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