xref: /aosp_15_r20/external/llvm-libc/src/__support/char_vector.h (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
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