blob: 2a114370566e388ffb86125436bc952c0ed39dd6 [file] [log] [blame]
Elliott Hugheseb4f6142011-07-15 17:43:51 -07001// Copyright 2011 Google Inc. All Rights Reserved.
Elliott Hugheseb4f6142011-07-15 17:43:51 -07002
3#include "stringprintf.h"
4
5#include <stdio.h>
6
Elliott Hughes11d1b0c2012-01-23 16:57:47 -08007namespace art {
8
Elliott Hugheseb4f6142011-07-15 17:43:51 -07009void StringAppendV(std::string* dst, const char* format, va_list ap) {
10 // First try with a small fixed size buffer
11 char space[1024];
12
13 // It's possible for methods that use a va_list to invalidate
14 // the data in it upon use. The fix is to make a copy
15 // of the structure before using it and use that copy instead.
16 va_list backup_ap;
17 va_copy(backup_ap, ap);
18 int result = vsnprintf(space, sizeof(space), format, backup_ap);
19 va_end(backup_ap);
20
21 if (result < int(sizeof(space))) {
22 if (result >= 0) {
23 // Normal case -- everything fit.
24 dst->append(space, result);
25 return;
26 }
27
28 if (result < 0) {
29 // Just an error.
30 return;
31 }
32 }
33
34 // Increase the buffer size to the size requested by vsnprintf,
35 // plus one for the closing \0.
36 int length = result+1;
37 char* buf = new char[length];
38
39 // Restore the va_list before we use it again
40 va_copy(backup_ap, ap);
41 result = vsnprintf(buf, length, format, backup_ap);
42 va_end(backup_ap);
43
44 if (result >= 0 && result < length) {
45 // It fit
46 dst->append(buf, result);
47 }
48 delete[] buf;
49}
50
51std::string StringPrintf(const char* fmt, ...) {
52 va_list ap;
53 va_start(ap, fmt);
54 std::string result;
55 StringAppendV(&result, fmt, ap);
56 va_end(ap);
57 return result;
58}
59
60void StringAppendF(std::string* dst, const char* format, ...) {
61 va_list ap;
62 va_start(ap, format);
63 StringAppendV(dst, format, ap);
64 va_end(ap);
65}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080066
67} // namespace art