From 50964e485f3272c8aa7f655d552577771c93bfb3 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 18 Nov 2018 11:57:08 +0100 Subject: Move i/o stream classes into own directory. Add README. --- src/io/Makefile.tst | 48 --- src/io/bufferstream.cpp | 144 ------- src/io/bufferstream.h | 98 ----- src/io/gzipstream.cpp | 459 ---------------------- src/io/gzipstream.h | 124 ------ src/io/inkscapestream.cpp | 800 --------------------------------------- src/io/inkscapestream.h | 668 -------------------------------- src/io/stream/Makefile.tst | 48 +++ src/io/stream/README | 13 + src/io/stream/bufferstream.cpp | 144 +++++++ src/io/stream/bufferstream.h | 98 +++++ src/io/stream/gzipstream.cpp | 459 ++++++++++++++++++++++ src/io/stream/gzipstream.h | 124 ++++++ src/io/stream/inkscapestream.cpp | 800 +++++++++++++++++++++++++++++++++++++++ src/io/stream/inkscapestream.h | 668 ++++++++++++++++++++++++++++++++ src/io/stream/streamtest.cpp | 256 +++++++++++++ src/io/stream/stringstream.cpp | 125 ++++++ src/io/stream/stringstream.h | 105 +++++ src/io/stream/uristream.cpp | 231 +++++++++++ src/io/stream/uristream.h | 101 +++++ src/io/stream/xsltstream.cpp | 248 ++++++++++++ src/io/stream/xsltstream.h | 140 +++++++ src/io/streamtest.cpp | 256 ------------- src/io/stringstream.cpp | 125 ------ src/io/stringstream.h | 105 ----- src/io/uristream.cpp | 231 ----------- src/io/uristream.h | 101 ----- src/io/xsltstream.cpp | 248 ------------ src/io/xsltstream.h | 140 ------- 29 files changed, 3560 insertions(+), 3547 deletions(-) delete mode 100644 src/io/Makefile.tst delete mode 100644 src/io/bufferstream.cpp delete mode 100644 src/io/bufferstream.h delete mode 100644 src/io/gzipstream.cpp delete mode 100644 src/io/gzipstream.h delete mode 100644 src/io/inkscapestream.cpp delete mode 100644 src/io/inkscapestream.h create mode 100644 src/io/stream/Makefile.tst create mode 100644 src/io/stream/README create mode 100644 src/io/stream/bufferstream.cpp create mode 100644 src/io/stream/bufferstream.h create mode 100644 src/io/stream/gzipstream.cpp create mode 100644 src/io/stream/gzipstream.h create mode 100644 src/io/stream/inkscapestream.cpp create mode 100644 src/io/stream/inkscapestream.h create mode 100644 src/io/stream/streamtest.cpp create mode 100644 src/io/stream/stringstream.cpp create mode 100644 src/io/stream/stringstream.h create mode 100644 src/io/stream/uristream.cpp create mode 100644 src/io/stream/uristream.h create mode 100644 src/io/stream/xsltstream.cpp create mode 100644 src/io/stream/xsltstream.h delete mode 100644 src/io/streamtest.cpp delete mode 100644 src/io/stringstream.cpp delete mode 100644 src/io/stringstream.h delete mode 100644 src/io/uristream.cpp delete mode 100644 src/io/uristream.h delete mode 100644 src/io/xsltstream.cpp delete mode 100644 src/io/xsltstream.h (limited to 'src') diff --git a/src/io/Makefile.tst b/src/io/Makefile.tst deleted file mode 100644 index 2e3142d42..000000000 --- a/src/io/Makefile.tst +++ /dev/null @@ -1,48 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -############################################## -# -# Test makefile for InkscapeStreams -# -############################################## - - -CC = gcc -CXX = g++ - - -INC = -I. -I.. - -XSLT_CFLAGS = `pkg-config --cflags libxslt` -XSLT_LIBS = `pkg-config --libs libxslt` - -GLIBMM_CFLAGS = `pkg-config --cflags glibmm-2.4` -GLIBMM_LIBS = `pkg-config --libs glibmm-2.4` - -CFLAGS = -g $(GLIBMM_CFLAGS) $(XSLT_CFLAGS) -LIBS = $(GLIBMM_LIBS) $(XSLT_LIBS) ../uri.o -lz - -OBJ = \ -inkscapestream.o \ -base64stream.o \ -gzipstream.o \ -stringstream.o \ -uristream.o \ -xsltstream.o \ -ftos.o - -all: streamtest - -streamtest: inkscapestream.h libstream.a streamtest.o - $(CXX) -o streamtest streamtest.o libstream.a $(LIBS) - -libstream.a: $(OBJ) - ar crv libstream.a $(OBJ) - - -.cpp.o: - $(CXX) $(CFLAGS) $(INC) -c -o $@ $< - -clean: - -$(RM) *.o *.a - -$(RM) streamtest - diff --git a/src/io/bufferstream.cpp b/src/io/bufferstream.cpp deleted file mode 100644 index 1723ee1ff..000000000 --- a/src/io/bufferstream.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/** - * @file - * Phoebe DOM Implementation. - * - * This is a C++ approximation of the W3C DOM model, which follows - * fairly closely the specifications in the various .idl files, copies of - * which are provided for reference. Most important is this one: - * - * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html - *//* - * Authors: - * see git history - * Bob Jamison - * - * Copyright (C) 2018 Authors - * Released under GNU LGPL v2.1+, read the file 'COPYING' for more information. - */ - -/** - * This class provided buffered endpoints for input and output. - */ - -#include "bufferstream.h" - -namespace Inkscape -{ -namespace IO -{ - -//######################################################################### -//# B U F F E R I N P U T S T R E A M -//######################################################################### -/** - * - */ -BufferInputStream::BufferInputStream( - const std::vector &sourceBuffer) - : buffer(sourceBuffer) -{ - position = 0; - closed = false; -} - -/** - * - */ -BufferInputStream::~BufferInputStream() -= default; - -/** - * 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 BufferInputStream::available() -{ - if (closed) - return -1; - return buffer.size() - position; -} - - -/** - * Closes this input stream and releases any system resources - * associated with the stream. - */ -void BufferInputStream::close() -{ - closed = true; -} - -/** - * Reads the next byte of data from the input stream. -1 if EOF - */ -int BufferInputStream::get() -{ - if (closed) - return -1; - if (position >= (int)buffer.size()) - return -1; - int ch = (int) buffer[position++]; - return ch; -} - - - - -//######################################################################### -//# B U F F E R O U T P U T S T R E A M -//######################################################################### - -/** - * - */ -BufferOutputStream::BufferOutputStream() -{ - closed = false; -} - -/** - * - */ -BufferOutputStream::~BufferOutputStream() -= default; - -/** - * Closes this output stream and releases any system resources - * associated with this stream. - */ -void BufferOutputStream::close() -{ - closed = true; -} - -/** - * Flushes this output stream and forces any buffered output - * bytes to be written out. - */ -void BufferOutputStream::flush() -{ - //nothing to do -} - -/** - * Writes the specified byte to this output stream. - */ -int BufferOutputStream::put(char ch) -{ - if (closed) - return -1; - buffer.push_back(ch); - return 1; -} - - - - -} //namespace IO -} //namespace Inkscape - -//######################################################################### -//# E N D O F F I L E -//######################################################################### diff --git a/src/io/bufferstream.h b/src/io/bufferstream.h deleted file mode 100644 index 811ab0d57..000000000 --- a/src/io/bufferstream.h +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/** - * @file - * Phoebe DOM Implementation. - * - * This is a C++ approximation of the W3C DOM model, which follows - * fairly closely the specifications in the various .idl files, copies of - * which are provided for reference. Most important is this one: - * - * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html - *//* - * Authors: - * see git history - * Bob Jamison - * - * Copyright (C) 2018 Authors - * Released under GNU LGPL v2.1+, read the file 'COPYING' for more information. - */ -#ifndef SEEN_BUFFERSTREAM_H -#define SEEN_BUFFERSTREAM_H - - -#include -#include "inkscapestream.h" - - -namespace Inkscape -{ -namespace IO -{ - -//######################################################################### -//# S T R I N G I N P U T S T R E A M -//######################################################################### - -/** - * This class is for reading character from a DOMString - * - */ -class BufferInputStream : public InputStream -{ - -public: - - BufferInputStream(const std::vector &sourceBuffer); - ~BufferInputStream() override; - int available() override; - void close() override; - int get() override; - -private: - const std::vector &buffer; - long position; - bool closed; - -}; // class BufferInputStream - - - - -//######################################################################### -//# B U F F E R O U T P U T S T R E A M -//######################################################################### - -/** - * This class is for sending a stream to a character buffer - * - */ -class BufferOutputStream : public OutputStream -{ - -public: - - BufferOutputStream(); - ~BufferOutputStream() override; - void close() override; - void flush() override; - int put(char ch) override; - virtual std::vector &getBuffer() - { return buffer; } - - virtual void clear() - { buffer.clear(); } - -private: - std::vector buffer; - bool closed; - -}; // class BufferOutputStream - - - -} //namespace IO -} //namespace Inkscape - - - -#endif // SEEN_BUFFERSTREAM_H diff --git a/src/io/gzipstream.cpp b/src/io/gzipstream.cpp deleted file mode 100644 index 03960b004..000000000 --- a/src/io/gzipstream.cpp +++ /dev/null @@ -1,459 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/** @file - * Zlib-enabled input and output streams - *//* - * Authors: - * see git history - * Bob Jamison - * - * - * Copyright (C) 2018 Authors - * Released under GNU LGPL v2.1+, read the file 'COPYING' for more information. - */ -/* - * This is a thin wrapper of libz calls, in order - * to provide a simple interface to our developers - * for gzip input and output. - */ - -#include "gzipstream.h" -#include -#include -#include -#include - -namespace Inkscape -{ -namespace IO -{ - -//######################################################################### -//# G Z I P I N P U T S T R E A M -//######################################################################### - -#define OUT_SIZE 4000 - -/** - * - */ -GzipInputStream::GzipInputStream(InputStream &sourceStream) - : BasicInputStream(sourceStream), - loaded(false), - totalIn(0), - totalOut(0), - outputBuf(nullptr), - srcBuf(nullptr), - crc(0), - srcCrc(0), - srcSiz(0), - srcConsumed(0), - srcLen(0), - outputBufPos(0), - outputBufLen(0) -{ - memset( &d_stream, 0, sizeof(d_stream) ); -} - -/** - * - */ -GzipInputStream::~GzipInputStream() -{ - close(); - if ( srcBuf ) { - delete[] srcBuf; - srcBuf = nullptr; - } - if ( outputBuf ) { - delete[] outputBuf; - outputBuf = nullptr; - } -} - -/** - * 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 GzipInputStream::available() -{ - if (closed || !outputBuf) - return 0; - return outputBufLen - outputBufPos; -} - - -/** - * Closes this input stream and releases any system resources - * associated with the stream. - */ -void GzipInputStream::close() -{ - if (closed) - return; - - int zerr = inflateEnd(&d_stream); - if (zerr != Z_OK) { - printf("inflateEnd: Some kind of problem: %d\n", zerr); - } - - if ( srcBuf ) { - delete[] srcBuf; - srcBuf = nullptr; - } - if ( outputBuf ) { - delete[] outputBuf; - outputBuf = nullptr; - } - closed = true; -} - -/** - * Reads the next byte of data from the input stream. -1 if EOF - */ -int GzipInputStream::get() -{ - int ch = -1; - if (closed) { - // leave return value -1 - } - else if (!loaded && !load()) { - closed=true; - } else { - loaded = true; - - if ( outputBufPos >= outputBufLen ) { - // time to read more, if we can - fetchMore(); - } - - if ( outputBufPos < outputBufLen ) { - ch = (int)outputBuf[outputBufPos++]; - } - } - - return ch; -} - -#define FTEXT 0x01 -#define FHCRC 0x02 -#define FEXTRA 0x04 -#define FNAME 0x08 -#define FCOMMENT 0x10 - -bool GzipInputStream::load() -{ - crc = crc32(0L, Z_NULL, 0); - - std::vector inputBuf; - while (true) - { - int ch = source.get(); - if (ch<0) - break; - inputBuf.push_back(static_cast(ch & 0xff)); - } - long inputBufLen = inputBuf.size(); - - if (inputBufLen < 19) //header + tail + 1 - { - return false; - } - - srcLen = inputBuf.size(); - srcBuf = new (std::nothrow) Byte [srcLen]; - if (!srcBuf) { - return false; - } - - outputBuf = new (std::nothrow) unsigned char [OUT_SIZE]; - if ( !outputBuf ) { - delete[] srcBuf; - srcBuf = nullptr; - return false; - } - outputBufLen = 0; // Not filled in yet - - std::vector::iterator iter; - Bytef *p = srcBuf; - for (iter=inputBuf.begin() ; iter != inputBuf.end() ; ++iter) - { - *p++ = *iter; - } - - int headerLen = 10; - - //Magic - //int val = (int)srcBuf[0]; - ////printf("val:%x\n", val); - //val = (int)srcBuf[1]; - ////printf("val:%x\n", val); - - ////Method - //val = (int)srcBuf[2]; - ////printf("val:%x\n", val); - - //flags - int flags = static_cast(srcBuf[3]); - - ////time - //val = (int)srcBuf[4]; - //val = (int)srcBuf[5]; - //val = (int)srcBuf[6]; - //val = (int)srcBuf[7]; - - ////xflags - //val = (int)srcBuf[8]; - ////OS - //val = (int)srcBuf[9]; - -// if ( flags & FEXTRA ) { -// headerLen += 2; -// int xlen = -// TODO deal with optional header parts -// } - if ( flags & FNAME ) { - int cur = 10; - while ( srcBuf[cur] ) - { - cur++; - headerLen++; - } - headerLen++; - } - - - srcCrc = ((0x0ff & srcBuf[srcLen - 5]) << 24) - | ((0x0ff & srcBuf[srcLen - 6]) << 16) - | ((0x0ff & srcBuf[srcLen - 7]) << 8) - | ((0x0ff & srcBuf[srcLen - 8]) << 0); - //printf("srcCrc:%lx\n", srcCrc); - - srcSiz = ((0x0ff & srcBuf[srcLen - 1]) << 24) - | ((0x0ff & srcBuf[srcLen - 2]) << 16) - | ((0x0ff & srcBuf[srcLen - 3]) << 8) - | ((0x0ff & srcBuf[srcLen - 4]) << 0); - //printf("srcSiz:%lx/%ld\n", srcSiz, srcSiz); - - //outputBufLen = srcSiz + srcSiz/100 + 14; - - unsigned char *data = srcBuf + headerLen; - unsigned long dataLen = srcLen - (headerLen + 8); - //printf("%x %x\n", data[0], data[dataLen-1]); - - d_stream.zalloc = (alloc_func)nullptr; - d_stream.zfree = (free_func)nullptr; - d_stream.opaque = (voidpf)nullptr; - d_stream.next_in = data; - d_stream.avail_in = dataLen; - d_stream.next_out = outputBuf; - d_stream.avail_out = OUT_SIZE; - - int zerr = inflateInit2(&d_stream, -MAX_WBITS); - if ( zerr == Z_OK ) - { - zerr = fetchMore(); - } else { - printf("inflateInit2: Some kind of problem: %d\n", zerr); - } - - - return (zerr == Z_OK) || (zerr == Z_STREAM_END); -} - - -int GzipInputStream::fetchMore() -{ - // TODO assumes we aren't called till the buffer is empty - d_stream.next_out = outputBuf; - d_stream.avail_out = OUT_SIZE; - outputBufLen = 0; - outputBufPos = 0; - - int zerr = inflate( &d_stream, Z_SYNC_FLUSH ); - if ( zerr == Z_OK || zerr == Z_STREAM_END ) { - outputBufLen = OUT_SIZE - d_stream.avail_out; - if ( outputBufLen ) { - crc = crc32(crc, const_cast(outputBuf), outputBufLen); - } - //printf("crc:%lx\n", crc); -// } else if ( zerr != Z_STREAM_END ) { -// // TODO check to be sure this won't happen for partial end reads -// printf("inflate: Some kind of problem: %d\n", zerr); - } - - return zerr; -} - -//######################################################################### -//# G Z I P O U T P U T S T R E A M -//######################################################################### - -/** - * - */ -GzipOutputStream::GzipOutputStream(OutputStream &destinationStream) - : BasicOutputStream(destinationStream) -{ - - totalIn = 0; - totalOut = 0; - crc = crc32(0L, Z_NULL, 0); - - //Gzip header - destination.put(0x1f); - destination.put(0x8b); - - //Say it is compressed - destination.put(Z_DEFLATED); - - //flags - destination.put(0); - - //time - destination.put(0); - destination.put(0); - destination.put(0); - destination.put(0); - - //xflags - destination.put(0); - - //OS code - from zutil.h - //destination.put(OS_CODE); - //apparently, we should not explicitly include zutil.h - destination.put(0); - -} - -/** - * - */ -GzipOutputStream::~GzipOutputStream() -{ - close(); -} - -/** - * Closes this output stream and releases any system resources - * associated with this stream. - */ -void GzipOutputStream::close() -{ - if (closed) - return; - - flush(); - - //# Send the CRC - uLong outlong = crc; - for (int n = 0; n < 4; n++) - { - destination.put(static_cast(outlong & 0xff)); - outlong >>= 8; - } - //# send the file length - outlong = totalIn & 0xffffffffL; - for (int n = 0; n < 4; n++) - { - destination.put(static_cast(outlong & 0xff)); - outlong >>= 8; - } - - destination.close(); - closed = true; -} - -/** - * Flushes this output stream and forces any buffered output - * bytes to be written out. - */ -void GzipOutputStream::flush() -{ - if (closed || inputBuf.empty()) - { - return; - } - - uLong srclen = inputBuf.size(); - Bytef *srcbuf = new (std::nothrow) Bytef [srclen]; - if (!srcbuf) - { - return; - } - - uLong destlen = srclen; - Bytef *destbuf = new (std::nothrow) Bytef [(destlen + (srclen/100) + 13)]; - if (!destbuf) - { - delete[] srcbuf; - return; - } - - std::vector::iterator iter; - Bytef *p = srcbuf; - for (iter=inputBuf.begin() ; iter != inputBuf.end() ; ++iter) - *p++ = *iter; - - crc = crc32(crc, const_cast(srcbuf), srclen); - - int zerr = compress(destbuf, static_cast(&destlen), srcbuf, srclen); - if (zerr != Z_OK) - { - printf("Some kind of problem\n"); - } - - totalOut += destlen; - //skip the redundant zlib header and checksum - for (uLong i=2; i - * - * Copyright (C) 2004 Inkscape.org - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include -#include "inkscapestream.h" -#include - -namespace Inkscape -{ -namespace IO -{ - -//######################################################################### -//# G Z I P I N P U T S T R E A M -//######################################################################### - -/** - * This class is for deflating a gzip-compressed InputStream source - * - */ -class GzipInputStream : public BasicInputStream -{ - -public: - - GzipInputStream(InputStream &sourceStream); - - ~GzipInputStream() override; - - int available() override; - - void close() override; - - int get() override; - -private: - - bool load(); - int fetchMore(); - - bool loaded; - - long totalIn; - long totalOut; - - unsigned char *outputBuf; - unsigned char *srcBuf; - - unsigned long crc; - unsigned long srcCrc; - unsigned long srcSiz; - unsigned long srcConsumed; - unsigned long srcLen; - long outputBufPos; - long outputBufLen; - - z_stream d_stream; -}; // class GzipInputStream - - - - -//######################################################################### -//# G Z I P O U T P U T S T R E A M -//######################################################################### - -/** - * This class is for gzip-compressing data going to the - * destination OutputStream - * - */ -class GzipOutputStream : public BasicOutputStream -{ - -public: - - GzipOutputStream(OutputStream &destinationStream); - - ~GzipOutputStream() override; - - void close() override; - - void flush() override; - - int put(char ch) override; - -private: - - std::vector inputBuf; - - long totalIn; - long totalOut; - unsigned long crc; - -}; // class GzipOutputStream - - - - - - - -} // namespace IO -} // namespace Inkscape - - -#endif /* __INKSCAPE_IO_GZIPSTREAM_H__ */ diff --git a/src/io/inkscapestream.cpp b/src/io/inkscapestream.cpp deleted file mode 100644 index 56ef7854e..000000000 --- a/src/io/inkscapestream.cpp +++ /dev/null @@ -1,800 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Our base input/output stream classes. These are is directly - * inherited from iostreams, and includes any extra - * functionality that we might need. - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2004 Inkscape.org - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include -#include "inkscapestream.h" - -namespace Inkscape -{ -namespace IO -{ - -//######################################################################### -//# U T I L I T Y -//######################################################################### - -void pipeStream(InputStream &source, OutputStream &dest) -{ - for (;;) - { - int ch = source.get(); - if (ch<0) - break; - dest.put(ch); - } - dest.flush(); -} - -//######################################################################### -//# B A S I C I N P U T S T R E A M -//######################################################################### - - -/** - * - */ -BasicInputStream::BasicInputStream(InputStream &sourceStream) - : source(sourceStream) -{ - closed = false; -} - -/** - * 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 BasicInputStream::available() -{ - if (closed) - return 0; - return source.available(); -} - - -/** - * Closes this input stream and releases any system resources - * associated with the stream. - */ -void BasicInputStream::close() -{ - if (closed) - return; - source.close(); - closed = true; -} - -/** - * Reads the next byte of data from the input stream. -1 if EOF - */ -int BasicInputStream::get() -{ - if (closed) - return -1; - return source.get(); -} - - - -//######################################################################### -//# B A S I C O U T P U T S T R E A M -//######################################################################### - -/** - * - */ -BasicOutputStream::BasicOutputStream(OutputStream &destinationStream) - : destination(destinationStream) -{ - closed = false; -} - -/** - * Closes this output stream and releases any system resources - * associated with this stream. - */ -void BasicOutputStream::close() -{ - if (closed) - return; - destination.close(); - closed = true; -} - -/** - * Flushes this output stream and forces any buffered output - * bytes to be written out. - */ -void BasicOutputStream::flush() -{ - if (closed) - return; - destination.flush(); -} - -/** - * Writes the specified byte to this output stream. - */ -int BasicOutputStream::put(char ch) -{ - if (closed) - return -1; - destination.put(ch); - return 1; -} - - - -//######################################################################### -//# B A S I C R E A D E R -//######################################################################### -/** - * - */ -BasicReader::BasicReader(Reader &sourceReader) -{ - source = &sourceReader; -} - -/** - * Returns the number of bytes that can be read (or skipped over) from - * this reader without blocking by the next caller of a method for - * this reader. - */ -int BasicReader::available() -{ - if (source) - return source->available(); - else - return 0; -} - - -/** - * Closes this reader and releases any system resources - * associated with the reader. - */ -void BasicReader::close() -{ - if (source) - source->close(); -} - -/** - * Reads the next byte of data from the reader. - */ -char BasicReader::get() -{ - if (source) - return source->get(); - else - return (char)-1; -} - - -/** - * Reads a line of data from the reader. - */ -Glib::ustring BasicReader::readLine() -{ - Glib::ustring str; - while (available() > 0) - { - char ch = get(); - if (ch == '\n') - break; - str.push_back(ch); - } - return str; -} - -/** - * Reads a line of data from the reader. - */ -Glib::ustring BasicReader::readWord() -{ - Glib::ustring str; - while (available() > 0) - { - char ch = get(); - if (!std::isprint(ch)) - break; - str.push_back(ch); - } - return str; -} - - -static bool getLong(Glib::ustring &str, long *val) -{ - const char *begin = str.raw().c_str(); - char *end; - long ival = strtol(begin, &end, 10); - if (str == end) - return false; - *val = ival; - return true; -} - -static bool getULong(Glib::ustring &str, unsigned long *val) -{ - const char *begin = str.raw().c_str(); - char *end; - unsigned long ival = strtoul(begin, &end, 10); - if (str == end) - return false; - *val = ival; - return true; -} - -static bool getDouble(Glib::ustring &str, double *val) -{ - const char *begin = str.raw().c_str(); - char *end; - double ival = strtod(begin, &end); - if (str == end) - return false; - *val = ival; - return true; -} - - - -const Reader &BasicReader::readBool (bool& val ) -{ - Glib::ustring buf = readWord(); - if (buf == "true") - val = true; - else - val = false; - return *this; -} - -const Reader &BasicReader::readShort (short& val ) -{ - Glib::ustring buf = readWord(); - long ival; - if (getLong(buf, &ival)) - val = (short) ival; - return *this; -} - -const Reader &BasicReader::readUnsignedShort (unsigned short& val ) -{ - Glib::ustring buf = readWord(); - unsigned long ival; - if (getULong(buf, &ival)) - val = (unsigned short) ival; - return *this; -} - -const Reader &BasicReader::readInt (int& val ) -{ - Glib::ustring buf = readWord(); - long ival; - if (getLong(buf, &ival)) - val = (int) ival; - return *this; -} - -const Reader &BasicReader::readUnsignedInt (unsigned int& val ) -{ - Glib::ustring buf = readWord(); - unsigned long ival; - if (getULong(buf, &ival)) - val = (unsigned int) ival; - return *this; -} - -const Reader &BasicReader::readLong (long& val ) -{ - Glib::ustring buf = readWord(); - long ival; - if (getLong(buf, &ival)) - val = ival; - return *this; -} - -const Reader &BasicReader::readUnsignedLong (unsigned long& val ) -{ - Glib::ustring buf = readWord(); - unsigned long ival; - if (getULong(buf, &ival)) - val = ival; - return *this; -} - -const Reader &BasicReader::readFloat (float& val ) -{ - Glib::ustring buf = readWord(); - double ival; - if (getDouble(buf, &ival)) - val = (float)ival; - return *this; -} - -const Reader &BasicReader::readDouble (double& val ) -{ - Glib::ustring buf = readWord(); - double ival; - if (getDouble(buf, &ival)) - val = ival; - return *this; -} - - - -//######################################################################### -//# I N P U T S T R E A M R E A D E R -//######################################################################### - - -InputStreamReader::InputStreamReader(InputStream &inputStreamSource) - : inputStream(inputStreamSource) -{ -} - - - -/** - * Close the underlying OutputStream - */ -void InputStreamReader::close() -{ - inputStream.close(); -} - -/** - * Flush the underlying OutputStream - */ -int InputStreamReader::available() -{ - return inputStream.available(); -} - -/** - * Overloaded to receive its bytes from an InputStream - * rather than a Reader - */ -char InputStreamReader::get() -{ - char ch = inputStream.get(); - return ch; -} - - - -//######################################################################### -//# S T D R E A D E R -//######################################################################### - - -/** - * - */ -StdReader::StdReader() -{ - inputStream = new StdInputStream(); -} - -/** - * - */ -StdReader::~StdReader() -{ - delete inputStream; -} - - - -/** - * Close the underlying OutputStream - */ -void StdReader::close() -{ - inputStream->close(); -} - -/** - * Flush the underlying OutputStream - */ -int StdReader::available() -{ - return inputStream->available(); -} - -/** - * Overloaded to receive its bytes from an InputStream - * rather than a Reader - */ -char StdReader::get() -{ - char ch = inputStream->get(); - return ch; -} - - - - - -//######################################################################### -//# B A S I C W R I T E R -//######################################################################### - -/** - * - */ -BasicWriter::BasicWriter(Writer &destinationWriter) -{ - destination = &destinationWriter; -} - -/** - * Closes this writer and releases any system resources - * associated with this writer. - */ -void BasicWriter::close() -{ - if (destination) - destination->close(); -} - -/** - * Flushes this output stream and forces any buffered output - * bytes to be written out. - */ -void BasicWriter::flush() -{ - if (destination) - destination->flush(); -} - -/** - * Writes the specified byte to this output writer. - */ -void BasicWriter::put(char ch) -{ - if (destination) - destination->put(ch); -} - -/** - * Provide printf()-like formatting - */ -Writer &BasicWriter::printf(char const *fmt, ...) -{ - va_list args; - va_start(args, fmt); - gchar *buf = g_strdup_vprintf(fmt, args); - va_end(args); - if (buf) { - writeString(buf); - g_free(buf); - } - return *this; -} -/** - * Writes the specified character to this output writer. - */ -Writer &BasicWriter::writeChar(char ch) -{ - put(ch); - return *this; -} - - -/** - * Writes the specified unicode string to this output writer. - */ -Writer &BasicWriter::writeUString(const Glib::ustring &str) -{ - writeStdString(str.raw()); - return *this; -} - -/** - * Writes the specified standard string to this output writer. - */ -Writer &BasicWriter::writeStdString(const std::string &str) -{ - for (auto it = str.begin(); it != str.end(); ++it) { - put(*it); - } - return *this; -} - -/** - * Writes the specified character string to this output writer. - */ -Writer &BasicWriter::writeString(const char *str) -{ - std::string tmp; - if (str) - tmp = str; - else - tmp = "null"; - writeStdString(tmp); - return *this; -} - - - - -/** - * - */ -Writer &BasicWriter::writeBool (bool val ) -{ - if (val) - writeString("true"); - else - writeString("false"); - return *this; -} - - -/** - * - */ -Writer &BasicWriter::writeShort (short val ) -{ - gchar *buf = g_strdup_printf("%d", val); - if (buf) { - writeString(buf); - g_free(buf); - } - return *this; -} - - - -/** - * - */ -Writer &BasicWriter::writeUnsignedShort (unsigned short val ) -{ - gchar *buf = g_strdup_printf("%u", val); - if (buf) { - writeString(buf); - g_free(buf); - } - return *this; -} - -/** - * - */ -Writer &BasicWriter::writeInt (int val) -{ - gchar *buf = g_strdup_printf("%d", val); - if (buf) { - writeString(buf); - g_free(buf); - } - return *this; -} - -/** - * - */ -Writer &BasicWriter::writeUnsignedInt (unsigned int val) -{ - gchar *buf = g_strdup_printf("%u", val); - if (buf) { - writeString(buf); - g_free(buf); - } - return *this; -} - -/** - * - */ -Writer &BasicWriter::writeLong (long val) -{ - gchar *buf = g_strdup_printf("%ld", val); - if (buf) { - writeString(buf); - g_free(buf); - } - return *this; -} - -/** - * - */ -Writer &BasicWriter::writeUnsignedLong(unsigned long val) -{ - gchar *buf = g_strdup_printf("%lu", val); - if (buf) { - writeString(buf); - g_free(buf); - } - return *this; -} - -/** - * - */ -Writer &BasicWriter::writeFloat(float val) -{ -#if 1 - gchar *buf = g_strdup_printf("%8.3f", val); - if (buf) { - writeString(buf); - g_free(buf); - } -#else - std::string tmp = ftos(val, 'g', 8, 3, 0); - writeStdString(tmp); -#endif - return *this; -} - -/** - * - */ -Writer &BasicWriter::writeDouble(double val) -{ -#if 1 - gchar *buf = g_strdup_printf("%8.3f", val); - if (buf) { - writeString(buf); - g_free(buf); - } -#else - std::string tmp = ftos(val, 'g', 8, 3, 0); - writeStdString(tmp); -#endif - return *this; -} - - -Writer& operator<< (Writer &writer, char val) - { return writer.writeChar(val); } - -Writer& operator<< (Writer &writer, Glib::ustring &val) - { return writer.writeUString(val); } - -Writer& operator<< (Writer &writer, std::string &val) - { return writer.writeStdString(val); } - -Writer& operator<< (Writer &writer, char const *val) - { return writer.writeString(val); } - -Writer& operator<< (Writer &writer, bool val) - { return writer.writeBool(val); } - -Writer& operator<< (Writer &writer, short val) - { return writer.writeShort(val); } - -Writer& operator<< (Writer &writer, unsigned short val) - { return writer.writeUnsignedShort(val); } - -Writer& operator<< (Writer &writer, int val) - { return writer.writeInt(val); } - -Writer& operator<< (Writer &writer, unsigned int val) - { return writer.writeUnsignedInt(val); } - -Writer& operator<< (Writer &writer, long val) - { return writer.writeLong(val); } - -Writer& operator<< (Writer &writer, unsigned long val) - { return writer.writeUnsignedLong(val); } - -Writer& operator<< (Writer &writer, float val) - { return writer.writeFloat(val); } - -Writer& operator<< (Writer &writer, double val) - { return writer.writeDouble(val); } - - - -//######################################################################### -//# O U T P U T S T R E A M W R I T E R -//######################################################################### - - -OutputStreamWriter::OutputStreamWriter(OutputStream &outputStreamDest) - : outputStream(outputStreamDest) -{ -} - - - -/** - * Close the underlying OutputStream - */ -void OutputStreamWriter::close() -{ - flush(); - outputStream.close(); -} - -/** - * Flush the underlying OutputStream - */ -void OutputStreamWriter::flush() -{ - outputStream.flush(); -} - -/** - * Overloaded to redirect the output chars from the next Writer - * in the chain to an OutputStream instead. - */ -void OutputStreamWriter::put(char ch) -{ - outputStream.put(ch); -} - -//######################################################################### -//# S T D W R I T E R -//######################################################################### - - -/** - * - */ -StdWriter::StdWriter() -{ - outputStream = new StdOutputStream(); -} - - -/** - * - */ -StdWriter::~StdWriter() -{ - delete outputStream; -} - - - -/** - * Close the underlying OutputStream - */ -void StdWriter::close() -{ - flush(); - outputStream->close(); -} - -/** - * Flush the underlying OutputStream - */ -void StdWriter::flush() -{ - outputStream->flush(); -} - -/** - * Overloaded to redirect the output chars from the next Writer - * in the chain to an OutputStream instead. - */ -void StdWriter::put(char ch) -{ - outputStream->put(ch); -} - - -} // namespace IO -} // namespace Inkscape - - -//######################################################################### -//# E N D O F F I L E -//######################################################################### diff --git a/src/io/inkscapestream.h b/src/io/inkscapestream.h deleted file mode 100644 index 68c28baa1..000000000 --- a/src/io/inkscapestream.h +++ /dev/null @@ -1,668 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#ifndef SEEN_INKSCAPE_IO_INKSCAPESTREAM_H -#define SEEN_INKSCAPE_IO_INKSCAPESTREAM_H -/* - * Authors: - * Bob Jamison - * - * Copyright (C) 2004 Inkscape.org - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include -#include - -namespace Inkscape -{ -namespace IO -{ - -class StreamException : public std::exception -{ -public: - - StreamException(const char *theReason) noexcept - { reason = theReason; } - StreamException(Glib::ustring &theReason) noexcept - { reason = theReason; } - ~StreamException() noexcept override - = default; - char const *what() const noexcept override - { return reason.c_str(); } - -private: - Glib::ustring reason; - -}; - -//######################################################################### -//# I N P U T S T R E A M -//######################################################################### - -/** - * This interface is the base of all input stream classes. Users who wish - * to make an InputStream that is part of a chain should inherit from - * BasicInputStream. Inherit from this class to make a source endpoint, - * such as a URI or buffer. - * - */ -class InputStream -{ - -public: - - /** - * Constructor. - */ - InputStream() = default; - - /** - * Destructor - */ - virtual ~InputStream() = default; - - /** - * Return the number of bytes that are currently available - * to be read - */ - virtual int available() = 0; - - /** - * Do whatever it takes to 'close' this input stream - * The most likely implementation of this method will be - * for endpoints that use a resource for their data. - */ - virtual void close() = 0; - - /** - * Read one byte from this input stream. This is a blocking - * call. If no data is currently available, this call will - * not return until it exists. If the user does not want - * their code to block, then the usual solution is: - * if (available() > 0) - * myChar = get(); - * This call returns -1 on end-of-file. - */ - virtual int get() = 0; - -}; // class InputStream - - - - -/** - * This is the class that most users should inherit, to provide - * their own streams. - * - */ -class BasicInputStream : public InputStream -{ - -public: - - BasicInputStream(InputStream &sourceStream); - - ~BasicInputStream() override = default; - - int available() override; - - void close() override; - - int get() override; - -protected: - - bool closed; - - InputStream &source; - -private: - - -}; // class BasicInputStream - - - -/** - * Convenience class for reading from standard input - */ -class StdInputStream : public InputStream -{ -public: - - int available() override - { return 0; } - - void close() override - { /* do nothing */ } - - int get() override - { return getchar(); } - -}; - - - - - - -//######################################################################### -//# O U T P U T S T R E A M -//######################################################################### - -/** - * This interface is the base of all input stream classes. Users who wish - * to make an OutputStream that is part of a chain should inherit from - * BasicOutputStream. Inherit from this class to make a destination endpoint, - * such as a URI or buffer. - */ -class OutputStream -{ - -public: - - /** - * Constructor. - */ - OutputStream() = default; - - /** - * Destructor - */ - virtual ~OutputStream() = default; - - /** - * This call should - * 1. flush itself - * 2. close itself - * 3. close the destination stream - */ - virtual void close() = 0; - - /** - * This call should push any pending data it might have to - * the destination stream. It should NOT call flush() on - * the destination stream. - */ - virtual void flush() = 0; - - /** - * Send one byte to the destination stream. - */ - virtual int put(char ch) = 0; - - -}; // class OutputStream - - -/** - * This is the class that most users should inherit, to provide - * their own output streams. - */ -class BasicOutputStream : public OutputStream -{ - -public: - - BasicOutputStream(OutputStream &destinationStream); - - ~BasicOutputStream() override = default; - - void close() override; - - void flush() override; - - int put(char ch) override; - -protected: - - bool closed; - - OutputStream &destination; - - -}; // class BasicOutputStream - - - -/** - * Convenience class for writing to standard output - */ -class StdOutputStream : public OutputStream -{ -public: - - void close() override - { } - - void flush() override - { } - - int put(char ch) override - {return putchar(ch); } - -}; - - - - -//######################################################################### -//# R E A D E R -//######################################################################### - - -/** - * This interface and its descendants are for unicode character-oriented input - * - */ -class Reader -{ - -public: - - /** - * Constructor. - */ - Reader() = default; - - /** - * Destructor - */ - virtual ~Reader() = default; - - - virtual int available() = 0; - - virtual void close() = 0; - - virtual char get() = 0; - - virtual Glib::ustring readLine() = 0; - - virtual Glib::ustring readWord() = 0; - - /* Input formatting */ - virtual const Reader& readBool (bool& val ) = 0; - virtual const Reader& operator>> (bool& val ) = 0; - - virtual const Reader& readShort (short &val) = 0; - virtual const Reader& operator>> (short &val) = 0; - - virtual const Reader& readUnsignedShort (unsigned short &val) = 0; - virtual const Reader& operator>> (unsigned short &val) = 0; - - virtual const Reader& readInt (int &val) = 0; - virtual const Reader& operator>> (int &val) = 0; - - virtual const Reader& readUnsignedInt (unsigned int &val) = 0; - virtual const Reader& operator>> (unsigned int &val) = 0; - - virtual const Reader& readLong (long &val) = 0; - virtual const Reader& operator>> (long &val) = 0; - - virtual const Reader& readUnsignedLong (unsigned long &val) = 0; - virtual const Reader& operator>> (unsigned long &val) = 0; - - virtual const Reader& readFloat (float &val) = 0; - virtual const Reader& operator>> (float &val) = 0; - - virtual const Reader& readDouble (double &val) = 0; - virtual const Reader& operator>> (double &val) = 0; - -}; // interface Reader - - - -/** - * This class and its descendants are for unicode character-oriented input - * - */ -class BasicReader : public Reader -{ - -public: - - BasicReader(Reader &sourceStream); - - ~BasicReader() override = default; - - int available() override; - - void close() override; - - char get() override; - - Glib::ustring readLine() override; - - Glib::ustring readWord() override; - - /* Input formatting */ - const Reader& readBool (bool& val ) override; - const Reader& operator>> (bool& val ) override - { return readBool(val); } - - const Reader& readShort (short &val) override; - const Reader& operator>> (short &val) override - { return readShort(val); } - - const Reader& readUnsignedShort (unsigned short &val) override; - const Reader& operator>> (unsigned short &val) override - { return readUnsignedShort(val); } - - const Reader& readInt (int &val) override; - const Reader& operator>> (int &val) override - { return readInt(val); } - - const Reader& readUnsignedInt (unsigned int &val) override; - const Reader& operator>> (unsigned int &val) override - { return readUnsignedInt(val); } - - const Reader& readLong (long &val) override; - const Reader& operator>> (long &val) override - { return readLong(val); } - - const Reader& readUnsignedLong (unsigned long &val) override; - const Reader& operator>> (unsigned long &val) override - { return readUnsignedLong(val); } - - const Reader& readFloat (float &val) override; - const Reader& operator>> (float &val) override - { return readFloat(val); } - - const Reader& readDouble (double &val) override; - const Reader& operator>> (double &val) override - { return readDouble(val); } - - -protected: - - Reader *source; - - BasicReader() - { source = nullptr; } - -private: - -}; // class BasicReader - - - -/** - * Class for placing a Reader on an open InputStream - * - */ -class InputStreamReader : public BasicReader -{ -public: - - InputStreamReader(InputStream &inputStreamSource); - - /*Overload these 3 for your implementation*/ - int available() override; - - void close() override; - - char get() override; - - -private: - - InputStream &inputStream; - - -}; - -/** - * Convenience class for reading formatted from standard input - * - */ -class StdReader : public BasicReader -{ -public: - - StdReader(); - - ~StdReader() override; - - /*Overload these 3 for your implementation*/ - int available() override; - - void close() override; - - char get() override; - - -private: - - InputStream *inputStream; - - -}; - - - - - -//######################################################################### -//# W R I T E R -//######################################################################### - -/** - * This interface and its descendants are for unicode character-oriented output - * - */ -class Writer -{ - -public: - - /** - * Constructor. - */ - Writer() = default; - - /** - * Destructor - */ - virtual ~Writer() = default; - - virtual void close() = 0; - - virtual void flush() = 0; - - virtual void put(char ch) = 0; - - /* Formatted output */ - virtual Writer& printf(char const *fmt, ...) G_GNUC_PRINTF(2,3) = 0; - - virtual Writer& writeChar(char val) = 0; - - virtual Writer& writeUString(const Glib::ustring &val) = 0; - - virtual Writer& writeStdString(const std::string &val) = 0; - - virtual Writer& writeString(const char *str) = 0; - - virtual Writer& writeBool (bool val ) = 0; - - virtual Writer& writeShort (short val ) = 0; - - virtual Writer& writeUnsignedShort (unsigned short val ) = 0; - - virtual Writer& writeInt (int val ) = 0; - - virtual Writer& writeUnsignedInt (unsigned int val ) = 0; - - virtual Writer& writeLong (long val ) = 0; - - virtual Writer& writeUnsignedLong (unsigned long val ) = 0; - - virtual Writer& writeFloat (float val ) = 0; - - virtual Writer& writeDouble (double val ) = 0; - - - -}; // interface Writer - - -/** - * This class and its descendants are for unicode character-oriented output - * - */ -class BasicWriter : public Writer -{ - -public: - - BasicWriter(Writer &destinationWriter); - - ~BasicWriter() override = default; - - /*Overload these 3 for your implementation*/ - void close() override; - - void flush() override; - - void put(char ch) override; - - - - /* Formatted output */ - Writer &printf(char const *fmt, ...) override G_GNUC_PRINTF(2,3); - - Writer& writeChar(char val) override; - - Writer& writeUString(const Glib::ustring &val) override; - - Writer& writeStdString(const std::string &val) override; - - Writer& writeString(const char *str) override; - - Writer& writeBool (bool val ) override; - - Writer& writeShort (short val ) override; - - Writer& writeUnsignedShort (unsigned short val ) override; - - Writer& writeInt (int val ) override; - - Writer& writeUnsignedInt (unsigned int val ) override; - - Writer& writeLong (long val ) override; - - Writer& writeUnsignedLong (unsigned long val ) override; - - Writer& writeFloat (float val ) override; - - Writer& writeDouble (double val ) override; - - -protected: - - Writer *destination; - - BasicWriter() - { destination = nullptr; } - -private: - -}; // class BasicWriter - - - -Writer& operator<< (Writer &writer, char val); - -Writer& operator<< (Writer &writer, Glib::ustring &val); - -Writer& operator<< (Writer &writer, std::string &val); - -Writer& operator<< (Writer &writer, char const *val); - -Writer& operator<< (Writer &writer, bool val); - -Writer& operator<< (Writer &writer, short val); - -Writer& operator<< (Writer &writer, unsigned short val); - -Writer& operator<< (Writer &writer, int val); - -Writer& operator<< (Writer &writer, unsigned int val); - -Writer& operator<< (Writer &writer, long val); - -Writer& operator<< (Writer &writer, unsigned long val); - -Writer& operator<< (Writer &writer, float val); - -Writer& operator<< (Writer &writer, double val); - - - - -/** - * Class for placing a Writer on an open OutputStream - * - */ -class OutputStreamWriter : public BasicWriter -{ -public: - - OutputStreamWriter(OutputStream &outputStreamDest); - - /*Overload these 3 for your implementation*/ - void close() override; - - void flush() override; - - void put(char ch) override; - - -private: - - OutputStream &outputStream; - - -}; - - -/** - * Convenience class for writing to standard output - */ -class StdWriter : public BasicWriter -{ -public: - StdWriter(); - - ~StdWriter() override; - - - void close() override; - - - void flush() override; - - - void put(char ch) override; - - -private: - - OutputStream *outputStream; - -}; - -//######################################################################### -//# U T I L I T Y -//######################################################################### - -void pipeStream(InputStream &source, OutputStream &dest); - - - -} // namespace IO -} // namespace Inkscape - - -#endif // SEEN_INKSCAPE_IO_INKSCAPESTREAM_H diff --git a/src/io/stream/Makefile.tst b/src/io/stream/Makefile.tst new file mode 100644 index 000000000..2e3142d42 --- /dev/null +++ b/src/io/stream/Makefile.tst @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +############################################## +# +# Test makefile for InkscapeStreams +# +############################################## + + +CC = gcc +CXX = g++ + + +INC = -I. -I.. + +XSLT_CFLAGS = `pkg-config --cflags libxslt` +XSLT_LIBS = `pkg-config --libs libxslt` + +GLIBMM_CFLAGS = `pkg-config --cflags glibmm-2.4` +GLIBMM_LIBS = `pkg-config --libs glibmm-2.4` + +CFLAGS = -g $(GLIBMM_CFLAGS) $(XSLT_CFLAGS) +LIBS = $(GLIBMM_LIBS) $(XSLT_LIBS) ../uri.o -lz + +OBJ = \ +inkscapestream.o \ +base64stream.o \ +gzipstream.o \ +stringstream.o \ +uristream.o \ +xsltstream.o \ +ftos.o + +all: streamtest + +streamtest: inkscapestream.h libstream.a streamtest.o + $(CXX) -o streamtest streamtest.o libstream.a $(LIBS) + +libstream.a: $(OBJ) + ar crv libstream.a $(OBJ) + + +.cpp.o: + $(CXX) $(CFLAGS) $(INC) -c -o $@ $< + +clean: + -$(RM) *.o *.a + -$(RM) streamtest + diff --git a/src/io/stream/README b/src/io/stream/README new file mode 100644 index 000000000..67d8721fa --- /dev/null +++ b/src/io/stream/README @@ -0,0 +1,13 @@ + +This directory contains code related to streams. + +Base class: + inkscapestream.h Used by other stream handling code and odf, filter-file + +Derived classes: + bufferstream.h Used by odf + gzipstream.h Used by repr-io.cpp + stringstream.h Used by rerp-io.cpp and ui/clipboard.cpp + Note file with same name in src/svg + uristream.h Used by repr-io.cpp + xsltstream.h Used by none one (except testfile) diff --git a/src/io/stream/bufferstream.cpp b/src/io/stream/bufferstream.cpp new file mode 100644 index 000000000..1723ee1ff --- /dev/null +++ b/src/io/stream/bufferstream.cpp @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * @file + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + *//* + * Authors: + * see git history + * Bob Jamison + * + * Copyright (C) 2018 Authors + * Released under GNU LGPL v2.1+, read the file 'COPYING' for more information. + */ + +/** + * This class provided buffered endpoints for input and output. + */ + +#include "bufferstream.h" + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# B U F F E R I N P U T S T R E A M +//######################################################################### +/** + * + */ +BufferInputStream::BufferInputStream( + const std::vector &sourceBuffer) + : buffer(sourceBuffer) +{ + position = 0; + closed = false; +} + +/** + * + */ +BufferInputStream::~BufferInputStream() += default; + +/** + * 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 BufferInputStream::available() +{ + if (closed) + return -1; + return buffer.size() - position; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void BufferInputStream::close() +{ + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int BufferInputStream::get() +{ + if (closed) + return -1; + if (position >= (int)buffer.size()) + return -1; + int ch = (int) buffer[position++]; + return ch; +} + + + + +//######################################################################### +//# B U F F E R O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +BufferOutputStream::BufferOutputStream() +{ + closed = false; +} + +/** + * + */ +BufferOutputStream::~BufferOutputStream() += default; + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void BufferOutputStream::close() +{ + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void BufferOutputStream::flush() +{ + //nothing to do +} + +/** + * Writes the specified byte to this output stream. + */ +int BufferOutputStream::put(char ch) +{ + if (closed) + return -1; + buffer.push_back(ch); + return 1; +} + + + + +} //namespace IO +} //namespace Inkscape + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/io/stream/bufferstream.h b/src/io/stream/bufferstream.h new file mode 100644 index 000000000..811ab0d57 --- /dev/null +++ b/src/io/stream/bufferstream.h @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * @file + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + *//* + * Authors: + * see git history + * Bob Jamison + * + * Copyright (C) 2018 Authors + * Released under GNU LGPL v2.1+, read the file 'COPYING' for more information. + */ +#ifndef SEEN_BUFFERSTREAM_H +#define SEEN_BUFFERSTREAM_H + + +#include +#include "inkscapestream.h" + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# S T R I N G I N P U T S T R E A M +//######################################################################### + +/** + * This class is for reading character from a DOMString + * + */ +class BufferInputStream : public InputStream +{ + +public: + + BufferInputStream(const std::vector &sourceBuffer); + ~BufferInputStream() override; + int available() override; + void close() override; + int get() override; + +private: + const std::vector &buffer; + long position; + bool closed; + +}; // class BufferInputStream + + + + +//######################################################################### +//# B U F F E R O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for sending a stream to a character buffer + * + */ +class BufferOutputStream : public OutputStream +{ + +public: + + BufferOutputStream(); + ~BufferOutputStream() override; + void close() override; + void flush() override; + int put(char ch) override; + virtual std::vector &getBuffer() + { return buffer; } + + virtual void clear() + { buffer.clear(); } + +private: + std::vector buffer; + bool closed; + +}; // class BufferOutputStream + + + +} //namespace IO +} //namespace Inkscape + + + +#endif // SEEN_BUFFERSTREAM_H diff --git a/src/io/stream/gzipstream.cpp b/src/io/stream/gzipstream.cpp new file mode 100644 index 000000000..03960b004 --- /dev/null +++ b/src/io/stream/gzipstream.cpp @@ -0,0 +1,459 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** @file + * Zlib-enabled input and output streams + *//* + * Authors: + * see git history + * Bob Jamison + * + * + * Copyright (C) 2018 Authors + * Released under GNU LGPL v2.1+, read the file 'COPYING' for more information. + */ +/* + * This is a thin wrapper of libz calls, in order + * to provide a simple interface to our developers + * for gzip input and output. + */ + +#include "gzipstream.h" +#include +#include +#include +#include + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# G Z I P I N P U T S T R E A M +//######################################################################### + +#define OUT_SIZE 4000 + +/** + * + */ +GzipInputStream::GzipInputStream(InputStream &sourceStream) + : BasicInputStream(sourceStream), + loaded(false), + totalIn(0), + totalOut(0), + outputBuf(nullptr), + srcBuf(nullptr), + crc(0), + srcCrc(0), + srcSiz(0), + srcConsumed(0), + srcLen(0), + outputBufPos(0), + outputBufLen(0) +{ + memset( &d_stream, 0, sizeof(d_stream) ); +} + +/** + * + */ +GzipInputStream::~GzipInputStream() +{ + close(); + if ( srcBuf ) { + delete[] srcBuf; + srcBuf = nullptr; + } + if ( outputBuf ) { + delete[] outputBuf; + outputBuf = nullptr; + } +} + +/** + * 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 GzipInputStream::available() +{ + if (closed || !outputBuf) + return 0; + return outputBufLen - outputBufPos; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void GzipInputStream::close() +{ + if (closed) + return; + + int zerr = inflateEnd(&d_stream); + if (zerr != Z_OK) { + printf("inflateEnd: Some kind of problem: %d\n", zerr); + } + + if ( srcBuf ) { + delete[] srcBuf; + srcBuf = nullptr; + } + if ( outputBuf ) { + delete[] outputBuf; + outputBuf = nullptr; + } + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int GzipInputStream::get() +{ + int ch = -1; + if (closed) { + // leave return value -1 + } + else if (!loaded && !load()) { + closed=true; + } else { + loaded = true; + + if ( outputBufPos >= outputBufLen ) { + // time to read more, if we can + fetchMore(); + } + + if ( outputBufPos < outputBufLen ) { + ch = (int)outputBuf[outputBufPos++]; + } + } + + return ch; +} + +#define FTEXT 0x01 +#define FHCRC 0x02 +#define FEXTRA 0x04 +#define FNAME 0x08 +#define FCOMMENT 0x10 + +bool GzipInputStream::load() +{ + crc = crc32(0L, Z_NULL, 0); + + std::vector inputBuf; + while (true) + { + int ch = source.get(); + if (ch<0) + break; + inputBuf.push_back(static_cast(ch & 0xff)); + } + long inputBufLen = inputBuf.size(); + + if (inputBufLen < 19) //header + tail + 1 + { + return false; + } + + srcLen = inputBuf.size(); + srcBuf = new (std::nothrow) Byte [srcLen]; + if (!srcBuf) { + return false; + } + + outputBuf = new (std::nothrow) unsigned char [OUT_SIZE]; + if ( !outputBuf ) { + delete[] srcBuf; + srcBuf = nullptr; + return false; + } + outputBufLen = 0; // Not filled in yet + + std::vector::iterator iter; + Bytef *p = srcBuf; + for (iter=inputBuf.begin() ; iter != inputBuf.end() ; ++iter) + { + *p++ = *iter; + } + + int headerLen = 10; + + //Magic + //int val = (int)srcBuf[0]; + ////printf("val:%x\n", val); + //val = (int)srcBuf[1]; + ////printf("val:%x\n", val); + + ////Method + //val = (int)srcBuf[2]; + ////printf("val:%x\n", val); + + //flags + int flags = static_cast(srcBuf[3]); + + ////time + //val = (int)srcBuf[4]; + //val = (int)srcBuf[5]; + //val = (int)srcBuf[6]; + //val = (int)srcBuf[7]; + + ////xflags + //val = (int)srcBuf[8]; + ////OS + //val = (int)srcBuf[9]; + +// if ( flags & FEXTRA ) { +// headerLen += 2; +// int xlen = +// TODO deal with optional header parts +// } + if ( flags & FNAME ) { + int cur = 10; + while ( srcBuf[cur] ) + { + cur++; + headerLen++; + } + headerLen++; + } + + + srcCrc = ((0x0ff & srcBuf[srcLen - 5]) << 24) + | ((0x0ff & srcBuf[srcLen - 6]) << 16) + | ((0x0ff & srcBuf[srcLen - 7]) << 8) + | ((0x0ff & srcBuf[srcLen - 8]) << 0); + //printf("srcCrc:%lx\n", srcCrc); + + srcSiz = ((0x0ff & srcBuf[srcLen - 1]) << 24) + | ((0x0ff & srcBuf[srcLen - 2]) << 16) + | ((0x0ff & srcBuf[srcLen - 3]) << 8) + | ((0x0ff & srcBuf[srcLen - 4]) << 0); + //printf("srcSiz:%lx/%ld\n", srcSiz, srcSiz); + + //outputBufLen = srcSiz + srcSiz/100 + 14; + + unsigned char *data = srcBuf + headerLen; + unsigned long dataLen = srcLen - (headerLen + 8); + //printf("%x %x\n", data[0], data[dataLen-1]); + + d_stream.zalloc = (alloc_func)nullptr; + d_stream.zfree = (free_func)nullptr; + d_stream.opaque = (voidpf)nullptr; + d_stream.next_in = data; + d_stream.avail_in = dataLen; + d_stream.next_out = outputBuf; + d_stream.avail_out = OUT_SIZE; + + int zerr = inflateInit2(&d_stream, -MAX_WBITS); + if ( zerr == Z_OK ) + { + zerr = fetchMore(); + } else { + printf("inflateInit2: Some kind of problem: %d\n", zerr); + } + + + return (zerr == Z_OK) || (zerr == Z_STREAM_END); +} + + +int GzipInputStream::fetchMore() +{ + // TODO assumes we aren't called till the buffer is empty + d_stream.next_out = outputBuf; + d_stream.avail_out = OUT_SIZE; + outputBufLen = 0; + outputBufPos = 0; + + int zerr = inflate( &d_stream, Z_SYNC_FLUSH ); + if ( zerr == Z_OK || zerr == Z_STREAM_END ) { + outputBufLen = OUT_SIZE - d_stream.avail_out; + if ( outputBufLen ) { + crc = crc32(crc, const_cast(outputBuf), outputBufLen); + } + //printf("crc:%lx\n", crc); +// } else if ( zerr != Z_STREAM_END ) { +// // TODO check to be sure this won't happen for partial end reads +// printf("inflate: Some kind of problem: %d\n", zerr); + } + + return zerr; +} + +//######################################################################### +//# G Z I P O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +GzipOutputStream::GzipOutputStream(OutputStream &destinationStream) + : BasicOutputStream(destinationStream) +{ + + totalIn = 0; + totalOut = 0; + crc = crc32(0L, Z_NULL, 0); + + //Gzip header + destination.put(0x1f); + destination.put(0x8b); + + //Say it is compressed + destination.put(Z_DEFLATED); + + //flags + destination.put(0); + + //time + destination.put(0); + destination.put(0); + destination.put(0); + destination.put(0); + + //xflags + destination.put(0); + + //OS code - from zutil.h + //destination.put(OS_CODE); + //apparently, we should not explicitly include zutil.h + destination.put(0); + +} + +/** + * + */ +GzipOutputStream::~GzipOutputStream() +{ + close(); +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void GzipOutputStream::close() +{ + if (closed) + return; + + flush(); + + //# Send the CRC + uLong outlong = crc; + for (int n = 0; n < 4; n++) + { + destination.put(static_cast(outlong & 0xff)); + outlong >>= 8; + } + //# send the file length + outlong = totalIn & 0xffffffffL; + for (int n = 0; n < 4; n++) + { + destination.put(static_cast(outlong & 0xff)); + outlong >>= 8; + } + + destination.close(); + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void GzipOutputStream::flush() +{ + if (closed || inputBuf.empty()) + { + return; + } + + uLong srclen = inputBuf.size(); + Bytef *srcbuf = new (std::nothrow) Bytef [srclen]; + if (!srcbuf) + { + return; + } + + uLong destlen = srclen; + Bytef *destbuf = new (std::nothrow) Bytef [(destlen + (srclen/100) + 13)]; + if (!destbuf) + { + delete[] srcbuf; + return; + } + + std::vector::iterator iter; + Bytef *p = srcbuf; + for (iter=inputBuf.begin() ; iter != inputBuf.end() ; ++iter) + *p++ = *iter; + + crc = crc32(crc, const_cast(srcbuf), srclen); + + int zerr = compress(destbuf, static_cast(&destlen), srcbuf, srclen); + if (zerr != Z_OK) + { + printf("Some kind of problem\n"); + } + + totalOut += destlen; + //skip the redundant zlib header and checksum + for (uLong i=2; i + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include +#include "inkscapestream.h" +#include + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# G Z I P I N P U T S T R E A M +//######################################################################### + +/** + * This class is for deflating a gzip-compressed InputStream source + * + */ +class GzipInputStream : public BasicInputStream +{ + +public: + + GzipInputStream(InputStream &sourceStream); + + ~GzipInputStream() override; + + int available() override; + + void close() override; + + int get() override; + +private: + + bool load(); + int fetchMore(); + + bool loaded; + + long totalIn; + long totalOut; + + unsigned char *outputBuf; + unsigned char *srcBuf; + + unsigned long crc; + unsigned long srcCrc; + unsigned long srcSiz; + unsigned long srcConsumed; + unsigned long srcLen; + long outputBufPos; + long outputBufLen; + + z_stream d_stream; +}; // class GzipInputStream + + + + +//######################################################################### +//# G Z I P O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for gzip-compressing data going to the + * destination OutputStream + * + */ +class GzipOutputStream : public BasicOutputStream +{ + +public: + + GzipOutputStream(OutputStream &destinationStream); + + ~GzipOutputStream() override; + + void close() override; + + void flush() override; + + int put(char ch) override; + +private: + + std::vector inputBuf; + + long totalIn; + long totalOut; + unsigned long crc; + +}; // class GzipOutputStream + + + + + + + +} // namespace IO +} // namespace Inkscape + + +#endif /* __INKSCAPE_IO_GZIPSTREAM_H__ */ diff --git a/src/io/stream/inkscapestream.cpp b/src/io/stream/inkscapestream.cpp new file mode 100644 index 000000000..56ef7854e --- /dev/null +++ b/src/io/stream/inkscapestream.cpp @@ -0,0 +1,800 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Our base input/output stream classes. These are is directly + * inherited from iostreams, and includes any extra + * functionality that we might need. + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include +#include "inkscapestream.h" + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# U T I L I T Y +//######################################################################### + +void pipeStream(InputStream &source, OutputStream &dest) +{ + for (;;) + { + int ch = source.get(); + if (ch<0) + break; + dest.put(ch); + } + dest.flush(); +} + +//######################################################################### +//# B A S I C I N P U T S T R E A M +//######################################################################### + + +/** + * + */ +BasicInputStream::BasicInputStream(InputStream &sourceStream) + : source(sourceStream) +{ + closed = false; +} + +/** + * 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 BasicInputStream::available() +{ + if (closed) + return 0; + return source.available(); +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void BasicInputStream::close() +{ + if (closed) + return; + source.close(); + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int BasicInputStream::get() +{ + if (closed) + return -1; + return source.get(); +} + + + +//######################################################################### +//# B A S I C O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +BasicOutputStream::BasicOutputStream(OutputStream &destinationStream) + : destination(destinationStream) +{ + closed = false; +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void BasicOutputStream::close() +{ + if (closed) + return; + destination.close(); + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void BasicOutputStream::flush() +{ + if (closed) + return; + destination.flush(); +} + +/** + * Writes the specified byte to this output stream. + */ +int BasicOutputStream::put(char ch) +{ + if (closed) + return -1; + destination.put(ch); + return 1; +} + + + +//######################################################################### +//# B A S I C R E A D E R +//######################################################################### +/** + * + */ +BasicReader::BasicReader(Reader &sourceReader) +{ + source = &sourceReader; +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this reader without blocking by the next caller of a method for + * this reader. + */ +int BasicReader::available() +{ + if (source) + return source->available(); + else + return 0; +} + + +/** + * Closes this reader and releases any system resources + * associated with the reader. + */ +void BasicReader::close() +{ + if (source) + source->close(); +} + +/** + * Reads the next byte of data from the reader. + */ +char BasicReader::get() +{ + if (source) + return source->get(); + else + return (char)-1; +} + + +/** + * Reads a line of data from the reader. + */ +Glib::ustring BasicReader::readLine() +{ + Glib::ustring str; + while (available() > 0) + { + char ch = get(); + if (ch == '\n') + break; + str.push_back(ch); + } + return str; +} + +/** + * Reads a line of data from the reader. + */ +Glib::ustring BasicReader::readWord() +{ + Glib::ustring str; + while (available() > 0) + { + char ch = get(); + if (!std::isprint(ch)) + break; + str.push_back(ch); + } + return str; +} + + +static bool getLong(Glib::ustring &str, long *val) +{ + const char *begin = str.raw().c_str(); + char *end; + long ival = strtol(begin, &end, 10); + if (str == end) + return false; + *val = ival; + return true; +} + +static bool getULong(Glib::ustring &str, unsigned long *val) +{ + const char *begin = str.raw().c_str(); + char *end; + unsigned long ival = strtoul(begin, &end, 10); + if (str == end) + return false; + *val = ival; + return true; +} + +static bool getDouble(Glib::ustring &str, double *val) +{ + const char *begin = str.raw().c_str(); + char *end; + double ival = strtod(begin, &end); + if (str == end) + return false; + *val = ival; + return true; +} + + + +const Reader &BasicReader::readBool (bool& val ) +{ + Glib::ustring buf = readWord(); + if (buf == "true") + val = true; + else + val = false; + return *this; +} + +const Reader &BasicReader::readShort (short& val ) +{ + Glib::ustring buf = readWord(); + long ival; + if (getLong(buf, &ival)) + val = (short) ival; + return *this; +} + +const Reader &BasicReader::readUnsignedShort (unsigned short& val ) +{ + Glib::ustring buf = readWord(); + unsigned long ival; + if (getULong(buf, &ival)) + val = (unsigned short) ival; + return *this; +} + +const Reader &BasicReader::readInt (int& val ) +{ + Glib::ustring buf = readWord(); + long ival; + if (getLong(buf, &ival)) + val = (int) ival; + return *this; +} + +const Reader &BasicReader::readUnsignedInt (unsigned int& val ) +{ + Glib::ustring buf = readWord(); + unsigned long ival; + if (getULong(buf, &ival)) + val = (unsigned int) ival; + return *this; +} + +const Reader &BasicReader::readLong (long& val ) +{ + Glib::ustring buf = readWord(); + long ival; + if (getLong(buf, &ival)) + val = ival; + return *this; +} + +const Reader &BasicReader::readUnsignedLong (unsigned long& val ) +{ + Glib::ustring buf = readWord(); + unsigned long ival; + if (getULong(buf, &ival)) + val = ival; + return *this; +} + +const Reader &BasicReader::readFloat (float& val ) +{ + Glib::ustring buf = readWord(); + double ival; + if (getDouble(buf, &ival)) + val = (float)ival; + return *this; +} + +const Reader &BasicReader::readDouble (double& val ) +{ + Glib::ustring buf = readWord(); + double ival; + if (getDouble(buf, &ival)) + val = ival; + return *this; +} + + + +//######################################################################### +//# I N P U T S T R E A M R E A D E R +//######################################################################### + + +InputStreamReader::InputStreamReader(InputStream &inputStreamSource) + : inputStream(inputStreamSource) +{ +} + + + +/** + * Close the underlying OutputStream + */ +void InputStreamReader::close() +{ + inputStream.close(); +} + +/** + * Flush the underlying OutputStream + */ +int InputStreamReader::available() +{ + return inputStream.available(); +} + +/** + * Overloaded to receive its bytes from an InputStream + * rather than a Reader + */ +char InputStreamReader::get() +{ + char ch = inputStream.get(); + return ch; +} + + + +//######################################################################### +//# S T D R E A D E R +//######################################################################### + + +/** + * + */ +StdReader::StdReader() +{ + inputStream = new StdInputStream(); +} + +/** + * + */ +StdReader::~StdReader() +{ + delete inputStream; +} + + + +/** + * Close the underlying OutputStream + */ +void StdReader::close() +{ + inputStream->close(); +} + +/** + * Flush the underlying OutputStream + */ +int StdReader::available() +{ + return inputStream->available(); +} + +/** + * Overloaded to receive its bytes from an InputStream + * rather than a Reader + */ +char StdReader::get() +{ + char ch = inputStream->get(); + return ch; +} + + + + + +//######################################################################### +//# B A S I C W R I T E R +//######################################################################### + +/** + * + */ +BasicWriter::BasicWriter(Writer &destinationWriter) +{ + destination = &destinationWriter; +} + +/** + * Closes this writer and releases any system resources + * associated with this writer. + */ +void BasicWriter::close() +{ + if (destination) + destination->close(); +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void BasicWriter::flush() +{ + if (destination) + destination->flush(); +} + +/** + * Writes the specified byte to this output writer. + */ +void BasicWriter::put(char ch) +{ + if (destination) + destination->put(ch); +} + +/** + * Provide printf()-like formatting + */ +Writer &BasicWriter::printf(char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + gchar *buf = g_strdup_vprintf(fmt, args); + va_end(args); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} +/** + * Writes the specified character to this output writer. + */ +Writer &BasicWriter::writeChar(char ch) +{ + put(ch); + return *this; +} + + +/** + * Writes the specified unicode string to this output writer. + */ +Writer &BasicWriter::writeUString(const Glib::ustring &str) +{ + writeStdString(str.raw()); + return *this; +} + +/** + * Writes the specified standard string to this output writer. + */ +Writer &BasicWriter::writeStdString(const std::string &str) +{ + for (auto it = str.begin(); it != str.end(); ++it) { + put(*it); + } + return *this; +} + +/** + * Writes the specified character string to this output writer. + */ +Writer &BasicWriter::writeString(const char *str) +{ + std::string tmp; + if (str) + tmp = str; + else + tmp = "null"; + writeStdString(tmp); + return *this; +} + + + + +/** + * + */ +Writer &BasicWriter::writeBool (bool val ) +{ + if (val) + writeString("true"); + else + writeString("false"); + return *this; +} + + +/** + * + */ +Writer &BasicWriter::writeShort (short val ) +{ + gchar *buf = g_strdup_printf("%d", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + + + +/** + * + */ +Writer &BasicWriter::writeUnsignedShort (unsigned short val ) +{ + gchar *buf = g_strdup_printf("%u", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeInt (int val) +{ + gchar *buf = g_strdup_printf("%d", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeUnsignedInt (unsigned int val) +{ + gchar *buf = g_strdup_printf("%u", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeLong (long val) +{ + gchar *buf = g_strdup_printf("%ld", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeUnsignedLong(unsigned long val) +{ + gchar *buf = g_strdup_printf("%lu", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeFloat(float val) +{ +#if 1 + gchar *buf = g_strdup_printf("%8.3f", val); + if (buf) { + writeString(buf); + g_free(buf); + } +#else + std::string tmp = ftos(val, 'g', 8, 3, 0); + writeStdString(tmp); +#endif + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeDouble(double val) +{ +#if 1 + gchar *buf = g_strdup_printf("%8.3f", val); + if (buf) { + writeString(buf); + g_free(buf); + } +#else + std::string tmp = ftos(val, 'g', 8, 3, 0); + writeStdString(tmp); +#endif + return *this; +} + + +Writer& operator<< (Writer &writer, char val) + { return writer.writeChar(val); } + +Writer& operator<< (Writer &writer, Glib::ustring &val) + { return writer.writeUString(val); } + +Writer& operator<< (Writer &writer, std::string &val) + { return writer.writeStdString(val); } + +Writer& operator<< (Writer &writer, char const *val) + { return writer.writeString(val); } + +Writer& operator<< (Writer &writer, bool val) + { return writer.writeBool(val); } + +Writer& operator<< (Writer &writer, short val) + { return writer.writeShort(val); } + +Writer& operator<< (Writer &writer, unsigned short val) + { return writer.writeUnsignedShort(val); } + +Writer& operator<< (Writer &writer, int val) + { return writer.writeInt(val); } + +Writer& operator<< (Writer &writer, unsigned int val) + { return writer.writeUnsignedInt(val); } + +Writer& operator<< (Writer &writer, long val) + { return writer.writeLong(val); } + +Writer& operator<< (Writer &writer, unsigned long val) + { return writer.writeUnsignedLong(val); } + +Writer& operator<< (Writer &writer, float val) + { return writer.writeFloat(val); } + +Writer& operator<< (Writer &writer, double val) + { return writer.writeDouble(val); } + + + +//######################################################################### +//# O U T P U T S T R E A M W R I T E R +//######################################################################### + + +OutputStreamWriter::OutputStreamWriter(OutputStream &outputStreamDest) + : outputStream(outputStreamDest) +{ +} + + + +/** + * Close the underlying OutputStream + */ +void OutputStreamWriter::close() +{ + flush(); + outputStream.close(); +} + +/** + * Flush the underlying OutputStream + */ +void OutputStreamWriter::flush() +{ + outputStream.flush(); +} + +/** + * Overloaded to redirect the output chars from the next Writer + * in the chain to an OutputStream instead. + */ +void OutputStreamWriter::put(char ch) +{ + outputStream.put(ch); +} + +//######################################################################### +//# S T D W R I T E R +//######################################################################### + + +/** + * + */ +StdWriter::StdWriter() +{ + outputStream = new StdOutputStream(); +} + + +/** + * + */ +StdWriter::~StdWriter() +{ + delete outputStream; +} + + + +/** + * Close the underlying OutputStream + */ +void StdWriter::close() +{ + flush(); + outputStream->close(); +} + +/** + * Flush the underlying OutputStream + */ +void StdWriter::flush() +{ + outputStream->flush(); +} + +/** + * Overloaded to redirect the output chars from the next Writer + * in the chain to an OutputStream instead. + */ +void StdWriter::put(char ch) +{ + outputStream->put(ch); +} + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/io/stream/inkscapestream.h b/src/io/stream/inkscapestream.h new file mode 100644 index 000000000..68c28baa1 --- /dev/null +++ b/src/io/stream/inkscapestream.h @@ -0,0 +1,668 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef SEEN_INKSCAPE_IO_INKSCAPESTREAM_H +#define SEEN_INKSCAPE_IO_INKSCAPESTREAM_H +/* + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include +#include + +namespace Inkscape +{ +namespace IO +{ + +class StreamException : public std::exception +{ +public: + + StreamException(const char *theReason) noexcept + { reason = theReason; } + StreamException(Glib::ustring &theReason) noexcept + { reason = theReason; } + ~StreamException() noexcept override + = default; + char const *what() const noexcept override + { return reason.c_str(); } + +private: + Glib::ustring reason; + +}; + +//######################################################################### +//# I N P U T S T R E A M +//######################################################################### + +/** + * This interface is the base of all input stream classes. Users who wish + * to make an InputStream that is part of a chain should inherit from + * BasicInputStream. Inherit from this class to make a source endpoint, + * such as a URI or buffer. + * + */ +class InputStream +{ + +public: + + /** + * Constructor. + */ + InputStream() = default; + + /** + * Destructor + */ + virtual ~InputStream() = default; + + /** + * Return the number of bytes that are currently available + * to be read + */ + virtual int available() = 0; + + /** + * Do whatever it takes to 'close' this input stream + * The most likely implementation of this method will be + * for endpoints that use a resource for their data. + */ + virtual void close() = 0; + + /** + * Read one byte from this input stream. This is a blocking + * call. If no data is currently available, this call will + * not return until it exists. If the user does not want + * their code to block, then the usual solution is: + * if (available() > 0) + * myChar = get(); + * This call returns -1 on end-of-file. + */ + virtual int get() = 0; + +}; // class InputStream + + + + +/** + * This is the class that most users should inherit, to provide + * their own streams. + * + */ +class BasicInputStream : public InputStream +{ + +public: + + BasicInputStream(InputStream &sourceStream); + + ~BasicInputStream() override = default; + + int available() override; + + void close() override; + + int get() override; + +protected: + + bool closed; + + InputStream &source; + +private: + + +}; // class BasicInputStream + + + +/** + * Convenience class for reading from standard input + */ +class StdInputStream : public InputStream +{ +public: + + int available() override + { return 0; } + + void close() override + { /* do nothing */ } + + int get() override + { return getchar(); } + +}; + + + + + + +//######################################################################### +//# O U T P U T S T R E A M +//######################################################################### + +/** + * This interface is the base of all input stream classes. Users who wish + * to make an OutputStream that is part of a chain should inherit from + * BasicOutputStream. Inherit from this class to make a destination endpoint, + * such as a URI or buffer. + */ +class OutputStream +{ + +public: + + /** + * Constructor. + */ + OutputStream() = default; + + /** + * Destructor + */ + virtual ~OutputStream() = default; + + /** + * This call should + * 1. flush itself + * 2. close itself + * 3. close the destination stream + */ + virtual void close() = 0; + + /** + * This call should push any pending data it might have to + * the destination stream. It should NOT call flush() on + * the destination stream. + */ + virtual void flush() = 0; + + /** + * Send one byte to the destination stream. + */ + virtual int put(char ch) = 0; + + +}; // class OutputStream + + +/** + * This is the class that most users should inherit, to provide + * their own output streams. + */ +class BasicOutputStream : public OutputStream +{ + +public: + + BasicOutputStream(OutputStream &destinationStream); + + ~BasicOutputStream() override = default; + + void close() override; + + void flush() override; + + int put(char ch) override; + +protected: + + bool closed; + + OutputStream &destination; + + +}; // class BasicOutputStream + + + +/** + * Convenience class for writing to standard output + */ +class StdOutputStream : public OutputStream +{ +public: + + void close() override + { } + + void flush() override + { } + + int put(char ch) override + {return putchar(ch); } + +}; + + + + +//######################################################################### +//# R E A D E R +//######################################################################### + + +/** + * This interface and its descendants are for unicode character-oriented input + * + */ +class Reader +{ + +public: + + /** + * Constructor. + */ + Reader() = default; + + /** + * Destructor + */ + virtual ~Reader() = default; + + + virtual int available() = 0; + + virtual void close() = 0; + + virtual char get() = 0; + + virtual Glib::ustring readLine() = 0; + + virtual Glib::ustring readWord() = 0; + + /* Input formatting */ + virtual const Reader& readBool (bool& val ) = 0; + virtual const Reader& operator>> (bool& val ) = 0; + + virtual const Reader& readShort (short &val) = 0; + virtual const Reader& operator>> (short &val) = 0; + + virtual const Reader& readUnsignedShort (unsigned short &val) = 0; + virtual const Reader& operator>> (unsigned short &val) = 0; + + virtual const Reader& readInt (int &val) = 0; + virtual const Reader& operator>> (int &val) = 0; + + virtual const Reader& readUnsignedInt (unsigned int &val) = 0; + virtual const Reader& operator>> (unsigned int &val) = 0; + + virtual const Reader& readLong (long &val) = 0; + virtual const Reader& operator>> (long &val) = 0; + + virtual const Reader& readUnsignedLong (unsigned long &val) = 0; + virtual const Reader& operator>> (unsigned long &val) = 0; + + virtual const Reader& readFloat (float &val) = 0; + virtual const Reader& operator>> (float &val) = 0; + + virtual const Reader& readDouble (double &val) = 0; + virtual const Reader& operator>> (double &val) = 0; + +}; // interface Reader + + + +/** + * This class and its descendants are for unicode character-oriented input + * + */ +class BasicReader : public Reader +{ + +public: + + BasicReader(Reader &sourceStream); + + ~BasicReader() override = default; + + int available() override; + + void close() override; + + char get() override; + + Glib::ustring readLine() override; + + Glib::ustring readWord() override; + + /* Input formatting */ + const Reader& readBool (bool& val ) override; + const Reader& operator>> (bool& val ) override + { return readBool(val); } + + const Reader& readShort (short &val) override; + const Reader& operator>> (short &val) override + { return readShort(val); } + + const Reader& readUnsignedShort (unsigned short &val) override; + const Reader& operator>> (unsigned short &val) override + { return readUnsignedShort(val); } + + const Reader& readInt (int &val) override; + const Reader& operator>> (int &val) override + { return readInt(val); } + + const Reader& readUnsignedInt (unsigned int &val) override; + const Reader& operator>> (unsigned int &val) override + { return readUnsignedInt(val); } + + const Reader& readLong (long &val) override; + const Reader& operator>> (long &val) override + { return readLong(val); } + + const Reader& readUnsignedLong (unsigned long &val) override; + const Reader& operator>> (unsigned long &val) override + { return readUnsignedLong(val); } + + const Reader& readFloat (float &val) override; + const Reader& operator>> (float &val) override + { return readFloat(val); } + + const Reader& readDouble (double &val) override; + const Reader& operator>> (double &val) override + { return readDouble(val); } + + +protected: + + Reader *source; + + BasicReader() + { source = nullptr; } + +private: + +}; // class BasicReader + + + +/** + * Class for placing a Reader on an open InputStream + * + */ +class InputStreamReader : public BasicReader +{ +public: + + InputStreamReader(InputStream &inputStreamSource); + + /*Overload these 3 for your implementation*/ + int available() override; + + void close() override; + + char get() override; + + +private: + + InputStream &inputStream; + + +}; + +/** + * Convenience class for reading formatted from standard input + * + */ +class StdReader : public BasicReader +{ +public: + + StdReader(); + + ~StdReader() override; + + /*Overload these 3 for your implementation*/ + int available() override; + + void close() override; + + char get() override; + + +private: + + InputStream *inputStream; + + +}; + + + + + +//######################################################################### +//# W R I T E R +//######################################################################### + +/** + * This interface and its descendants are for unicode character-oriented output + * + */ +class Writer +{ + +public: + + /** + * Constructor. + */ + Writer() = default; + + /** + * Destructor + */ + virtual ~Writer() = default; + + virtual void close() = 0; + + virtual void flush() = 0; + + virtual void put(char ch) = 0; + + /* Formatted output */ + virtual Writer& printf(char const *fmt, ...) G_GNUC_PRINTF(2,3) = 0; + + virtual Writer& writeChar(char val) = 0; + + virtual Writer& writeUString(const Glib::ustring &val) = 0; + + virtual Writer& writeStdString(const std::string &val) = 0; + + virtual Writer& writeString(const char *str) = 0; + + virtual Writer& writeBool (bool val ) = 0; + + virtual Writer& writeShort (short val ) = 0; + + virtual Writer& writeUnsignedShort (unsigned short val ) = 0; + + virtual Writer& writeInt (int val ) = 0; + + virtual Writer& writeUnsignedInt (unsigned int val ) = 0; + + virtual Writer& writeLong (long val ) = 0; + + virtual Writer& writeUnsignedLong (unsigned long val ) = 0; + + virtual Writer& writeFloat (float val ) = 0; + + virtual Writer& writeDouble (double val ) = 0; + + + +}; // interface Writer + + +/** + * This class and its descendants are for unicode character-oriented output + * + */ +class BasicWriter : public Writer +{ + +public: + + BasicWriter(Writer &destinationWriter); + + ~BasicWriter() override = default; + + /*Overload these 3 for your implementation*/ + void close() override; + + void flush() override; + + void put(char ch) override; + + + + /* Formatted output */ + Writer &printf(char const *fmt, ...) override G_GNUC_PRINTF(2,3); + + Writer& writeChar(char val) override; + + Writer& writeUString(const Glib::ustring &val) override; + + Writer& writeStdString(const std::string &val) override; + + Writer& writeString(const char *str) override; + + Writer& writeBool (bool val ) override; + + Writer& writeShort (short val ) override; + + Writer& writeUnsignedShort (unsigned short val ) override; + + Writer& writeInt (int val ) override; + + Writer& writeUnsignedInt (unsigned int val ) override; + + Writer& writeLong (long val ) override; + + Writer& writeUnsignedLong (unsigned long val ) override; + + Writer& writeFloat (float val ) override; + + Writer& writeDouble (double val ) override; + + +protected: + + Writer *destination; + + BasicWriter() + { destination = nullptr; } + +private: + +}; // class BasicWriter + + + +Writer& operator<< (Writer &writer, char val); + +Writer& operator<< (Writer &writer, Glib::ustring &val); + +Writer& operator<< (Writer &writer, std::string &val); + +Writer& operator<< (Writer &writer, char const *val); + +Writer& operator<< (Writer &writer, bool val); + +Writer& operator<< (Writer &writer, short val); + +Writer& operator<< (Writer &writer, unsigned short val); + +Writer& operator<< (Writer &writer, int val); + +Writer& operator<< (Writer &writer, unsigned int val); + +Writer& operator<< (Writer &writer, long val); + +Writer& operator<< (Writer &writer, unsigned long val); + +Writer& operator<< (Writer &writer, float val); + +Writer& operator<< (Writer &writer, double val); + + + + +/** + * Class for placing a Writer on an open OutputStream + * + */ +class OutputStreamWriter : public BasicWriter +{ +public: + + OutputStreamWriter(OutputStream &outputStreamDest); + + /*Overload these 3 for your implementation*/ + void close() override; + + void flush() override; + + void put(char ch) override; + + +private: + + OutputStream &outputStream; + + +}; + + +/** + * Convenience class for writing to standard output + */ +class StdWriter : public BasicWriter +{ +public: + StdWriter(); + + ~StdWriter() override; + + + void close() override; + + + void flush() override; + + + void put(char ch) override; + + +private: + + OutputStream *outputStream; + +}; + +//######################################################################### +//# U T I L I T Y +//######################################################################### + +void pipeStream(InputStream &source, OutputStream &dest); + + + +} // namespace IO +} // namespace Inkscape + + +#endif // SEEN_INKSCAPE_IO_INKSCAPESTREAM_H diff --git a/src/io/stream/streamtest.cpp b/src/io/stream/streamtest.cpp new file mode 100644 index 000000000..5d270580b --- /dev/null +++ b/src/io/stream/streamtest.cpp @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** @file + * TODO: insert short description here + *//* + * Authors: see git history + * + * Copyright (C) 2015 Authors + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + + +#include +#include // realpath +#include // mkdtemp, realpath +#include // chdir +#include // strlen, strncpy, strrchr + +#include "inkscapestream.h" +#include "base64stream.h" +#include "gzipstream.h" +#include "stringstream.h" +#include "uristream.h" +#include "xsltstream.h" + +// quick way to pass the name of the executable into the test +char myself[PATH_MAX]; + +// names and path storage for other tests +char *xmlname = "crystalegg.xml"; +char xmlpath[PATH_MAX]; +char *xslname = "doc2html.xsl"; +char xslpath[PATH_MAX]; + +bool testUriStream() +{ + printf("######### UriStream copy ############\n"); + Inkscape::URI inUri(myself); + Inkscape::IO::UriInputStream ins(inUri); + Inkscape::URI outUri("streamtest.copy"); + Inkscape::IO::UriOutputStream outs(outUri); + + pipeStream(ins, outs); + + ins.close(); + outs.close(); + + return true; +} + +bool testWriter() +{ + printf("######### OutputStreamWriter ############\n"); + Inkscape::IO::StdOutputStream outs; + Inkscape::IO::OutputStreamWriter writer(outs); + + writer << "Hello, world! " << 123.45 << " times\n"; + + writer.printf("There are %f quick brown foxes in %d states\n", 123.45, 88); + + return true; +} + +bool testStdWriter() +{ + printf("######### StdWriter ############\n"); + Inkscape::IO::StdWriter writer; + + writer << "Hello, world! " << 123.45 << " times\n"; + + writer.printf("There are %f quick brown foxes in %d states\n", 123.45, 88); + + return true; +} + +bool testBase64() +{ + printf("######### Base64 Out ############\n"); + Inkscape::URI plainInUri(xmlpath); + Inkscape::IO::UriInputStream ins1(plainInUri); + + Inkscape::URI b64OutUri("crystalegg.xml.b64"); + Inkscape::IO::UriOutputStream outs1(b64OutUri); + Inkscape::IO::Base64OutputStream b64Outs(outs1); + + pipeStream(ins1, b64Outs); + + ins1.close(); + b64Outs.close(); + + printf("######### Base64 In ############\n"); + Inkscape::URI b64InUri("crystalegg.xml.b64"); + Inkscape::IO::UriInputStream ins2(b64InUri); + Inkscape::IO::Base64InputStream b64Ins(ins2); + + Inkscape::URI plainOutUri("crystalegg.xml.b64dec"); + Inkscape::IO::UriOutputStream outs2(plainOutUri); + + pipeStream(b64Ins, outs2); + + outs2.close(); + b64Ins.close(); + + return true; +} + +bool testXslt() +{ + printf("######### XSLT Sheet ############\n"); + Inkscape::URI xsltSheetUri(xslpath); + Inkscape::IO::UriInputStream xsltSheetIns(xsltSheetUri); + Inkscape::IO::XsltStyleSheet stylesheet(xsltSheetIns); + xsltSheetIns.close(); + + Inkscape::URI sourceUri(xmlpath); + Inkscape::IO::UriInputStream xmlIns(sourceUri); + + printf("######### XSLT Input ############\n"); + Inkscape::URI destUri("test.html"); + Inkscape::IO::UriOutputStream xmlOuts(destUri); + + Inkscape::IO::XsltInputStream xsltIns(xmlIns, stylesheet); + pipeStream(xsltIns, xmlOuts); + xsltIns.close(); + xmlOuts.close(); + + + printf("######### XSLT Output ############\n"); + + Inkscape::IO::UriInputStream xmlIns2(sourceUri); + + Inkscape::URI destUri2("test2.html"); + Inkscape::IO::UriOutputStream xmlOuts2(destUri2); + + Inkscape::IO::XsltOutputStream xsltOuts(xmlOuts2, stylesheet); + pipeStream(xmlIns2, xsltOuts); + xmlIns2.close(); + xsltOuts.close(); + + return true; +} + +bool testGzip() +{ + + printf("######### Gzip Output ############\n"); + Inkscape::URI gzUri("test.gz"); + Inkscape::URI sourceUri(xmlpath); + Inkscape::IO::UriInputStream sourceIns(sourceUri); + Inkscape::IO::UriOutputStream gzOuts(gzUri); + + Inkscape::IO::GzipOutputStream gzipOuts(gzOuts); + pipeStream(sourceIns, gzipOuts); + sourceIns.close(); + gzipOuts.close(); + + printf("######### Gzip Input ############\n"); + + Inkscape::IO::UriInputStream gzIns(gzUri); + Inkscape::URI destUri("crystalegg2.xml"); + Inkscape::IO::UriOutputStream destOuts(destUri); + + Inkscape::IO::GzipInputStream gzipIns(gzIns); + pipeStream(gzipIns, destOuts); + gzipIns.close(); + destOuts.close(); + + return true; +} + +bool doTest() +{ + if (!testUriStream()) + { + return false; + } + if (!testWriter()) + { + return false; + } + if (!testStdWriter()) + { + return false; + } + if (!testBase64()) + { + return false; + } + if (!testXslt()) + { + return false; + } + if (!testGzip()) + { + return false; + } + return true; +} + +void path_init(char *path, char *name) +{ + if (strlen(name)>PATH_MAX-strlen(myself)) + { + printf("merging paths would be too long\n"); + exit(1); + } + strncpy(path,myself,PATH_MAX); + char * ptr = strrchr(path,'/'); + if (!ptr) + { + printf("path '%s' is missing any slashes\n",path); + exit(1); + } + strncpy(ptr+1,name,strlen(name)+1); + path[PATH_MAX-1] = '\0'; + printf("'%s'\n",path); +} + + +int main(int argc, char **argv) +{ + if (!realpath(argv[0],myself)) + { + perror("realpath"); + return 1; + } + path_init(xmlpath,xmlname); + path_init(xslpath,xslname); + + // create temp files somewhere else instead of current dir + // TODO: clean them up too + char * testpath = strdup("/tmp/streamtest-XXXXXX"); + char * testpath2; + testpath2 = mkdtemp(testpath); + free(testpath); + if (!testpath2) + { + perror("mkdtemp"); + return 1; + } + if (chdir(testpath2)) + { + perror("chdir"); + return 1; + } + + if (!doTest()) + { + printf("#### Test failed\n"); + return 1; + } + else + { + printf("##### Test succeeded\n"); + } + return 0; +} diff --git a/src/io/stream/stringstream.cpp b/src/io/stream/stringstream.cpp new file mode 100644 index 000000000..0259869f7 --- /dev/null +++ b/src/io/stream/stringstream.cpp @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Our base String stream classes. We implement these to + * be based on Glib::ustring + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + + +#include "stringstream.h" + +namespace Inkscape +{ +namespace IO +{ + + +//######################################################################### +//# S T R I N G I N P U T S T R E A M +//######################################################################### + + +/** + * + */ +StringInputStream::StringInputStream(Glib::ustring &sourceString) + : buffer(sourceString) +{ + position = 0; +} + +/** + * + */ +StringInputStream::~StringInputStream() += default; + +/** + * 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 StringInputStream::available() +{ + return buffer.size() - position; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void StringInputStream::close() +{ +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int StringInputStream::get() +{ + if (position >= (int)buffer.size()) + return -1; + int ch = (int) buffer[position++]; + return ch; +} + + + + +//######################################################################### +//# S T R I N G O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +StringOutputStream::StringOutputStream() += default; + +/** + * + */ +StringOutputStream::~StringOutputStream() += default; + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void StringOutputStream::close() +{ +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void StringOutputStream::flush() +{ + //nothing to do +} + +/** + * Writes the specified byte to this output stream. + */ +int StringOutputStream::put(char ch) +{ + buffer.push_back(ch); + return 1; +} + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/io/stream/stringstream.h b/src/io/stream/stringstream.h new file mode 100644 index 000000000..3afb9a870 --- /dev/null +++ b/src/io/stream/stringstream.h @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** @file + * TODO: insert short description here + *//* + * Authors: see git history + * + * Copyright (C) 2018 Authors + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ +#ifndef __INKSCAPE_IO_STRINGSTREAM_H__ +#define __INKSCAPE_IO_STRINGSTREAM_H__ + +#include + +#include "inkscapestream.h" + + +namespace Inkscape +{ +namespace IO +{ + + +//######################################################################### +//# S T R I N G I N P U T S T R E A M +//######################################################################### + +/** + * This class is for reading character from a Glib::ustring + * + */ +class StringInputStream : public InputStream +{ + +public: + + StringInputStream(Glib::ustring &sourceString); + + ~StringInputStream() override; + + int available() override; + + void close() override; + + int get() override; + +private: + + Glib::ustring &buffer; + + long position; + +}; // class StringInputStream + + + + +//######################################################################### +//# S T R I N G O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for sending a stream to a Glib::ustring + * + */ +class StringOutputStream : public OutputStream +{ + +public: + + StringOutputStream(); + + ~StringOutputStream() override; + + void close() override; + + void flush() override; + + int put(char ch) override; + + virtual Glib::ustring &getString() + { return buffer; } + + virtual void clear() + { buffer = ""; } + +private: + + Glib::ustring buffer; + + +}; // class StringOutputStream + + + + + + + +} // namespace IO +} // namespace Inkscape + + + +#endif /* __INKSCAPE_IO_STRINGSTREAM_H__ */ diff --git a/src/io/stream/uristream.cpp b/src/io/stream/uristream.cpp new file mode 100644 index 000000000..2ff7460e0 --- /dev/null +++ b/src/io/stream/uristream.cpp @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Our base String stream classes. We implement these to + * be based on Glib::ustring + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + + +#include "uristream.h" +#include "sys.h" +#include +#include + + +namespace Inkscape +{ +namespace IO +{ + +/* + * URI scheme types + */ +#define SCHEME_NONE 0 +#define SCHEME_FILE 1 +#define SCHEME_DATA 2 + +/* + * A temporary modification of Jon Cruz's portable fopen(). + * Simplified a bit, since we will always use binary +*/ + +#define FILE_READ 1 +#define FILE_WRITE 2 + +static FILE *fopen_utf8name( char const *utf8name, int mode ) +{ + FILE *fp = nullptr; + if (!utf8name) + { + return nullptr; + } + if (mode!=FILE_READ && mode!=FILE_WRITE) + { + return nullptr; + } + +#ifndef _WIN32 + gchar *filename = g_filename_from_utf8( utf8name, -1, nullptr, nullptr, nullptr ); + if ( filename ) { + if (mode == FILE_READ) + fp = std::fopen(filename, "rb"); + else + fp = std::fopen(filename, "wb"); + g_free(filename); + } +#else + { + gunichar2 *wideName = g_utf8_to_utf16( utf8name, -1, NULL, NULL, NULL ); + if ( wideName ) { + if (mode == FILE_READ) + fp = _wfopen( (wchar_t*)wideName, L"rb" ); + else + fp = _wfopen( (wchar_t*)wideName, L"wb" ); + g_free( wideName ); + } else { + gchar *safe = Inkscape::IO::sanitizeString(utf8name); + g_message("Unable to convert filename from UTF-8 to UTF-16 [%s]", safe); + g_free(safe); + } + } +#endif + + return fp; +} + + + +//######################################################################### +//# F I L E I N P U T S T R E A M +//######################################################################### + + +/** + * + */ +FileInputStream::FileInputStream(FILE *source) + : inf(source) +{ + if (!inf) { + Glib::ustring err = "FileInputStream passed NULL"; + throw StreamException(err); + } +} + +/** + * + */ +FileInputStream::~FileInputStream() +{ + 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 FileInputStream::available() +{ + return 0; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void FileInputStream::close() +{ + if (!inf) + return; + fflush(inf); + fclose(inf); + inf=nullptr; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int FileInputStream::get() +{ + int retVal = -1; + if (!inf || feof(inf)) + { + retVal = -1; + } + else + { + retVal = fgetc(inf); + } + + return retVal; +} + + + + +//######################################################################### +//# F I L E O U T P U T S T R E A M +//######################################################################### + +FileOutputStream::FileOutputStream(FILE *fp) + : ownsFile(false) + , outf(fp) +{ + if (!outf) { + Glib::ustring err = "FileOutputStream given null file "; + throw StreamException(err); + } +} + +/** + * + */ +FileOutputStream::~FileOutputStream() +{ + close(); +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void FileOutputStream::close() +{ + if (!outf) + return; + fflush(outf); + if ( ownsFile ) + fclose(outf); + outf=nullptr; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void FileOutputStream::flush() +{ + if (!outf) + return; + fflush(outf); +} + +/** + * Writes the specified byte to this output stream. + */ +int FileOutputStream::put(char ch) +{ + unsigned char uch; + + if (!outf) + return -1; + uch = (unsigned char)(ch & 0xff); + if (fputc(uch, outf) == EOF) { + Glib::ustring err = "ERROR writing to file "; + throw StreamException(err); + } + + return 1; +} + + + + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### + +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/io/stream/uristream.h b/src/io/stream/uristream.h new file mode 100644 index 000000000..f0544d876 --- /dev/null +++ b/src/io/stream/uristream.h @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef SEEN_INKSCAPE_IO_URISTREAM_H +#define SEEN_INKSCAPE_IO_URISTREAM_H +/** + * @file + * This should be the only way that we provide sources/sinks + * to any input/output stream. + */ +/* + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + + +#include "object/uri.h" + +#include "inkscapestream.h" + + +namespace Inkscape +{ + +class URI; + +namespace IO +{ + +//######################################################################### +//# F I L E I N P U T S T R E A M +//######################################################################### + +/** + * This class is for receiving a stream of data from a file + */ +class FileInputStream : public InputStream +{ + +public: + FileInputStream(FILE *source); + + ~FileInputStream() override; + + int available() override; + + void close() override; + + int get() override; + +private: + FILE *inf; //for file: uris + +}; // class FileInputStream + + + + +//######################################################################### +//# F I L E O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for sending a stream to a destination file + */ +class FileOutputStream : public OutputStream +{ + +public: + + FileOutputStream(FILE *fp); + + ~FileOutputStream() override; + + void close() override; + + void flush() override; + + int put(char ch) override; + +private: + + bool ownsFile; + + FILE *outf; //for file: uris + +}; // class FileOutputStream + + + + + +} // namespace IO +} // namespace Inkscape + + +#endif // SEEN_INKSCAPE_IO_URISTREAM_H + +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/io/stream/xsltstream.cpp b/src/io/stream/xsltstream.cpp new file mode 100644 index 000000000..882db30b2 --- /dev/null +++ b/src/io/stream/xsltstream.cpp @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * XSL Transforming input and output classes + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004-2008 Inkscape.org + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + + +#include "xsltstream.h" +#include "stringstream.h" +#include + + + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# X S L T S T Y L E S H E E T +//######################################################################### + +/** + * + */ +XsltStyleSheet::XsltStyleSheet(InputStream &xsltSource) + + : stylesheet(nullptr) +{ + if (!read(xsltSource)) { + throw StreamException("read failed"); + } +} + +/** + * + */ +XsltStyleSheet::XsltStyleSheet() + : stylesheet(nullptr) +{ +} + + + +/** + * + */ +bool XsltStyleSheet::read(InputStream &xsltSource) +{ + StringOutputStream outs; + pipeStream(xsltSource, outs); + std::string strBuf = outs.getString().raw(); + xmlDocPtr doc = xmlParseMemory(strBuf.c_str(), strBuf.size()); + stylesheet = xsltParseStylesheetDoc(doc); + //following not necessary. handled by xsltFreeStylesheet(stylesheet); + //xmlFreeDoc(doc); + if (!stylesheet) + return false; + return true; +} + + +/** + * + */ +XsltStyleSheet::~XsltStyleSheet() +{ + if (stylesheet) + xsltFreeStylesheet(stylesheet); +} + + + +//######################################################################### +//# X S L T I N P U T S T R E A M +//######################################################################### + + +/** + * + */ +XsltInputStream::XsltInputStream(InputStream &xmlSource, XsltStyleSheet &sheet) + : BasicInputStream(xmlSource), stylesheet(sheet) +{ + //Load the data + StringOutputStream outs; + pipeStream(source, outs); + std::string strBuf = outs.getString().raw(); + + //Do the processing + const char *params[1]; + params[0] = nullptr; + xmlDocPtr srcDoc = xmlParseMemory(strBuf.c_str(), strBuf.size()); + xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params); + xmlDocDumpFormatMemory(resDoc, &outbuf, &outsize, 1); + outpos = 0; + + //Free our mem + xmlFreeDoc(resDoc); + xmlFreeDoc(srcDoc); +} + +/** + * + */ +XsltInputStream::~XsltInputStream() +{ + xmlFree(outbuf); +} + +/** + * 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 XsltInputStream::available() +{ + return outsize - outpos; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void XsltInputStream::close() +{ + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int XsltInputStream::get() +{ + if (closed) + return -1; + if (outpos >= outsize) + return -1; + int ch = (int) outbuf[outpos++]; + return ch; +} + + + + + + +//######################################################################### +//# X S L T O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +XsltOutputStream::XsltOutputStream(OutputStream &dest, XsltStyleSheet &sheet) + : BasicOutputStream(dest), stylesheet(sheet) +{ + flushed = false; +} + +/** + * + */ +XsltOutputStream::~XsltOutputStream() +{ + //do not automatically close +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void XsltOutputStream::close() +{ + flush(); + destination.close(); +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void XsltOutputStream::flush() +{ + if (flushed) + { + destination.flush(); + return; + } + + //Do the processing + xmlChar *resbuf; + int resSize; + const char *params[1]; + params[0] = nullptr; + xmlDocPtr srcDoc = xmlParseMemory(outbuf.raw().c_str(), outbuf.size()); + xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params); + xmlDocDumpFormatMemory(resDoc, &resbuf, &resSize, 1); + /* + xmlErrorPtr err = xmlGetLastError(); + if (err) + { + throw StreamException(err->message); + } + */ + + for (int i=0 ; i + * + * Copyright (C) 2004-2008 Inkscape.org + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + + +#include "inkscapestream.h" + +#include +#include + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# X S L T S T Y L E S H E E T +//######################################################################### +/** + * This is a container for reusing a loaded stylesheet + */ +class XsltStyleSheet +{ + +public: + + /** + * Constructor with loading + */ + XsltStyleSheet(InputStream &source); + + /** + * Simple constructor, no loading + */ + XsltStyleSheet(); + + /** + * Loader + */ + bool read(InputStream &source); + + /** + * Destructor + */ + virtual ~XsltStyleSheet(); + + xsltStylesheetPtr stylesheet; + + +}; // class XsltStyleSheet + + +//######################################################################### +//# X S L T I N P U T S T R E A M +//######################################################################### + +/** + * This class is for transforming stream input by a given stylesheet + */ +class XsltInputStream : public BasicInputStream +{ + +public: + + XsltInputStream(InputStream &xmlSource, XsltStyleSheet &stylesheet); + + ~XsltInputStream() override; + + int available() override; + + void close() override; + + int get() override; + + +private: + + XsltStyleSheet &stylesheet; + + xmlChar *outbuf; + int outsize; + int outpos; + +}; // class XsltInputStream + + + + +//######################################################################### +//# X S L T O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for transforming stream output by a given stylesheet + */ +class XsltOutputStream : public BasicOutputStream +{ + +public: + + XsltOutputStream(OutputStream &destination, XsltStyleSheet &stylesheet); + + ~XsltOutputStream() override; + + void close() override; + + void flush() override; + + int put(char ch) override; + +private: + + XsltStyleSheet &stylesheet; + + Glib::ustring outbuf; + + bool flushed; + +}; // class XsltOutputStream + + + +} // namespace IO +} // namespace Inkscape + + +#endif /* __INKSCAPE_IO_XSLTSTREAM_H__ */ diff --git a/src/io/streamtest.cpp b/src/io/streamtest.cpp deleted file mode 100644 index 5d270580b..000000000 --- a/src/io/streamtest.cpp +++ /dev/null @@ -1,256 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/** @file - * TODO: insert short description here - *//* - * Authors: see git history - * - * Copyright (C) 2015 Authors - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - - -#include -#include // realpath -#include // mkdtemp, realpath -#include // chdir -#include // strlen, strncpy, strrchr - -#include "inkscapestream.h" -#include "base64stream.h" -#include "gzipstream.h" -#include "stringstream.h" -#include "uristream.h" -#include "xsltstream.h" - -// quick way to pass the name of the executable into the test -char myself[PATH_MAX]; - -// names and path storage for other tests -char *xmlname = "crystalegg.xml"; -char xmlpath[PATH_MAX]; -char *xslname = "doc2html.xsl"; -char xslpath[PATH_MAX]; - -bool testUriStream() -{ - printf("######### UriStream copy ############\n"); - Inkscape::URI inUri(myself); - Inkscape::IO::UriInputStream ins(inUri); - Inkscape::URI outUri("streamtest.copy"); - Inkscape::IO::UriOutputStream outs(outUri); - - pipeStream(ins, outs); - - ins.close(); - outs.close(); - - return true; -} - -bool testWriter() -{ - printf("######### OutputStreamWriter ############\n"); - Inkscape::IO::StdOutputStream outs; - Inkscape::IO::OutputStreamWriter writer(outs); - - writer << "Hello, world! " << 123.45 << " times\n"; - - writer.printf("There are %f quick brown foxes in %d states\n", 123.45, 88); - - return true; -} - -bool testStdWriter() -{ - printf("######### StdWriter ############\n"); - Inkscape::IO::StdWriter writer; - - writer << "Hello, world! " << 123.45 << " times\n"; - - writer.printf("There are %f quick brown foxes in %d states\n", 123.45, 88); - - return true; -} - -bool testBase64() -{ - printf("######### Base64 Out ############\n"); - Inkscape::URI plainInUri(xmlpath); - Inkscape::IO::UriInputStream ins1(plainInUri); - - Inkscape::URI b64OutUri("crystalegg.xml.b64"); - Inkscape::IO::UriOutputStream outs1(b64OutUri); - Inkscape::IO::Base64OutputStream b64Outs(outs1); - - pipeStream(ins1, b64Outs); - - ins1.close(); - b64Outs.close(); - - printf("######### Base64 In ############\n"); - Inkscape::URI b64InUri("crystalegg.xml.b64"); - Inkscape::IO::UriInputStream ins2(b64InUri); - Inkscape::IO::Base64InputStream b64Ins(ins2); - - Inkscape::URI plainOutUri("crystalegg.xml.b64dec"); - Inkscape::IO::UriOutputStream outs2(plainOutUri); - - pipeStream(b64Ins, outs2); - - outs2.close(); - b64Ins.close(); - - return true; -} - -bool testXslt() -{ - printf("######### XSLT Sheet ############\n"); - Inkscape::URI xsltSheetUri(xslpath); - Inkscape::IO::UriInputStream xsltSheetIns(xsltSheetUri); - Inkscape::IO::XsltStyleSheet stylesheet(xsltSheetIns); - xsltSheetIns.close(); - - Inkscape::URI sourceUri(xmlpath); - Inkscape::IO::UriInputStream xmlIns(sourceUri); - - printf("######### XSLT Input ############\n"); - Inkscape::URI destUri("test.html"); - Inkscape::IO::UriOutputStream xmlOuts(destUri); - - Inkscape::IO::XsltInputStream xsltIns(xmlIns, stylesheet); - pipeStream(xsltIns, xmlOuts); - xsltIns.close(); - xmlOuts.close(); - - - printf("######### XSLT Output ############\n"); - - Inkscape::IO::UriInputStream xmlIns2(sourceUri); - - Inkscape::URI destUri2("test2.html"); - Inkscape::IO::UriOutputStream xmlOuts2(destUri2); - - Inkscape::IO::XsltOutputStream xsltOuts(xmlOuts2, stylesheet); - pipeStream(xmlIns2, xsltOuts); - xmlIns2.close(); - xsltOuts.close(); - - return true; -} - -bool testGzip() -{ - - printf("######### Gzip Output ############\n"); - Inkscape::URI gzUri("test.gz"); - Inkscape::URI sourceUri(xmlpath); - Inkscape::IO::UriInputStream sourceIns(sourceUri); - Inkscape::IO::UriOutputStream gzOuts(gzUri); - - Inkscape::IO::GzipOutputStream gzipOuts(gzOuts); - pipeStream(sourceIns, gzipOuts); - sourceIns.close(); - gzipOuts.close(); - - printf("######### Gzip Input ############\n"); - - Inkscape::IO::UriInputStream gzIns(gzUri); - Inkscape::URI destUri("crystalegg2.xml"); - Inkscape::IO::UriOutputStream destOuts(destUri); - - Inkscape::IO::GzipInputStream gzipIns(gzIns); - pipeStream(gzipIns, destOuts); - gzipIns.close(); - destOuts.close(); - - return true; -} - -bool doTest() -{ - if (!testUriStream()) - { - return false; - } - if (!testWriter()) - { - return false; - } - if (!testStdWriter()) - { - return false; - } - if (!testBase64()) - { - return false; - } - if (!testXslt()) - { - return false; - } - if (!testGzip()) - { - return false; - } - return true; -} - -void path_init(char *path, char *name) -{ - if (strlen(name)>PATH_MAX-strlen(myself)) - { - printf("merging paths would be too long\n"); - exit(1); - } - strncpy(path,myself,PATH_MAX); - char * ptr = strrchr(path,'/'); - if (!ptr) - { - printf("path '%s' is missing any slashes\n",path); - exit(1); - } - strncpy(ptr+1,name,strlen(name)+1); - path[PATH_MAX-1] = '\0'; - printf("'%s'\n",path); -} - - -int main(int argc, char **argv) -{ - if (!realpath(argv[0],myself)) - { - perror("realpath"); - return 1; - } - path_init(xmlpath,xmlname); - path_init(xslpath,xslname); - - // create temp files somewhere else instead of current dir - // TODO: clean them up too - char * testpath = strdup("/tmp/streamtest-XXXXXX"); - char * testpath2; - testpath2 = mkdtemp(testpath); - free(testpath); - if (!testpath2) - { - perror("mkdtemp"); - return 1; - } - if (chdir(testpath2)) - { - perror("chdir"); - return 1; - } - - if (!doTest()) - { - printf("#### Test failed\n"); - return 1; - } - else - { - printf("##### Test succeeded\n"); - } - return 0; -} diff --git a/src/io/stringstream.cpp b/src/io/stringstream.cpp deleted file mode 100644 index 0259869f7..000000000 --- a/src/io/stringstream.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Our base String stream classes. We implement these to - * be based on Glib::ustring - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2004 Inkscape.org - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - - -#include "stringstream.h" - -namespace Inkscape -{ -namespace IO -{ - - -//######################################################################### -//# S T R I N G I N P U T S T R E A M -//######################################################################### - - -/** - * - */ -StringInputStream::StringInputStream(Glib::ustring &sourceString) - : buffer(sourceString) -{ - position = 0; -} - -/** - * - */ -StringInputStream::~StringInputStream() -= default; - -/** - * 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 StringInputStream::available() -{ - return buffer.size() - position; -} - - -/** - * Closes this input stream and releases any system resources - * associated with the stream. - */ -void StringInputStream::close() -{ -} - -/** - * Reads the next byte of data from the input stream. -1 if EOF - */ -int StringInputStream::get() -{ - if (position >= (int)buffer.size()) - return -1; - int ch = (int) buffer[position++]; - return ch; -} - - - - -//######################################################################### -//# S T R I N G O U T P U T S T R E A M -//######################################################################### - -/** - * - */ -StringOutputStream::StringOutputStream() -= default; - -/** - * - */ -StringOutputStream::~StringOutputStream() -= default; - -/** - * Closes this output stream and releases any system resources - * associated with this stream. - */ -void StringOutputStream::close() -{ -} - -/** - * Flushes this output stream and forces any buffered output - * bytes to be written out. - */ -void StringOutputStream::flush() -{ - //nothing to do -} - -/** - * Writes the specified byte to this output stream. - */ -int StringOutputStream::put(char ch) -{ - buffer.push_back(ch); - return 1; -} - - -} // namespace IO -} // namespace Inkscape - - -//######################################################################### -//# E N D O F F I L E -//######################################################################### diff --git a/src/io/stringstream.h b/src/io/stringstream.h deleted file mode 100644 index 3afb9a870..000000000 --- a/src/io/stringstream.h +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/** @file - * TODO: insert short description here - *//* - * Authors: see git history - * - * Copyright (C) 2018 Authors - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ -#ifndef __INKSCAPE_IO_STRINGSTREAM_H__ -#define __INKSCAPE_IO_STRINGSTREAM_H__ - -#include - -#include "inkscapestream.h" - - -namespace Inkscape -{ -namespace IO -{ - - -//######################################################################### -//# S T R I N G I N P U T S T R E A M -//######################################################################### - -/** - * This class is for reading character from a Glib::ustring - * - */ -class StringInputStream : public InputStream -{ - -public: - - StringInputStream(Glib::ustring &sourceString); - - ~StringInputStream() override; - - int available() override; - - void close() override; - - int get() override; - -private: - - Glib::ustring &buffer; - - long position; - -}; // class StringInputStream - - - - -//######################################################################### -//# S T R I N G O U T P U T S T R E A M -//######################################################################### - -/** - * This class is for sending a stream to a Glib::ustring - * - */ -class StringOutputStream : public OutputStream -{ - -public: - - StringOutputStream(); - - ~StringOutputStream() override; - - void close() override; - - void flush() override; - - int put(char ch) override; - - virtual Glib::ustring &getString() - { return buffer; } - - virtual void clear() - { buffer = ""; } - -private: - - Glib::ustring buffer; - - -}; // class StringOutputStream - - - - - - - -} // namespace IO -} // namespace Inkscape - - - -#endif /* __INKSCAPE_IO_STRINGSTREAM_H__ */ diff --git a/src/io/uristream.cpp b/src/io/uristream.cpp deleted file mode 100644 index 2ff7460e0..000000000 --- a/src/io/uristream.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Our base String stream classes. We implement these to - * be based on Glib::ustring - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2004 Inkscape.org - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - - -#include "uristream.h" -#include "sys.h" -#include -#include - - -namespace Inkscape -{ -namespace IO -{ - -/* - * URI scheme types - */ -#define SCHEME_NONE 0 -#define SCHEME_FILE 1 -#define SCHEME_DATA 2 - -/* - * A temporary modification of Jon Cruz's portable fopen(). - * Simplified a bit, since we will always use binary -*/ - -#define FILE_READ 1 -#define FILE_WRITE 2 - -static FILE *fopen_utf8name( char const *utf8name, int mode ) -{ - FILE *fp = nullptr; - if (!utf8name) - { - return nullptr; - } - if (mode!=FILE_READ && mode!=FILE_WRITE) - { - return nullptr; - } - -#ifndef _WIN32 - gchar *filename = g_filename_from_utf8( utf8name, -1, nullptr, nullptr, nullptr ); - if ( filename ) { - if (mode == FILE_READ) - fp = std::fopen(filename, "rb"); - else - fp = std::fopen(filename, "wb"); - g_free(filename); - } -#else - { - gunichar2 *wideName = g_utf8_to_utf16( utf8name, -1, NULL, NULL, NULL ); - if ( wideName ) { - if (mode == FILE_READ) - fp = _wfopen( (wchar_t*)wideName, L"rb" ); - else - fp = _wfopen( (wchar_t*)wideName, L"wb" ); - g_free( wideName ); - } else { - gchar *safe = Inkscape::IO::sanitizeString(utf8name); - g_message("Unable to convert filename from UTF-8 to UTF-16 [%s]", safe); - g_free(safe); - } - } -#endif - - return fp; -} - - - -//######################################################################### -//# F I L E I N P U T S T R E A M -//######################################################################### - - -/** - * - */ -FileInputStream::FileInputStream(FILE *source) - : inf(source) -{ - if (!inf) { - Glib::ustring err = "FileInputStream passed NULL"; - throw StreamException(err); - } -} - -/** - * - */ -FileInputStream::~FileInputStream() -{ - 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 FileInputStream::available() -{ - return 0; -} - - -/** - * Closes this input stream and releases any system resources - * associated with the stream. - */ -void FileInputStream::close() -{ - if (!inf) - return; - fflush(inf); - fclose(inf); - inf=nullptr; -} - -/** - * Reads the next byte of data from the input stream. -1 if EOF - */ -int FileInputStream::get() -{ - int retVal = -1; - if (!inf || feof(inf)) - { - retVal = -1; - } - else - { - retVal = fgetc(inf); - } - - return retVal; -} - - - - -//######################################################################### -//# F I L E O U T P U T S T R E A M -//######################################################################### - -FileOutputStream::FileOutputStream(FILE *fp) - : ownsFile(false) - , outf(fp) -{ - if (!outf) { - Glib::ustring err = "FileOutputStream given null file "; - throw StreamException(err); - } -} - -/** - * - */ -FileOutputStream::~FileOutputStream() -{ - close(); -} - -/** - * Closes this output stream and releases any system resources - * associated with this stream. - */ -void FileOutputStream::close() -{ - if (!outf) - return; - fflush(outf); - if ( ownsFile ) - fclose(outf); - outf=nullptr; -} - -/** - * Flushes this output stream and forces any buffered output - * bytes to be written out. - */ -void FileOutputStream::flush() -{ - if (!outf) - return; - fflush(outf); -} - -/** - * Writes the specified byte to this output stream. - */ -int FileOutputStream::put(char ch) -{ - unsigned char uch; - - if (!outf) - return -1; - uch = (unsigned char)(ch & 0xff); - if (fputc(uch, outf) == EOF) { - Glib::ustring err = "ERROR writing to file "; - throw StreamException(err); - } - - return 1; -} - - - - - -} // namespace IO -} // namespace Inkscape - - -//######################################################################### -//# E N D O F F I L E -//######################################################################### - -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/io/uristream.h b/src/io/uristream.h deleted file mode 100644 index f0544d876..000000000 --- a/src/io/uristream.h +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#ifndef SEEN_INKSCAPE_IO_URISTREAM_H -#define SEEN_INKSCAPE_IO_URISTREAM_H -/** - * @file - * This should be the only way that we provide sources/sinks - * to any input/output stream. - */ -/* - * Authors: - * Bob Jamison - * - * Copyright (C) 2004 Inkscape.org - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - - -#include "object/uri.h" - -#include "inkscapestream.h" - - -namespace Inkscape -{ - -class URI; - -namespace IO -{ - -//######################################################################### -//# F I L E I N P U T S T R E A M -//######################################################################### - -/** - * This class is for receiving a stream of data from a file - */ -class FileInputStream : public InputStream -{ - -public: - FileInputStream(FILE *source); - - ~FileInputStream() override; - - int available() override; - - void close() override; - - int get() override; - -private: - FILE *inf; //for file: uris - -}; // class FileInputStream - - - - -//######################################################################### -//# F I L E O U T P U T S T R E A M -//######################################################################### - -/** - * This class is for sending a stream to a destination file - */ -class FileOutputStream : public OutputStream -{ - -public: - - FileOutputStream(FILE *fp); - - ~FileOutputStream() override; - - void close() override; - - void flush() override; - - int put(char ch) override; - -private: - - bool ownsFile; - - FILE *outf; //for file: uris - -}; // class FileOutputStream - - - - - -} // namespace IO -} // namespace Inkscape - - -#endif // SEEN_INKSCAPE_IO_URISTREAM_H - -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/io/xsltstream.cpp b/src/io/xsltstream.cpp deleted file mode 100644 index 882db30b2..000000000 --- a/src/io/xsltstream.cpp +++ /dev/null @@ -1,248 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * XSL Transforming input and output classes - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2004-2008 Inkscape.org - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - - -#include "xsltstream.h" -#include "stringstream.h" -#include - - - - -namespace Inkscape -{ -namespace IO -{ - -//######################################################################### -//# X S L T S T Y L E S H E E T -//######################################################################### - -/** - * - */ -XsltStyleSheet::XsltStyleSheet(InputStream &xsltSource) - - : stylesheet(nullptr) -{ - if (!read(xsltSource)) { - throw StreamException("read failed"); - } -} - -/** - * - */ -XsltStyleSheet::XsltStyleSheet() - : stylesheet(nullptr) -{ -} - - - -/** - * - */ -bool XsltStyleSheet::read(InputStream &xsltSource) -{ - StringOutputStream outs; - pipeStream(xsltSource, outs); - std::string strBuf = outs.getString().raw(); - xmlDocPtr doc = xmlParseMemory(strBuf.c_str(), strBuf.size()); - stylesheet = xsltParseStylesheetDoc(doc); - //following not necessary. handled by xsltFreeStylesheet(stylesheet); - //xmlFreeDoc(doc); - if (!stylesheet) - return false; - return true; -} - - -/** - * - */ -XsltStyleSheet::~XsltStyleSheet() -{ - if (stylesheet) - xsltFreeStylesheet(stylesheet); -} - - - -//######################################################################### -//# X S L T I N P U T S T R E A M -//######################################################################### - - -/** - * - */ -XsltInputStream::XsltInputStream(InputStream &xmlSource, XsltStyleSheet &sheet) - : BasicInputStream(xmlSource), stylesheet(sheet) -{ - //Load the data - StringOutputStream outs; - pipeStream(source, outs); - std::string strBuf = outs.getString().raw(); - - //Do the processing - const char *params[1]; - params[0] = nullptr; - xmlDocPtr srcDoc = xmlParseMemory(strBuf.c_str(), strBuf.size()); - xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params); - xmlDocDumpFormatMemory(resDoc, &outbuf, &outsize, 1); - outpos = 0; - - //Free our mem - xmlFreeDoc(resDoc); - xmlFreeDoc(srcDoc); -} - -/** - * - */ -XsltInputStream::~XsltInputStream() -{ - xmlFree(outbuf); -} - -/** - * 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 XsltInputStream::available() -{ - return outsize - outpos; -} - - -/** - * Closes this input stream and releases any system resources - * associated with the stream. - */ -void XsltInputStream::close() -{ - closed = true; -} - -/** - * Reads the next byte of data from the input stream. -1 if EOF - */ -int XsltInputStream::get() -{ - if (closed) - return -1; - if (outpos >= outsize) - return -1; - int ch = (int) outbuf[outpos++]; - return ch; -} - - - - - - -//######################################################################### -//# X S L T O U T P U T S T R E A M -//######################################################################### - -/** - * - */ -XsltOutputStream::XsltOutputStream(OutputStream &dest, XsltStyleSheet &sheet) - : BasicOutputStream(dest), stylesheet(sheet) -{ - flushed = false; -} - -/** - * - */ -XsltOutputStream::~XsltOutputStream() -{ - //do not automatically close -} - -/** - * Closes this output stream and releases any system resources - * associated with this stream. - */ -void XsltOutputStream::close() -{ - flush(); - destination.close(); -} - -/** - * Flushes this output stream and forces any buffered output - * bytes to be written out. - */ -void XsltOutputStream::flush() -{ - if (flushed) - { - destination.flush(); - return; - } - - //Do the processing - xmlChar *resbuf; - int resSize; - const char *params[1]; - params[0] = nullptr; - xmlDocPtr srcDoc = xmlParseMemory(outbuf.raw().c_str(), outbuf.size()); - xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params); - xmlDocDumpFormatMemory(resDoc, &resbuf, &resSize, 1); - /* - xmlErrorPtr err = xmlGetLastError(); - if (err) - { - throw StreamException(err->message); - } - */ - - for (int i=0 ; i - * - * Copyright (C) 2004-2008 Inkscape.org - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - - -#include "inkscapestream.h" - -#include -#include - - -namespace Inkscape -{ -namespace IO -{ - -//######################################################################### -//# X S L T S T Y L E S H E E T -//######################################################################### -/** - * This is a container for reusing a loaded stylesheet - */ -class XsltStyleSheet -{ - -public: - - /** - * Constructor with loading - */ - XsltStyleSheet(InputStream &source); - - /** - * Simple constructor, no loading - */ - XsltStyleSheet(); - - /** - * Loader - */ - bool read(InputStream &source); - - /** - * Destructor - */ - virtual ~XsltStyleSheet(); - - xsltStylesheetPtr stylesheet; - - -}; // class XsltStyleSheet - - -//######################################################################### -//# X S L T I N P U T S T R E A M -//######################################################################### - -/** - * This class is for transforming stream input by a given stylesheet - */ -class XsltInputStream : public BasicInputStream -{ - -public: - - XsltInputStream(InputStream &xmlSource, XsltStyleSheet &stylesheet); - - ~XsltInputStream() override; - - int available() override; - - void close() override; - - int get() override; - - -private: - - XsltStyleSheet &stylesheet; - - xmlChar *outbuf; - int outsize; - int outpos; - -}; // class XsltInputStream - - - - -//######################################################################### -//# X S L T O U T P U T S T R E A M -//######################################################################### - -/** - * This class is for transforming stream output by a given stylesheet - */ -class XsltOutputStream : public BasicOutputStream -{ - -public: - - XsltOutputStream(OutputStream &destination, XsltStyleSheet &stylesheet); - - ~XsltOutputStream() override; - - void close() override; - - void flush() override; - - int put(char ch) override; - -private: - - XsltStyleSheet &stylesheet; - - Glib::ustring outbuf; - - bool flushed; - -}; // class XsltOutputStream - - - -} // namespace IO -} // namespace Inkscape - - -#endif /* __INKSCAPE_IO_XSLTSTREAM_H__ */ -- cgit v1.2.3