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