xcellus 1.4 → 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/bin/libxcbindings-darwin-amd64.so +0 -0
- data/bin/libxcbindings-linux-amd64.so +0 -0
- data/bin/libxcbindings.h +50 -0
- data/ext/xcellus_bin/xcellus_bin.c +111 -14
- data/lib/xcellus.rb +120 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bac93b8471393ce3d5e92154698d54864149a4d8
|
4
|
+
data.tar.gz: ef401569deab2ef3820e55ea65680ee8bfd1682a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5de44ea299ba6910ef178e2b48a35b8368247afb43ad6334a7aa22f31c0409785c0ed0943f7b93b07972d55ceb20e34325a9620b9e52a45ce7754dc3c381386
|
7
|
+
data.tar.gz: 5a7c6ef8f8a30b53141a151c8a32320c355929aac12d19d6885e085bfcbc64b9254ac1d59ad12dc30c1442b357e20e052a0c3f98c8e5ec5b20340f6b79eb38b0
|
Binary file
|
Binary file
|
data/bin/libxcbindings.h
CHANGED
@@ -80,6 +80,56 @@ struct go_xcellus_process_return {
|
|
80
80
|
|
81
81
|
extern struct go_xcellus_process_return go_xcellus_process(char* p0);
|
82
82
|
|
83
|
+
/* Return type for go_xcellus_load */
|
84
|
+
struct go_xcellus_load_return {
|
85
|
+
GoUint8 r0; /* failed */
|
86
|
+
char* r1; /* err */
|
87
|
+
char* r2; /* handle */
|
88
|
+
};
|
89
|
+
|
90
|
+
extern struct go_xcellus_load_return go_xcellus_load(char* p0);
|
91
|
+
|
92
|
+
/* Return type for go_xcellus_append */
|
93
|
+
struct go_xcellus_append_return {
|
94
|
+
GoUint8 r0; /* failed */
|
95
|
+
char* r1; /* err */
|
96
|
+
};
|
97
|
+
|
98
|
+
extern struct go_xcellus_append_return go_xcellus_append(char* p0, char* p1);
|
99
|
+
|
100
|
+
/* Return type for go_xcellus_save */
|
101
|
+
struct go_xcellus_save_return {
|
102
|
+
GoUint8 r0; /* failed */
|
103
|
+
char* r1; /* err */
|
104
|
+
};
|
105
|
+
|
106
|
+
extern struct go_xcellus_save_return go_xcellus_save(char* p0, char* p1);
|
107
|
+
|
108
|
+
/* Return type for go_xcellus_end */
|
109
|
+
struct go_xcellus_end_return {
|
110
|
+
GoUint8 r0; /* failed */
|
111
|
+
char* r1; /* err */
|
112
|
+
};
|
113
|
+
|
114
|
+
extern struct go_xcellus_end_return go_xcellus_end(char* p0);
|
115
|
+
|
116
|
+
/* Return type for go_xcellus_find_in_column */
|
117
|
+
struct go_xcellus_find_in_column_return {
|
118
|
+
GoUint8 r0; /* failed */
|
119
|
+
char* r1; /* err */
|
120
|
+
GoInt r2; /* idxResult */
|
121
|
+
};
|
122
|
+
|
123
|
+
extern struct go_xcellus_find_in_column_return go_xcellus_find_in_column(char* p0, char* p1, char* p2, GoInt p3);
|
124
|
+
|
125
|
+
/* Return type for go_xcellus_replace_row */
|
126
|
+
struct go_xcellus_replace_row_return {
|
127
|
+
GoUint8 r0; /* failed */
|
128
|
+
char* r1; /* err */
|
129
|
+
};
|
130
|
+
|
131
|
+
extern struct go_xcellus_replace_row_return go_xcellus_replace_row(char* p0, char* p1, char* p2, GoInt p3);
|
132
|
+
|
83
133
|
#ifdef __cplusplus
|
84
134
|
}
|
85
135
|
#endif
|
@@ -2,25 +2,122 @@
|
|
2
2
|
#include <ruby.h>
|
3
3
|
#include "../../bin/libxcbindings.h"
|
4
4
|
|
5
|
-
VALUE
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
5
|
+
VALUE rb_xcellus_transform(VALUE self, VALUE str) {
|
6
|
+
if (RB_TYPE_P(str, T_STRING) == 0) return Qnil;
|
7
|
+
struct go_xcellus_process_return result = go_xcellus_process(RSTRING_PTR(str));
|
8
|
+
bool failed = result.r0 == 1;
|
9
|
+
char *error_description = result.r1;
|
10
|
+
GoInt buffer_len = result.r2;
|
11
|
+
char *buffer = result.r3;
|
12
|
+
if(failed) {
|
13
|
+
VALUE errObj = rb_exc_new2(rb_eStandardError, error_description);
|
14
|
+
free(error_description);
|
15
|
+
rb_exc_raise(errObj);
|
16
|
+
}
|
17
17
|
|
18
18
|
VALUE retval = rb_str_new(buffer, buffer_len);
|
19
19
|
free(buffer);
|
20
20
|
return retval;
|
21
21
|
}
|
22
22
|
|
23
|
+
VALUE rb_xcellus_load(VALUE self, VALUE path) {
|
24
|
+
if (RB_TYPE_P(path, T_STRING) == 0) return Qnil;
|
25
|
+
struct go_xcellus_load_return result = go_xcellus_load(RSTRING_PTR(path));
|
26
|
+
bool failed = result.r0 == 1;
|
27
|
+
char *error_description = result.r1;
|
28
|
+
char *handle = result.r2;
|
29
|
+
if(failed) {
|
30
|
+
VALUE errObj = rb_exc_new2(rb_eStandardError, error_description);
|
31
|
+
free(error_description);
|
32
|
+
rb_exc_raise(errObj);
|
33
|
+
}
|
34
|
+
VALUE retval = rb_str_new_cstr(handle);
|
35
|
+
return retval;
|
36
|
+
}
|
37
|
+
|
38
|
+
VALUE rb_xcellus_find_in_column(VALUE self, VALUE handle, VALUE sheetName, VALUE index, VALUE value) {
|
39
|
+
if (RB_TYPE_P(handle, T_STRING) == 0) return Qnil;
|
40
|
+
if (RB_TYPE_P(sheetName, T_STRING) == 0) return Qnil;
|
41
|
+
if (RB_TYPE_P(index, T_FIXNUM) == 0) return Qnil;
|
42
|
+
if (RB_TYPE_P(value, T_STRING) == 0) return Qnil;
|
43
|
+
struct go_xcellus_find_in_column_return result = go_xcellus_find_in_column(RSTRING_PTR(handle), RSTRING_PTR(sheetName), RSTRING_PTR(value), FIX2INT(index));
|
44
|
+
bool failed = result.r0 == 1;
|
45
|
+
char *error_description = result.r1;
|
46
|
+
long long foundIndex = result.r2;
|
47
|
+
if(failed) {
|
48
|
+
VALUE errObj = rb_exc_new2(rb_eStandardError, error_description);
|
49
|
+
free(error_description);
|
50
|
+
rb_exc_raise(errObj);
|
51
|
+
}
|
52
|
+
return INT2NUM(foundIndex);
|
53
|
+
}
|
54
|
+
|
55
|
+
VALUE rb_xcellus_replace_row(VALUE self, VALUE handle, VALUE sheetName, VALUE data, VALUE index) {
|
56
|
+
if (RB_TYPE_P(handle, T_STRING) == 0) return Qnil;
|
57
|
+
if (RB_TYPE_P(sheetName, T_STRING) == 0) return Qnil;
|
58
|
+
if (RB_TYPE_P(index, T_FIXNUM) == 0) return Qnil;
|
59
|
+
if (RB_TYPE_P(data, T_STRING) == 0) return Qnil;
|
60
|
+
struct go_xcellus_replace_row_return result = go_xcellus_replace_row(RSTRING_PTR(handle), RSTRING_PTR(sheetName), RSTRING_PTR(data), FIX2INT(index));
|
61
|
+
bool failed = result.r0 == 1;
|
62
|
+
char *error_description = result.r1;
|
63
|
+
if(failed) {
|
64
|
+
VALUE errObj = rb_exc_new2(rb_eStandardError, error_description);
|
65
|
+
free(error_description);
|
66
|
+
rb_exc_raise(errObj);
|
67
|
+
}
|
68
|
+
return Qtrue;
|
69
|
+
}
|
70
|
+
|
71
|
+
VALUE rb_xcellus_close(VALUE self, VALUE handle) {
|
72
|
+
if (RB_TYPE_P(handle, T_STRING) == 0) return Qnil;
|
73
|
+
struct go_xcellus_end_return result = go_xcellus_end(RSTRING_PTR(handle));
|
74
|
+
bool failed = result.r0 == 1;
|
75
|
+
char *error_description = result.r1;
|
76
|
+
if(failed) {
|
77
|
+
VALUE errObj = rb_exc_new2(rb_eStandardError, error_description);
|
78
|
+
free(error_description);
|
79
|
+
rb_exc_raise(errObj);
|
80
|
+
}
|
81
|
+
return Qtrue;
|
82
|
+
}
|
83
|
+
|
84
|
+
VALUE rb_xcellus_save(VALUE self, VALUE handle, VALUE path) {
|
85
|
+
if (RB_TYPE_P(handle, T_STRING) == 0) return Qnil;
|
86
|
+
if (RB_TYPE_P(path, T_STRING) == 0) return Qnil;
|
87
|
+
struct go_xcellus_save_return result = go_xcellus_save(RSTRING_PTR(handle), RSTRING_PTR(path));
|
88
|
+
bool failed = result.r0 == 1;
|
89
|
+
char *error_description = result.r1;
|
90
|
+
if(failed) {
|
91
|
+
VALUE errObj = rb_exc_new2(rb_eStandardError, error_description);
|
92
|
+
free(error_description);
|
93
|
+
rb_exc_raise(errObj);
|
94
|
+
}
|
95
|
+
return Qtrue;
|
96
|
+
}
|
97
|
+
|
98
|
+
VALUE rb_xcellus_append(VALUE self, VALUE handle, VALUE data) {
|
99
|
+
if (RB_TYPE_P(handle, T_STRING) == 0 || RB_TYPE_P(data, T_STRING) == 0)
|
100
|
+
return Qnil;
|
101
|
+
struct go_xcellus_append_return result = go_xcellus_append(RSTRING_PTR(handle), RSTRING_PTR(data));
|
102
|
+
bool failed = result.r0 == 1;
|
103
|
+
char *error_description = result.r1;
|
104
|
+
if(failed) {
|
105
|
+
VALUE errObj = rb_exc_new2(rb_eStandardError, error_description);
|
106
|
+
free(error_description);
|
107
|
+
rb_exc_raise(errObj);
|
108
|
+
}
|
109
|
+
return Qtrue;
|
110
|
+
}
|
111
|
+
|
23
112
|
void Init_xcellus_bin() {
|
24
|
-
|
25
|
-
|
113
|
+
VALUE module = rb_define_module("Xcellus");
|
114
|
+
|
115
|
+
rb_define_singleton_method(module, "_transform", rb_xcellus_transform, 1);
|
116
|
+
rb_define_singleton_method(module, "_load", rb_xcellus_load, 1);
|
117
|
+
|
118
|
+
rb_define_singleton_method(module, "_find_in_column", rb_xcellus_find_in_column, 4);
|
119
|
+
rb_define_singleton_method(module, "_replace_row", rb_xcellus_replace_row, 4);
|
120
|
+
rb_define_singleton_method(module, "_save", rb_xcellus_save, 2);
|
121
|
+
rb_define_singleton_method(module, "_close", rb_xcellus_close, 2);
|
122
|
+
rb_define_singleton_method(module, "_append", rb_xcellus_append, 2);
|
26
123
|
}
|
data/lib/xcellus.rb
CHANGED
@@ -2,15 +2,133 @@ require File.expand_path('../xcellus_bin', __FILE__)
|
|
2
2
|
|
3
3
|
require 'json'
|
4
4
|
|
5
|
+
# Xcellus provides a clean interface to an underlying, native XLSX parser/writer
|
5
6
|
module Xcellus
|
6
|
-
VERSION = '
|
7
|
+
VERSION = '2.0'.freeze
|
7
8
|
|
8
9
|
class << self
|
10
|
+
# Transforms a provided array of objects into a XLSX file, and returns it as
|
11
|
+
# a StringIO object.
|
12
|
+
# Example:
|
13
|
+
# Xcellus.transform [
|
14
|
+
# {
|
15
|
+
# title: 'Brian\'s Worksheet',
|
16
|
+
# headers: [:Artist, :Track, :Playcount],
|
17
|
+
# rows: [
|
18
|
+
# ['Metallica', 'Hero of the Day', 242],
|
19
|
+
# ['Metallica', 'The Shortest Straw', 186],
|
20
|
+
# ['Queens of the Stone Age', 'My God Is the Sun', 276],
|
21
|
+
# ['Queens of the Stone Age', 'I Sat by the Ocean', 270],
|
22
|
+
# ['Gorillaz', 'On Melancholy Hill', 203],
|
23
|
+
# ['Gorillaz', 'Kids With Guns', 184],
|
24
|
+
# ]
|
25
|
+
# }
|
26
|
+
# ]
|
27
|
+
# => StringIO
|
28
|
+
# The returned XLSX file will contain a single worksheet named "Brian's
|
29
|
+
# Worksheet", and the provided headers and rows.
|
9
30
|
def transform(input)
|
10
31
|
unless input.kind_of? Array
|
11
32
|
raise ArgumentError, 'Xcellus.transform only accepts Arrays'
|
12
33
|
end
|
13
|
-
StringIO.new(Xcellus::
|
34
|
+
StringIO.new(Xcellus::_transform(input.to_json))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Loads a XLSX file from the provided path, returning an object of type
|
38
|
+
# Xcellus::Instance, that exposes methods for manipulating data in the
|
39
|
+
# file
|
40
|
+
def load(path)
|
41
|
+
unless path.kind_of? String
|
42
|
+
raise ArgumentError, 'Xcellus.load expects a string path'
|
43
|
+
end
|
44
|
+
handle = Xcellus::_load(path)
|
45
|
+
return Xcellus::Instance.new(handle)
|
46
|
+
end
|
47
|
+
|
48
|
+
# with opens the provided file and passes the loaded instance to the
|
49
|
+
# provided block. It ensures `close` is called, freeing resources.
|
50
|
+
# Example:
|
51
|
+
# Xcellus.with '/path/to/file' do |file|
|
52
|
+
# file.append ...
|
53
|
+
# file.replace_row ...
|
54
|
+
# file.save '/new/path/to/file'
|
55
|
+
# end
|
56
|
+
def with(path)
|
57
|
+
raise ArgumentError, 'with requires a block' unless block_given?
|
58
|
+
instance = load(path)
|
59
|
+
result = yield instance
|
60
|
+
instance.close
|
61
|
+
return result
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Instance represents a XLSX file, and exposes methods to manipulate data
|
66
|
+
# on the file
|
67
|
+
class Instance
|
68
|
+
# Internal: Creates a new instance with the provided handle
|
69
|
+
def initialize(handle)
|
70
|
+
@handle = handle
|
71
|
+
end
|
72
|
+
|
73
|
+
# Searches a given sheet for a provided value in a specific column.
|
74
|
+
# sheet_name: Name of the sheet to lookup for `value`. Immediately returns
|
75
|
+
# -1 when the sheet cannot be found.
|
76
|
+
# column_index: Index of the column to lookup for the provided value.
|
77
|
+
# value: Value to lookup for. Automatically converted and compared
|
78
|
+
# as an String.
|
79
|
+
def find_in_column(sheet_name, column_index, value)
|
80
|
+
unless sheet_name.kind_of? String
|
81
|
+
raise ArgumentError, 'Invalid sheet name'
|
82
|
+
end
|
83
|
+
unless column_index.kind_of? Integer
|
84
|
+
raise ArgumentError, 'Invalid column index'
|
85
|
+
end
|
86
|
+
Xcellus::_find_in_column(@handle, sheet_name, column_index, value.to_s)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Replaces the row at `index` in the provided `sheet_name`.
|
90
|
+
# sheet_name: Name of the sheet in which the row must be replaced. Throws
|
91
|
+
# a StandardException when a sheet with the provided name
|
92
|
+
# cannot be found.
|
93
|
+
# index: Index of the row to be replaced.
|
94
|
+
# value: An array with values to be replaced. Passing `nil` prevents
|
95
|
+
# values of the cell in the same index from being changed.
|
96
|
+
def replace_row(sheet_name, index, value)
|
97
|
+
unless sheet_name.kind_of? String
|
98
|
+
raise ArgumentError, 'Invalid sheet name'
|
99
|
+
end
|
100
|
+
unless index.kind_of? Integer
|
101
|
+
raise ArgumentError, 'Invalid column index'
|
102
|
+
end
|
103
|
+
unless value.kind_of? Array
|
104
|
+
raise ArgumentError, 'Invalid value: should be an array'
|
105
|
+
end
|
106
|
+
Xcellus::_replace_row(@handle, sheet_name, value.to_json, index)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Close ensures that all resources allocated when `load` is called are
|
110
|
+
# freed. This method MUST be called after you're done handling data.
|
111
|
+
def close
|
112
|
+
Xcellus::_close(@handle)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Saves the current modifications to the provided path.
|
116
|
+
def save(path)
|
117
|
+
unless path.kind_of? String
|
118
|
+
raise ArgumentError, 'save expects a string path'
|
119
|
+
end
|
120
|
+
|
121
|
+
Xcellus::_save(@handle, path)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Appends sheets and rows to the loaded file. This method expects the same
|
125
|
+
# structure of Xcellus::transform, with the difference that it creates (when
|
126
|
+
# necessary) sheets, and appends data to them.
|
127
|
+
def append(data)
|
128
|
+
unless input.kind_of? Array
|
129
|
+
raise ArgumentError, 'Xcellus.append only accepts Arrays'
|
130
|
+
end
|
131
|
+
StringIO.new(Xcellus::_transform(input.to_json))
|
14
132
|
end
|
15
133
|
end
|
16
134
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xcellus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '
|
4
|
+
version: '2.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Gama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|