blob: 2c10b4d69bfbf924a6aea5ac056182970a0c2e25 [file] [log] [blame]
// Copyright 2019 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#include "pw_string/type_to_string.h"
#include <array>
#include <cmath>
#include <cstddef>
#include <cstring>
#include <limits>
#include "lib/stdcompat/bit.h"
namespace pw::string {
StatusWithSize IntToHexString(uint64_t value,
span<char> buffer,
uint_fast8_t min_width) {
const uint_fast8_t digits = std::max(HexDigitCount(value), min_width);
if (digits >= buffer.size()) {
return internal::HandleExhaustedBuffer(buffer);
}
for (int i = static_cast<int>(digits) - 1; i >= 0; --i) {
buffer[static_cast<size_t>(i)] = "0123456789abcdef"[value & 0xF];
value >>= 4;
}
buffer[digits] = '\0';
return StatusWithSize(digits);
}
StatusWithSize FloatAsIntToString(float value, span<char> buffer) {
// If it's finite and fits in an int64_t, print it as a rounded integer.
if (std::isfinite(value) &&
std::abs(value) <
static_cast<float>(std::numeric_limits<int64_t>::max())) {
return IntToString<int64_t>(static_cast<int64_t>(std::roundf(value)),
buffer);
}
// Otherwise, print inf or NaN, if they fit.
if (const size_t written = 3 + std::signbit(value); written < buffer.size()) {
char* out = buffer.data();
if (std::signbit(value)) {
*out++ = '-';
}
std::memcpy(out, std::isnan(value) ? "NaN" : "inf", sizeof("NaN"));
return StatusWithSize(written);
}
return internal::HandleExhaustedBuffer(buffer);
}
StatusWithSize BoolToString(bool value, span<char> buffer) {
return CopyEntireStringOrNull(value ? "true" : "false", buffer);
}
StatusWithSize PointerToString(const void* pointer, span<char> buffer) {
if (pointer == nullptr) {
return CopyEntireStringOrNull(kNullPointerString, buffer);
}
return IntToHexString(reinterpret_cast<uintptr_t>(pointer), buffer);
}
StatusWithSize CopyEntireStringOrNull(std::string_view value,
span<char> buffer) {
if (value.size() >= buffer.size()) {
return internal::HandleExhaustedBuffer(buffer);
}
std::memcpy(buffer.data(), value.data(), value.size());
buffer[value.size()] = '\0';
return StatusWithSize(value.size());
}
} // namespace pw::string