-
Notifications
You must be signed in to change notification settings - Fork 9
/
unzipper.h
99 lines (77 loc) · 2.24 KB
/
unzipper.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#ifndef UNZIPPER_H
#define UNZIPPER_H
#include <node.h>
#include <node_buffer.h>
#include "macros.h"
#define UNZ_BUFFER_FRAMES 1024
using namespace v8;
using namespace node;
namespace pcmutils {
class Unzipper;
class Unzipper : public ObjectWrap {
public:
static void Init(Handle<Object> exports);
protected:
Unzipper() : ObjectWrap(), channels(0), alignment(0), frameAlignment(0), unzipping(false) {
channelBuffers.Clear();
}
~Unzipper() {
channels = 0;
alignment = 0;
frameAlignment = 0;
unzipping = false;
channelBuffers.Dispose();
}
struct Baton {
uv_work_t request;
Unzipper* unz;
Baton(Unzipper* unz_) : unz(unz_) {
unz->Ref();
request.data = this;
}
virtual ~Baton() {
unz->Unref();
}
};
struct UnzipBaton : Baton {
Persistent<Function> callback;
Persistent<Object> chunk;
size_t chunkLength;
char* chunkData;
char** channelData;
int totalFrames;
int unzippedFrames;
UnzipBaton(Unzipper* unz_, Handle<Function> cb_, Handle<Object> chunk_) : Baton(unz_),
chunkLength(0), chunkData(NULL), channelData(NULL), totalFrames(0), unzippedFrames(0) {
callback = Persistent<Function>::New(cb_);
chunk = Persistent<Object>::New(chunk_);
chunkData = Buffer::Data(chunk);
chunkLength = Buffer::Length(chunk);
channelData = (char**)malloc(unz->channels * sizeof(char*));
for (int i = 0; i < unz->channels; i++) {
channelData[i] = Buffer::Data(unz->channelBuffers->Get(i)->ToObject());
}
totalFrames = chunkLength / unz->frameAlignment;
// Todo - check for and handle alignment issues
// int leftoverBytes = chunkLength % unz->frameAlignment;
// if (leftoverBytes != 0) fprintf(stderr, "LEFTOVRES: %d\n", leftoverBytes);
}
virtual ~UnzipBaton() {
callback.Dispose();
chunk.Dispose();
free(channelData);
}
};
static Handle<Value> New(const Arguments& args);
static Handle<Value> Unzip(const Arguments& args);
static void BeginUnzip(Baton* baton);
static void DoUnzip(uv_work_t* req);
static void AfterUnzip(uv_work_t* req);
Persistent<Array> channelBuffers;
int channels;
int alignment;
int frameAlignment;
bool unzipping;
};
}
#endif