From 179fa413b047bede6e32109e2ce82437c5fb8d34 Mon Sep 17 00:00:00 2001 From: MenTaLguY Date: Mon, 16 Jan 2006 02:36:01 +0000 Subject: moving trunk for module inkscape (bzr r1) --- src/io/base64stream.cpp | 315 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 src/io/base64stream.cpp (limited to 'src/io/base64stream.cpp') diff --git a/src/io/base64stream.cpp b/src/io/base64stream.cpp new file mode 100644 index 000000000..e9f8fe2a2 --- /dev/null +++ b/src/io/base64stream.cpp @@ -0,0 +1,315 @@ +/** + * Base64-enabled input and output streams + * + * This class allows easy encoding and decoding + * of Base64 data with a stream interface, hiding + * the implementation from the user. + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "base64stream.h" + + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# B A S E 6 4 I N P U T S T R E A M +//######################################################################### + +static int base64decode[] = +{ +/*00*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*08*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*10*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*18*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*20*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*28*/ -1, -1, -1, 62, -1, -1, -1, 63, +/*30*/ 52, 53, 54, 55, 56, 57, 58, 59, +/*38*/ 60, 61, -1, -1, -1, -1, -1, -1, +/*40*/ -1, 0, 1, 2, 3, 4, 5, 6, +/*48*/ 7, 8, 9, 10, 11, 12, 13, 14, +/*50*/ 15, 16, 17, 18, 19, 20, 21, 22, +/*58*/ 23, 24, 25, -1, -1, -1, -1, -1, +/*60*/ -1, 26, 27, 28, 29, 30, 31, 32, +/*68*/ 33, 34, 35, 36, 37, 38, 39, 40, +/*70*/ 41, 42, 43, 44, 45, 46, 47, 48, +/*78*/ 49, 50, 51, -1, -1, -1, -1, -1 +}; + + +/** + * + */ +Base64InputStream::Base64InputStream(InputStream &sourceStream) + : BasicInputStream(sourceStream) +{ + outCount = 0; + padCount = 0; + closed = false; + done = false; +} + +/** + * + */ +Base64InputStream::~Base64InputStream() +{ + close(); +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int Base64InputStream::available() +{ + if (closed ) + return 0; + int len = source.available() * 2 / 3; + return len; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void Base64InputStream::close() +{ + if (closed) + return; + source.close(); + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int Base64InputStream::get() +{ + if (closed) + return -1; + + if (outCount - padCount > 0) + { + return outBytes[3-(outCount--)]; + } + + if (done) + return -1; + + int inBytes[4]; + int inCount = 0; + while (inCount < 4) + { + int ch = source.get(); + if (ch < 0) + { + while (inCount < 4) //pad if needed + { + inBytes[inCount++] = 0; + padCount++; + } + done = true; + break; + } + if (isspace(ch)) //ascii whitespace + { + //nothing + } + else if (ch == '=') //padding + { + inBytes[inCount++] = 0; + padCount++; + } + else + { + int byteVal = base64decode[ch & 0x7f]; + //printf("char:%c %d\n", ch, byteVal); + if (byteVal < 0) + { + //Bad lookup value + } + inBytes[inCount++] = byteVal; + } + } + + outBytes[0] = ((inBytes[0]<<2) & 0xfc) | ((inBytes[1]>>4) & 0x03); + outBytes[1] = ((inBytes[1]<<4) & 0xf0) | ((inBytes[2]>>2) & 0x0f); + outBytes[2] = ((inBytes[2]<<6) & 0xc0) | ((inBytes[3] ) & 0x3f); + + outCount = 3; + + //try again + if (outCount - padCount > 0) + { + return outBytes[3-(outCount--)]; + } + + return -1; + +} + + +//######################################################################### +//# B A S E 6 4 O U T P U T S T R E A M +//######################################################################### + +static char *base64encode = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/** + * + */ +Base64OutputStream::Base64OutputStream(OutputStream &destinationStream) + : BasicOutputStream(destinationStream) +{ + column = 0; + columnWidth = 72; + outBuf = 0L; + bitCount = 0; +} + +/** + * + */ +Base64OutputStream::~Base64OutputStream() +{ + close(); +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void Base64OutputStream::close() +{ + if (closed) + return; + + //get any last bytes (1 or 2) out of the buffer + if (bitCount == 16) + { + outBuf <<= 2; //pad to make 18 bits + + int indx = (int)((outBuf & 0x0003f000L) >> 12); + int obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x00000fc0L) >> 6); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x0000003fL) ); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + putCh('='); + } + else if (bitCount == 8) + { + outBuf <<= 4; //pad to make 12 bits + + int indx = (int)((outBuf & 0x00000fc0L) >> 6); + int obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x0000003fL) ); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + putCh('='); + putCh('='); + } + + if (columnWidth > 0) //if <=0, no newlines + destination.put('\n'); + + destination.close(); + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void Base64OutputStream::flush() +{ + if (closed) + return; + //dont flush here. do it on close() + destination.flush(); +} + +/** + * Private. Put a char to the output stream, checking for line length + */ +void Base64OutputStream::putCh(int ch) +{ + destination.put(ch); + column++; + if (columnWidth > 0 && column >= columnWidth) + { + destination.put('\n'); + column = 0; + } +} + + +/** + * Writes the specified byte to this output stream. + */ +void Base64OutputStream::put(int ch) +{ + if (closed) + { + //probably throw an exception here + return; + } + + outBuf <<= 8; + outBuf |= (ch & 0xff); + bitCount += 8; + if (bitCount >= 24) + { + int indx = (int)((outBuf & 0x00fc0000L) >> 18); + int obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x0003f000L) >> 12); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x00000fc0L) >> 6); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x0000003fL) ); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + bitCount = 0; + outBuf = 0L; + } +} + + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### -- cgit v1.2.3