vox-etf 0.1.0 → 0.1.5

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
  SHA256:
3
- metadata.gz: 38c4afc3d3f48eb9687bfc79372892ee356c7e9f4d70211c71ddedf0b59d4318
4
- data.tar.gz: 2f1b5060659fc9a35fa8d0b1ee1f5665c5c37d4254864961c14ead7d07048b9b
3
+ metadata.gz: e3745f75f9a0e5ea20d7ad1706dd25ac300839caecc8bf1263842e8ff1439652
4
+ data.tar.gz: e1c7a531f1e24b2af0b29bd5fd691874c6c3db0a6023aa5988c550575c2baeec
5
5
  SHA512:
6
- metadata.gz: 8fd31825a494ea4b863be1f3a5c252951598987cca09137f7eb8c71e62a01992011dfaff5c72f123845667ece12c96db6ab5663276d47f59b70d17cd3e9c2d06
7
- data.tar.gz: de91811cddb61a4523cf66501c86893fe4e1c6dd16fd9ca07dd6984a06d64fce3bab2d8daa82050f67bb1b3ee8287fcd3cdc6282c23039f80d2a445bd8333e48
6
+ metadata.gz: 0ae99c55b1320297ba7e79449979d744491adf02622cfb1bd0c58cb0249354026866c1bbb9f198f31ea5d32605eafa8142bb112b30e479855881102d12870488
7
+ data.tar.gz: 55076b6cea67d53c7c6acedae4806979e3ff933d56b4786d9062cbf2b6c57a407b34f9605535091e449538d86cf38ba5b9b11834d55a0afbf959cd0d3461d2e0
data/.gitignore CHANGED
@@ -9,3 +9,6 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+
13
+ lib/vox/etf.so
14
+ Gemfile.lock
data/README.md CHANGED
@@ -1,8 +1,4 @@
1
- # Vox::Etf
2
-
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/vox/etf`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
1
+ # Vox::ETF
6
2
 
7
3
  ## Installation
8
4
 
@@ -22,17 +18,24 @@ Or install it yourself as:
22
18
 
23
19
  ## Usage
24
20
 
25
- TODO: Write usage instructions here
21
+ To use the encoder/decoder independently use the respective `#encode` and `#decode` methods.
22
+
23
+ ```ruby
24
+ require 'vox/etf'
25
+
26
+ p Vox::ETF.decode("\x83l\x00\x00\x00\x03a\x01a\x02a\x03j")
27
+ # => [1, 2, 3]
26
28
 
27
- ## Development
29
+ p Vox::ETF.encode({foo: "bar"})
30
+ # => "\x83t\x00\x00\x00\x01w\x03foom\x00\x00\x00\x03bar"
31
+ ```
28
32
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
33
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
34
+ To use with the Vox gateway, add this gem to your Gemfile and provide `:etf` as the encoding option to `Vox::Gateway::Client#initialize`.
32
35
 
33
36
  ## Contributing
34
37
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/vox-etf. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/vox-etf/blob/master/CODE_OF_CONDUCT.md).
38
+ Bug reports and pull requests are welcome on GitHub at https://github.com/swarley/vox-etf. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/swarley/vox-etf/blob/master/CODE_OF_CONDUCT.md).
36
39
 
37
40
 
38
41
  ## License
data/Rakefile CHANGED
@@ -11,4 +11,5 @@ Rake::ExtensionTask.new('etf') do |ext|
11
11
  ext.lib_dir = 'lib/vox'
12
12
  end
13
13
 
14
- task(default: :compile)
14
+ task(default: :spec)
15
+ task spec: ['compile']
@@ -4,6 +4,33 @@
4
4
  #include "erlpack/sysdep.h"
5
5
  #include "erlpack/constants.h"
6
6
 
7
+ /* This code is highly derivative of discord's erlpack decoder
8
+ * targeting Javascript.
9
+ *
10
+ *
11
+ * MIT License
12
+ *
13
+ * Copyright (c) 2017 Discord
14
+ *
15
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ * of this software and associated documentation files (the "Software"), to deal
17
+ * in the Software without restriction, including without limitation the rights
18
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ * copies of the Software, and to permit persons to whom the Software is
20
+ * furnished to do so, subject to the following conditions:
21
+ *
22
+ * The above copyright notice and this permission notice shall be included in all
23
+ * copies or substantial portions of the Software.
24
+ *
25
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
+ * SOFTWARE.
32
+ */
33
+
7
34
  namespace etf
