| 10 | |
| 11 | namespace Exiv2::Internal { |
| 12 | std::string stringFormat(const char* format, ...) { |
| 13 | std::string result; |
| 14 | std::vector<char> buffer; |
| 15 | size_t need = std::strlen(format) * 8; // initial guess |
| 16 | int rc = -1; |
| 17 | |
| 18 | // vsnprintf writes at most size (2nd parameter) bytes (including \0) |
| 19 | // returns the number of bytes required for the formatted string excluding \0 |
| 20 | // the following loop goes through: |
| 21 | // one iteration (if 'need' was large enough for the for formatted string) |
| 22 | // or two iterations (after the first call to vsnprintf we know the required length) |
| 23 | do { |
| 24 | buffer.resize(need + 1); |
| 25 | va_list args; // variable arg list |
| 26 | va_start(args, format); // args start after format |
| 27 | rc = vsnprintf(buffer.data(), buffer.size(), format, args); |
| 28 | va_end(args); // free the args |
| 29 | if (rc > 0) |
| 30 | need = static_cast<size_t>(rc); |
| 31 | } while (buffer.size() <= need); |
| 32 | |
| 33 | if (rc > 0) |
| 34 | result = std::string(buffer.data(), need); |
| 35 | return result; |
| 36 | } |
| 37 | |
| 38 | [[nodiscard]] std::string indent(size_t i) { |
| 39 | return std::string(2 * i, ' '); |
no test coverage detected