11b1150312d9638c1ee7da0491ba6e9df59edd77
[WebKit-https.git] / Source / WebCore / platform / text / LineBreakIteratorPoolICU.h
1 /*
2  * Copyright (C) 2011 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef LineBreakIteratorPoolICU_h
27 #define LineBreakIteratorPoolICU_h
28
29 #include "TextBreakIteratorInternalICU.h"
30 #include "ThreadGlobalData.h"
31 #include <unicode/ubrk.h>
32 #include <wtf/Assertions.h>
33 #include <wtf/HashMap.h>
34 #include <wtf/PassOwnPtr.h>
35 #include <wtf/text/CString.h>
36
37 namespace WebCore {
38
39 class LineBreakIteratorPool {
40     WTF_MAKE_NONCOPYABLE(LineBreakIteratorPool);
41 public:
42     static LineBreakIteratorPool& sharedPool()
43     {
44         return threadGlobalData().lineBreakIteratorPool();
45     }
46
47     static PassOwnPtr<LineBreakIteratorPool> create() { return adoptPtr(new LineBreakIteratorPool); }
48
49     UBreakIterator* take(const AtomicString& locale)
50     {
51         UBreakIterator* iterator = 0;
52         for (size_t i = 0; i < m_pool.size(); ++i) {
53             if (m_pool[i].first == locale) {
54                 iterator = m_pool[i].second;
55                 m_pool.remove(i);
56                 break;
57             }
58         }
59
60         if (!iterator) {
61             UErrorCode openStatus = U_ZERO_ERROR;
62             iterator = ubrk_open(UBRK_LINE, locale.isEmpty() ? currentTextBreakLocaleID() : locale.string().utf8().data(), 0, 0, &openStatus);
63             if (U_FAILURE(openStatus)) {
64                 LOG_ERROR("ubrk_open failed with status %d", openStatus);
65                 return 0;
66             }
67         }
68
69         ASSERT(!m_vendedIterators.contains(iterator));
70         m_vendedIterators.set(iterator, locale);
71         return iterator;
72     }
73
74     void put(UBreakIterator* iterator)
75     {
76         ASSERT_ARG(iterator, m_vendedIterators.contains(iterator));
77
78         if (m_pool.size() == capacity) {
79             ubrk_close(m_pool[0].second);
80             m_pool.remove(0);
81         }
82
83         m_pool.append(Entry(m_vendedIterators.take(iterator), iterator));
84     }
85
86 private:
87     LineBreakIteratorPool() { }
88
89     static const size_t capacity = 4;
90
91     typedef pair<AtomicString, UBreakIterator*> Entry;
92     typedef Vector<Entry, capacity> Pool;
93     Pool m_pool;
94     HashMap<UBreakIterator*, AtomicString> m_vendedIterators;
95 };
96
97 }
98
99 #endif