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