• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "src/__support/common.h" // LIBC_INLINE
13 
14 #include <stddef.h> // size_t
15 #include <stdlib.h> // malloc, realloc, free
16 
17 namespace LIBC_NAMESPACE {
18 
19 // This is very simple alternate of the std::string class. There is no
20 // bounds check performed in any of the methods. The callers are expected to
21 // do the checks before invoking the methods.
22 //
23 // This class will be extended as needed in future.
24 
25 class CharVector {
26   static constexpr size_t INIT_BUFF_SIZE = 64;
27   char local_buffer[INIT_BUFF_SIZE];
28   char *cur_str = local_buffer;
29   size_t cur_buff_size = INIT_BUFF_SIZE;
30   size_t index = 0;
31 
32 public:
33   CharVector() = default;
~CharVector()34   LIBC_INLINE ~CharVector() {
35     if (cur_str != local_buffer)
36       free(cur_str);
37   }
38 
39   // append returns true on success and false on allocation failure.
append(char new_char)40   LIBC_INLINE bool append(char new_char) {
41     // Subtract 1 for index starting at 0 and another for the null terminator.
42     if (index >= cur_buff_size - 2) {
43       // If the new character would cause the string to be longer than the
44       // buffer's size, attempt to allocate a new buffer.
45       cur_buff_size = cur_buff_size * 2;
46       if (cur_str == local_buffer) {
47         char *new_str;
48         new_str = reinterpret_cast<char *>(malloc(cur_buff_size));
49         if (new_str == nullptr) {
50           return false;
51         }
52         // TODO: replace with inline memcpy
53         for (size_t i = 0; i < index; ++i)
54           new_str[i] = cur_str[i];
55         cur_str = new_str;
56       } else {
57         cur_str = reinterpret_cast<char *>(realloc(cur_str, cur_buff_size));
58         if (cur_str == nullptr) {
59           return false;
60         }
61       }
62     }
63     cur_str[index] = new_char;
64     ++index;
65     return true;
66   }
67 
c_str()68   LIBC_INLINE char *c_str() {
69     cur_str[index] = '\0';
70     return cur_str;
71   }
72 
length()73   LIBC_INLINE size_t length() { return index; }
74 };
75 
76 } // namespace LIBC_NAMESPACE
77 
78 #endif // LLVM_LIBC_SRC___SUPPORT_CHARVECTOR_H
79