xref: /aosp_15_r20/external/libtextclassifier/native/utils/strings/append.cc (revision 993b0882672172b81d12fad7a7ac0c3e5c824a12)
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "utils/strings/append.h"
18 
19 #include <stdarg.h>
20 
21 #include <cstring>
22 #include <string>
23 #include <vector>
24 
25 namespace libtextclassifier3 {
26 namespace strings {
27 
SStringAppendV(std::string * strp,int bufsize,const char * fmt,va_list arglist)28 void SStringAppendV(std::string *strp, int bufsize, const char *fmt,
29                     va_list arglist) {
30   int capacity = bufsize;
31   if (capacity <= 0) {
32     va_list backup;
33     va_copy(backup, arglist);
34     capacity = vsnprintf(nullptr, 0, fmt, backup);
35     va_end(arglist);
36   }
37 
38   size_t start = strp->size();
39   strp->resize(strp->size() + capacity + 1);
40 
41   int written = vsnprintf(&(*strp)[start], capacity + 1, fmt, arglist);
42   va_end(arglist);
43   strp->resize(start + std::min(capacity, written));
44 }
45 
SStringAppendF(std::string * strp,int bufsize,const char * fmt,...)46 void SStringAppendF(std::string *strp,
47                                 int bufsize,
48                                 const char *fmt, ...) {
49   va_list arglist;
50   va_start(arglist, fmt);
51   SStringAppendV(strp, bufsize, fmt, arglist);
52 }
53 
StringPrintf(const char * fmt,...)54 std::string StringPrintf(const char* fmt, ...) {
55   std::string s;
56   va_list arglist;
57   va_start(arglist, fmt);
58   SStringAppendV(&s, 0, fmt, arglist);
59   return s;
60 }
61 
JoinStrings(const char * delim,const std::vector<std::string> & vec)62 std::string JoinStrings(const char *delim,
63                         const std::vector<std::string> &vec) {
64   int delim_len = strlen(delim);
65 
66   // Calc size.
67   int out_len = 0;
68   for (size_t i = 0; i < vec.size(); i++) {
69     out_len += vec[i].size() + delim_len;
70   }
71 
72   // Write out.
73   std::string ret;
74   ret.reserve(out_len);
75   for (size_t i = 0; i < vec.size(); i++) {
76     ret.append(vec[i]);
77     ret.append(delim, delim_len);
78   }
79 
80   // Strip last delimiter.
81   if (!ret.empty()) {
82     // Must be at least delim_len.
83     ret.resize(ret.size() - delim_len);
84   }
85   return ret;
86 }
87 
88 }  // namespace strings
89 }  // namespace libtextclassifier3
90