1 //===-- Standalone implementation of a char vector --------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_LIBC_SRC___SUPPORT_CHARVECTOR_H 10 #define LLVM_LIBC_SRC___SUPPORT_CHARVECTOR_H 11 12 #include "hdr/func/free.h" 13 #include "hdr/func/malloc.h" 14 #include "hdr/func/realloc.h" 15 #include "src/__support/common.h" // LIBC_INLINE 16 #include "src/__support/macros/config.h" 17 18 #include <stddef.h> // size_t 19 20 namespace LIBC_NAMESPACE_DECL { 21 22 // This is very simple alternate of the std::string class. There is no 23 // bounds check performed in any of the methods. The callers are expected to 24 // do the checks before invoking the methods. 25 // 26 // This class will be extended as needed in future. 27 28 class CharVector { 29 static constexpr size_t INIT_BUFF_SIZE = 64; 30 char local_buffer[INIT_BUFF_SIZE]; 31 char *cur_str = local_buffer; 32 size_t cur_buff_size = INIT_BUFF_SIZE; 33 size_t index = 0; 34 35 public: 36 CharVector() = default; ~CharVector()37 LIBC_INLINE ~CharVector() { 38 if (cur_str != local_buffer) 39 free(cur_str); 40 } 41 42 // append returns true on success and false on allocation failure. append(char new_char)43 LIBC_INLINE bool append(char new_char) { 44 // Subtract 1 for index starting at 0 and another for the null terminator. 45 if (index >= cur_buff_size - 2) { 46 // If the new character would cause the string to be longer than the 47 // buffer's size, attempt to allocate a new buffer. 48 cur_buff_size = cur_buff_size * 2; 49 if (cur_str == local_buffer) { 50 char *new_str; 51 new_str = reinterpret_cast<char *>(malloc(cur_buff_size)); 52 if (new_str == nullptr) { 53 return false; 54 } 55 // TODO: replace with inline memcpy 56 for (size_t i = 0; i < index; ++i) 57 new_str[i] = cur_str[i]; 58 cur_str = new_str; 59 } else { 60 cur_str = reinterpret_cast<char *>(realloc(cur_str, cur_buff_size)); 61 if (cur_str == nullptr) { 62 return false; 63 } 64 } 65 } 66 cur_str[index] = new_char; 67 ++index; 68 return true; 69 } 70 c_str()71 LIBC_INLINE char *c_str() { 72 cur_str[index] = '\0'; 73 return cur_str; 74 } 75 length()76 LIBC_INLINE size_t length() { return index; } 77 }; 78 79 } // namespace LIBC_NAMESPACE_DECL 80 81 #endif // LLVM_LIBC_SRC___SUPPORT_CHARVECTOR_H 82