/* * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "DeprecatedValueListImpl.h" #include "Shared.h" #include namespace WebCore { class DeprecatedValueListImpl::Private : public Shared { public: Private(void (*deleteFunc)(DeprecatedValueListImplNode *), DeprecatedValueListImplNode *(*copyFunc)(DeprecatedValueListImplNode *)); Private(const Private &other); ~Private(); void copyList(DeprecatedValueListImplNode *l, DeprecatedValueListImplNode *&head, DeprecatedValueListImplNode *&tail) const; void deleteList(DeprecatedValueListImplNode *l); DeprecatedValueListImplNode *head; DeprecatedValueListImplNode *tail; void (*deleteNode)(DeprecatedValueListImplNode *); DeprecatedValueListImplNode *(*copyNode)(DeprecatedValueListImplNode *); unsigned count; }; inline DeprecatedValueListImpl::Private::Private(void (*deleteFunc)(DeprecatedValueListImplNode*), DeprecatedValueListImplNode* (*copyFunc)(DeprecatedValueListImplNode*)) : head(NULL), tail(NULL), deleteNode(deleteFunc), copyNode(copyFunc), count(0) { } inline DeprecatedValueListImpl::Private::Private(const Private &other) : Shared(), deleteNode(other.deleteNode), copyNode(other.copyNode), count(other.count) { other.copyList(other.head, head, tail); } inline DeprecatedValueListImpl::Private::~Private() { deleteList(head); } void DeprecatedValueListImpl::Private::copyList(DeprecatedValueListImplNode *l, DeprecatedValueListImplNode *&head, DeprecatedValueListImplNode *&tail) const { DeprecatedValueListImplNode *prev = NULL; DeprecatedValueListImplNode *node = l; head = NULL; while (node != NULL) { DeprecatedValueListImplNode *copy = copyNode(node); if (prev == NULL) { head = copy; } else { prev->next = copy; } copy->prev = prev; copy->next = NULL; prev = copy; node = node->next; } tail = prev; } void DeprecatedValueListImpl::Private::deleteList(DeprecatedValueListImplNode *l) { DeprecatedValueListImplNode *p = l; while (p != NULL) { DeprecatedValueListImplNode *next = p->next; deleteNode(p); p = next; } } DeprecatedValueListImpl::DeprecatedValueListImpl(void (*deleteFunc)(DeprecatedValueListImplNode *), DeprecatedValueListImplNode *(*copyFunc)(DeprecatedValueListImplNode *)) : d(new Private(deleteFunc, copyFunc)) { } DeprecatedValueListImpl::DeprecatedValueListImpl(const DeprecatedValueListImpl &other) : d(other.d) { } DeprecatedValueListImpl::~DeprecatedValueListImpl() { } void DeprecatedValueListImpl::clear() { if (d->head) { copyOnWrite(); d->deleteList(d->head); d->head = NULL; d->tail = NULL; d->count = 0; } } unsigned DeprecatedValueListImpl::count() const { return d->count; } bool DeprecatedValueListImpl::isEmpty() const { return d->count == 0; } DeprecatedValueListImplIterator DeprecatedValueListImpl::appendNode(DeprecatedValueListImplNode *node) { copyOnWrite(); node->next = NULL; node->prev = d->tail; d->tail = node; if (d->head == NULL) { d->head = node; } else { node->prev->next = node; } d->count++; return node; } DeprecatedValueListImplIterator DeprecatedValueListImpl::prependNode(DeprecatedValueListImplNode *node) { copyOnWrite(); node->next = d->head; node->prev = NULL; d->head = node; if (d->tail == NULL) { d->tail = node; } else { node->next->prev = node; } d->count++; return node; } void DeprecatedValueListImpl::removeEqualNodes(DeprecatedValueListImplNode *node, bool (*equalFunc)(const DeprecatedValueListImplNode *, const DeprecatedValueListImplNode *)) { copyOnWrite(); DeprecatedValueListImplNode *next; for (DeprecatedValueListImplNode *p = d->head; p != NULL; p = next) { next = p->next; if (equalFunc(node, p)) { if (p->next != NULL) { p->next->prev = p->prev; } else { d->tail = p->prev; } if (p->prev != NULL) { p->prev->next = p->next; } else { d->head = p->next; } d->deleteNode(p); d->count--; } } } unsigned DeprecatedValueListImpl::containsEqualNodes(DeprecatedValueListImplNode *node, bool (*equalFunc)(const DeprecatedValueListImplNode *, const DeprecatedValueListImplNode *)) const { unsigned contains = 0; for (DeprecatedValueListImplNode *p = d->head; p != NULL; p = p->next) { if (equalFunc(node, p)) { ++contains; } } return contains; } DeprecatedValueListImplIterator DeprecatedValueListImpl::findEqualNode(DeprecatedValueListImplNode *node, bool (*equalFunc)(const DeprecatedValueListImplNode *, const DeprecatedValueListImplNode *)) const { DeprecatedValueListImplIterator it = begin(); DeprecatedValueListImplIterator endIt = end(); while (it != endIt) { if (equalFunc(node, it.node())) { break; } it++; } return it; } DeprecatedValueListImplIterator DeprecatedValueListImpl::insert(const DeprecatedValueListImplIterator &iterator, DeprecatedValueListImplNode *node) { copyOnWrite(); DeprecatedValueListImplNode *next = iterator.nodeImpl; if (next == NULL) return appendNode(node); if (next == d->head) return prependNode(node); DeprecatedValueListImplNode *prev = next->prev; node->next = next; node->prev = prev; next->prev = node; prev->next = node; d->count++; return node; } DeprecatedValueListImplIterator DeprecatedValueListImpl::removeIterator(DeprecatedValueListImplIterator &iterator) { copyOnWrite(); if (iterator.nodeImpl == NULL) { return iterator; } DeprecatedValueListImplNode *next = iterator.nodeImpl->next; // detach node if (iterator.nodeImpl->next != NULL) { iterator.nodeImpl->next->prev = iterator.nodeImpl->prev; } else { d->tail = iterator.nodeImpl->prev; } if (iterator.nodeImpl->prev != NULL) { iterator.nodeImpl->prev->next = iterator.nodeImpl->next; } else { d->head = iterator.nodeImpl->next; } d->deleteNode(iterator.nodeImpl); d->count--; return DeprecatedValueListImplIterator(next); } DeprecatedValueListImplIterator DeprecatedValueListImpl::fromLast() { copyOnWrite(); return DeprecatedValueListImplIterator(lastNode()); } DeprecatedValueListImplNode *DeprecatedValueListImpl::firstNode() { copyOnWrite(); return ((const DeprecatedValueListImpl *)this)->firstNode(); } DeprecatedValueListImplNode *DeprecatedValueListImpl::lastNode() { copyOnWrite(); return ((const DeprecatedValueListImpl *)this)->lastNode(); } DeprecatedValueListImplNode *DeprecatedValueListImpl::firstNode() const { return d->head; } DeprecatedValueListImplNode *DeprecatedValueListImpl::lastNode() const { return d->tail; } DeprecatedValueListImplIterator DeprecatedValueListImpl::begin() { copyOnWrite(); return ((const DeprecatedValueListImpl *)this)->begin(); } DeprecatedValueListImplIterator DeprecatedValueListImpl::end() { copyOnWrite(); return ((const DeprecatedValueListImpl *)this)->end(); } DeprecatedValueListImplIterator DeprecatedValueListImpl::begin() const { return DeprecatedValueListImplIterator(firstNode()); } DeprecatedValueListImplIterator DeprecatedValueListImpl::end() const { return DeprecatedValueListImplIterator(NULL); } DeprecatedValueListImplIterator DeprecatedValueListImpl::fromLast() const { return DeprecatedValueListImplIterator(lastNode()); } DeprecatedValueListImplNode *DeprecatedValueListImpl::nodeAt(unsigned index) { copyOnWrite(); if (d->count <= index) { return NULL; } DeprecatedValueListImplNode *p = d->head; for (unsigned i = 0; i < index; i++) { p = p->next; } return p; } DeprecatedValueListImplNode *DeprecatedValueListImpl::nodeAt(unsigned index) const { if (d->count <= index) { return NULL; } DeprecatedValueListImplNode *p = d->head; for (unsigned i = 0; i < index; i++) { p = p->next; } return p; } DeprecatedValueListImpl& DeprecatedValueListImpl::operator=(const DeprecatedValueListImpl &other) { DeprecatedValueListImpl tmp(other); RefPtr tmpD = tmp.d; tmp.d = d; d = tmpD; return *this; } void DeprecatedValueListImpl::copyOnWrite() { if (!d->hasOneRef()) d = new Private(*d); } bool DeprecatedValueListImpl::isEqual(const DeprecatedValueListImpl &other, bool (*equalFunc)(const DeprecatedValueListImplNode *, const DeprecatedValueListImplNode *)) const { DeprecatedValueListImplNode *p, *q; for (p = d->head, q = other.d->head; p && q; p = p->next, q = q->next) { if (!equalFunc(p, q)) { return false; } } return !p && !q; } }