xdrgen 0.1.0 → 0.1.1
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/.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