10 #include "LibStringFormat.hpp"
11 #include "LibStreamOut.hpp"
13 const char LibStringFormat::HEX_CHARS_LOWER_CASE[] =
"0123456789abcdef";
14 const char LibStringFormat::HEX_CHARS_UPPER_CASE[] =
"0123456789ABCDEF";
18 int LibStringFormat::printf(LibStreamOut& stream,
const char* format, ...) {
22 va_start(vaList, format);
24 len = vprintf(stream, format, vaList);
31 int LibStringFormat::vprintf(LibStreamOut& stream,
const char* format, va_list vaList) {
37 const char* start = format;
39 if (*format ==
'\0') {
40 size_t segLen = format - start;
42 len += stream.write(start, segLen);
47 size_t segLen = format - start;
49 len += stream.write(start, segLen);
59 len += stream.write(format++, 1);
63 FORMAT_PARAMETERS parameters;
66 format = parseFlags(format, parameters.flags);
69 format = parseWidth(format, parameters.width);
72 format = parsePrecision(format, parameters.precision);
75 format = parseLength(format, parameters.length);
79 len += writeChar(stream, va_arg(vaList,
int), parameters);
83 int value = va_arg(vaList,
int);
86 parameters.flags.bits.isNegative =
true;
89 len += writeNaturalNumber(stream, value, parameters);
93 double value = va_arg(vaList,
double);
96 parameters.flags.bits.isNegative =
true;
99 len += writeFloat(stream, value, parameters);
104 len += writeString(stream, va_arg(vaList,
char *), parameters);
107 parameters.base = 10;
108 len += writeNaturalNumber(stream, va_arg(vaList,
unsigned int), parameters);
111 parameters.flags.bits.isLowerCase =
true;
113 parameters.base = 16;
114 len += writeNaturalNumber(stream, va_arg(vaList,
unsigned int), parameters);
117 len += stream.write(format++, 1);
125 int LibStringFormat::writeChar(LibStreamOut& stream,
const char c,
const FORMAT_PARAMETERS& parameters) {
128 int padLen = parameters.width - 1;
130 if (!parameters.flags.bits.leftJustify) {
131 len += writePad(stream,
' ', padLen);
134 len += stream.write(&c, 1);
136 len += writePad(stream,
' ', padLen);
141 int LibStringFormat::writeNaturalNumber(LibStreamOut& stream,
unsigned int value,
const FORMAT_PARAMETERS& parameters) {
144 int idx =
sizeof(buffer);
146 const char* chars = HEX_CHARS_UPPER_CASE;
148 if (parameters.flags.bits.isLowerCase) {
149 chars = HEX_CHARS_LOWER_CASE;
157 for (; idx > 0 && value > 0;) {
158 buffer[--idx] = chars[value % parameters.base];
159 value /= parameters.base;
163 if (parameters.flags.bits.isNegative && (idx >= 1)) {
166 else if (parameters.flags.bits.forceSign && (idx >= 1)) {
169 else if (parameters.flags.bits.forceSpace && (idx >= 1)) {
173 if (parameters.flags.bits.sharp && (parameters.base == 16) && (idx >= 1)) {
175 if (parameters.flags.bits.isLowerCase) {
183 int len = (
sizeof(buffer) - idx);
184 int padLen = parameters.width - len;
186 if (!parameters.flags.bits.leftJustify) {
187 if (parameters.flags.bits.leftPadWith0) {
188 len += writePad(stream,
'0', padLen);
191 len += writePad(stream,
' ', padLen);
195 stream.write(&buffer[idx], (
int)
sizeof(buffer) - idx);
197 len += writePad(stream,
' ', padLen);
202 int LibStringFormat::writeFloat(LibStreamOut& stream,
double value, FORMAT_PARAMETERS& parameters) {
206 for (
int i = 0; i < parameters.precision; i++) {
210 uint32_t intValue = value * multiplier;
213 if ((((uint32_t) (value * multiplier * 10)) % 10) >= 5) {
217 uint32_t integerPart = intValue / multiplier;
218 uint32_t decimalPart = intValue % multiplier;
220 len = writeNaturalNumber(stream, integerPart, parameters);
222 if (parameters.precision <= 0) {
227 len += stream.write(&c, 1);
230 parameters.width = parameters.precision;
231 parameters.flags.bits.leftPadWith0 =
true;
232 parameters.flags.bits.isNegative =
false;
233 len += writeNaturalNumber(stream, decimalPart, parameters);
238 int LibStringFormat::writeString(LibStreamOut& stream,
const char*
string,
const FORMAT_PARAMETERS& parameters) {
240 const char* parser = string;
248 int padLen = parameters.width - strLen;
250 if (!parameters.flags.bits.leftJustify) {
251 len += writePad(stream,
' ', padLen);
254 len += stream.write(
string, strLen);
256 len += writePad(stream,
' ', padLen);
261 int LibStringFormat::writePad(LibStreamOut& stream,
const char c,
int& size) {
264 if (!stream.write(&c, 1)) {
272 const char* LibStringFormat::parseFlags(
const char* format, FLAGS& flags) {
277 flags.bits.leftJustify =
true;
280 flags.bits.forceSign =
true;
283 flags.bits.forceSpace =
true;
286 flags.bits.sharp =
true;
289 flags.bits.leftPadWith0 =
true;
298 const char* LibStringFormat::parseWidth(
const char* format,
int& width) {
301 if ((*format <
'0') || (*format >
'9')) {
305 width += *format++ -
'0';
309 const char* LibStringFormat::parsePrecision(
const char* format,
int& precision) {
311 if (*format !=
'.') {
316 if ((*format <
'0') || (*format >
'9')) {
320 precision += *format++ -
'0';
324 const char* LibStringFormat::parseLength(
const char* format,
int& length) {
328 length = LENGTH_HALF;
331 length = LENGTH_LONG;
334 length = LENGTH_DOUBLE;