1 | // |
2 | // Copyright (c) 2018 The ANGLE Project Authors. All rights reserved. |
3 | // Use of this source code is governed by a BSD-style license that can be |
4 | // found in the LICENSE file. |
5 | // |
6 | // ImmutableStringBuilder.h: Stringstream-like utility for building pool allocated strings where the |
7 | // maximum length is known in advance. |
8 | // |
9 | |
10 | #ifndef COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_ |
11 | #define COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_ |
12 | |
13 | #include "compiler/translator/ImmutableString.h" |
14 | |
15 | namespace sh |
16 | { |
17 | |
18 | class ImmutableStringBuilder |
19 | { |
20 | public: |
21 | ImmutableStringBuilder(size_t maxLength) |
22 | : mPos(0u), mMaxLength(maxLength), mData(AllocateEmptyPoolCharArray(maxLength)) |
23 | {} |
24 | |
25 | ImmutableStringBuilder &operator<<(const ImmutableString &str); |
26 | |
27 | ImmutableStringBuilder &operator<<(const char *str); |
28 | |
29 | ImmutableStringBuilder &operator<<(const char &c); |
30 | |
31 | // This invalidates the ImmutableStringBuilder, so it should only be called once. |
32 | operator ImmutableString(); |
33 | |
34 | void appendDecimal(const uint32_t &i); |
35 | |
36 | template <typename T> |
37 | void appendHex(T number) |
38 | { |
39 | ASSERT(mData != nullptr); |
40 | ASSERT(mPos + sizeof(T) * 2u <= mMaxLength); |
41 | int index = static_cast<int>(sizeof(T)) * 2 - 1; |
42 | // Loop through leading zeroes. |
43 | while (((number >> (index * 4)) & 0xfu) == 0 && index > 0) |
44 | { |
45 | --index; |
46 | } |
47 | // Write the rest of the hex digits. |
48 | while (index >= 0) |
49 | { |
50 | char digit = static_cast<char>((number >> (index * 4)) & 0xfu); |
51 | char digitChar = (digit < 10) ? (digit + '0') : (digit + ('a' - 10)); |
52 | mData[mPos++] = digitChar; |
53 | --index; |
54 | } |
55 | } |
56 | |
57 | template <typename T> |
58 | static constexpr size_t GetHexCharCount() |
59 | { |
60 | return sizeof(T) * 2; |
61 | } |
62 | |
63 | private: |
64 | inline static char *AllocateEmptyPoolCharArray(size_t strLength) |
65 | { |
66 | size_t requiredSize = strLength + 1u; |
67 | return static_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize)); |
68 | } |
69 | |
70 | size_t mPos; |
71 | size_t mMaxLength; |
72 | char *mData; |
73 | }; |
74 | |
75 | // GLSL ES 3.00.6 section 3.9: the maximum length of an identifier is 1024 characters. |
76 | constexpr unsigned int kESSLMaxIdentifierLength = 1024u; |
77 | |
78 | } // namespace sh |
79 | |
80 | #endif // COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_ |
81 | |