summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2012-03-22 01:22:51 +0000
committerrandomdan <randomdan@localhost>2012-03-22 01:22:51 +0000
commit0278f4a8efb30d4688ce57101cdcf7db34596e46 (patch)
tree655ad8951f769ab229e058355011d3bcc4c64469
parentStream bug fix (diff)
downloadproject2-0278f4a8efb30d4688ce57101cdcf7db34596e46.tar.bz2
project2-0278f4a8efb30d4688ce57101cdcf7db34596e46.tar.xz
project2-0278f4a8efb30d4688ce57101cdcf7db34596e46.zip
A generic variadic template loader
A nocomp (pass through) stream decompressor A tidy up and plugin implementation for stream decompressors
-rw-r--r--project2/common/genericLoader.h27
-rw-r--r--project2/compression/decompressStream.cpp30
-rw-r--r--project2/compression/decompressor.h18
-rw-r--r--project2/compression/gzip.cpp53
-rw-r--r--project2/compression/nocomp.cpp14
-rw-r--r--project2/compression/z.cpp67
6 files changed, 142 insertions, 67 deletions
diff --git a/project2/common/genericLoader.h b/project2/common/genericLoader.h
new file mode 100644
index 0000000..cd129f0
--- /dev/null
+++ b/project2/common/genericLoader.h
@@ -0,0 +1,27 @@
+#ifndef GENERICLOADER_H
+#define GENERICLOADER_H
+
+#include "scriptLoader.h"
+
+template <class Impl, typename... Params>
+class GenLoader : public ComponentLoader {
+ public:
+ template <class T>
+ class For : public GenLoader<Impl, Params...> {
+ public:
+ inline Impl * create(const Params & ... p) const
+ {
+ return new T(p...);
+ }
+ };
+ virtual Impl * create(const Params & ...) const = 0;
+ inline static boost::shared_ptr<GenLoader<Impl, Params...>> getFor(const char * n)
+ {
+ return LoaderBase::getLoader<GenLoader<Impl, Params...>, NotSupported>(n);
+ }
+};
+#define DECLARE_GENERIC_LOADER(N, B, T) \
+ DECLARE_CUSTOM_COMPONENT_LOADER(N, T, B::For<T>, B);
+
+#endif
+
diff --git a/project2/compression/decompressStream.cpp b/project2/compression/decompressStream.cpp
new file mode 100644
index 0000000..eb32833
--- /dev/null
+++ b/project2/compression/decompressStream.cpp
@@ -0,0 +1,30 @@
+#include "stream.h"
+#include "scriptLoader.h"
+#include "decompressor.h"
+#include "scripts.h"
+#include "scopeObject.h"
+#include "scriptStorage.h"
+
+class DecompressStream : public Stream {
+ public:
+ DecompressStream(ScriptNodePtr p) :
+ Stream(p),
+ method(p, "method")
+ {
+ p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&stream));
+ }
+
+ void runStream(const Sink & sink) const
+ {
+ DecompressorPtr decomp = DecompressorLoader::getFor(method())->create();
+ stream->runStream([&](const char * data, size_t len) -> size_t {
+ decomp->decompress(data, len, sink);
+ return len;
+ });
+ }
+
+ StreamPtr stream;
+ const Variable method;
+};
+
+DECLARE_LOADER("decompstream", DecompressStream);
diff --git a/project2/compression/decompressor.h b/project2/compression/decompressor.h
new file mode 100644
index 0000000..dfa1db7
--- /dev/null
+++ b/project2/compression/decompressor.h
@@ -0,0 +1,18 @@
+#ifndef DECOMPRESSOR
+#define DECOMPRESSOR
+
+#include "stream.h"
+#include "genericLoader.h"
+#include "intrusivePtrBase.h"
+
+class Decompressor : public IntrusivePtrBase {
+ public:
+ virtual ~Decompressor()
+ {
+ }
+ virtual void decompress(const char * dataIn, size_t lengthIn, const Stream::Sink &) = 0;
+};
+typedef boost::intrusive_ptr<Decompressor> DecompressorPtr;
+typedef GenLoader<Decompressor> DecompressorLoader;
+
+#endif
diff --git a/project2/compression/gzip.cpp b/project2/compression/gzip.cpp
new file mode 100644
index 0000000..2bf0a8d
--- /dev/null
+++ b/project2/compression/gzip.cpp
@@ -0,0 +1,53 @@
+#include "stream.h"
+#include "scriptLoader.h"
+#include "decompressor.h"
+#include <zlib.h>
+
+class GZip : public Decompressor {
+ public:
+ GZip()
+ {
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ status = inflateInit2(&strm, 16+MAX_WBITS);
+ if (status != Z_OK)
+ throw std::runtime_error("inflateInit failed");
+ }
+ ~GZip()
+ {
+ inflateEnd(&strm);
+ if (status != Z_STREAM_END) {
+ throw std::runtime_error("decompression of stream failed");
+ }
+ }
+ void decompress(const char * data, size_t len, const Stream::Sink & sink)
+ {
+ unsigned char out[BUFSIZ];
+ strm.avail_in = len;
+ strm.next_in = (unsigned char *)data;
+ do {
+ strm.avail_out = BUFSIZ;
+ strm.next_out = out;
+ status = inflate(&strm, Z_NO_FLUSH);
+ assert(status != Z_STREAM_ERROR);
+ switch (status) {
+ case Z_NEED_DICT:
+ status = Z_DATA_ERROR;
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ throw std::runtime_error("inflate failed");
+ }
+ unsigned int have;
+ have = BUFSIZ - strm.avail_out;
+ sink(reinterpret_cast<const char *>(out), have);
+ } while (strm.avail_out == 0);
+ }
+ private:
+ z_stream strm;
+ int status;
+};
+DECLARE_GENERIC_LOADER("gz", DecompressorLoader, GZip);
+
diff --git a/project2/compression/nocomp.cpp b/project2/compression/nocomp.cpp
new file mode 100644
index 0000000..6861171
--- /dev/null
+++ b/project2/compression/nocomp.cpp
@@ -0,0 +1,14 @@
+#include "stream.h"
+#include "scriptLoader.h"
+#include "decompressor.h"
+
+class NoComp : public Decompressor {
+ public:
+ void decompress(const char * data, size_t len, const Stream::Sink & sink)
+ {
+ sink(data, len);
+ }
+};
+DECLARE_GENERIC_LOADER("nocomp", DecompressorLoader, NoComp);
+
+
diff --git a/project2/compression/z.cpp b/project2/compression/z.cpp
deleted file mode 100644
index 7d5d06b..0000000
--- a/project2/compression/z.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#include "stream.h"
-#include "scriptLoader.h"
-#include "scripts.h"
-#include "scopeObject.h"
-#include "scriptStorage.h"
-#include <zlib.h>
-
-class DecompressStream : public Stream {
- public:
- DecompressStream(ScriptNodePtr p) :
- Stream(p),
- method(p, "method")
- {
- p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&stream));
- }
-
- void runStream(const Sink & sink) const
- {
- unsigned have;
- z_stream strm;
- unsigned char out[BUFSIZ];
-
- /* allocate inflate state */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
- int ret = inflateInit2(&strm, 16+MAX_WBITS);
- if (ret != Z_OK)
- throw std::runtime_error("inflateInit failed");
- ScopeObject tidy([&]{ inflateEnd(&strm); });
-
- /* decompress until deflate stream ends or end of file */
- stream->runStream([&](const char * data, size_t len) -> size_t {
- strm.avail_in = len;
- strm.next_in = (unsigned char *)data;
-
- /* run inflate() on input until output buffer not full */
- do {
- strm.avail_out = BUFSIZ;
- strm.next_out = out;
- ret = inflate(&strm, Z_NO_FLUSH);
- assert(ret != Z_STREAM_ERROR); /* state not clobbered */
- switch (ret) {
- case Z_NEED_DICT:
- ret = Z_DATA_ERROR; /* and fall through */
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- throw std::runtime_error("inflate failed");
- }
- have = BUFSIZ - strm.avail_out;
- sink(reinterpret_cast<const char *>(out), have);
- } while (strm.avail_out == 0);
-
- return len; });
-
- if (ret != Z_STREAM_END) {
- throw std::runtime_error("decompression of stream failed");
- }
- }
-
- StreamPtr stream;
- const Variable method;
-};
-
-DECLARE_LOADER("decompstream", DecompressStream);