ninjudd-tuple 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/VERSION.yml +1 -1
  2. data/ext/extconf.rb +5 -0
  3. data/ext/tuple.c +152 -0
  4. metadata +7 -5
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 0
3
- :patch: 3
3
+ :patch: 4
4
4
  :major: 0
data/ext/extconf.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+ # have_library('icui18n')
3
+ # have_library('icuio')
4
+ # create_makefile('unicode')
5
+ create_makefile('tuple')
data/ext/tuple.c ADDED
@@ -0,0 +1,152 @@
1
+ #include "ruby.h"
2
+
3
+ VALUE mTuple;
4
+
5
+ #define TRUE_SORT 128 // TrueClass
6
+ #define SYM_SORT 64 // Symbol
7
+ #define STR_SORT 32 // String
8
+ #define INTP_SORT 16 // Integer (Positive)
9
+ #define INTN_SORT 8 // Integer (Negative)
10
+ #define FALSE_SORT 1 // FalseClass
11
+ #define NIL_SORT 0 // NilClass
12
+
13
+ #define MAX_INT 0xffffffff
14
+
15
+ #define BDIGITS(x) ((BDIGIT*)RBIGNUM(x)->digits)
16
+
17
+ /*
18
+ * call-seq:
19
+ * Tuple.dump(tuple) -> string
20
+ *
21
+ * Dumps an array of simple Ruby types into a string of binary data.
22
+ *
23
+ */
24
+ static VALUE tuple_dump(VALUE self, VALUE tuple) {
25
+ VALUE data = rb_str_new2("");
26
+ VALUE item;
27
+ int i, j, len, sign;
28
+ u_int8_t header[4];
29
+ u_int32_t digit;
30
+ BDIGIT *digits;
31
+
32
+ Check_Type(tuple, T_ARRAY);
33
+ for (i = 0; i < RARRAY(tuple)->len; i++) {
34
+ item = RARRAY(tuple)->ptr[i];
35
+ header[0] = header[1] = header[2] = header[3] = 0;
36
+ if (FIXNUM_P(item)) {
37
+ sign = (digit >= 0);
38
+ header[2] = (sign ? INTP_SORT : INTN_SORT);
39
+ header[3] = 0;
40
+ rb_str_cat(data, (char*)&header, sizeof(header));
41
+
42
+ digit = htonl(FIX2INT(item) + (sign ? 0 : MAX_INT));
43
+ rb_str_cat(data, (char*)&digit, sizeof(digit));
44
+ } else if (TYPE(item) == T_BIGNUM) {
45
+ sign = RBIGNUM(item)->sign;
46
+ header[2] = sign ? INTP_SORT : INTN_SORT;
47
+ header[3] = RBIGNUM(item)->len;
48
+ rb_str_cat(data, (char*)&header, sizeof(header));
49
+
50
+ digits = BDIGITS(item);
51
+ for (j = header[3]-1; j >= 0; j--) {
52
+ digit = htonl(sign ? digits[j] : (MAX_INT - digits[j]));
53
+ rb_str_cat(data, (char*)&digit, sizeof(digit));
54
+ }
55
+ } else if (SYMBOL_P(item) || TYPE(item) == T_STRING) {
56
+ if (SYMBOL_P(item)) {
57
+ header[2] = SYM_SORT;
58
+ item = rb_funcall(item, rb_intern("to_s"), 0);
59
+ } else {
60
+ header[2] = STR_SORT;
61
+ }
62
+ rb_str_cat(data, (char*)&header, sizeof(header));
63
+ len = RSTRING_LEN(item);
64
+ rb_str_cat(data, RSTRING_PTR(item), len);
65
+
66
+ // Pad with null bytes so subsequent fields will be aligned.
67
+ while (len % 4 != 0) {
68
+ rb_str_cat(data, (char*)&header, 1);
69
+ len++;
70
+ }
71
+ } else {
72
+ if (item == Qnil) header[2] = NIL_SORT;
73
+ else if (item == Qtrue) header[2] = TRUE_SORT;
74
+ else if (item == Qfalse) header[2] = FALSE_SORT;
75
+ else rb_raise(rb_eTypeError, "invalid type %s in tuple", rb_obj_classname(item));
76
+
77
+ rb_str_cat(data, (char*)&header, sizeof(header));
78
+ }
79
+ }
80
+ return data;
81
+ }
82
+
83
+ /*
84
+ * call-seq:
85
+ * Tuple.load(string) -> tuple
86
+ *
87
+ * Reads in a previously dumped tuple from a string of binary data.
88
+ *
89
+ */
90
+ static VALUE tuple_load(VALUE self, VALUE data) {
91
+ VALUE tuple = rb_ary_new();
92
+ VALUE item;
93
+ data = StringValue(data);
94
+ void* ptr = RSTRING_PTR(data);
95
+ void* end = ptr + RSTRING_LEN(data);
96
+ int i, len, sign;
97
+ u_int8_t header[4];
98
+ u_int32_t digit;
99
+ BDIGIT *digits;
100
+
101
+ while (ptr < end) {
102
+ memcpy(header, ptr, 4);
103
+ ptr += 4;
104
+
105
+ switch(header[2]) {
106
+ case TRUE_SORT: rb_ary_push(tuple, Qtrue); break;
107
+ case FALSE_SORT: rb_ary_push(tuple, Qfalse); break;
108
+ case NIL_SORT: rb_ary_push(tuple, Qnil); break;
109
+ case INTP_SORT:
110
+ case INTN_SORT:
111
+ sign = (header[2] == INTP_SORT);
112
+ if (header[3] == 0) {
113
+ digit = ntohl(*(u_int32_t*)ptr) - (sign ? 0 : MAX_INT);
114
+ ptr += 4;
115
+ rb_ary_push(tuple, INT2NUM(digit));
116
+ } else {
117
+ // Create an empty bignum with the right number of digits.
118
+ NEWOBJ(item, struct RBignum);
119
+ OBJSETUP(item, rb_cBignum, T_BIGNUM);
120
+ item->sign = sign ? 1 : 0;
121
+ item->len = header[3];
122
+ item->digits = ALLOC_N(BDIGIT, header[3]);
123
+
124
+ digits = BDIGITS(item);
125
+ for (i = header[3]-1; i >= 0; i--) {
126
+ digit = ntohl(*(u_int32_t*)ptr);
127
+ digits[i] = sign ? digit : MAX_INT - digit;
128
+ ptr += 4;
129
+ }
130
+ rb_ary_push(tuple, (VALUE)item);
131
+ }
132
+ break;
133
+ case STR_SORT:
134
+ case SYM_SORT:
135
+ item = rb_str_new2(ptr);
136
+ len = RSTRING_LEN(item);
137
+ while (len % 4 != 0) len++;
138
+ ptr += len;
139
+ if (header[2] == SYM_SORT) item = rb_funcall(item, rb_intern("to_sym"), 0);
140
+ rb_ary_push(tuple, item);
141
+ break;
142
+ }
143
+ }
144
+ return tuple;
145
+ }
146
+
147
+ VALUE mTuple;
148
+ void Init_tuple() {
149
+ mTuple = rb_define_module("Tuple");
150
+ rb_define_module_function(mTuple, "dump", tuple_dump, 1);
151
+ rb_define_module_function(mTuple, "load", tuple_load, 1);
152
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ninjudd-tuple
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Balthrop
@@ -17,13 +17,15 @@ description: Fast, binary-sortable serialization for arrays of simple Ruby types
17
17
  email: code@justinbalthrop.com
18
18
  executables: []
19
19
 
20
- extensions: []
21
-
20
+ extensions:
21
+ - ext/extconf.rb
22
22
  extra_rdoc_files: []
23
23
 
24
24
  files:
25
25
  - README.rdoc
26
26
  - VERSION.yml
27
+ - ext/tuple.c
28
+ - ext/extconf.rb
27
29
  - test/test_helper.rb
28
30
  - test/tuple_test.rb
29
31
  has_rdoc: true
@@ -34,7 +36,7 @@ rdoc_options:
34
36
  - --inline-source
35
37
  - --charset=UTF-8
36
38
  require_paths:
37
- - lib
39
+ - ext
38
40
  required_ruby_version: !ruby/object:Gem::Requirement
39
41
  requirements:
40
42
  - - ">="
@@ -53,6 +55,6 @@ rubyforge_project:
53
55
  rubygems_version: 1.3.5
54
56
  signing_key:
55
57
  specification_version: 2
56
- summary: TODO
58
+ summary: Tuple serialization functions.
57
59
  test_files: []
58
60