blob: 8fd9257048e3a4f90dd2339b6c50e94a36bf2cce [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 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 */
Elliott Hugheseb4f6142011-07-15 17:43:51 -070016
17#include "stringprintf.h"
18
19#include <stdio.h>
20
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080021namespace art {
22
Elliott Hugheseb4f6142011-07-15 17:43:51 -070023void StringAppendV(std::string* dst, const char* format, va_list ap) {
24 // First try with a small fixed size buffer
25 char space[1024];
26
27 // It's possible for methods that use a va_list to invalidate
28 // the data in it upon use. The fix is to make a copy
29 // of the structure before using it and use that copy instead.
30 va_list backup_ap;
31 va_copy(backup_ap, ap);
32 int result = vsnprintf(space, sizeof(space), format, backup_ap);
33 va_end(backup_ap);
34
Elliott Hughes398f64b2012-03-26 18:05:48 -070035 if (result < static_cast<int>(sizeof(space))) {
Elliott Hugheseb4f6142011-07-15 17:43:51 -070036 if (result >= 0) {
37 // Normal case -- everything fit.
38 dst->append(space, result);
39 return;
40 }
41
42 if (result < 0) {
43 // Just an error.
44 return;
45 }
46 }
47
48 // Increase the buffer size to the size requested by vsnprintf,
49 // plus one for the closing \0.
50 int length = result+1;
51 char* buf = new char[length];
52
53 // Restore the va_list before we use it again
54 va_copy(backup_ap, ap);
55 result = vsnprintf(buf, length, format, backup_ap);
56 va_end(backup_ap);
57
58 if (result >= 0 && result < length) {
59 // It fit
60 dst->append(buf, result);
61 }
62 delete[] buf;
63}
64
65std::string StringPrintf(const char* fmt, ...) {
66 va_list ap;
67 va_start(ap, fmt);
68 std::string result;
69 StringAppendV(&result, fmt, ap);
70 va_end(ap);
71 return result;
72}
73
74void StringAppendF(std::string* dst, const char* format, ...) {
75 va_list ap;
76 va_start(ap, format);
77 StringAppendV(dst, format, ap);
78 va_end(ap);
79}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080080
81} // namespace art