1*8975f5c5SAndroid Build Coastguard Worker // 2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2018 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker // 6*8975f5c5SAndroid Build Coastguard Worker // ImmutableStringBuilder.cpp: Stringstream-like utility for building pool allocated strings where 7*8975f5c5SAndroid Build Coastguard Worker // the maximum length is known in advance. 8*8975f5c5SAndroid Build Coastguard Worker // 9*8975f5c5SAndroid Build Coastguard Worker 10*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/ImmutableStringBuilder.h" 11*8975f5c5SAndroid Build Coastguard Worker 12*8975f5c5SAndroid Build Coastguard Worker #include <inttypes.h> 13*8975f5c5SAndroid Build Coastguard Worker #include <stdio.h> 14*8975f5c5SAndroid Build Coastguard Worker 15*8975f5c5SAndroid Build Coastguard Worker namespace sh 16*8975f5c5SAndroid Build Coastguard Worker { 17*8975f5c5SAndroid Build Coastguard Worker operator <<(const ImmutableString & str)18*8975f5c5SAndroid Build Coastguard WorkerImmutableStringBuilder &ImmutableStringBuilder::operator<<(const ImmutableString &str) 19*8975f5c5SAndroid Build Coastguard Worker { 20*8975f5c5SAndroid Build Coastguard Worker ASSERT(mData != nullptr); 21*8975f5c5SAndroid Build Coastguard Worker ASSERT(mPos + str.length() <= mMaxLength); 22*8975f5c5SAndroid Build Coastguard Worker memcpy(mData + mPos, str.data(), str.length()); 23*8975f5c5SAndroid Build Coastguard Worker mPos += str.length(); 24*8975f5c5SAndroid Build Coastguard Worker return *this; 25*8975f5c5SAndroid Build Coastguard Worker } 26*8975f5c5SAndroid Build Coastguard Worker operator <<(char c)27*8975f5c5SAndroid Build Coastguard WorkerImmutableStringBuilder &ImmutableStringBuilder::operator<<(char c) 28*8975f5c5SAndroid Build Coastguard Worker { 29*8975f5c5SAndroid Build Coastguard Worker ASSERT(mData != nullptr); 30*8975f5c5SAndroid Build Coastguard Worker ASSERT(mPos + 1 <= mMaxLength); 31*8975f5c5SAndroid Build Coastguard Worker mData[mPos++] = c; 32*8975f5c5SAndroid Build Coastguard Worker return *this; 33*8975f5c5SAndroid Build Coastguard Worker } 34*8975f5c5SAndroid Build Coastguard Worker operator <<(uint64_t v)35*8975f5c5SAndroid Build Coastguard WorkerImmutableStringBuilder &ImmutableStringBuilder::operator<<(uint64_t v) 36*8975f5c5SAndroid Build Coastguard Worker { 37*8975f5c5SAndroid Build Coastguard Worker // + 1 is because snprintf writes at most bufsz - 1 and then \0. 38*8975f5c5SAndroid Build Coastguard Worker // Our bufsz is mMaxLength + 1. 39*8975f5c5SAndroid Build Coastguard Worker int numChars = snprintf(mData + mPos, mMaxLength - mPos + 1, "%" PRIu64, v); 40*8975f5c5SAndroid Build Coastguard Worker ASSERT(numChars >= 0); 41*8975f5c5SAndroid Build Coastguard Worker ASSERT(mPos + numChars <= mMaxLength); 42*8975f5c5SAndroid Build Coastguard Worker mPos += numChars; 43*8975f5c5SAndroid Build Coastguard Worker return *this; 44*8975f5c5SAndroid Build Coastguard Worker } 45*8975f5c5SAndroid Build Coastguard Worker operator <<(int64_t v)46*8975f5c5SAndroid Build Coastguard WorkerImmutableStringBuilder &ImmutableStringBuilder::operator<<(int64_t v) 47*8975f5c5SAndroid Build Coastguard Worker { 48*8975f5c5SAndroid Build Coastguard Worker // + 1 is because snprintf writes at most bufsz - 1 and then \0. 49*8975f5c5SAndroid Build Coastguard Worker // Our bufsz is mMaxLength + 1. 50*8975f5c5SAndroid Build Coastguard Worker int numChars = snprintf(mData + mPos, mMaxLength - mPos + 1, "%" PRId64, v); 51*8975f5c5SAndroid Build Coastguard Worker ASSERT(numChars >= 0); 52*8975f5c5SAndroid Build Coastguard Worker ASSERT(mPos + numChars <= mMaxLength); 53*8975f5c5SAndroid Build Coastguard Worker mPos += numChars; 54*8975f5c5SAndroid Build Coastguard Worker return *this; 55*8975f5c5SAndroid Build Coastguard Worker } 56*8975f5c5SAndroid Build Coastguard Worker operator ImmutableString()57*8975f5c5SAndroid Build Coastguard WorkerImmutableStringBuilder::operator ImmutableString() 58*8975f5c5SAndroid Build Coastguard Worker { 59*8975f5c5SAndroid Build Coastguard Worker mData[mPos] = '\0'; 60*8975f5c5SAndroid Build Coastguard Worker ImmutableString str(mData, mPos); 61*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_ASSERTS) 62*8975f5c5SAndroid Build Coastguard Worker // Make sure that nothing is added to the string after it is finalized. 63*8975f5c5SAndroid Build Coastguard Worker mData = nullptr; 64*8975f5c5SAndroid Build Coastguard Worker #endif 65*8975f5c5SAndroid Build Coastguard Worker return str; 66*8975f5c5SAndroid Build Coastguard Worker } 67*8975f5c5SAndroid Build Coastguard Worker 68*8975f5c5SAndroid Build Coastguard Worker } // namespace sh 69