/** Print a formatted double to the output stream. */ void _print_double(std::ostringstream& ss, size_t width, double value) { if(long(value) == value) { std::string sv = std::to_string(long(value)); if(sv.size() < width) { _print_string(ss, width, sv); return; } } ss << ' '; size_t start_pos = ss.tellp(); bool printed_normally = false; { std::ostringstream ss_buf; ss_buf.width(width); ss_buf << std::left << value; if(size_t(ss_buf.tellp()) <= width) { ss << ss_buf.str(); printed_normally = true; } } if(!printed_normally) { // Find a good precision with which to print this; loop until it // breaks or we hit 4 decimal places. size_t precision = 0; for(;precision < 5; ++precision) { std::ostringstream ss_buf; ss_buf.width(width); ss_buf << std::left << std::setprecision(precision) << value; if(ss_buf.tellp() > long(width)) { precision = (precision == 0) ? 0 : (precision - 1); std::ostringstream ss_buf_2; ss_buf_2.width(width); ss_buf_2 << std::left << std::setprecision(precision) << value; ss << ss_buf_2.str(); break; } } } // Add in padding as needed. while(size_t(ss.tellp()) < start_pos + width) ss << ' '; ss << ' ' << '|'; }
void _printJsonString(int isfirst, char *label, char *string) { if(isfirst) { printf("\"%s\": \"", label); } else { printf(", \"%s\": \"", label); } _print_string(string); printf("\""); }
/** Print a formatted long integer to the output stream. */ void _print_long(std::ostringstream& ss, size_t width, long v) { std::ostringstream ss_buf; ss_buf << std::left << v; if(size_t(ss_buf.tellp()) <= width) { _print_string(ss, width, ss_buf.str()); } else { _print_double(ss, width, v); } }
/** Print a formatted flexible type to the output stream. */ void _print_flexible_type(std::ostringstream& ss, size_t width, const flexible_type& t) { switch(t.get_type()) { case flex_type_enum::FLOAT: _print_double(ss, width, t.get<double>()); return; case flex_type_enum::INTEGER: _print_long(ss, width, t.get<flex_int>()); return; case flex_type_enum::STRING: _print_string(ss, width, t.get<flex_string>()); return; default: _print_string(ss, width, std::string(t)); return; } }
/** Print a formatted time to the output stream ss. */ void _print_time(std::ostringstream& ss, size_t width, double t) { std::stringstream ts; if(t < 0.001) { ts << (1000000*t) << "us"; } else if(t < 1) { ts << (1000*t) << "ms"; } else if(t < 60) { size_t nhs = size_t(floor(100*t)) % 100; ts << (int(floor(t))) << (nhs >= 10 ? "." : ".0") << nhs << "s"; } else if(t < 3600) { ts << int(floor(t/60)) << "m " << (int(floor(t)) % 60) << "s"; } else if(t < 86400) { // < 1 days ts << int(floor(t/3600)) << "h " << ((int(floor(t)) % 3600) / 60) << "m"; } else if(t < 10*86400) { // < 10 days ts << int(floor(t/86400)) << "d " << ((int(floor(t)) % 86400) /3600) << "h " << ((int(floor(t)) % 3600) / 60) << "m"; } else { ts << int(floor(t/86400)) << "d " << ((int(floor(t)) % 86400) /3600) << "h "; } _print_string(ss, width, ts.str()); }
/** * 格式化输出到屏幕 * 支持形如%d %ld %c %s %-7s %7s的格式 * @param[in] fmt 格式字符串 * @param[in] utf8 输入是否为UTF-8编码 * @param[in] ap 参数列表 */ static void screen_vprintf(const char *fmt, bool utf8, va_list ap) { const char *ptr = fmt; while (*fmt != '\0') { if (*fmt == '%') { _put_string(ptr, fmt, utf8); bool left_adjust = false, long_ = false; size_t width = 0; ++fmt; switch (*fmt) { case '-': left_adjust = true; ++fmt; break; case 'l': long_ = true; ++fmt; break; } while (isdigit(*fmt)) { width *= 10; width += *fmt - '0'; ++fmt; } switch (*fmt) { case 's': { const char *ptr = va_arg(ap, const char *); _print_string(ptr, width, utf8, left_adjust); break; } case 'd': { int64_t n; if (long_) { n = va_arg(ap, int64_t); } else { n = va_arg(ap, int); } char buf[24]; snprintf(buf, sizeof(buf), "%ld", n); _print_string(buf, width, true, left_adjust); break; } case 'c': { int i = va_arg(ap, int); screen_putc(i); break; } case '\0': return; default: if (utf8) screen_putc(*fmt); else screen_put_gbk(*fmt); break; } ptr = ++fmt; } else { ++fmt;
/** Print a formatted boolean to the output stream */ void _print_bool(std::ostringstream& ss, size_t width, bool b) { if(width >= 5) _print_string(ss, width, std::string(b ? "True" : "False")); else _print_string(ss, width, std::string(b ? "T" : "F")); }
void print(std::ostringstream& ss, size_t width) { _print_string(ss, width, value); }