xdrgen 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +23 -0
- data/README.md +2 -1
- data/lib/xdrgen/cli.rb +3 -3
- data/lib/xdrgen/generators.rb +1 -0
- data/lib/xdrgen/generators/csharp.rb +580 -0
- data/lib/xdrgen/generators/elixir.rb +1 -1
- data/lib/xdrgen/generators/java.rb +100 -6
- data/lib/xdrgen/generators/javascript.rb +1 -1
- data/lib/xdrgen/version.rb +1 -1
- metadata +9 -8
- data/.travis.yml +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 838bb9438d35d145a409589e774549bf2e74ef83c25156abf40f410e2064a32b
|
4
|
+
data.tar.gz: 25488d84cb7c5c641c52308e915d8b2d4d63631c67aa7bcda22c18635fb0fd7b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5bb40e6312ffc8c27febe50c367ab0b99141751b0b1b47c4a51c3cff7d33420b8a1410318175657756dbefc4ed20d7e9de5f37415692f423cd7043476e45842a
|
7
|
+
data.tar.gz: 33d7132dad38f3baedf34e17acc5704c688fdd280908864732f607821e831d6eca7e6544d258a80ff1575e547e50b38985131ed54d6a7286b05777942c2e729b
|
@@ -0,0 +1,23 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
test:
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
strategy:
|
12
|
+
matrix:
|
13
|
+
ruby-version: ['2.7', '3.0']
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- name: Set up Ruby
|
18
|
+
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
19
|
+
with:
|
20
|
+
ruby-version: ${{ matrix.ruby-version }}
|
21
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
22
|
+
- name: Run Rspec tests
|
23
|
+
run: bundle exec rspec
|
data/README.md
CHANGED
@@ -25,7 +25,8 @@ golang, and elixir:
|
|
25
25
|
- golang: currently using a fork of go-xdr, but has complete support
|
26
26
|
- elixir: support is experimental as the SDK is in early development. Generated
|
27
27
|
code requires [:exdr](https://github.com/revelrylabs/exdr) in your deps
|
28
|
-
|
28
|
+
- C#: complete support
|
29
|
+
|
29
30
|
Testing is _very_ sparse, but will improve over time.
|
30
31
|
|
31
32
|
## Usage as a binary
|
data/lib/xdrgen/cli.rb
CHANGED
@@ -5,7 +5,7 @@ module Xdrgen
|
|
5
5
|
def self.run(args)
|
6
6
|
args = args.dup
|
7
7
|
opts = Slop.parse! args do
|
8
|
-
banner 'Usage: xdrgen -o OUTPUT_DIR INPUT --
|
8
|
+
banner 'Usage: xdrgen -o OUTPUT_DIR INPUT --language=ruby'
|
9
9
|
on 'o', 'output=', 'The output directory'
|
10
10
|
on 'l', 'language=', 'The output language', default: 'ruby'
|
11
11
|
on 'n', 'namespace=', '"namespace" to generate code within (language-specific)'
|
@@ -16,7 +16,7 @@ module Xdrgen
|
|
16
16
|
|
17
17
|
compilation = Compilation.new(
|
18
18
|
args,
|
19
|
-
output_dir: opts[:output],
|
19
|
+
output_dir: opts[:output],
|
20
20
|
language: opts[:language].to_sym,
|
21
21
|
namespace: opts[:namespace]
|
22
22
|
)
|
@@ -28,4 +28,4 @@ module Xdrgen
|
|
28
28
|
exit(code)
|
29
29
|
end
|
30
30
|
end
|
31
|
-
end
|
31
|
+
end
|
data/lib/xdrgen/generators.rb
CHANGED
@@ -0,0 +1,580 @@
|
|
1
|
+
module Xdrgen
|
2
|
+
module Generators
|
3
|
+
class Csharp < Xdrgen::Generators::Base
|
4
|
+
def generate
|
5
|
+
render_lib
|
6
|
+
render_definitions(@top)
|
7
|
+
end
|
8
|
+
|
9
|
+
def render_lib; end
|
10
|
+
|
11
|
+
def render_definitions(node)
|
12
|
+
node.namespaces.each { |n| render_definitions n }
|
13
|
+
node.definitions.each(&method(:render_definition))
|
14
|
+
end
|
15
|
+
|
16
|
+
def render_definition(defn)
|
17
|
+
case defn
|
18
|
+
when AST::Definitions::Struct
|
19
|
+
render_element 'public class', defn do |out|
|
20
|
+
render_struct defn, out
|
21
|
+
render_nested_definitions defn, out
|
22
|
+
end
|
23
|
+
when AST::Definitions::Enum
|
24
|
+
render_element 'public class', defn do |out|
|
25
|
+
render_enum defn, out
|
26
|
+
end
|
27
|
+
when AST::Definitions::Union
|
28
|
+
render_element 'public class', defn do |out|
|
29
|
+
render_union defn, out
|
30
|
+
render_nested_definitions defn, out
|
31
|
+
end
|
32
|
+
when AST::Definitions::Typedef
|
33
|
+
render_element 'public class', defn do |out|
|
34
|
+
render_typedef defn, out
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def render_nested_definitions(defn, out)
|
40
|
+
return unless defn.respond_to? :nested_definitions
|
41
|
+
defn.nested_definitions.each do |ndefn|
|
42
|
+
case ndefn
|
43
|
+
when AST::Definitions::Struct
|
44
|
+
name = name ndefn
|
45
|
+
out.puts "public class #{name} {"
|
46
|
+
out.indent do
|
47
|
+
render_struct ndefn, out
|
48
|
+
render_nested_definitions ndefn, out
|
49
|
+
end
|
50
|
+
out.puts '}'
|
51
|
+
when AST::Definitions::Enum
|
52
|
+
name = name ndefn
|
53
|
+
out.puts "public class #{name} {"
|
54
|
+
out.indent do
|
55
|
+
render_enum ndefn, out
|
56
|
+
end
|
57
|
+
out.puts '}'
|
58
|
+
when AST::Definitions::Union
|
59
|
+
name = name ndefn
|
60
|
+
out.puts "public class #{name} {"
|
61
|
+
out.indent do
|
62
|
+
render_union ndefn, out
|
63
|
+
render_nested_definitions ndefn, out
|
64
|
+
end
|
65
|
+
out.puts '}'
|
66
|
+
when AST::Definitions::Typedef
|
67
|
+
name = name ndefn
|
68
|
+
out.puts "public class #{name} {"
|
69
|
+
out.indent do
|
70
|
+
render_typedef ndefn, out
|
71
|
+
end
|
72
|
+
out.puts '}'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def render_element(type, element, post_name = '')
|
78
|
+
path = element.name.camelize + '.cs'
|
79
|
+
name = name_string element.name
|
80
|
+
out = @output.open(path)
|
81
|
+
render_top_matter out
|
82
|
+
render_source_comment out, element
|
83
|
+
|
84
|
+
out.puts "#{type} #{name} #{post_name} {"
|
85
|
+
out.indent do
|
86
|
+
yield out
|
87
|
+
out.unbreak
|
88
|
+
end
|
89
|
+
out.puts '}'
|
90
|
+
out.puts '}'
|
91
|
+
end
|
92
|
+
|
93
|
+
def render_enum(enum, out)
|
94
|
+
enumname = enum.name + 'Enum'
|
95
|
+
|
96
|
+
out.puts "public enum #{enumname} {"
|
97
|
+
out.balance_after /,[\s]*/ do
|
98
|
+
enum.members.each do |em|
|
99
|
+
out.puts "#{em.name} = #{em.value},"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
out.puts "}\n"
|
103
|
+
out.puts <<-EOS.strip_heredoc
|
104
|
+
public #{enumname} InnerValue {get; set;} = default(#{enumname});
|
105
|
+
|
106
|
+
public static #{enum.name} Create(#{enumname} v)
|
107
|
+
{
|
108
|
+
return new #{enum.name} {
|
109
|
+
InnerValue = v
|
110
|
+
};
|
111
|
+
}
|
112
|
+
|
113
|
+
public static #{name_string enum.name} Decode(XdrDataInputStream stream) {
|
114
|
+
int value = stream.ReadInt();
|
115
|
+
switch (value) {
|
116
|
+
EOS
|
117
|
+
out.indent 2 do
|
118
|
+
enum.members.each do |em|
|
119
|
+
out.puts "case #{em.value}: return Create(#{enumname}.#{em.name});"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
out.puts <<-EOS.strip_heredoc
|
123
|
+
default:
|
124
|
+
throw new Exception("Unknown enum value: " + value);
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
public static void Encode(XdrDataOutputStream stream, #{name_string enum.name} value) {
|
129
|
+
stream.WriteInt((int)value.InnerValue);
|
130
|
+
}
|
131
|
+
EOS
|
132
|
+
out.break
|
133
|
+
end
|
134
|
+
|
135
|
+
def render_struct(struct, out)
|
136
|
+
out.puts "public #{name struct} () {}"
|
137
|
+
struct.members.each do |m|
|
138
|
+
out.puts <<-EOS.strip_heredoc
|
139
|
+
public #{decl_string(m.declaration)} #{m.name.camelize} {get; set;}
|
140
|
+
EOS
|
141
|
+
end
|
142
|
+
out.puts "\n"
|
143
|
+
out.puts "public static void Encode(XdrDataOutputStream stream, #{name struct} encoded#{name struct}) {"
|
144
|
+
struct.members.each do |m|
|
145
|
+
out.indent do
|
146
|
+
encode_member "encoded#{name struct}", m, out
|
147
|
+
end
|
148
|
+
end
|
149
|
+
out.puts '}'
|
150
|
+
|
151
|
+
out.puts <<-EOS.strip_heredoc
|
152
|
+
public static #{name struct} Decode(XdrDataInputStream stream) {
|
153
|
+
#{name struct} decoded#{name struct} = new #{name struct}();
|
154
|
+
EOS
|
155
|
+
struct.members.each do |m|
|
156
|
+
out.indent do
|
157
|
+
decode_member "decoded#{name struct}", m, out
|
158
|
+
end
|
159
|
+
end
|
160
|
+
out.indent do
|
161
|
+
out.puts "return decoded#{name struct};"
|
162
|
+
end
|
163
|
+
out.puts '}'
|
164
|
+
|
165
|
+
out.break
|
166
|
+
end
|
167
|
+
|
168
|
+
def render_typedef(typedef, out)
|
169
|
+
out.puts <<-EOS.strip_heredoc
|
170
|
+
public #{decl_string typedef.declaration} InnerValue {get; set;} = default(#{decl_string typedef.declaration});
|
171
|
+
|
172
|
+
public #{typedef.name.camelize}() {}
|
173
|
+
|
174
|
+
public #{typedef.name.camelize}(#{decl_string typedef.declaration} value)
|
175
|
+
{
|
176
|
+
InnerValue = value;
|
177
|
+
}
|
178
|
+
|
179
|
+
EOS
|
180
|
+
out.puts "public static void Encode(XdrDataOutputStream stream, #{name typedef} encoded#{name typedef}) {"
|
181
|
+
encode_innervalue_member "encoded#{name typedef}", typedef, out
|
182
|
+
out.puts '}'
|
183
|
+
|
184
|
+
out.puts <<-EOS.strip_heredoc
|
185
|
+
public static #{name typedef} Decode(XdrDataInputStream stream) {
|
186
|
+
#{name typedef} decoded#{name typedef} = new #{name typedef}();
|
187
|
+
EOS
|
188
|
+
decode_innervalue_member "decoded#{name typedef}", typedef, out
|
189
|
+
out.indent do
|
190
|
+
out.puts "return decoded#{name typedef};"
|
191
|
+
end
|
192
|
+
out.puts '}'
|
193
|
+
end
|
194
|
+
|
195
|
+
def render_union(union, out)
|
196
|
+
has_inner_value = false
|
197
|
+
|
198
|
+
out.puts "public #{name union} () {}"
|
199
|
+
out.puts <<-EOS.strip_heredoc
|
200
|
+
|
201
|
+
public #{type_string union.discriminant.type} Discriminant { get; set; } = new #{type_string union.discriminant.type}();
|
202
|
+
|
203
|
+
EOS
|
204
|
+
union.arms.each do |arm|
|
205
|
+
next if arm.void?
|
206
|
+
out.puts <<-EOS.strip_heredoc
|
207
|
+
public #{decl_string(arm.declaration)} #{arm.name.camelize} {get; set;}
|
208
|
+
EOS
|
209
|
+
end
|
210
|
+
|
211
|
+
out.puts "public static void Encode(XdrDataOutputStream stream, #{name union} encoded#{name union}) {"
|
212
|
+
if union.discriminant.type.is_a?(AST::Typespecs::Int)
|
213
|
+
out.puts "stream.WriteInt((int)encoded#{name union}.Discriminant);"
|
214
|
+
out.puts "switch (encoded#{name union}.Discriminant) {"
|
215
|
+
# elsif [discriminant is AST::Definitions::Typedef]
|
216
|
+
# out.puts "stream.writeInt(encoded#{name union}.getDiscriminant().get#{name union.discriminant.type}());"
|
217
|
+
else
|
218
|
+
has_inner_value = true
|
219
|
+
out.puts "stream.WriteInt((int)encoded#{name union}.Discriminant.InnerValue);"
|
220
|
+
out.puts "switch (encoded#{name union}.Discriminant.InnerValue) {"
|
221
|
+
end
|
222
|
+
|
223
|
+
union.arms.each do |arm|
|
224
|
+
case arm
|
225
|
+
when AST::Definitions::UnionDefaultArm
|
226
|
+
out.puts 'default:'
|
227
|
+
else
|
228
|
+
arm.cases.each do |kase|
|
229
|
+
if kase.value.is_a?(AST::Identifier)
|
230
|
+
out.puts "case #{type_string union.discriminant.type}.#{type_string union.discriminant.type}Enum.#{kase.value.name}:"
|
231
|
+
else
|
232
|
+
out.puts "case #{kase.value.value}:"
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
encode_member "encoded#{name union}", arm, out
|
237
|
+
out.puts 'break;'
|
238
|
+
end
|
239
|
+
out.puts "}\n}"
|
240
|
+
|
241
|
+
out.puts "public static #{name union} Decode(XdrDataInputStream stream) {"
|
242
|
+
out.puts "#{name union} decoded#{name union} = new #{name union}();"
|
243
|
+
if union.discriminant.type.is_a?(AST::Typespecs::Int)
|
244
|
+
out.puts 'int discriminant = stream.ReadInt();'
|
245
|
+
out.puts "decoded#{name union}.Discriminant = discriminant;"
|
246
|
+
out.puts "switch (decoded#{name union}.Discriminant) {"
|
247
|
+
else
|
248
|
+
out.puts "#{name union.discriminant.type} discriminant = #{name union.discriminant.type}.Decode(stream);"
|
249
|
+
out.puts "decoded#{name union}.Discriminant = discriminant;"
|
250
|
+
out.puts "switch (decoded#{name union}.Discriminant.InnerValue) {"
|
251
|
+
end
|
252
|
+
|
253
|
+
union.arms.each do |arm|
|
254
|
+
case arm
|
255
|
+
when AST::Definitions::UnionDefaultArm
|
256
|
+
out.puts 'default:'
|
257
|
+
else
|
258
|
+
arm.cases.each do |kase|
|
259
|
+
if kase.value.is_a?(AST::Identifier)
|
260
|
+
out.puts "case #{type_string union.discriminant.type}.#{type_string union.discriminant.type}Enum.#{kase.value.name}:"
|
261
|
+
else
|
262
|
+
out.puts "case #{kase.value.value}:"
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
decode_member "decoded#{name union}", arm, out
|
267
|
+
out.puts 'break;'
|
268
|
+
end
|
269
|
+
out.puts "}\n"
|
270
|
+
out.indent do
|
271
|
+
out.puts "return decoded#{name union};"
|
272
|
+
end
|
273
|
+
out.puts '}'
|
274
|
+
|
275
|
+
out.break
|
276
|
+
end
|
277
|
+
|
278
|
+
def render_top_matter(out)
|
279
|
+
out.puts <<-EOS.strip_heredoc
|
280
|
+
// Automatically generated by xdrgen
|
281
|
+
// DO NOT EDIT or your changes may be overwritten
|
282
|
+
using System;
|
283
|
+
|
284
|
+
namespace #{@namespace} {
|
285
|
+
EOS
|
286
|
+
out.break
|
287
|
+
end
|
288
|
+
|
289
|
+
def render_source_comment(out, defn)
|
290
|
+
return if defn.is_a?(AST::Definitions::Namespace)
|
291
|
+
|
292
|
+
out.puts <<-EOS.strip_heredoc
|
293
|
+
// === xdr source ============================================================
|
294
|
+
|
295
|
+
EOS
|
296
|
+
|
297
|
+
out.puts '// ' + defn.text_value.split("\n").join("\n// ")
|
298
|
+
|
299
|
+
out.puts <<-EOS.strip_heredoc
|
300
|
+
|
301
|
+
// ===========================================================================
|
302
|
+
EOS
|
303
|
+
end
|
304
|
+
|
305
|
+
def encode_innervalue_member(value, member, out)
|
306
|
+
case member.declaration
|
307
|
+
when AST::Declarations::Void
|
308
|
+
return
|
309
|
+
end
|
310
|
+
|
311
|
+
if member.type.sub_type == :optional
|
312
|
+
out.puts "if (#{value}.InnerValue != null) {"
|
313
|
+
out.puts 'stream.WriteInt(1);'
|
314
|
+
end
|
315
|
+
|
316
|
+
case member.declaration
|
317
|
+
when AST::Declarations::Opaque
|
318
|
+
out.puts "int #{member.name}size = #{value}.InnerValue.Length;"
|
319
|
+
unless member.declaration.fixed?
|
320
|
+
out.puts "stream.WriteInt(#{member.name.camelize}size);"
|
321
|
+
end
|
322
|
+
out.puts <<-EOS.strip_heredoc
|
323
|
+
stream.Write(#{value}.InnerValue, 0, #{member.name}size);
|
324
|
+
EOS
|
325
|
+
when AST::Declarations::Array
|
326
|
+
out.puts "int #{member.name}size = #{value}.InnerValue.Length;"
|
327
|
+
unless member.declaration.fixed?
|
328
|
+
out.puts "stream.WriteInt(#{member.name}size);"
|
329
|
+
end
|
330
|
+
out.puts <<-EOS.strip_heredoc
|
331
|
+
for (int i = 0; i < #{member.name}size; i++) {
|
332
|
+
#{encode_type member.declaration.type, "#{value}.InnerValue[i]"};
|
333
|
+
}
|
334
|
+
EOS
|
335
|
+
else
|
336
|
+
out.puts "#{encode_type member.declaration.type, "#{value}.InnerValue"};"
|
337
|
+
end
|
338
|
+
if member.type.sub_type == :optional
|
339
|
+
out.puts '} else {'
|
340
|
+
out.puts 'stream.WriteInt(0);'
|
341
|
+
out.puts '}'
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def encode_member(value, member, out)
|
346
|
+
case member.declaration
|
347
|
+
when AST::Declarations::Void
|
348
|
+
return
|
349
|
+
end
|
350
|
+
|
351
|
+
if member.type.sub_type == :optional
|
352
|
+
out.puts "if (#{value}.#{member.name.camelize} != null) {"
|
353
|
+
out.puts 'stream.WriteInt(1);'
|
354
|
+
end
|
355
|
+
case member.declaration
|
356
|
+
when AST::Declarations::Opaque
|
357
|
+
out.puts "int #{member.name}size = #{value}.#{member.name.camelize}.Length;"
|
358
|
+
unless member.declaration.fixed?
|
359
|
+
out.puts "stream.WriteInt(#{member.name.camelize}size);"
|
360
|
+
end
|
361
|
+
out.puts <<-EOS.strip_heredoc
|
362
|
+
stream.Write(#{value}.#{member.name.camelize}, 0, #{member.name}size);
|
363
|
+
EOS
|
364
|
+
when AST::Declarations::Array
|
365
|
+
out.puts "int #{member.name}size = #{value}.#{member.name.camelize}.Length;"
|
366
|
+
unless member.declaration.fixed?
|
367
|
+
out.puts "stream.WriteInt(#{member.name}size);"
|
368
|
+
end
|
369
|
+
out.puts <<-EOS.strip_heredoc
|
370
|
+
for (int i = 0; i < #{member.name}size; i++) {
|
371
|
+
#{encode_type member.declaration.type, "#{value}.#{member.name.camelize}[i]"};
|
372
|
+
}
|
373
|
+
EOS
|
374
|
+
else
|
375
|
+
out.puts "#{encode_type member.declaration.type, "#{value}.#{member.name.camelize}"};"
|
376
|
+
end
|
377
|
+
if member.type.sub_type == :optional
|
378
|
+
out.puts '} else {'
|
379
|
+
out.puts 'stream.WriteInt(0);'
|
380
|
+
out.puts '}'
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
def encode_type(type, value)
|
385
|
+
case type
|
386
|
+
when AST::Typespecs::Int
|
387
|
+
"stream.WriteInt(#{value})"
|
388
|
+
when AST::Typespecs::UnsignedInt
|
389
|
+
"stream.WriteInt(#{value})"
|
390
|
+
when AST::Typespecs::Hyper
|
391
|
+
"stream.WriteLong(#{value})"
|
392
|
+
when AST::Typespecs::UnsignedHyper
|
393
|
+
"stream.WriteLong(#{value})"
|
394
|
+
when AST::Typespecs::Float
|
395
|
+
"stream.WriteFloat(#{value})"
|
396
|
+
when AST::Typespecs::Double
|
397
|
+
"stream.WriteDouble(#{value})"
|
398
|
+
when AST::Typespecs::Quadruple
|
399
|
+
raise 'cannot render quadruple in c#'
|
400
|
+
when AST::Typespecs::Bool
|
401
|
+
"stream.WriteInt(#{value} ? 1 : 0)"
|
402
|
+
when AST::Typespecs::String
|
403
|
+
"stream.WriteString(#{value})"
|
404
|
+
when AST::Typespecs::Simple
|
405
|
+
"#{name type.resolved_type}.Encode(stream, #{value})"
|
406
|
+
when AST::Concerns::NestedDefinition
|
407
|
+
"#{name type}.Encode(stream, #{value})"
|
408
|
+
else
|
409
|
+
raise "Unknown typespec: #{type.class.name}"
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
def decode_innervalue_member(value, member, out)
|
414
|
+
case member.declaration
|
415
|
+
when AST::Declarations::Void
|
416
|
+
return
|
417
|
+
end
|
418
|
+
if member.type.sub_type == :optional
|
419
|
+
out.puts <<-EOS.strip_heredoc
|
420
|
+
int #{member.name.camelize}Present = stream.ReadInt();
|
421
|
+
if (#{member.name.camelize}Present != 0) {
|
422
|
+
EOS
|
423
|
+
end
|
424
|
+
case member.declaration
|
425
|
+
when AST::Declarations::Opaque
|
426
|
+
if member.declaration.fixed?
|
427
|
+
out.puts "int #{member.name}size = #{member.declaration.size};"
|
428
|
+
else
|
429
|
+
out.puts "int #{member.name}size = stream.ReadInt();"
|
430
|
+
end
|
431
|
+
out.puts <<-EOS.strip_heredoc
|
432
|
+
#{value}.InnerValue = new byte[#{member.name}size];
|
433
|
+
stream.Read(#{value}.InnerValue, 0, #{member.name}size);
|
434
|
+
EOS
|
435
|
+
when AST::Declarations::Array
|
436
|
+
if member.declaration.fixed?
|
437
|
+
out.puts "int #{member.name}size = #{member.declaration.size};"
|
438
|
+
else
|
439
|
+
out.puts "int #{member.name}size = stream.ReadInt();"
|
440
|
+
end
|
441
|
+
out.puts <<-EOS.strip_heredoc
|
442
|
+
#{value}.InnerValue = new #{type_string member.type}[#{member.name}size];
|
443
|
+
for (int i = 0; i < #{member.name}size; i++) {
|
444
|
+
#{value}.InnerValue[i] = #{decode_type member.declaration.type};
|
445
|
+
}
|
446
|
+
EOS
|
447
|
+
else
|
448
|
+
out.puts "#{value}.InnerValue = #{decode_type member.declaration.type};"
|
449
|
+
end
|
450
|
+
out.puts '}' if member.type.sub_type == :optional
|
451
|
+
end
|
452
|
+
|
453
|
+
def decode_member(value, member, out)
|
454
|
+
case member.declaration
|
455
|
+
when AST::Declarations::Void
|
456
|
+
return
|
457
|
+
end
|
458
|
+
if member.type.sub_type == :optional
|
459
|
+
out.puts <<-EOS.strip_heredoc
|
460
|
+
int #{member.name.camelize}Present = stream.ReadInt();
|
461
|
+
if (#{member.name.camelize}Present != 0) {
|
462
|
+
EOS
|
463
|
+
end
|
464
|
+
case member.declaration
|
465
|
+
when AST::Declarations::Opaque
|
466
|
+
if member.declaration.fixed?
|
467
|
+
out.puts "int #{member.name}size = #{member.declaration.size};"
|
468
|
+
else
|
469
|
+
out.puts "int #{member.name}size = stream.ReadInt();"
|
470
|
+
end
|
471
|
+
out.puts <<-EOS.strip_heredoc
|
472
|
+
#{value}.#{member.name.camelize} = new byte[#{member.name}size];
|
473
|
+
stream.Read(#{value}.#{member.name.camelize},0,#{member.name}size);
|
474
|
+
EOS
|
475
|
+
when AST::Declarations::Array
|
476
|
+
if member.declaration.fixed?
|
477
|
+
out.puts "int #{member.name}size = #{member.declaration.size};"
|
478
|
+
else
|
479
|
+
out.puts "int #{member.name}size = stream.ReadInt();"
|
480
|
+
end
|
481
|
+
out.puts <<-EOS.strip_heredoc
|
482
|
+
#{value}.#{member.name.camelize} = new #{type_string member.type}[#{member.name}size];
|
483
|
+
for (int i = 0; i < #{member.name}size; i++) {
|
484
|
+
#{value}.#{member.name.camelize}[i] = #{decode_type member.declaration.type};
|
485
|
+
}
|
486
|
+
EOS
|
487
|
+
else
|
488
|
+
out.puts "#{value}.#{member.name.camelize} = #{decode_type member.declaration.type};"
|
489
|
+
end
|
490
|
+
out.puts '}' if member.type.sub_type == :optional
|
491
|
+
end
|
492
|
+
|
493
|
+
def decode_type(type)
|
494
|
+
case type
|
495
|
+
when AST::Typespecs::Int
|
496
|
+
'stream.ReadInt()'
|
497
|
+
when AST::Typespecs::UnsignedInt
|
498
|
+
'stream.ReadInt()'
|
499
|
+
when AST::Typespecs::Hyper
|
500
|
+
'stream.ReadLong()'
|
501
|
+
when AST::Typespecs::UnsignedHyper
|
502
|
+
'stream.ReadLong()'
|
503
|
+
when AST::Typespecs::Float
|
504
|
+
'stream.ReadFloat()'
|
505
|
+
when AST::Typespecs::Double
|
506
|
+
'stream.ReadDouble()'
|
507
|
+
when AST::Typespecs::Quadruple
|
508
|
+
raise 'cannot render quadruple in c#'
|
509
|
+
when AST::Typespecs::Bool
|
510
|
+
'stream.ReadInt() == 1 ? true : false'
|
511
|
+
when AST::Typespecs::String
|
512
|
+
'stream.ReadString()'
|
513
|
+
when AST::Typespecs::Simple
|
514
|
+
"#{name type.resolved_type}.Decode(stream)"
|
515
|
+
when AST::Concerns::NestedDefinition
|
516
|
+
"#{name type}.Decode(stream)"
|
517
|
+
else
|
518
|
+
raise "Unknown typespec: #{type.class.name}"
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
def decl_string(decl)
|
523
|
+
case decl
|
524
|
+
when AST::Declarations::Opaque
|
525
|
+
'byte[]'
|
526
|
+
when AST::Declarations::String
|
527
|
+
'String'
|
528
|
+
when AST::Declarations::Array
|
529
|
+
"#{type_string decl.type}[]"
|
530
|
+
when AST::Declarations::Optional
|
531
|
+
type_string(decl.type).to_s
|
532
|
+
when AST::Declarations::Simple
|
533
|
+
type_string(decl.type)
|
534
|
+
else
|
535
|
+
raise "Unknown declaration type: #{decl.class.name}"
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
def type_string(type)
|
540
|
+
case type
|
541
|
+
when AST::Typespecs::Int
|
542
|
+
'int'
|
543
|
+
when AST::Typespecs::UnsignedInt
|
544
|
+
'int'
|
545
|
+
when AST::Typespecs::Hyper
|
546
|
+
'long'
|
547
|
+
when AST::Typespecs::UnsignedHyper
|
548
|
+
'long'
|
549
|
+
when AST::Typespecs::Float
|
550
|
+
'float'
|
551
|
+
when AST::Typespecs::Double
|
552
|
+
'double'
|
553
|
+
when AST::Typespecs::Quadruple
|
554
|
+
'Tuple'
|
555
|
+
when AST::Typespecs::Bool
|
556
|
+
'bool'
|
557
|
+
when AST::Typespecs::Opaque
|
558
|
+
"Byte[#{type.size}]"
|
559
|
+
when AST::Typespecs::Simple
|
560
|
+
name type.resolved_type
|
561
|
+
when AST::Concerns::NestedDefinition
|
562
|
+
name type
|
563
|
+
else
|
564
|
+
raise "Unknown typespec: #{type.class.name}"
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
def name(named)
|
569
|
+
parent = name named.parent_defn if named.is_a?(AST::Concerns::NestedDefinition)
|
570
|
+
result = named.name.camelize
|
571
|
+
|
572
|
+
"#{parent}#{result}"
|
573
|
+
end
|
574
|
+
|
575
|
+
def name_string(name)
|
576
|
+
name.camelize
|
577
|
+
end
|
578
|
+
end
|
579
|
+
end
|
580
|
+
end
|
@@ -164,7 +164,7 @@ module Xdrgen
|
|
164
164
|
parent = name named.parent_defn if named.is_a?(AST::Concerns::NestedDefinition)
|
165
165
|
|
166
166
|
# NOTE: classify will strip plurality, so we restore it if necessary
|
167
|
-
plural = named.name.downcase.pluralize == named.name.downcase
|
167
|
+
plural = named.name.underscore.downcase.pluralize == named.name.underscore.downcase
|
168
168
|
base = named.name.underscore.classify
|
169
169
|
result = plural ? base.pluralize : base
|
170
170
|
|
@@ -305,33 +305,77 @@ module Xdrgen
|
|
305
305
|
out.puts <<-EOS.strip_heredoc
|
306
306
|
@Override
|
307
307
|
public boolean equals(Object object) {
|
308
|
-
if (
|
308
|
+
if (!(object instanceof #{type})) {
|
309
309
|
return false;
|
310
310
|
}
|
311
311
|
|
312
312
|
#{type} other = (#{type}) object;
|
313
313
|
return #{equalExpression};
|
314
314
|
}
|
315
|
+
|
315
316
|
EOS
|
316
317
|
|
318
|
+
out.puts "public static final class Builder {"
|
319
|
+
out.indent do
|
320
|
+
struct.members.map { |m|
|
321
|
+
out.puts "private #{decl_string(m.declaration)} #{m.name};"
|
322
|
+
}
|
323
|
+
|
324
|
+
struct.members.map { |m|
|
325
|
+
out.puts <<-EOS.strip_heredoc
|
326
|
+
|
327
|
+
public Builder #{m.name}(#{decl_string(m.declaration)} #{m.name}) {
|
328
|
+
this.#{m.name} = #{m.name};
|
329
|
+
return this;
|
330
|
+
}
|
331
|
+
EOS
|
332
|
+
}
|
333
|
+
|
334
|
+
end
|
335
|
+
|
336
|
+
|
337
|
+
out.indent do
|
338
|
+
out.break
|
339
|
+
out.puts "public #{name struct} build() {"
|
340
|
+
out.indent do
|
341
|
+
out.puts "#{name struct} val = new #{name struct}();"
|
342
|
+
struct.members.map { |m|
|
343
|
+
out.puts "val.set#{m.name.slice(0,1).capitalize+m.name.slice(1..-1)}(#{m.name});"
|
344
|
+
}
|
345
|
+
out.puts "return val;"
|
346
|
+
end
|
347
|
+
out.puts "}"
|
348
|
+
end
|
349
|
+
out.puts "}"
|
317
350
|
out.break
|
318
351
|
end
|
319
352
|
|
320
353
|
def render_typedef(typedef, out)
|
321
354
|
out.puts <<-EOS.strip_heredoc
|
322
355
|
private #{decl_string typedef.declaration} #{typedef.name};
|
356
|
+
|
357
|
+
public #{typedef.name.camelize}() {}
|
358
|
+
|
359
|
+
public #{typedef.name.camelize}(#{decl_string typedef.declaration} #{typedef.name}) {
|
360
|
+
this.#{typedef.name} = #{typedef.name};
|
361
|
+
}
|
362
|
+
|
323
363
|
public #{decl_string typedef.declaration} get#{typedef.name.slice(0,1).capitalize+typedef.name.slice(1..-1)}() {
|
324
364
|
return this.#{typedef.name};
|
325
365
|
}
|
366
|
+
|
326
367
|
public void set#{typedef.name.slice(0,1).capitalize+typedef.name.slice(1..-1)}(#{decl_string typedef.declaration} value) {
|
327
368
|
this.#{typedef.name} = value;
|
328
369
|
}
|
329
|
-
EOS
|
330
370
|
|
371
|
+
EOS
|
331
372
|
|
332
373
|
out.puts "public static void encode(XdrDataOutputStream stream, #{name typedef} encoded#{name typedef}) throws IOException {"
|
333
|
-
|
374
|
+
out.indent do
|
375
|
+
encode_member "encoded#{name typedef}", typedef, out
|
376
|
+
end
|
334
377
|
out.puts "}"
|
378
|
+
out.break
|
335
379
|
|
336
380
|
out.puts <<-EOS.strip_heredoc
|
337
381
|
public void encode(XdrDataOutputStream stream) throws IOException {
|
@@ -343,11 +387,12 @@ module Xdrgen
|
|
343
387
|
public static #{name typedef} decode(XdrDataInputStream stream) throws IOException {
|
344
388
|
#{name typedef} decoded#{name typedef} = new #{name typedef}();
|
345
389
|
EOS
|
346
|
-
decode_member "decoded#{name typedef}", typedef, out
|
347
390
|
out.indent do
|
391
|
+
decode_member "decoded#{name typedef}", typedef, out
|
348
392
|
out.puts "return decoded#{name typedef};"
|
349
393
|
end
|
350
394
|
out.puts "}"
|
395
|
+
out.break
|
351
396
|
|
352
397
|
hash_coder_for_decl =
|
353
398
|
if is_decl_array(typedef.declaration)
|
@@ -360,6 +405,7 @@ module Xdrgen
|
|
360
405
|
public int hashCode() {
|
361
406
|
return #{hash_coder_for_decl}(this.#{typedef.name});
|
362
407
|
}
|
408
|
+
|
363
409
|
EOS
|
364
410
|
|
365
411
|
equals_for_decl =
|
@@ -372,7 +418,7 @@ module Xdrgen
|
|
372
418
|
out.puts <<-EOS.strip_heredoc
|
373
419
|
@Override
|
374
420
|
public boolean equals(Object object) {
|
375
|
-
if (
|
421
|
+
if (!(object instanceof #{type})) {
|
376
422
|
return false;
|
377
423
|
}
|
378
424
|
|
@@ -405,6 +451,54 @@ module Xdrgen
|
|
405
451
|
}
|
406
452
|
EOS
|
407
453
|
end
|
454
|
+
out.break
|
455
|
+
|
456
|
+
out.puts "public static final class Builder {"
|
457
|
+
out.indent do
|
458
|
+
out.puts "private #{type_string union.discriminant.type} discriminant;"
|
459
|
+
union.arms.each do |arm|
|
460
|
+
next if arm.void?
|
461
|
+
out.puts "private #{decl_string(arm.declaration)} #{arm.name};"
|
462
|
+
end
|
463
|
+
out.break
|
464
|
+
|
465
|
+
out.puts <<-EOS.strip_heredoc
|
466
|
+
public Builder discriminant(#{type_string union.discriminant.type} discriminant) {
|
467
|
+
this.discriminant = discriminant;
|
468
|
+
return this;
|
469
|
+
}
|
470
|
+
EOS
|
471
|
+
|
472
|
+
union.arms.each do |arm|
|
473
|
+
next if arm.void?
|
474
|
+
out.puts <<-EOS.strip_heredoc
|
475
|
+
|
476
|
+
public Builder #{arm.name}(#{decl_string(arm.declaration)} #{arm.name}) {
|
477
|
+
this.#{arm.name} = #{arm.name};
|
478
|
+
return this;
|
479
|
+
}
|
480
|
+
EOS
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
out.indent do
|
485
|
+
out.break
|
486
|
+
out.puts "public #{name union} build() {"
|
487
|
+
out.indent do
|
488
|
+
out.puts "#{name union} val = new #{name union}();"
|
489
|
+
out.puts "val.setDiscriminant(discriminant);"
|
490
|
+
union.arms.each do |arm|
|
491
|
+
next if arm.void?
|
492
|
+
out.puts "val.set#{arm.name.slice(0,1).capitalize+arm.name.slice(1..-1)}(#{arm.name});"
|
493
|
+
end
|
494
|
+
out.puts "return val;"
|
495
|
+
end
|
496
|
+
out.puts "}"
|
497
|
+
end
|
498
|
+
out.puts "}"
|
499
|
+
out.break
|
500
|
+
|
501
|
+
|
408
502
|
out.puts "public static void encode(XdrDataOutputStream stream, #{name union} encoded#{name union}) throws IOException {"
|
409
503
|
out.puts('//' + union.discriminant.type.class.to_s)
|
410
504
|
out.puts("//" + type_string(union.discriminant.type))
|
@@ -543,7 +637,7 @@ module Xdrgen
|
|
543
637
|
out.puts <<-EOS.strip_heredoc
|
544
638
|
@Override
|
545
639
|
public boolean equals(Object object) {
|
546
|
-
if (
|
640
|
+
if (!(object instanceof #{type})) {
|
547
641
|
return false;
|
548
642
|
}
|
549
643
|
|
@@ -178,7 +178,7 @@ module Xdrgen
|
|
178
178
|
# "BEGIN_SPONSORING_FUTURE_RESERVEs" == "BEGIN_SPONSORING_FUTURE_RESERVES"
|
179
179
|
# => false
|
180
180
|
#
|
181
|
-
plural = named.name.downcase.pluralize == named.name.downcase
|
181
|
+
plural = named.name.underscore.downcase.pluralize == named.name.underscore.downcase
|
182
182
|
base = named.name.underscore.classify
|
183
183
|
result = plural ? base.pluralize : base
|
184
184
|
|
data/lib/xdrgen/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xdrgen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Fleckenstein
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: treetop
|
@@ -136,7 +136,7 @@ dependencies:
|
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
-
description:
|
139
|
+
description:
|
140
140
|
email:
|
141
141
|
- scott@stellar.org
|
142
142
|
executables:
|
@@ -144,8 +144,8 @@ executables:
|
|
144
144
|
extensions: []
|
145
145
|
extra_rdoc_files: []
|
146
146
|
files:
|
147
|
+
- ".github/workflows/ruby.yml"
|
147
148
|
- ".gitignore"
|
148
|
-
- ".travis.yml"
|
149
149
|
- Gemfile
|
150
150
|
- Guardfile
|
151
151
|
- LICENSE.txt
|
@@ -209,6 +209,7 @@ files:
|
|
209
209
|
- lib/xdrgen/compilation.rb
|
210
210
|
- lib/xdrgen/generators.rb
|
211
211
|
- lib/xdrgen/generators/base.rb
|
212
|
+
- lib/xdrgen/generators/csharp.rb
|
212
213
|
- lib/xdrgen/generators/elixir.rb
|
213
214
|
- lib/xdrgen/generators/go.rb
|
214
215
|
- lib/xdrgen/generators/java.rb
|
@@ -258,7 +259,7 @@ homepage: http://github.com/stellar/xdrgen
|
|
258
259
|
licenses:
|
259
260
|
- ISC
|
260
261
|
metadata: {}
|
261
|
-
post_install_message:
|
262
|
+
post_install_message:
|
262
263
|
rdoc_options: []
|
263
264
|
require_paths:
|
264
265
|
- lib
|
@@ -273,8 +274,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
273
274
|
- !ruby/object:Gem::Version
|
274
275
|
version: '0'
|
275
276
|
requirements: []
|
276
|
-
rubygems_version: 3.
|
277
|
-
signing_key:
|
277
|
+
rubygems_version: 3.2.15
|
278
|
+
signing_key:
|
278
279
|
specification_version: 4
|
279
280
|
summary: An XDR code generator
|
280
281
|
test_files:
|
data/.travis.yml
DELETED