blob: 073d226e76294fc5750a61efa65ad33d95397296 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <stdarg.h>
#include <stdio.h>
#include <ktl/algorithm.h>
namespace {
class String {
public:
String() = delete;
String(char* buf, size_t size) : buffer_(buf), capacity_(size) {}
FILE* file() { return &file_; }
~String() {
if (capacity_ > 0) {
buffer_[pos_] = '\0';
}
}
private:
FILE file_{&Callback, this};
char* buffer_;
size_t capacity_;
size_t pos_ = 0;
int Write(ktl::string_view str) {
// The capacity includes the NUL terminator not written here.
if (pos_ + 1 < capacity_) {
size_t copy = ktl::min(str.size(), capacity_ - 1 - pos_);
memcpy(&buffer_[pos_], str.data(), copy);
pos_ += copy;
}
return static_cast<int>(str.size());
}
static int Callback(void* ptr, ktl::string_view str) {
return static_cast<String*>(ptr)->Write(str);
}
};
} // namespace
int vsnprintf(char* buf, size_t len, const char* fmt, va_list args) {
String out{buf, len};
return vfprintf(out.file(), fmt, args);
}
int snprintf(char* buf, size_t len, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
int result = vsnprintf(buf, len, fmt, args);
va_end(args);
return result;
}