mspack_rb 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/mspack_native/chm_decompressor.c +71 -31
- data/ext/mspack_native/chm_decompressor_file.c +8 -0
- data/ext/mspack_native/io_system.c +176 -0
- data/ext/mspack_native/io_system.h +33 -0
- data/lib/mspack/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7344a42572aaac8736edceaa4b344f7ae61125bf
|
4
|
+
data.tar.gz: 05fcde6d525e3e7814212b00cd7987dcd8d7e94d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e43ac5361052d84ec4d166c202022dfd4938c95595856e1b8215ca3e29dd69541e3e266e6bcd58db7c4e0a908cd29a84bc523d633c3396fa496fb126fea49aa2
|
7
|
+
data.tar.gz: c47aa65dc8dba1e5a632090d1f1c9e6a9358bca907ea36899df79b594380ae5c72315ca8ff7152decdaf3989777a88b0f0fa95511df70f639af660d76d9a8743
|
@@ -1,10 +1,19 @@
|
|
1
1
|
#include "chm_decompressor.h"
|
2
|
+
|
2
3
|
#include "mspack_native.h"
|
4
|
+
|
3
5
|
#include "chm_decompressor_header.h"
|
4
6
|
#include "chm_decompressor_file.h"
|
5
7
|
|
8
|
+
#include "io_system.h"
|
9
|
+
|
6
10
|
#include <mspack.h>
|
7
11
|
|
12
|
+
struct decom_wrapper {
|
13
|
+
struct mschm_decompressor *decom;
|
14
|
+
struct mspack_system *system;
|
15
|
+
};
|
16
|
+
|
8
17
|
/*
|
9
18
|
* utility methods
|
10
19
|
*/
|
@@ -59,16 +68,16 @@ static inline VALUE _error_code_sym(int code) {
|
|
59
68
|
static inline VALUE _open(VALUE self, VALUE path, int fast_bool) {
|
60
69
|
Check_Type(path, T_STRING);
|
61
70
|
|
62
|
-
struct
|
63
|
-
Data_Get_Struct(self, struct
|
71
|
+
struct decom_wrapper *wrapper;
|
72
|
+
Data_Get_Struct(self, struct decom_wrapper, wrapper);
|
64
73
|
|
65
74
|
struct mschmd_header *header;
|
66
75
|
|
67
76
|
if (fast_bool) {
|
68
|
-
header = decom->fast_open(decom, StringValueCStr(path));
|
77
|
+
header = wrapper->decom->fast_open(wrapper->decom, StringValueCStr(path));
|
69
78
|
}
|
70
79
|
else {
|
71
|
-
header = decom->open(decom, StringValueCStr(path));
|
80
|
+
header = wrapper->decom->open(wrapper->decom, StringValueCStr(path));
|
72
81
|
}
|
73
82
|
|
74
83
|
if (!header) {
|
@@ -86,13 +95,17 @@ static inline VALUE _open(VALUE self, VALUE path, int fast_bool) {
|
|
86
95
|
* decompressor
|
87
96
|
*/
|
88
97
|
|
89
|
-
void chmd_deallocate(void *
|
90
|
-
mspack_destroy_chm_decompressor(decom);
|
98
|
+
void chmd_deallocate(void *wrapper) {
|
99
|
+
mspack_destroy_chm_decompressor(((struct decom_wrapper *)wrapper)->decom);
|
100
|
+
free(((struct decom_wrapper *)wrapper)->system);
|
101
|
+
free((struct decom_wrapper *)wrapper);
|
91
102
|
}
|
92
103
|
|
93
104
|
VALUE chmd_allocate(VALUE self) {
|
94
|
-
struct
|
95
|
-
|
105
|
+
struct decom_wrapper *wrapper = malloc(sizeof(struct decom_wrapper));
|
106
|
+
wrapper->system = io_system();
|
107
|
+
wrapper->decom = mspack_create_chm_decompressor(wrapper->system);
|
108
|
+
return Data_Wrap_Struct(self, NULL, chmd_deallocate, wrapper);
|
96
109
|
}
|
97
110
|
|
98
111
|
VALUE chmd_open(VALUE self, VALUE path) {
|
@@ -104,39 +117,65 @@ VALUE chmd_close(VALUE self, VALUE header) {
|
|
104
117
|
rb_raise(rb_eTypeError, "Parameter must be a CHM decompression header");
|
105
118
|
}
|
106
119
|
|
107
|
-
struct
|
108
|
-
Data_Get_Struct(self, struct
|
120
|
+
struct decom_wrapper *wrapper;
|
121
|
+
Data_Get_Struct(self, struct decom_wrapper, wrapper);
|
109
122
|
|
110
123
|
struct mschmd_header *headerPtr;
|
111
124
|
Data_Get_Struct(header, struct mschmd_header, headerPtr);
|
112
125
|
|
113
|
-
decom->close(decom, headerPtr);
|
126
|
+
wrapper->decom->close(wrapper->decom, headerPtr);
|
114
127
|
return Qnil;
|
115
128
|
}
|
116
129
|
|
117
|
-
|
130
|
+
/*
|
131
|
+
* Form 1:
|
132
|
+
* extract_to_path(file, outputPath)
|
133
|
+
*
|
134
|
+
* Form 2:
|
135
|
+
* extract_to_path(file) { |data_chunk| do_something(data_chunk) }
|
136
|
+
*/
|
137
|
+
VALUE chmd_extract_to_path(int argc, VALUE* argv, VALUE self) {
|
138
|
+
VALUE file;
|
139
|
+
VALUE outputPath;
|
140
|
+
rb_scan_args(argc, argv, "11", &file, &outputPath);
|
141
|
+
const char *pathStr;
|
142
|
+
|
118
143
|
if (!CLASS_OF(file) == ChmDFile) {
|
119
144
|
rb_raise(rb_eTypeError, "First parameter must be a CHM decompression file");
|
120
145
|
}
|
121
146
|
|
122
|
-
|
147
|
+
if (argc == 1) {
|
148
|
+
rb_need_block();
|
123
149
|
|
124
|
-
|
125
|
-
|
150
|
+
VALUE block;
|
151
|
+
block = rb_block_proc();
|
126
152
|
|
127
|
-
|
128
|
-
|
129
|
-
|
153
|
+
VALUE blockName = rb_funcall(block, rb_intern("to_s"), 0);
|
154
|
+
pathStr = StringValueCStr(blockName);
|
155
|
+
add_block(&blockName, &block);
|
156
|
+
}
|
157
|
+
else {
|
158
|
+
Check_Type(outputPath, T_STRING);
|
159
|
+
pathStr = StringValueCStr(outputPath);
|
160
|
+
}
|
161
|
+
|
162
|
+
struct decom_wrapper *wrapper;
|
163
|
+
Data_Get_Struct(self, struct decom_wrapper, wrapper);
|
164
|
+
|
165
|
+
struct chmd_file_wrapper *headerWrapper;
|
166
|
+
Data_Get_Struct(file, struct chmd_file_wrapper, headerWrapper);
|
167
|
+
|
168
|
+
int result =
|
169
|
+
wrapper->decom->extract(wrapper->decom, headerWrapper->file, pathStr);
|
130
170
|
|
131
|
-
int result = decom->extract(decom, wrapper->file, pathStr);
|
132
171
|
return result == MSPACK_ERR_OK ? Qtrue : Qfalse;
|
133
172
|
}
|
134
173
|
|
135
174
|
VALUE chmd_last_error(VALUE self) {
|
136
|
-
struct
|
137
|
-
Data_Get_Struct(self, struct
|
175
|
+
struct decom_wrapper *wrapper;
|
176
|
+
Data_Get_Struct(self, struct decom_wrapper, wrapper);
|
138
177
|
|
139
|
-
int error = decom->last_error(decom);
|
178
|
+
int error = wrapper->decom->last_error(wrapper->decom);
|
140
179
|
return _error_code_sym(error);
|
141
180
|
}
|
142
181
|
|
@@ -145,8 +184,8 @@ VALUE chmd_fast_open(VALUE self, VALUE path) {
|
|
145
184
|
}
|
146
185
|
|
147
186
|
VALUE chmd_fast_find(VALUE self, VALUE header, VALUE filename) {
|
148
|
-
struct
|
149
|
-
Data_Get_Struct(self, struct
|
187
|
+
struct decom_wrapper *wrapper;
|
188
|
+
Data_Get_Struct(self, struct decom_wrapper, wrapper);
|
150
189
|
|
151
190
|
struct mschmd_header *headerPtr;
|
152
191
|
Data_Get_Struct(header, struct mschmd_header, headerPtr);
|
@@ -156,8 +195,8 @@ VALUE chmd_fast_find(VALUE self, VALUE header, VALUE filename) {
|
|
156
195
|
int structSize = sizeof(struct mschmd_file);
|
157
196
|
struct mschmd_file *file = malloc(structSize);
|
158
197
|
|
159
|
-
int result =
|
160
|
-
|
198
|
+
int result = wrapper->decom->fast_find(
|
199
|
+
wrapper->decom, headerPtr, filenameStr, file, structSize);
|
161
200
|
|
162
201
|
if (result != MSPACK_ERR_OK || file->length == 0) {
|
163
202
|
free(file);
|
@@ -167,11 +206,12 @@ VALUE chmd_fast_find(VALUE self, VALUE header, VALUE filename) {
|
|
167
206
|
file->filename = malloc(sizeof(char) * strlen(filenameStr) + 1);
|
168
207
|
strcpy(file->filename, filenameStr);
|
169
208
|
|
170
|
-
struct chmd_file_wrapper *
|
171
|
-
|
172
|
-
|
209
|
+
struct chmd_file_wrapper *fileWrapper =
|
210
|
+
malloc(sizeof(struct chmd_file_wrapper));
|
211
|
+
fileWrapper->is_fast_find = 1;
|
212
|
+
fileWrapper->file = file;
|
173
213
|
|
174
|
-
return Data_Wrap_Struct(ChmDFile, NULL, chmd_file_free,
|
214
|
+
return Data_Wrap_Struct(ChmDFile, NULL, chmd_file_free, fileWrapper);
|
175
215
|
}
|
176
216
|
|
177
217
|
void Init_chm_decompressor() {
|
@@ -179,7 +219,7 @@ void Init_chm_decompressor() {
|
|
179
219
|
rb_define_alloc_func(ChmDecom, chmd_allocate);
|
180
220
|
rb_define_method(ChmDecom, "open", chmd_open, 1);
|
181
221
|
rb_define_method(ChmDecom, "close", chmd_close, 1);
|
182
|
-
rb_define_method(ChmDecom, "extract_to_path", chmd_extract_to_path,
|
222
|
+
rb_define_method(ChmDecom, "extract_to_path", chmd_extract_to_path, -1);
|
183
223
|
rb_define_method(ChmDecom, "last_error", chmd_last_error, 0);
|
184
224
|
rb_define_method(ChmDecom, "fast_open", chmd_fast_open, 1);
|
185
225
|
rb_define_method(ChmDecom, "fast_find", chmd_fast_find, 2);
|
@@ -39,12 +39,19 @@ VALUE chmd_file_next(VALUE self) {
|
|
39
39
|
|
40
40
|
struct chmd_file_wrapper *next_wrapper =
|
41
41
|
malloc(sizeof(struct chmd_file_wrapper));
|
42
|
+
|
42
43
|
next_wrapper->is_fast_find = 0;
|
43
44
|
next_wrapper->file = next;
|
44
45
|
|
45
46
|
return Data_Wrap_Struct(ChmDFile, NULL, chmd_file_free, next_wrapper);
|
46
47
|
}
|
47
48
|
|
49
|
+
VALUE chmd_file_length(VALUE self) {
|
50
|
+
struct chmd_file_wrapper *wrapper;
|
51
|
+
Data_Get_Struct(self, struct chmd_file_wrapper, wrapper);
|
52
|
+
return LONG2FIX(wrapper->file->length);
|
53
|
+
}
|
54
|
+
|
48
55
|
VALUE chmd_file_is_fast_find(VALUE self) {
|
49
56
|
struct chmd_file_wrapper *wrapper;
|
50
57
|
Data_Get_Struct(self, struct chmd_file_wrapper, wrapper);
|
@@ -55,5 +62,6 @@ void Init_chm_decompressor_file() {
|
|
55
62
|
ChmDFile = rb_define_class_under(ChmDecom, "File", rb_cObject);
|
56
63
|
rb_define_method(ChmDFile, "filename", chmd_file_filename, 0);
|
57
64
|
rb_define_method(ChmDFile, "next", chmd_file_next, 0);
|
65
|
+
rb_define_method(ChmDFile, "length", chmd_file_length, 0);
|
58
66
|
rb_define_method(ChmDFile, "fast_find?", chmd_file_is_fast_find, 0);
|
59
67
|
}
|
@@ -0,0 +1,176 @@
|
|
1
|
+
#include "io_system.h"
|
2
|
+
#include "chm_decompressor.h"
|
3
|
+
|
4
|
+
#include <stdarg.h>
|
5
|
+
#include <stdio.h>
|
6
|
+
#include <string.h>
|
7
|
+
|
8
|
+
#define IO_SYSTEM_MAX_BLOCKS 5
|
9
|
+
|
10
|
+
union io_file_value {
|
11
|
+
FILE *file;
|
12
|
+
VALUE *block;
|
13
|
+
};
|
14
|
+
|
15
|
+
struct io_file {
|
16
|
+
char *name; // only used for block handle
|
17
|
+
union io_file_value value;
|
18
|
+
};
|
19
|
+
|
20
|
+
struct io_file *blocks[IO_SYSTEM_MAX_BLOCKS];
|
21
|
+
|
22
|
+
inline struct io_file *pop_block(const char *name) {
|
23
|
+
for (int i = 0; i < IO_SYSTEM_MAX_BLOCKS - 1; ++i) {
|
24
|
+
struct io_file *block = blocks[i];
|
25
|
+
|
26
|
+
if (block) {
|
27
|
+
if (strcmp(name, block->name) == 0) {
|
28
|
+
blocks[i] = NULL;
|
29
|
+
return block;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
return NULL;
|
35
|
+
}
|
36
|
+
|
37
|
+
struct mspack_file *
|
38
|
+
io_open(struct mspack_system *self, const char *filename, int mode) {
|
39
|
+
struct io_file *block = NULL;
|
40
|
+
|
41
|
+
if (mode != MSPACK_SYS_OPEN_READ) {
|
42
|
+
block = pop_block(filename);
|
43
|
+
}
|
44
|
+
|
45
|
+
if (block) {
|
46
|
+
return (struct mspack_file *)block;
|
47
|
+
}
|
48
|
+
else {
|
49
|
+
const char *modeStr;
|
50
|
+
|
51
|
+
switch (mode) {
|
52
|
+
case MSPACK_SYS_OPEN_READ:
|
53
|
+
modeStr = "r";
|
54
|
+
break;
|
55
|
+
case MSPACK_SYS_OPEN_WRITE:
|
56
|
+
modeStr = "w";
|
57
|
+
break;
|
58
|
+
case MSPACK_SYS_OPEN_UPDATE:
|
59
|
+
modeStr = "w+";
|
60
|
+
break;
|
61
|
+
case MSPACK_SYS_OPEN_APPEND:
|
62
|
+
modeStr = "a+";
|
63
|
+
break;
|
64
|
+
default:
|
65
|
+
return NULL;
|
66
|
+
}
|
67
|
+
|
68
|
+
struct io_file *file = malloc(sizeof(struct io_file));
|
69
|
+
file->value.file = fopen(filename, modeStr);
|
70
|
+
file->name = NULL;
|
71
|
+
|
72
|
+
if (file->value.file) {
|
73
|
+
return (struct mspack_file *)file;
|
74
|
+
}
|
75
|
+
else {
|
76
|
+
free(file);
|
77
|
+
return NULL;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
void io_close(struct mspack_file *file) {
|
83
|
+
if (!((struct io_file *)file)->name) {
|
84
|
+
fclose(((struct io_file *)file)->value.file);
|
85
|
+
}
|
86
|
+
else {
|
87
|
+
free(((struct io_file *)file)->name);
|
88
|
+
}
|
89
|
+
|
90
|
+
free(file);
|
91
|
+
}
|
92
|
+
|
93
|
+
int io_read(struct mspack_file *file, void *buffer, int bytes) {
|
94
|
+
return (int)fread(buffer, 1, bytes, ((struct io_file *)file)->value.file);
|
95
|
+
}
|
96
|
+
|
97
|
+
int io_write(struct mspack_file *file, void *buffer, int bytes) {
|
98
|
+
if (!((struct io_file *)file)->name) {
|
99
|
+
return (int)fwrite(buffer, 1, bytes, ((struct io_file *)file)->value.file);
|
100
|
+
}
|
101
|
+
else {
|
102
|
+
VALUE fixnum;
|
103
|
+
int *intBuffer = buffer;
|
104
|
+
VALUE data = rb_ary_new2(bytes);
|
105
|
+
|
106
|
+
for (int i = 0; i < bytes; ++i) {
|
107
|
+
fixnum = LONG2FIX(intBuffer[i]);
|
108
|
+
rb_ary_push(data, fixnum);
|
109
|
+
}
|
110
|
+
|
111
|
+
VALUE *block;
|
112
|
+
block = ((struct io_file *)file)->value.block;
|
113
|
+
rb_funcall(*block, rb_intern("yield"), 1, data);
|
114
|
+
return bytes;
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
int io_seek(struct mspack_file *file, off_t offset, int mode) {
|
119
|
+
return fseek(((struct io_file *)file)->value.file, offset, mode);
|
120
|
+
}
|
121
|
+
|
122
|
+
off_t io_tell(struct mspack_file *file) {
|
123
|
+
return ftell(((struct io_file *)file)->value.file);
|
124
|
+
}
|
125
|
+
|
126
|
+
void io_message(struct mspack_file *file, const char *format, ...) {
|
127
|
+
va_list args;
|
128
|
+
va_start(args, format);
|
129
|
+
vprintf(format, args);
|
130
|
+
va_end(args);
|
131
|
+
}
|
132
|
+
|
133
|
+
void *io_alloc(struct mspack_system *self, size_t bytes) {
|
134
|
+
return malloc(bytes);
|
135
|
+
}
|
136
|
+
|
137
|
+
void io_free(void *ptr) {
|
138
|
+
free(ptr);
|
139
|
+
}
|
140
|
+
|
141
|
+
void io_copy(void *src, void *dest, size_t bytes) {
|
142
|
+
memcpy(dest, src, bytes);
|
143
|
+
}
|
144
|
+
|
145
|
+
struct mspack_system *io_system() {
|
146
|
+
struct mspack_system *system = malloc(sizeof(struct mspack_system));
|
147
|
+
system->open = io_open;
|
148
|
+
system->close = io_close;
|
149
|
+
system->read = io_read;
|
150
|
+
system->write = io_write;
|
151
|
+
system->seek = io_seek;
|
152
|
+
system->tell = io_tell;
|
153
|
+
system->message = io_message;
|
154
|
+
system->alloc = io_alloc;
|
155
|
+
system->free = io_free;
|
156
|
+
system->copy = io_copy;
|
157
|
+
system->null_ptr = NULL;
|
158
|
+
return system;
|
159
|
+
}
|
160
|
+
|
161
|
+
// TODO: chuck an error if we're full
|
162
|
+
void add_block(VALUE *name, VALUE *block) {
|
163
|
+
for (int i = 0; i < IO_SYSTEM_MAX_BLOCKS - 1; ++i) {
|
164
|
+
|
165
|
+
if (!blocks[i]) {
|
166
|
+
struct io_file *file = malloc(sizeof(struct io_file));
|
167
|
+
file->value.block = block;
|
168
|
+
|
169
|
+
const char *nameStr = StringValueCStr(*name);
|
170
|
+
file->name = malloc(sizeof(char) * strlen(nameStr) + 1);
|
171
|
+
strcpy(file->name, nameStr);
|
172
|
+
|
173
|
+
blocks[i] = file;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#ifndef IO_SYSTEM_H
|
2
|
+
#define IO_SYSTEM_H
|
3
|
+
|
4
|
+
#include <mspack.h>
|
5
|
+
#include <ruby.h>
|
6
|
+
|
7
|
+
struct mspack_file *
|
8
|
+
io_open(struct mspack_system *self, const char *filename, int mode);
|
9
|
+
|
10
|
+
void io_close(struct mspack_file *file);
|
11
|
+
|
12
|
+
int io_read(struct mspack_file *file, void *buffer, int bytes);
|
13
|
+
|
14
|
+
int io_write(struct mspack_file *file, void *buffer, int bytes);
|
15
|
+
|
16
|
+
int io_seek(struct mspack_file *file, off_t offset, int mode);
|
17
|
+
|
18
|
+
off_t io_tell(struct mspack_file *file);
|
19
|
+
|
20
|
+
void io_message(struct mspack_file *file, const char *format, ...);
|
21
|
+
|
22
|
+
void *io_alloc(struct mspack_system *self, size_t bytes);
|
23
|
+
|
24
|
+
void io_free(void *ptr);
|
25
|
+
|
26
|
+
void io_copy(void *src, void *dest, size_t bytes);
|
27
|
+
|
28
|
+
|
29
|
+
struct mspack_system *io_system();
|
30
|
+
|
31
|
+
void add_block(VALUE *name, VALUE *block);
|
32
|
+
|
33
|
+
#endif
|
data/lib/mspack/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mspack_rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -118,6 +118,8 @@ files:
|
|
118
118
|
- ext/mspack_native/chm_decompressor_header.c
|
119
119
|
- ext/mspack_native/chm_decompressor_header.h
|
120
120
|
- ext/mspack_native/extconf.rb
|
121
|
+
- ext/mspack_native/io_system.c
|
122
|
+
- ext/mspack_native/io_system.h
|
121
123
|
- ext/mspack_native/mspack_native.c
|
122
124
|
- ext/mspack_native/mspack_native.h
|
123
125
|
- lib/mspack.rb
|