X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fdom%2Fio%2Fdomstream.cpp;h=c6234d462e652a7b46384af026d203777c098b03;hb=cfb5fa826062314dac912b3627f932aab8250988;hp=3ffba53feefab4f27719624cd18b41b7f6b0425f;hpb=0e5bd184457cc156711e9fd6320cd4de8169ffa0;p=inkscape.git diff --git a/src/dom/io/domstream.cpp b/src/dom/io/domstream.cpp index 3ffba53fe..c6234d462 100644 --- a/src/dom/io/domstream.cpp +++ b/src/dom/io/domstream.cpp @@ -34,6 +34,7 @@ * */ +#include #include #include "domstream.h" @@ -65,6 +66,359 @@ void pipeStream(InputStream &source, OutputStream &dest) dest.flush(); } + + +//######################################################################### +//# F O R M A T T E D P R I N T I N G +//######################################################################### + +static char *digits = "0123456789abcdefghijklmnopqrstuvwxyz"; + +static int dprintInt(Writer &outs, + long arg, int base, + int flag, int width, int precision) +{ + + DOMString buf; + + //### Get the digits + while (arg > 0) + { + int ch = arg % base; + buf.insert(buf.begin(), digits[ch]); + arg /= base; + } + + if (flag == '#' && base == 16) + { + buf.insert(buf.begin(), 'x'); + buf.insert(buf.begin(), '0'); + } + + if (buf.size() == 0) + buf = "0"; + + int pad = width - (int)buf.size(); + for (int i=0 ; i 0) + pad -= precision + 1; + else if (flag == '#') + pad--; + + + //### Signs + if (negative) + buf.push_back('-'); + else if (flag == '+') + buf.push_back('+'); + + //### Prefix pad + if (pad > 0 && flag == '0') + { + while (pad--) + buf.push_back('0'); + } + + //### Integer digits + intPart = (intPart + 0.1 ) / scale; // turn 12345.678 to .12345678 + while (intDigits--) + { + intPart *= 10.0; + double dig; + intPart = modf(intPart, &dig); + char ch = '0' + (int)dig; + buf.push_back(ch); + } + if (buf.size() == 0) + buf = "0"; + + //### Decimal point + if (flag == '#' || precision > 0) + { + buf.push_back('.'); + } + + //### Fractional digits + while (precision--) + { + fracPart *= 10.0; + double dig; + fracPart = modf(fracPart, &dig); + char ch = '0' + (int)dig; + buf.push_back(ch); + } + + //### Left justify if requested + if (pad > 0 && flag == '-') + { + while (pad--) + buf.push_back(' '); + } + + //### Output the result + for (unsigned int i=0 ; i') + outs.writeString(">"); + else if (ch == '"') + outs.writeString("""); + else if (ch == '\'') + outs.writeString("'"); + else + outs.put(ch); + } + } + else + { + outs.writeString(str); + } + + return 1; +} + + + +static int getint(const DOMString &buf, int pos, int *ret) +{ + int len = buf.size(); + if (!len) + { + *ret = 0; + return pos; + } + + bool has_sign = false; + int val = 0; + if (buf[pos] == '-') + { + has_sign = true; + pos++; + } + while (pos < len) + { + XMLCh ch = buf[pos]; + if (ch >= '0' && ch <= '9') + val = val * 10 + (ch - '0'); + else + break; + pos++; + } + if (has_sign) + val = -val; + + *ret = val; + + return pos; +} + + + +static int dprintf(Writer &outs, const DOMString &fmt, va_list ap) +{ + + int len = fmt.size(); + + for (int pos=0 ; pos < len ; pos++) + { + XMLCh ch = fmt[pos]; + + //## normal character + if (ch != '%') + { + if (outs.put(ch)<0) + { + return -1; + } + continue; + } + + if (++pos >= len) + { + return -1; + } + + ch = fmt[pos]; + + //## is this %% ? + if (ch == '%') // escaped '%' + { + if (outs.put('%')<0) + { + return -1; + } + continue; + } + + //## flag + char flag = '\0'; + if (ch == '-' || ch == '+' || ch == ' ' || + ch == '#' || ch == '0') + { + flag = ch; + if (++pos >= len) + { + return -1; + } + ch = fmt[pos]; + } + + //## width.precision + int width = 0; + int precision = 0; + pos = getint(fmt, pos, &width); + if (pos >= len) + { + return -1; + } + ch = fmt[pos]; + if (ch == '.') + { + if (++pos >= len) + { + return -1; + } + pos = getint(fmt, pos, &precision); + if (pos >= len) + { + return -1; + } + ch = fmt[pos]; + } + + //## length + char length = '\0'; + if (ch == 'l' || ch == 'h') + { + length = ch; + if (++pos >= len) + { + return -1; + } + ch = fmt[pos]; + } + + //## data type + switch (ch) + { + case 'f': + case 'g': + { + double val = va_arg(ap, double); + dprintDouble(outs, val, flag, width, precision); + break; + } + case 'd': + { + long val = 0; + if (length == 'l') + val = va_arg(ap, long); + else if (length == 'h') + val = (long)va_arg(ap, int); + else + val = (long)va_arg(ap, int); + dprintInt(outs, val, 10, flag, width, precision); + break; + } + case 'x': + { + long val = 0; + if (length == 'l') + val = va_arg(ap, long); + else if (length == 'h') + val = (long)va_arg(ap, int); + else + val = (long)va_arg(ap, int); + dprintInt(outs, val, 16, flag, width, precision); + break; + } + case 's': + { + DOMString val = va_arg(ap, char *); + dprintString(outs, val, flag, width, precision); + break; + } + default: + { + break; + } + } + } + + return 1; +} + + //######################################################################### //# B A S I C I N P U T S T R E A M //######################################################################### @@ -155,11 +509,13 @@ void BasicOutputStream::flush() /** * Writes the specified byte to this output stream. */ -void BasicOutputStream::put(XMLCh ch) +int BasicOutputStream::put(XMLCh ch) { if (closed) - return; - destination.put(ch); + return -1; + if (destination.put(ch) < 0) + return -1; + return 1; } @@ -529,15 +885,17 @@ void BasicWriter::flush() /** * Writes the specified byte to this output writer. */ -void BasicWriter::put(XMLCh ch) +int BasicWriter::put(XMLCh ch) { - if (destination) - destination->put(ch); + if (destination && destination->put(ch)>=0) + return 1; + return -1; } /** * Provide printf()-like formatting */ +/* Writer &BasicWriter::printf(char *fmt, ...) { va_list args; @@ -549,6 +907,16 @@ Writer &BasicWriter::printf(char *fmt, ...) return *this; } +*/ +Writer &BasicWriter::printf(const DOMString &fmt, ...) +{ + va_list args; + va_start(args, fmt); + dprintf(*this, fmt, args); + return *this; +} + + /** * Writes the specified character to this output writer. */ @@ -710,11 +1078,13 @@ void OutputStreamWriter::flush() * Overloaded to redirect the output chars from the next Writer * in the chain to an OutputStream instead. */ -void OutputStreamWriter::put(XMLCh ch) +int OutputStreamWriter::put(XMLCh ch) { //Do we need conversions here? int intCh = (int) ch; - outputStream.put(intCh); + if (outputStream.put(intCh) < 0) + return -1; + return 1; } //######################################################################### @@ -762,11 +1132,13 @@ void StdWriter::flush() * Overloaded to redirect the output chars from the next Writer * in the chain to an OutputStream instead. */ -void StdWriter::put(XMLCh ch) +int StdWriter::put(XMLCh ch) { //Do we need conversions here? int intCh = (int) ch; - outputStream->put(intCh); + if (outputStream->put(intCh) < 0) + return -1; + return 1; }