mspack_rb 0.1.5 → 0.1.6

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: c69d841d0a58a91453d2b8ebd9f3a91030b67c64
4
- data.tar.gz: c087616dcf7d380e2c635f9e07d056b77c632c85
3
+ metadata.gz: 7f9c40d23c5867b56e2fa1b1960fd31309cfa799
4
+ data.tar.gz: 642ae95857d11d712c584a11b2f20ba0b2daeca3
5
5
  SHA512:
6
- metadata.gz: 86224b683f84c19b88445c65587d9cbca548a20e398b0681f1fb9fecf2d4467f4711abcb410b4c85cc4eec42895f28ba229425a4ff5d8a0052258be199385a03
7
- data.tar.gz: 67bba4649f8e0be72c7fbe2791e35c65f3ffcd8321d69564639ef358335e7a31363c0ce71fed9fe98ff1281ff6fbbc23f21b4d166a1bb2839b42b8f54774d7cc
6
+ metadata.gz: 508fd382485b88754746f25ff1bae5006a68306c5ced69a141e52c053470a2c89d6014cb8999f2ea7a261f5e9a535eb4cf5fffd40b46322ef013ca0bc7199f68
7
+ data.tar.gz: 64dd35882e4fa5fbfa80c147ad422ec30d83caf27d89df1ea130ec743d2e2bb02889b64287b9855375ebbda35851bf155f095b66b8dae948a10beb83b6ad564b
data/.gitignore CHANGED
@@ -1,10 +1,14 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
+ /.byebug_history
4
+
3
5
  /Gemfile.lock
4
6
  /_yardoc/
7
+
5
8
  /coverage/
6
9
  /doc/
7
10
  /pkg/
8
11
  /spec/reports/
9
12
  /tmp/
10
- /lib/mspack/mspack.bundle
13
+
14
+ /lib/mspack_native.bundle
data/README.md CHANGED
@@ -2,14 +2,24 @@
2
2
 
3
3
  ### A simple Ruby native extension gem wrapper for [libmspack](https://www.cabextract.org.uk/libmspack/)
4
4
 
5
- Requires libmspack to be installed, and currently, only basic CHM
6
- extraction has been implemented.
5
+ Requires libmspack to be installed, and currently, only CHM extraction has been
6
+ implemented.
7
7
 