8
35
  {
9
36
  class decoder
@@ -131,12 +158,12 @@ namespace etf
131
158
  return val;
132
159
  }
133
160
 
134
- VALUE decode_small_integer(void)
161
+ VALUE decode_small_integer()
135
162
  {
136
163
  return INT2FIX(read8());
137
164
  }
138
165
 
139
- VALUE decode_integer(void)
166
+ VALUE decode_integer()
140
167
  {
141
168
  return INT2NUM(read32());
142
169
  }
@@ -156,7 +183,7 @@ namespace etf
156
183
  VALUE array = decode_array(length);
157
184
  const uint8_t tail = read8();
158
185
 
159
- if (tail != term::nil)
186
+ if (tail != NIL_EXT)
160
187
  {
161
188
  rb_raise(rb_eArgError, "List doesn't end with `NIL`, but it must!");
162
189
  return Qnil;
@@ -278,7 +305,7 @@ namespace etf
278
305
  const uint8_t sign = read8();
279
306
  const char *buff = read_string(length);
280
307
 
281
- auto flags = INTEGER_PACK_LITTLE_ENDIAN | (sign * INTEGER_PACK_NEGATIVE);
308
+ int flags = INTEGER_PACK_LITTLE_ENDIAN | (sign * INTEGER_PACK_NEGATIVE);
282
309
  return rb_integer_unpack(buff, length, 1, 0, flags);
283
310
  }
284
311
 
@@ -1,5 +1,7 @@
1
1
  #include "erlpack/encoder.h"
2
+ #include "erlpack/constants.h"
2
3
  #include "etf.hpp"
4
+ #include "ruby.h"
3
5
 
4
6
  namespace etf
5
7
  {
@@ -56,13 +58,23 @@ namespace etf
56
58
  encode_hash(input);
57
59
  break;
58
60
  default:
59
- rb_raise(rb_eArgError, "Unsupported serialization type");
61
+ if (rb_respond_to(input, rb_intern("to_hash")))
62
+ {
63
+ VALUE hash = rb_funcall(input, rb_intern("to_hash"), 0);
64
+ Check_Type(hash, T_HASH);
65
+ encode_hash(hash);
66
+ }
67
+ else
68
+ {
69
+ rb_raise(rb_eArgError, "Unsupported serialization type");
70
+ }
71
+
60
72
  break;
61
73
  }
62
74
  }
63
75
 
64
76
  VALUE
65
- r_string(void)
77
+ r_string()
66
78
  {
67
79
  return rb_str_new(erl_buff->buf, erl_buff->length);
68
80
  }
