web-deploy/node_modules/zlib/src/node-zlib.cc

96 lines
4.5 KiB
C++

#include <v8.h>
#include <node.h>
#include <node_buffer.h>
#include <node_version.h>
#include <zlib.h>
#include <cstring>
#include <cstdlib>
using namespace v8;
using namespace node;
// node v0.2.x compatibility
#if NODE_VERSION_AT_LEAST(0,3,0)
#define Buffer_Data Buffer::Data
#define Buffer_Length Buffer::Length
#define Buffer_New Buffer::New
#else
inline char* Buffer_Data(Handle<Object> obj) {
return (ObjectWrap::Unwrap<Buffer>(obj))->data();
}
inline size_t Buffer_Length(Handle<Object> obj) {
return (ObjectWrap::Unwrap<Buffer>(obj))->length();
}
inline Buffer* Buffer_New(char* data, size_t length) {
Buffer* buffer = Buffer::New(length);
memcpy(buffer->data(), data, length);
return buffer;
}
#endif
z_stream deflate_s;
z_stream inflate_s;
inline Handle<Value> ZLib_error(const char* msg = NULL) {
return ThrowException(Exception::Error(
String::New(msg ? msg : "Unknown Error")));
}
#define ZLib_Xflate(x, factor) \
Handle<Value> ZLib_##x##flate(const Arguments& args) { \
HandleScope scope; \
\
if (args.Length() < 1 || !Buffer::HasInstance(args[0])) { \
return ZLib_error("Expected Buffer as first argument"); \
} \
\
if ((x##flateReset(&x##flate_s)) != Z_OK) { \
assert((false, "ZLib stream is beyond repair")); \
} \
\
Local<Object> input = args[0]->ToObject(); \
x##flate_s.next_in = (Bytef*)Buffer_Data(input); \
int length = x##flate_s.avail_in = Buffer_Length(input); \
\
int ret; \
char* result = NULL; \
\
int compressed = 0; \
do { \
result = (char*)realloc(result, compressed + factor * length); \
if (!result) return ZLib_error("Could not allocate memory"); \
\
x##flate_s.avail_out = factor * length; \
x##flate_s.next_out = (Bytef*)result + compressed; \
\
ret = x##flate(&x##flate_s, Z_FINISH); \
if (ret != Z_STREAM_END && ret != Z_OK && ret != Z_BUF_ERROR) { \
free(result); \
return ZLib_error(x##flate_s.msg); \
} \
\
compressed += (factor * length - x##flate_s.avail_out); \
} while (x##flate_s.avail_out == 0); \
\
Buffer* output = Buffer_New(result, compressed); \
free(result); \
return scope.Close(Local<Value>::New(output->handle_)); \
}
ZLib_Xflate(de, 1);
ZLib_Xflate(in, 2);
extern "C" void init (Handle<Object> target) {
deflate_s.zalloc = inflate_s.zalloc = Z_NULL;
deflate_s.zfree = inflate_s.zfree = Z_NULL;
deflate_s.opaque = inflate_s.opaque = Z_NULL;
deflateInit(&deflate_s, Z_DEFAULT_COMPRESSION);
inflateInit(&inflate_s);
NODE_SET_METHOD(target, "deflate", ZLib_deflate);
NODE_SET_METHOD(target, "inflate", ZLib_inflate);
}