xref: /aosp_15_r20/external/angle/src/compiler/translator/ImmutableStringBuilder.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 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 <cstring>
14 
15 #include "compiler/translator/ImmutableString.h"
16 
17 namespace sh
18 {
19 
20 class ImmutableStringBuilder
21 {
22   public:
ImmutableStringBuilder(size_t maxLength)23     ImmutableStringBuilder(size_t maxLength)
24         : mPos(0u), mMaxLength(maxLength), mData(AllocateEmptyPoolCharArray(maxLength))
25     {}
26 
27     ImmutableStringBuilder &operator<<(const ImmutableString &str);
28     ImmutableStringBuilder &operator<<(const char *str) { return *this << ImmutableString(str); }
29     ImmutableStringBuilder &operator<<(char c);
30     ImmutableStringBuilder &operator<<(int i) { return *this << static_cast<int64_t>(i); }
31     ImmutableStringBuilder &operator<<(unsigned i) { return *this << static_cast<uint64_t>(i); }
32     ImmutableStringBuilder &operator<<(int64_t i);
33     ImmutableStringBuilder &operator<<(uint64_t i);
34 
35     // This invalidates the ImmutableStringBuilder, so it should only be called once.
36     operator ImmutableString();
37 
38     template <typename T>
appendHex(T number)39     void appendHex(T number)
40     {
41         ASSERT(mData != nullptr);
42         ASSERT(mPos + sizeof(T) * 2u <= mMaxLength);
43         int index = static_cast<int>(sizeof(T)) * 2 - 1;
44         // Loop through leading zeroes.
45         while (((number >> (index * 4)) & 0xfu) == 0 && index > 0)
46         {
47             --index;
48         }
49         // Write the rest of the hex digits.
50         while (index >= 0)
51         {
52             char digit     = static_cast<char>((number >> (index * 4)) & 0xfu);
53             char digitChar = (digit < 10) ? (digit + '0') : (digit + ('a' - 10));
54             mData[mPos++]  = digitChar;
55             --index;
56         }
57     }
58 
59     template <typename T>
GetHexCharCount()60     static constexpr size_t GetHexCharCount()
61     {
62         return sizeof(T) * 2;
63     }
64 
65   private:
AllocateEmptyPoolCharArray(size_t strLength)66     inline static char *AllocateEmptyPoolCharArray(size_t strLength)
67     {
68         size_t requiredSize = strLength + 1u;
69         return static_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize));
70     }
71 
72     size_t mPos;
73     size_t mMaxLength;
74     char *mData;
75 };
76 
77 // GLSL ES 3.00.6 section 3.9: the maximum length of an identifier is 1024 characters.
78 constexpr unsigned int kESSLMaxIdentifierLength = 1024u;
79 
80 namespace impl
81 {
82 
GetCharCount(uint64_t x)83 constexpr inline size_t GetCharCount(uint64_t x)
84 {
85     size_t digits = 1;
86     uint64_t max  = 10;
87     for (; digits < 19; ++digits)
88     {
89         if (x < max)
90             break;
91         max *= 10;
92     }
93     return digits;
94 }
95 
GetCharCount(int64_t x)96 constexpr inline size_t GetCharCount(int64_t x)
97 {
98     if (x == INT64_MIN)
99     {
100         return 19 + 1;
101     }
102     if (x < 0)
103     {
104         return GetCharCount(static_cast<uint64_t>(-x)) + 1;
105     }
106     return GetCharCount(static_cast<uint64_t>(x));
107 }
108 
GetCharCount(int x)109 constexpr inline size_t GetCharCount(int x)
110 {
111     return GetCharCount(static_cast<int64_t>(x));
112 }
113 
GetCharCount(unsigned x)114 constexpr inline size_t GetCharCount(unsigned x)
115 {
116     return GetCharCount(static_cast<int64_t>(x));
117 }
118 
GetCharCount(const ImmutableString & str)119 constexpr inline size_t GetCharCount(const ImmutableString &str)
120 {
121     return str.length();
122 }
123 
GetCharCount(const char * str)124 constexpr inline size_t GetCharCount(const char *str)
125 {
126     return angle::ConstStrLen(str);
127 }
128 
GetCharCount(char)129 constexpr inline size_t GetCharCount(char)
130 {
131     return 1;
132 }
133 
134 }  // namespace impl
135 
136 template <typename... Args>
BuildConcatenatedImmutableString(Args...args)137 ImmutableString BuildConcatenatedImmutableString(Args... args)
138 {
139     ImmutableStringBuilder builder((impl::GetCharCount(args) + ...));
140     (builder << ... << args);
141     return builder;
142 }
143 
144 }  // namespace sh
145 
146 #endif  // COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_
147