mspack_rb 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5ca23ebbd613db3fe80bd92522255ba960a7b039
4
- data.tar.gz: a9f7f8bb5d4be741d535d3c6c4b03ae2430c80d5
3
+ metadata.gz: 7344a42572aaac8736edceaa4b344f7ae61125bf
4
+ data.tar.gz: 05fcde6d525e3e7814212b00cd7987dcd8d7e94d
5
5
  SHA512:
6
- metadata.gz: 413f41de3155794d82dcfb7d0e4e5f58319cd4026f652dcaa333ea0b62a300008aa4f27e3edf8d428c3d0d83000becc008b602ad65d98206dc7ab89f6daea72c
7
- data.tar.gz: 91758d054375b7d19a7de6e6551b5627161e6eb14744858dbf73394f18b7255f115dfe47260ab20cf32312a984fcb1faf44e7e45f45714409fa75d710a79c955
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 mschm_decompressor *decom;
63
- Data_Get_Struct(self, struct mschm_decompressor, decom);
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 *decom) {
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 mschm_decompressor *decom = mspack_create_chm_decompressor(NULL);
95
- return Data_Wrap_Struct(self, NULL, chmd_deallocate, decom);
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 mschm_decompressor *decom;
108
- Data_Get_Struct(self, struct mschm_decompressor, decom);
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
- VALUE chmd_extract_to_path(VALUE self, VALUE file, VALUE outputPath) {
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
- Check_Type(outputPath, T_STRING);
147
+ if (argc == 1) {
148
+ rb_need_block();
123
149
 
124
- struct mschm_decompressor *decom;
125
- Data_Get_Struct(self, struct mschm_decompressor, decom);
150
+ VALUE block;
151
+ block = rb_block_proc();
126
152
 
127
- struct chmd_file_wrapper *wrapper;
128
- Data_Get_Struct(file, struct chmd_file_wrapper, wrapper);
129
- const char *pathStr = StringValueCStr(outputPath);
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 mschm_decompressor *decom;
137
- Data_Get_Struct(self, struct mschm_decompressor, decom);
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 mschm_decompressor *decom;
149
- Data_Get_Struct(self, struct mschm_decompressor, decom);
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
- decom->fast_find(decom, headerPtr, filenameStr, file, structSize);
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 *wrapper = malloc(sizeof(struct chmd_file_wrapper));
171
- wrapper->is_fast_find = 1;
172
- wrapper->file = file;
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, wrapper);
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, 2);
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
@@ -1,3 +1,3 @@
1
1
  module Mspack
2
- VERSION = "0.1.7"
2
+ VERSION = "0.2.0"
3
3
  end
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.1.7
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-21 00:00:00.000000000 Z
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