1 | /* |
2 | * Copyright (C) 2014 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. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #pragma once |
27 | |
28 | #include <unicode/utext.h> |
29 | |
30 | namespace WTF { |
31 | |
32 | enum class UTextProviderContext { |
33 | NoContext, |
34 | PriorContext, |
35 | PrimaryContext |
36 | }; |
37 | |
38 | inline UTextProviderContext uTextProviderContext(const UText* text, int64_t nativeIndex, UBool forward) |
39 | { |
40 | if (!text->b || nativeIndex > text->b) |
41 | return UTextProviderContext::PrimaryContext; |
42 | if (nativeIndex == text->b) |
43 | return forward ? UTextProviderContext::PrimaryContext : UTextProviderContext::PriorContext; |
44 | return UTextProviderContext::PriorContext; |
45 | } |
46 | |
47 | inline void initializeContextAwareUTextProvider(UText* text, const UTextFuncs* funcs, const void* string, unsigned length, const UChar* priorContext, int priorContextLength) |
48 | { |
49 | text->pFuncs = funcs; |
50 | text->providerProperties = 1 << UTEXT_PROVIDER_STABLE_CHUNKS; |
51 | text->context = string; |
52 | text->p = string; |
53 | text->a = length; |
54 | text->q = priorContext; |
55 | text->b = priorContextLength; |
56 | } |
57 | |
58 | // Shared implementation for the UTextClone function on UTextFuncs. |
59 | |
60 | UText* uTextCloneImpl(UText* destination, const UText* source, UBool deep, UErrorCode* status); |
61 | |
62 | |
63 | // Helpers for the UTextAccess function on UTextFuncs. |
64 | |
65 | inline int64_t uTextAccessPinIndex(int64_t& index, int64_t limit) |
66 | { |
67 | if (index < 0) |
68 | index = 0; |
69 | else if (index > limit) |
70 | index = limit; |
71 | return index; |
72 | } |
73 | |
74 | inline bool uTextAccessInChunkOrOutOfRange(UText* text, int64_t nativeIndex, int64_t nativeLength, UBool forward, UBool& isAccessible) |
75 | { |
76 | if (forward) { |
77 | if (nativeIndex >= text->chunkNativeStart && nativeIndex < text->chunkNativeLimit) { |
78 | int64_t offset = nativeIndex - text->chunkNativeStart; |
79 | // Ensure chunk offset is well formed if computed offset exceeds int32_t range. |
80 | ASSERT(offset < std::numeric_limits<int32_t>::max()); |
81 | text->chunkOffset = offset < std::numeric_limits<int32_t>::max() ? static_cast<int32_t>(offset) : 0; |
82 | isAccessible = TRUE; |
83 | return true; |
84 | } |
85 | if (nativeIndex >= nativeLength && text->chunkNativeLimit == nativeLength) { |
86 | text->chunkOffset = text->chunkLength; |
87 | isAccessible = FALSE; |
88 | return true; |
89 | } |
90 | } else { |
91 | if (nativeIndex > text->chunkNativeStart && nativeIndex <= text->chunkNativeLimit) { |
92 | int64_t offset = nativeIndex - text->chunkNativeStart; |
93 | // Ensure chunk offset is well formed if computed offset exceeds int32_t range. |
94 | ASSERT(offset < std::numeric_limits<int32_t>::max()); |
95 | text->chunkOffset = offset < std::numeric_limits<int32_t>::max() ? static_cast<int32_t>(offset) : 0; |
96 | isAccessible = TRUE; |
97 | return true; |
98 | } |
99 | if (nativeIndex <= 0 && !text->chunkNativeStart) { |
100 | text->chunkOffset = 0; |
101 | isAccessible = FALSE; |
102 | return true; |
103 | } |
104 | } |
105 | return false; |
106 | } |
107 | |
108 | } // namespace WTF |
109 | |