8
8
  The gem is available over at [https://rubygems.org/gems/mspack_rb](https://rubygems.org/gems/mspack_rb).
9
9
 
10
10
  ### Usage:
11
11
  require 'mspack'
12
12
 
13
+ # Extract all files to disk
13
14
  dcom = Mspack::ChmDecompressor.new
14
15
  header = dcom.open('path/to/a/chm/file')
15
16
  header.each_file { |file| dcom.extract(file, out_path) }
17
+ dcom.close(header)
18
+
19
+ # Extract a specific file by name
20
+ fast_open_header = dcom.fast_open('path/to/a/chm/file')
21
+ file = dcom.fast_find(fast_open_header, '/index.html')
22
+ dcom.extract(file) unless file.nil?
23
+
24
+ # check last error
25
+ p 'w00t' if dcom.last_error == :ok
@@ -1,35 +1,109 @@
1
1
  #include "chm_decompressor.h"
2
+ #include "mspack_native.h"
3
+ #include "chm_decompressor_header.h"
4
+ #include "chm_decompressor_file.h"
2
5
 
3
6
  #include <mspack.h>
4
7
 
5
- VALUE ChmDecom = Qnil;
6
- VALUE ChmDHeader = Qnil;
7
- VALUE ChmDFile = Qnil;
8
+ /*
9
+ * utility methods
10
+ */
11
+
12
+ static inline VALUE _error_code_sym(int code) {
13
+ const char *str;
14
+
15
+ switch (code) {
16
+ case MSPACK_ERR_OK:
17
+ str = "ok";
18
+ break;
19
+ case MSPACK_ERR_ARGS:
20
+ str = "args";
21
+ break;
22
+ case MSPACK_ERR_OPEN:
23
+ str = "open";
24
+ break;
25
+ case MSPACK_ERR_READ:
26
+ str = "read";
27
+ break;
28
+ case MSPACK_ERR_WRITE:
29
+ str = "write";
30
+ break;
31
+ case MSPACK_ERR_SEEK:
32
+ str = "seek";
33
+ break;
34
+ case MSPACK_ERR_NOMEMORY:
35
+ str = "no_memory";
36
+ break;
37
+ case MSPACK_ERR_SIGNATURE:
38
+ str = "signature";
39
+ break;
40
+ case MSPACK_ERR_DATAFORMAT:
41
+ str = "data_format";
42
+ break;
43
+ case MSPACK_ERR_CHECKSUM:
44
+ str = "checksum";
45
+ break;
46
+ case MSPACK_ERR_CRUNCH:
47
+ str = "crunch";
48
+ break;
49
+ case MSPACK_ERR_DECRUNCH:
50
+ str = "decrunch";
51
+ break;
52
+ default:
53
+ str = "unknown";
54
+ }
8
55
 
9
- void chmd_deallocate(void *decom) {
10
- mspack_destroy_chm_decompressor(decom);
56
+ return ID2SYM(rb_intern(str));
11
57
  }
12
58
 
13
- VALUE chmd_allocate(VALUE self) {
14
- struct mschm_decompressor *decom = mspack_create_chm_decompressor(NULL);
15
- return Data_Wrap_Struct(self, NULL, chmd_deallocate, decom);
16
- }
59
+ static inline VALUE _open(VALUE self, VALUE path, int fast_bool) {
60
+ Check_Type(path, T_STRING);
17
61
 
18
- VALUE chmd_open(VALUE self, VALUE path) {
19
62
  struct mschm_decompressor *decom;
20
63
  Data_Get_Struct(self, struct mschm_decompressor, decom);
21
- struct mschmd_header *header = decom->open(decom, StringValueCStr(path));
64
+
65
+ struct mschmd_header *header;
66
+
67
+ if (fast_bool) {
68
+ header = decom->fast_open(decom, StringValueCStr(path));
69
+ }
70
+ else {
71
+ header = decom->open(decom, StringValueCStr(path));
72
+ }
22
73
 
23
74
  if (!header) {
24
75
  return Qnil;
25
76
  }
26
77
 
27
- VALUE headerObj = rb_obj_alloc(ChmDHeader);
28
- rb_obj_call_init(headerObj, 0, NULL);
29
- return Data_Wrap_Struct(ChmDHeader, NULL, NULL, header);
78
+ VALUE headerObj = Data_Wrap_Struct(ChmDHeader, NULL, NULL, header);
79
+ VALUE is_fast_open = fast_bool ? Qtrue : Qfalse;
80
+ rb_iv_set(headerObj, "is_fast_open", is_fast_open);
81
+
82
+ return headerObj;
83
+ }
84
+
85
+ /*
86
+ * decompressor
87
+ */
88
+
89
+ void chmd_deallocate(void *decom) {
90
+ mspack_destroy_chm_decompressor(decom);
91
+ }
92
+
93
+ 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);
96
+ }
97
+
98
+ VALUE chmd_open(VALUE self, VALUE path) {
99
+ return _open(self, path, 0);
30
100
  }
31
101
 
32
102
  VALUE chmd_close(VALUE self, VALUE header) {
103
+ if (!CLASS_OF(header) == ChmDHeader) {
104
+ rb_raise(rb_eTypeError, "Parameter must be a CHM decompression header");
105
+ }
106
+
33
107
  struct mschm_decompressor *decom;
34
108
  Data_Get_Struct(self, struct mschm_decompressor, decom);
35
109
 
@@ -41,50 +115,61 @@ VALUE chmd_close(VALUE self, VALUE header) {
41
115
  }
42
116
 
43
117
  VALUE chmd_extract_to_path(VALUE self, VALUE file, VALUE outputPath) {
118
+ if (!CLASS_OF(file) == ChmDFile) {
119
+ rb_raise(rb_eTypeError, "First parameter must be a CHM decompression file");
120
+ }
121
+
122
+ Check_Type(outputPath, T_STRING);
123
+
44
124
  struct mschm_decompressor *decom;
45
125
  Data_Get_Struct(self, struct mschm_decompressor, decom);
46
126
 
47
127
  struct mschmd_file *filePtr;
48
128
  Data_Get_Struct(file, struct mschmd_file, filePtr);
49
-
50
129
  const char *pathStr = StringValueCStr(outputPath);
51
- return decom->extract(decom, filePtr, pathStr) == MSPACK_ERR_OK ?
52
- Qtrue : Qfalse;
53
- }
54
130
 
55
- VALUE chmd_header_filename(VALUE self) {
56
- struct mschmd_header *header;
57
- Data_Get_Struct(self, struct mschmd_header, header);
58
- return rb_str_new2(header->filename);
131
+ int result = decom->extract(decom, filePtr, pathStr);
132
+ return result == MSPACK_ERR_OK ? Qtrue : Qfalse;
59
133
  }
60
134
 
61
- VALUE chmd_header_files(VALUE self) {
62
- struct mschmd_header *header;
63
- Data_Get_Struct(self, struct mschmd_header, header);
64
-
65
- VALUE fileObj = rb_obj_alloc(ChmDFile);
66
- rb_obj_call_init(fileObj, 0, NULL);
67
- return Data_Wrap_Struct(ChmDFile, NULL, NULL, header->files);
135
+ VALUE chmd_last_error(VALUE self) {
136
+ struct mschm_decompressor *decom;
137
+ Data_Get_Struct(self, struct mschm_decompressor, decom);
138
+
139
+ int error = decom->last_error(decom);
140
+ return _error_code_sym(error);
68
141
  }
69
142
 
70
- VALUE chmd_file_filename(VALUE self) {
71
- struct mschmd_file *file;
72
- Data_Get_Struct(self, struct mschmd_file, file);
73
- return rb_str_new2(file->filename);
143
+ VALUE chmd_fast_open(VALUE self, VALUE path) {
144
+ return _open(self, path, 1);
74
145
  }
75
146
 
76
- VALUE chmd_file_next(VALUE self) {
77
- struct mschmd_file *file;
78
- Data_Get_Struct(self, struct mschmd_file, file);
79
- struct mschmd_file *next = file->next;
147
+ VALUE chmd_fast_find(VALUE self, VALUE header, VALUE filename) {
148
+ struct mschm_decompressor *decom;
149
+ Data_Get_Struct(self, struct mschm_decompressor, decom);
150
+
151
+ struct mschmd_header *headerPtr;
152
+ Data_Get_Struct(header, struct mschmd_header, headerPtr);
153
+
154
+ const char *filenameStr = StringValueCStr(filename);
80
155
 
81
- if (next == NULL) {
156
+ int structSize = sizeof(struct mschmd_file);
157
+ struct mschmd_file *file = malloc(structSize);
158
+
159
+ int result =
160
+ decom->fast_find(decom, headerPtr, filenameStr, file, structSize);
161
+
162
+ if (result != MSPACK_ERR_OK || file->length == 0) {
163
+ free(file);
82
164
  return Qnil;
83
- }
165
+ }
84
166
 
85
- VALUE nextObj = rb_obj_alloc(ChmDFile);
86
- rb_obj_call_init(nextObj, 0, NULL);
87
- return Data_Wrap_Struct(ChmDFile, NULL, NULL, next);
167
+ file->filename = malloc(sizeof(char) * strlen(filenameStr) + 1);
168
+ strcpy(file->filename, filenameStr);
169
+
170
+ VALUE fileObj = Data_Wrap_Struct(ChmDFile, NULL, NULL, file);
171
+ rb_iv_set(fileObj, "is_fast_find", Qtrue);
172
+ return fileObj;
88
173
  }
89
174
 
90
175
  void Init_chm_decompressor() {
@@ -93,12 +178,7 @@ void Init_chm_decompressor() {
93
178
  rb_define_method(ChmDecom, "open", chmd_open, 1);
94
179
  rb_define_method(ChmDecom, "close", chmd_close, 1);
95
180
  rb_define_method(ChmDecom, "extract_to_path", chmd_extract_to_path, 2);
96
-
97
- ChmDHeader = rb_define_class_under(ChmDecom, "Header", rb_cObject);
98
- rb_define_method(ChmDHeader, "filename", chmd_header_filename, 0);
99
- rb_define_method(ChmDHeader, "files", chmd_header_files, 0);
100
-
101
- ChmDFile = rb_define_class_under(ChmDecom, "File", rb_cObject);
102
- rb_define_method(ChmDFile, "filename", chmd_file_filename, 0);
103
- rb_define_method(ChmDFile, "next", chmd_file_next, 0);
181
+ rb_define_method(ChmDecom, "last_error", chmd_last_error, 0);
182
+ rb_define_method(ChmDecom, "fast_open", chmd_fast_open, 1);
183
+ rb_define_method(ChmDecom, "fast_find", chmd_fast_find, 2);
104
184
  }
@@ -1,11 +1,7 @@
1
1
  #ifndef CHM_DECOMPRESSOR_H
2
2
  #define CHM_DECOMPRESSOR_H
3
3
 
4
- #include "mspack_native.h"
5
-
6
- extern VALUE ChmDecom;
7
- extern VALUE ChmDHeader;
8
- extern VALUE ChmDFile;
4
+ #include <ruby.h>
9
5
 
10
6
  void Init_chm_decompressor();
11
7
 
@@ -0,0 +1,52 @@
1
+ #include "chm_decompressor_file.h"
2
+ #include "mspack_native.h"
3
+
4
+ #include <mspack.h>
5
+
6
+ void chmd_file_free(void *ptr) {
7
+ struct mschmd_file *file = (struct mschmd_file *)ptr;
8
+
9
+ if (file->length == 0) { // only free if it was created in fast_find
10
+ //if (file->filename) {
11
+ // free(file->filename);
12
+ //}
13
+
14
+ free(file);
15
+ }
16
+ }
17
+
18
+ VALUE chmd_file_filename(VALUE self) {
19
+ struct mschmd_file *file;
20
+ Data_Get_Struct(self, struct mschmd_file, file);
21
+
22
+ if (!file->filename) {
23
+ return Qnil;
24
+ }
25
+
26
+ return rb_str_new2(file->filename);
27
+ }
28
+
29
+ VALUE chmd_file_next(VALUE self) {
30
+ struct mschmd_file *file;
31
+ Data_Get_Struct(self, struct mschmd_file, file);
32
+ struct mschmd_file *next = file->next;
33
+
34
+ if (!next) {
35
+ return Qnil;
36
+ }
37
+
38
+ VALUE nextObj = Data_Wrap_Struct(ChmDFile, NULL, chmd_file_free, next);
39
+ rb_iv_set(nextObj, "is_fast_find", Qfalse);
40
+ return nextObj;
41
+ }
42
+
43
+ VALUE chmd_file_is_fast_find(VALUE self) {
44
+ return rb_iv_get(self, "is_fast_find");
45
+ }
46
+
47
+ void Init_chm_decompressor_file() {
48
+ ChmDFile = rb_define_class_under(ChmDecom, "File", rb_cObject);
49
+ rb_define_method(ChmDFile, "filename", chmd_file_filename, 0);
50
+ rb_define_method(ChmDFile, "next", chmd_file_next, 0);
51
+ rb_define_method(ChmDFile, "fast_find?", chmd_file_is_fast_find, 0);
52
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef CHM_DECOMPRESSOR_FILE_H
2
+ #define CHM_DECOMPRESSOR_FILE_H
3
+
4
+ #include <ruby.h>
5
+
6
+ void Init_chm_decompressor_file();
7
+
8
+ #endif
@@ -0,0 +1,34 @@
1
+ #include "chm_decompressor_header.h"
2
+ #include "mspack_native.h"
3
+
4
+ #include <mspack.h>
5
+
6
+ VALUE chmd_header_filename(VALUE self) {
7
+ struct mschmd_header *header;
8
+ Data_Get_Struct(self, struct mschmd_header, header);
9
+ return rb_str_new2(header->filename);
10
+ }
11
+
12
+ VALUE chmd_header_files(VALUE self) {
13
+ struct mschmd_header *header;
14
+ Data_Get_Struct(self, struct mschmd_header, header);
15
+
16
+ if (!header->files) {
17
+ return Qnil;
18
+ }
19
+
20
+ VALUE file = Data_Wrap_Struct(ChmDFile, NULL, NULL, header->files);
21
+ rb_iv_set(file, "is_fast_find", Qfalse);
22
+ return file;
23
+ }
24
+
25
+ VALUE chmd_header_is_fast_open(VALUE self) {
26
+ return rb_iv_get(self, "is_fast_open");
27
+ }
28
+
29
+ void Init_chm_decompressor_header() {
30
+ ChmDHeader = rb_define_class_under(ChmDecom, "Header", rb_cObject);
31
+ rb_define_method(ChmDHeader, "filename", chmd_header_filename, 0);
32
+ rb_define_method(ChmDHeader, "files", chmd_header_files, 0);
33
+ rb_define_method(ChmDHeader, "fast_open?", chmd_header_is_fast_open, 0);
34
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef CHM_DECOMPRESSOR_HEADER_H
2
+ #define CHM_DECOMPRESSOR_HEADER_H
3
+
4
+ #include <ruby.h>
5
+
6
+ void Init_chm_decompressor_header();
7
+
8
+ #endif
@@ -1,9 +1,14 @@
1
1
  #include "mspack_native.h"
2
2
  #include "chm_decompressor.h"
3
+ #include "chm_decompressor_file.h"
4
+ #include "chm_decompressor_header.h"
3
5
 
4
6
  #include <mspack.h>
5
7
 
6
8
  VALUE Mspack = Qnil;
9
+ VALUE ChmDecom = Qnil;
10
+ VALUE ChmDHeader = Qnil;
11
+ VALUE ChmDFile = Qnil;
7
12
 
8
13
  VALUE mspack_test() {
9
14
  int result;
@@ -16,4 +21,6 @@ void Init_mspack_native() {
16
21
  rb_define_singleton_method(Mspack, "test", mspack_test, 0);
17
22
 
18
23
  Init_chm_decompressor();
24
+ Init_chm_decompressor_header();
25
+ Init_chm_decompressor_file();
19
26
  }
@@ -4,5 +4,8 @@
4
4
  #include <ruby.h>
5
5
 
6
6
  extern VALUE Mspack;
7
+ extern VALUE ChmDecom;
8
+ extern VALUE ChmDHeader;
9
+ extern VALUE ChmDFile;
7
10
 
8
11
  #endif
@@ -36,7 +36,6 @@ module Mspack
36
36
  index += 1
37
37
  end
38
38
  end
39
-
40
39
  end
41
40
 
42
41
 
@@ -1,3 +1,3 @@
1
1
  module Mspack
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
data/lib/mspack.rb CHANGED
@@ -12,6 +12,10 @@ module Mspack
12
12
  # Raises an error if the final, expanded path is outside of dir.
13
13
  # Returns the expanded file path.
14
14
  def self.ensure_path(filename, dir)
15
+ unless filename.is_a?(String) && dir.is_a?(String)
16
+ raise TypeError, 'both parameters must be strings'
17
+ end
18
+
15
19
  raise PathError, "#{dir} is not a directory" unless ::File.directory?(dir)
16
20
  raise PathError, "#{dir} is not writable" unless ::File.writable?(dir)
17
21
 
data/mspack.gemspec CHANGED
@@ -23,9 +23,13 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ["lib"]
24
24
  spec.extensions << 'ext/mspack_native/extconf.rb'
25
25
 
26
- spec.add_development_dependency "bundler", "~> 1.13"
27
- spec.add_development_dependency "rake", "~> 10.0"
28
- spec.add_development_dependency "rake-compiler", "~> 1.0"
29
- spec.add_development_dependency "rspec", "~> 3.0"
30
- spec.add_development_dependency "guard-rspec", "~> 4.7"
26
+ spec.add_development_dependency 'bundler', '~> 1.13'
27
+
28
+ spec.add_development_dependency 'rake', '~> 10.0'
29
+ spec.add_development_dependency 'rake-compiler', '~> 1.0'
30
+
31
+ spec.add_development_dependency 'rspec', '~> 3.0'
32
+ spec.add_development_dependency 'guard-rspec','~> 4.7'
33
+
34
+ spec.add_development_dependency 'byebug'
31
35
  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.5
4
+ version: 0.1.6
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-04 00:00:00.000000000 Z
11
+ date: 2017-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '4.7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description: A ruby gem wrapper for libmspack
84
98
  email:
85
99
  - 8enwilliams@gmail.com
@@ -99,13 +113,16 @@ files:
99
113
  - bin/setup
100
114
  - ext/mspack_native/chm_decompressor.c
101
115
  - ext/mspack_native/chm_decompressor.h
116
+ - ext/mspack_native/chm_decompressor_file.c
117
+ - ext/mspack_native/chm_decompressor_file.h
118
+ - ext/mspack_native/chm_decompressor_header.c
119
+ - ext/mspack_native/chm_decompressor_header.h
102
120
  - ext/mspack_native/extconf.rb
103
121
  - ext/mspack_native/mspack_native.c
104
122
  - ext/mspack_native/mspack_native.h
105
123
  - lib/mspack.rb
106
124
  - lib/mspack/chm_decompressor.rb
107
125
  - lib/mspack/version.rb
108
- - lib/mspack_native.bundle
109
126
  - mspack.gemspec
110
127
  homepage: https://github.com/benjineering/mspack_rb
111
128
  licenses:
Binary file