printf.cpp 1018 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. #include "output.h"
  2. #include "printf.h"
  3. #include <util/generic/scope.h>
  4. #include <util/memory/tempbuf.h>
  5. size_t Printf(IOutputStream& out, const char* fmt, ...) {
  6. va_list lst;
  7. va_start(lst, fmt);
  8. Y_DEFER {
  9. va_end(lst);
  10. };
  11. return Printf(out, fmt, lst);
  12. }
  13. static inline size_t TryPrintf(void* ptr, size_t len, IOutputStream& out, const char* fmt, va_list params) {
  14. va_list lst;
  15. va_copy(lst, params);
  16. const int ret = vsnprintf((char*)ptr, len, fmt, lst);
  17. va_end(lst);
  18. if (ret < 0) {
  19. return len;
  20. }
  21. if ((size_t)ret < len) {
  22. out.Write(ptr, (size_t)ret);
  23. }
  24. return (size_t)ret;
  25. }
  26. size_t Printf(IOutputStream& out, const char* fmt, va_list params) {
  27. size_t guess = 0;
  28. while (true) {
  29. TTempBuf tmp(guess);
  30. const size_t ret = TryPrintf(tmp.Data(), tmp.Size(), out, fmt, params);
  31. if (ret < tmp.Size()) {
  32. return ret;
  33. }
  34. guess = Max(tmp.Size() * 2, ret + 1);
  35. }
  36. return 0;
  37. }