1/* 2 * Copyright (C) 2007-2014 Apple Inc. All rights reserved. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 * Boston, MA 02111-1307, USA. 18 * 19 */ 20 21#ifndef SpaceSplitString_h 22#define SpaceSplitString_h 23 24#include <wtf/MainThread.h> 25#include <wtf/text/AtomicString.h> 26 27namespace WebCore { 28 29class SpaceSplitStringData { 30 WTF_MAKE_NONCOPYABLE(SpaceSplitStringData); 31 WTF_MAKE_FAST_ALLOCATED; 32public: 33 static PassRefPtr<SpaceSplitStringData> create(const AtomicString&); 34 35 bool contains(const AtomicString& string) 36 { 37 const AtomicString* data = tokenArrayStart(); 38 unsigned i = 0; 39 do { 40 if (data[i] == string) 41 return true; 42 ++i; 43 } while (i < m_size); 44 return false; 45 } 46 47 bool containsAll(SpaceSplitStringData&); 48 49 unsigned size() const { return m_size; } 50 static ptrdiff_t sizeMemoryOffset() { return OBJECT_OFFSETOF(SpaceSplitStringData, m_size); } 51 52 const AtomicString& operator[](unsigned i) 53 { 54 RELEASE_ASSERT(i < m_size); 55 return tokenArrayStart()[i]; 56 } 57 58 void ref() 59 { 60 ASSERT(isMainThread()); 61 ASSERT(m_refCount); 62 ++m_refCount; 63 } 64 65 void deref() 66 { 67 ASSERT(isMainThread()); 68 ASSERT(m_refCount); 69 unsigned tempRefCount = m_refCount - 1; 70 if (!tempRefCount) { 71 destroy(this); 72 return; 73 } 74 m_refCount = tempRefCount; 75 } 76 77 static ptrdiff_t tokensMemoryOffset() { return sizeof(SpaceSplitStringData); } 78 79private: 80 static PassRefPtr<SpaceSplitStringData> create(const AtomicString&, unsigned tokenCount); 81 SpaceSplitStringData(const AtomicString& string, unsigned size) 82 : m_keyString(string) 83 , m_refCount(1) 84 , m_size(size) 85 { 86 ASSERT(!string.isEmpty()); 87 ASSERT_WITH_MESSAGE(m_size, "SpaceSplitStringData should never be empty by definition. There is no difference between empty and null."); 88 } 89 90 ~SpaceSplitStringData() { } 91 static void destroy(SpaceSplitStringData*); 92 93 AtomicString* tokenArrayStart() { return reinterpret_cast<AtomicString*>(this + 1); } 94 95 AtomicString m_keyString; 96 unsigned m_refCount; 97 unsigned m_size; 98}; 99 100class SpaceSplitString { 101public: 102 SpaceSplitString() { } 103 SpaceSplitString(const AtomicString& string, bool shouldFoldCase) { set(string, shouldFoldCase); } 104 105 bool operator!=(const SpaceSplitString& other) const { return m_data != other.m_data; } 106 107 void set(const AtomicString&, bool shouldFoldCase); 108 void clear() { m_data.clear(); } 109 110 bool contains(const AtomicString& string) const { return m_data && m_data->contains(string); } 111 bool containsAll(const SpaceSplitString& names) const { return !names.m_data || (m_data && m_data->containsAll(*names.m_data)); } 112 113 unsigned size() const { return m_data ? m_data->size() : 0; } 114 bool isEmpty() const { return !m_data; } 115 const AtomicString& operator[](unsigned i) const 116 { 117 ASSERT_WITH_SECURITY_IMPLICATION(m_data); 118 return (*m_data)[i]; 119 } 120 121 static bool spaceSplitStringContainsValue(const String& spaceSplitString, const char* value, unsigned length, bool shouldFoldCase); 122 template<size_t length> 123 static bool spaceSplitStringContainsValue(const String& spaceSplitString, const char (&value)[length], bool shouldFoldCase) 124 { 125 return spaceSplitStringContainsValue(spaceSplitString, value, length - 1, shouldFoldCase); 126 } 127 128private: 129 RefPtr<SpaceSplitStringData> m_data; 130}; 131 132} // namespace WebCore 133 134#endif // SpaceSplitString_h 135