| 126 | } |
| 127 | |
| 128 | std::string StrFormatImp(const char* msg, va_list args) { |
| 129 | // we might need a second shot at this, so pre-emptivly make a copy |
| 130 | va_list args_cp; |
| 131 | va_copy(args_cp, args); |
| 132 | |
| 133 | // TODO(ericwf): use std::array for first attempt to avoid one memory |
| 134 | // allocation guess what the size might be |
| 135 | std::array<char, 256> local_buff; |
| 136 | |
| 137 | // 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation |
| 138 | // in the android-ndk |
| 139 | auto ret = vsnprintf(local_buff.data(), local_buff.size(), msg, args_cp); |
| 140 | |
| 141 | va_end(args_cp); |
| 142 | |
| 143 | // handle empty expansion |
| 144 | if (ret == 0) return std::string{}; |
| 145 | if (static_cast<std::size_t>(ret) < local_buff.size()) |
| 146 | return std::string(local_buff.data()); |
| 147 | |
| 148 | // we did not provide a long enough buffer on our first attempt. |
| 149 | // add 1 to size to account for null-byte in size cast to prevent overflow |
| 150 | std::size_t size = static_cast<std::size_t>(ret) + 1; |
| 151 | auto buff_ptr = std::unique_ptr<char[]>(new char[size]); |
| 152 | // 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation |
| 153 | // in the android-ndk |
| 154 | vsnprintf(buff_ptr.get(), size, msg, args); |
| 155 | return std::string(buff_ptr.get()); |
| 156 | } |
| 157 | |
| 158 | std::string StrFormat(const char* format, ...) { |
| 159 | va_list args; |