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 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