@@ -101,7 +113,7 @@ namespace etf
101
113
  {
102
114
  // id byte | n byte | sign byte | data
103
115
  uint8_t buff[3 + byte_count];
104
- buff[0] = term::small_big;
116
+ buff[0] = SMALL_BIG_EXT;
105
117
  buff[1] = byte_count;
106
118
  buff[2] = FIX2LONG(bignum) >= 0 ? 0 : 1;
107
119
  rb_integer_pack(bignum, buff + 3, byte_count, sizeof(uint8_t), 0, INTEGER_PACK_LITTLE_ENDIAN);
@@ -111,7 +123,7 @@ namespace etf
111
123
  {
112
124
  // id byte | 4 byte n | sign byte | data
113
125
  uint8_t buff[6 + byte_count];
114
- buff[0] = term::large_big;
126
+ buff[0] = LARGE_BIG_EXT;
115
127
  _erlpack_store32(buff + 1, byte_count);
116
128
  buff[5] = RBIGNUM_SIGN(bignum) ? 0 : 1;
117
129
  rb_integer_pack(bignum, buff + 6, byte_count, sizeof(uint8_t), 0, INTEGER_PACK_LITTLE_ENDIAN);
@@ -126,12 +138,20 @@ namespace etf
126
138
 
127
139
  void encode_array(VALUE array)
128
140
  {
129
- erlpack_append_list_header(erl_buff, RARRAY_LEN(array));
130
141
  uint32_t size = RARRAY_LEN(array);
142
+ if (size == 0)
143
+ {
144
+ erlpack_append_nil_ext(erl_buff);
145
+ return;
146
+ }
147
+
148
+ erlpack_append_list_header(erl_buff, size);
131
149
  for (uint32_t index = 0; index < size; index++)
132
150
  {
133
151
  encode_object(RARRAY_AREF(array, index));
134
152
  }
153
+
154
+ erlpack_append_nil_ext(erl_buff);
135
155
  }
136
156
 
137
157
  void encode_symbol(VALUE symbol)
@@ -154,7 +174,11 @@ namespace etf
154
174
  for (uint32_t index = 0; index < size * 2; index += 2)
155
175
  {
156
176
  VALUE key = RARRAY_AREF(keys, index / 2);
157
- encode_object(key);
177
+ // Normalize keys to strings because discord
178
+ if (TYPE(key) == T_SYMBOL)
179
+ encode_object(rb_sym2str(key));
180
+ else
181
+ encode_object(key);
158
182
  encode_object(rb_hash_aref(hash, key));
159
183
  }
160
184
  }
@@ -3,10 +3,6 @@
3
3
  #include "decoder.hpp"
4
4
  #include "etf.hpp"
5
5
 
6
- // Decode an ETF term from a ruby string
7
- // @param self [Object] Vox::ETF
8
- // @param input [Rice::String] The ETF term to be decoded.
9
- // @return [Rice::Object] Whatever the term is, as a ruby object.
10
6
  VALUE decode(VALUE self, VALUE input)
11
7
  {
12
8
  Check_Type(input, T_STRING);
@@ -1,57 +1,8 @@
1
1
  #pragma once
2
2
 
3
- #include "./etf_reader.hpp"
4
-
5
3
  #define ETF_VERSION 131
6
4
 
7
- // Term IDs, first byte of any term.
8
- enum term
9
- {
10
- new_float = 70,
11
- bit_binary = 77,
12
- atom_cache = 82,
13
- new_pid = 88,
14
- new_port = 89,
15
- newer_reference = 90,
16
- small_integer = 97,
17
- integer = 98,
18
- // annoying
19
- etf_float = 99,
20
- atom = 100,
21
- reference = 101,
22
- port = 102,
23
- pid = 103,
24
- small_tuple = 104,
25
- large_tuple = 105,
26
- nil = 106,
27
- string = 107,
28
- list = 108,
29
- binary = 109,
30
- small_big = 110,
31
- large_big = 111,
32
- new_fun = 112,
33
- // annoying
34
- etf_export = 113,
35
- new_reference = 114,
36
- small_atom = 115,
37
- map = 116,
38
- fun = 117,
39
- atom_utf8 = 118,
40
- small_atom_utf8 = 119
41
- };
42
-
43
5
  VALUE decode(VALUE self, VALUE input);
44
- inline VALUE decode_small_tuple(etf_reader *reader);
45
- inline VALUE decode_large_tuple(etf_reader *reader);
46
- inline VALUE decode_map(etf_reader *reader);
47
- inline VALUE decode_list(etf_reader *reader);
48
- inline VALUE decode_binary(etf_reader *reader);
49
- inline VALUE decode_string(etf_reader *reader);
50
- inline VALUE decode_atom(etf_reader *reader);
51
- inline VALUE decode_small_atom(etf_reader *reader);
52
- inline VALUE decode_small_bignum(etf_reader *reader);
53
- inline VALUE decode_large_bignum(etf_reader *reader);
54
-
55
6
  VALUE encode(VALUE self, VALUE input);
56
7
 
57
8
  // Setup function for ruby FFI.
@@ -1,7 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Container for Vox components.
3
4
  module Vox
5
+ # Default ETF adapter for vox's gateway component.
4
6
  module ETF
5
- VERSION = '0.1.0'
7
+ # @!parse [ruby]
8
+ # # Encode an object to an ETF term. This method accepts, `Integer`, `Float`,
9
+ # # `String`, `Symbol`, `Hash`, `Array`, `nil`, `true`, and `false` objects.
10
+ # # It also allows any object that responds to `#to_hash => Hash`.
11
+ # # @param input [Object, #to_hash] The object to be encoded as an ETF term.
12
+ # # @return [String] The ETF term encoded as a packed string.
13
+ # def self.encode(input)
14
+ # end
15
+
16
+ # @!parse [ruby]
17
+ # # Decode an ETF term from a string.
18
+ # # @param input [String] The ETF term to be decoded.
19
+ # # @return [Object] The ETF term decoded to an object.
20
+ # def self.decode(input)
21
+ # end
22
+
23
+ # Gem version
24
+ VERSION = '0.1.5'
6
25
  end
7
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vox-etf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Carey
@@ -160,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
160
  - !ruby/object:Gem::Version
161
161
  version: '0'
162
162
  requirements: []
163
- rubygems_version: 3.1.2
163
+ rubygems_version: 3.0.3
164
164
  signing_key:
165
165
  specification_version: 4
166
166
  summary: ETF decoding/encoding for vox.