bson 4.15.0-java → 5.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +4 -4
  4. data/Rakefile +5 -0
  5. data/lib/bson/active_support.rb +1 -0
  6. data/lib/bson/array.rb +57 -31
  7. data/lib/bson/big_decimal.rb +16 -6
  8. data/lib/bson/binary.rb +255 -128
  9. data/lib/bson/boolean.rb +1 -0
  10. data/lib/bson/code.rb +9 -11
  11. data/lib/bson/code_with_scope.rb +8 -10
  12. data/lib/bson/config.rb +1 -27
  13. data/lib/bson/date.rb +2 -1
  14. data/lib/bson/date_time.rb +2 -1
  15. data/lib/bson/db_pointer.rb +11 -12
  16. data/lib/bson/dbref.rb +11 -9
  17. data/lib/bson/decimal128/builder.rb +9 -8
  18. data/lib/bson/decimal128.rb +24 -110
  19. data/lib/bson/document.rb +1 -0
  20. data/lib/bson/environment.rb +1 -0
  21. data/lib/bson/error/bson_decode_error.rb +11 -0
  22. data/lib/bson/error/ext_json_parse_error.rb +11 -0
  23. data/lib/bson/error/illegal_key.rb +23 -0
  24. data/lib/bson/error/invalid_binary_type.rb +37 -0
  25. data/lib/bson/error/invalid_dbref_argument.rb +12 -0
  26. data/lib/bson/error/invalid_decimal128_argument.rb +25 -0
  27. data/lib/bson/error/invalid_decimal128_range.rb +27 -0
  28. data/lib/bson/error/invalid_decimal128_string.rb +26 -0
  29. data/lib/bson/error/invalid_key.rb +24 -0
  30. data/lib/bson/error/invalid_object_id.rb +11 -0
  31. data/lib/bson/error/invalid_regexp_pattern.rb +13 -0
  32. data/lib/bson/error/unrepresentable_precision.rb +19 -0
  33. data/lib/bson/error/unserializable_class.rb +13 -0
  34. data/lib/bson/error/unsupported_binary_subtype.rb +12 -0
  35. data/lib/bson/error/unsupported_type.rb +11 -0
  36. data/lib/bson/error.rb +16 -28
  37. data/lib/bson/ext_json.rb +1 -0
  38. data/lib/bson/false_class.rb +2 -1
  39. data/lib/bson/float.rb +2 -1
  40. data/lib/bson/hash.rb +127 -72
  41. data/lib/bson/int32.rb +16 -4
  42. data/lib/bson/int64.rb +16 -4
  43. data/lib/bson/integer.rb +3 -4
  44. data/lib/bson/json.rb +1 -0
  45. data/lib/bson/max_key.rb +7 -9
  46. data/lib/bson/min_key.rb +7 -9
  47. data/lib/bson/nil_class.rb +1 -0
  48. data/lib/bson/object.rb +5 -25
  49. data/lib/bson/object_id.rb +75 -121
  50. data/lib/bson/open_struct.rb +3 -2
  51. data/lib/bson/regexp.rb +35 -64
  52. data/lib/bson/registry.rb +2 -6
  53. data/lib/bson/specialized.rb +2 -1
  54. data/lib/bson/string.rb +4 -27
  55. data/lib/bson/symbol.rb +22 -19
  56. data/lib/bson/time.rb +2 -1
  57. data/lib/bson/time_with_zone.rb +13 -1
  58. data/lib/bson/timestamp.rb +2 -1
  59. data/lib/bson/true_class.rb +2 -1
  60. data/lib/bson/undefined.rb +14 -0
  61. data/lib/bson/version.rb +2 -1
  62. data/lib/bson-ruby.jar +0 -0
  63. data/lib/bson.rb +3 -2
  64. data/spec/bson/array_spec.rb +19 -60
  65. data/spec/bson/big_decimal_spec.rb +16 -4
  66. data/spec/bson/binary_spec.rb +83 -74
  67. data/spec/bson/binary_uuid_spec.rb +1 -0
  68. data/spec/bson/boolean_spec.rb +1 -0
  69. data/spec/bson/byte_buffer_read_spec.rb +1 -0
  70. data/spec/bson/byte_buffer_spec.rb +1 -0
  71. data/spec/bson/byte_buffer_write_spec.rb +1 -0
  72. data/spec/bson/code_spec.rb +5 -3
  73. data/spec/bson/code_with_scope_spec.rb +5 -3
  74. data/spec/bson/config_spec.rb +1 -35
  75. data/spec/bson/date_spec.rb +1 -0
  76. data/spec/bson/date_time_spec.rb +1 -0
  77. data/spec/bson/dbref_legacy_spec.rb +20 -3
  78. data/spec/bson/dbref_spec.rb +9 -9
  79. data/spec/bson/decimal128_spec.rb +40 -20
  80. data/spec/bson/document_as_spec.rb +1 -0
  81. data/spec/bson/document_spec.rb +1 -1
  82. data/spec/bson/ext_json_parse_spec.rb +1 -0
  83. data/spec/bson/false_class_spec.rb +8 -0
  84. data/spec/bson/float_spec.rb +8 -3
  85. data/spec/bson/hash_as_spec.rb +1 -0
  86. data/spec/bson/hash_spec.rb +87 -75
  87. data/spec/bson/int32_spec.rb +21 -6
  88. data/spec/bson/int64_spec.rb +21 -6
  89. data/spec/bson/integer_spec.rb +45 -13
  90. data/spec/bson/json_spec.rb +1 -0
  91. data/spec/bson/max_key_spec.rb +5 -3
  92. data/spec/bson/min_key_spec.rb +5 -3
  93. data/spec/bson/nil_class_spec.rb +1 -0
  94. data/spec/bson/object_id_spec.rb +43 -4
  95. data/spec/bson/object_spec.rb +2 -1
  96. data/spec/bson/open_struct_spec.rb +14 -71
  97. data/spec/bson/raw_spec.rb +9 -15
  98. data/spec/bson/regexp_spec.rb +4 -3
  99. data/spec/bson/registry_spec.rb +2 -1
  100. data/spec/bson/string_spec.rb +13 -38
  101. data/spec/bson/symbol_raw_spec.rb +25 -0
  102. data/spec/bson/symbol_spec.rb +15 -18
  103. data/spec/bson/time_spec.rb +1 -0
  104. data/spec/bson/time_with_zone_spec.rb +1 -0
  105. data/spec/bson/timestamp_spec.rb +1 -0
  106. data/spec/bson/true_class_spec.rb +8 -0
  107. data/spec/bson/undefined_spec.rb +27 -0
  108. data/spec/bson_spec.rb +1 -0
  109. data/spec/runners/common_driver.rb +6 -5
  110. data/spec/runners/corpus.rb +6 -0
  111. data/spec/runners/corpus_legacy.rb +1 -0
  112. data/spec/shared/lib/mrss/constraints.rb +8 -16
  113. data/spec/shared/lib/mrss/docker_runner.rb +30 -3
  114. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  115. data/spec/shared/lib/mrss/event_subscriber.rb +15 -5
  116. data/spec/shared/lib/mrss/lite_constraints.rb +48 -1
  117. data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
  118. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  119. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  120. data/spec/shared/lib/mrss/utils.rb +28 -6
  121. data/spec/shared/share/Dockerfile.erb +68 -85
  122. data/spec/shared/shlib/config.sh +27 -0
  123. data/spec/shared/shlib/server.sh +73 -24
  124. data/spec/shared/shlib/set_env.sh +39 -1
  125. data/spec/spec_helper.rb +1 -0
  126. data/spec/spec_tests/common_driver_spec.rb +9 -4
  127. data/spec/spec_tests/corpus_legacy_spec.rb +1 -0
  128. data/spec/spec_tests/corpus_spec.rb +13 -3
  129. data/spec/spec_tests/data/corpus/binary.json +5 -0
  130. data/spec/spec_tests/data/corpus/code.json +13 -13
  131. data/spec/spec_tests/data/corpus/decimal128-4.json +48 -0
  132. data/spec/spec_tests/data/corpus/decimal128-6.json +12 -0
  133. data/spec/spec_tests/data/corpus/decimal128-7.json +4 -0
  134. data/spec/spec_tests/data/corpus/document.json +20 -0
  135. data/spec/spec_tests/data/corpus/symbol.json +7 -7
  136. data/spec/spec_tests/data/corpus/top.json +18 -3
  137. data/spec/support/shared_examples.rb +28 -5
  138. data/spec/support/spec_config.rb +1 -0
  139. data/spec/support/utils.rb +49 -1
  140. data.tar.gz.sig +0 -0
  141. metadata +166 -142
  142. metadata.gz.sig +0 -0
@@ -20,48 +20,48 @@
20
20
  },
21
21
  {
22
22
  "description": "two-byte UTF-8 (\u00e9)",
23
- "canonical_bson": "190000000261000D000000C3A9C3A9C3A9C3A9C3A9C3A90000",
24
- "canonical_extjson": "{\"a\" : \"\\u00e9\\u00e9\\u00e9\\u00e9\\u00e9\\u00e9\"}"
23
+ "canonical_bson": "190000000D61000D000000C3A9C3A9C3A9C3A9C3A9C3A90000",
24
+ "canonical_extjson": "{\"a\" : {\"$code\" : \"\\u00e9\\u00e9\\u00e9\\u00e9\\u00e9\\u00e9\"}}"
25
25
  },
26
26
  {
27
27
  "description": "three-byte UTF-8 (\u2606)",
28
- "canonical_bson": "190000000261000D000000E29886E29886E29886E298860000",
29
- "canonical_extjson": "{\"a\" : \"\\u2606\\u2606\\u2606\\u2606\"}"
28
+ "canonical_bson": "190000000D61000D000000E29886E29886E29886E298860000",
29
+ "canonical_extjson": "{\"a\" : {\"$code\" : \"\\u2606\\u2606\\u2606\\u2606\"}}"
30
30
  },
31
31
  {
32
32
  "description": "Embedded nulls",
33
- "canonical_bson": "190000000261000D0000006162006261620062616261620000",
34
- "canonical_extjson": "{\"a\" : \"ab\\u0000bab\\u0000babab\"}"
33
+ "canonical_bson": "190000000D61000D0000006162006261620062616261620000",
34
+ "canonical_extjson": "{\"a\" : {\"$code\" : \"ab\\u0000bab\\u0000babab\"}}"
35
35
  }
36
36
  ],
37
37
  "decodeErrors": [
38
38
  {
39
39
  "description": "bad code string length: 0 (but no 0x00 either)",
40
- "bson": "0C0000000261000000000000"
40
+ "bson": "0C0000000D61000000000000"
41
41
  },
42
42
  {
43
43
  "description": "bad code string length: -1",
44
- "bson": "0C000000026100FFFFFFFF00"
44
+ "bson": "0C0000000D6100FFFFFFFF00"
45
45
  },
46
46
  {
47
47
  "description": "bad code string length: eats terminator",
48
- "bson": "10000000026100050000006200620000"
48
+ "bson": "100000000D6100050000006200620000"
49
49
  },
50
50
  {
51
51
  "description": "bad code string length: longer than rest of document",
52
- "bson": "120000000200FFFFFF00666F6F6261720000"
52
+ "bson": "120000000D00FFFFFF00666F6F6261720000"
53
53
  },
54
54
  {
55
55
  "description": "code string is not null-terminated",
56
- "bson": "1000000002610004000000616263FF00"
56
+ "bson": "100000000D610004000000616263FF00"
57
57
  },
58
58
  {
59
59
  "description": "empty code string, but extra null",
60
- "bson": "0E00000002610001000000000000"
60
+ "bson": "0E0000000D610001000000000000"
61
61
  },
62
62
  {
63
63
  "description": "invalid UTF-8",
64
- "bson": "0E00000002610002000000E90000"
64
+ "bson": "0E0000000D610002000000E90000"
65
65
  }
66
66
  ]
67
67
  }
@@ -112,6 +112,54 @@
112
112
  {
113
113
  "description": "[basx563] Near-specials (Conversion_syntax)",
114
114
  "string": "NaNs"
115
+ },
116
+ {
117
+ "description": "[dqbas939] overflow results at different rounding modes (Overflow & Inexact & Rounded)",
118
+ "string": "-7e10000"
119
+ },
120
+ {
121
+ "description": "[dqbsr534] negatives (Rounded & Inexact)",
122
+ "string": "-1.11111111111111111111111111111234650"
123
+ },
124
+ {
125
+ "description": "[dqbsr535] negatives (Rounded & Inexact)",
126
+ "string": "-1.11111111111111111111111111111234551"
127
+ },
128
+ {
129
+ "description": "[dqbsr533] negatives (Rounded & Inexact)",
130
+ "string": "-1.11111111111111111111111111111234550"
131
+ },
132
+ {
133
+ "description": "[dqbsr532] negatives (Rounded & Inexact)",
134
+ "string": "-1.11111111111111111111111111111234549"
135
+ },
136
+ {
137
+ "description": "[dqbsr432] check rounding modes heeded (Rounded & Inexact)",
138
+ "string": "1.11111111111111111111111111111234549"
139
+ },
140
+ {
141
+ "description": "[dqbsr433] check rounding modes heeded (Rounded & Inexact)",
142
+ "string": "1.11111111111111111111111111111234550"
143
+ },
144
+ {
145
+ "description": "[dqbsr435] check rounding modes heeded (Rounded & Inexact)",
146
+ "string": "1.11111111111111111111111111111234551"
147
+ },
148
+ {
149
+ "description": "[dqbsr434] check rounding modes heeded (Rounded & Inexact)",
150
+ "string": "1.11111111111111111111111111111234650"
151
+ },
152
+ {
153
+ "description": "[dqbas938] overflow results at different rounding modes (Overflow & Inexact & Rounded)",
154
+ "string": "7e10000"
155
+ },
156
+ {
157
+ "description": "Inexact rounding#1",
158
+ "string": "100000000000000000000000000000000000000000000000000000000001"
159
+ },
160
+ {
161
+ "description": "Inexact rounding#2",
162
+ "string": "1E-6177"
115
163
  }
116
164
  ]
117
165
  }
@@ -75,6 +75,18 @@
75
75
  "description": "Empty string",
76
76
  "string": ""
77
77
  },
78
+ {
79
+ "description": "leading white space positive number",
80
+ "string": " 1"
81
+ },
82
+ {
83
+ "description": "leading white space negative number",
84
+ "string": " -1"
85
+ },
86
+ {
87
+ "description": "trailing white space",
88
+ "string": "1 "
89
+ },
78
90
  {
79
91
  "description": "Invalid",
80
92
  "string": "E"
@@ -267,6 +267,10 @@
267
267
  "description": "[basx570] Near-specials (Conversion_syntax)",
268
268
  "string": "9Inf"
269
269
  },
270
+ {
271
+ "description": "[basx512] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax)",
272
+ "string": "12 "
273
+ },
270
274
  {
271
275
  "description": "[basx517] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax)",
272
276
  "string": "12-"
@@ -17,6 +17,26 @@
17
17
  "description": "Single-character key subdoc",
18
18
  "canonical_bson": "160000000378000E0000000261000200000062000000",
19
19
  "canonical_extjson": "{\"x\" : {\"a\" : \"b\"}}"
20
+ },
21
+ {
22
+ "description": "Dollar-prefixed key in sub-document",
23
+ "canonical_bson": "170000000378000F000000022461000200000062000000",
24
+ "canonical_extjson": "{\"x\" : {\"$a\" : \"b\"}}"
25
+ },
26
+ {
27
+ "description": "Dollar as key in sub-document",
28
+ "canonical_bson": "160000000378000E0000000224000200000061000000",
29
+ "canonical_extjson": "{\"x\" : {\"$\" : \"a\"}}"
30
+ },
31
+ {
32
+ "description": "Dotted key in sub-document",
33
+ "canonical_bson": "180000000378001000000002612E62000200000063000000",
34
+ "canonical_extjson": "{\"x\" : {\"a.b\" : \"c\"}}"
35
+ },
36
+ {
37
+ "description": "Dot as key in sub-document",
38
+ "canonical_bson": "160000000378000E000000022E000200000061000000",
39
+ "canonical_extjson": "{\"x\" : {\".\" : \"a\"}}"
20
40
  }
21
41
  ],
22
42
  "decodeErrors": [
@@ -50,31 +50,31 @@
50
50
  "decodeErrors": [
51
51
  {
52
52
  "description": "bad symbol length: 0 (but no 0x00 either)",
53
- "bson": "0C0000000261000000000000"
53
+ "bson": "0C0000000E61000000000000"
54
54
  },
55
55
  {
56
56
  "description": "bad symbol length: -1",
57
- "bson": "0C000000026100FFFFFFFF00"
57
+ "bson": "0C0000000E6100FFFFFFFF00"
58
58
  },
59
59
  {
60
60
  "description": "bad symbol length: eats terminator",
61
- "bson": "10000000026100050000006200620000"
61
+ "bson": "100000000E6100050000006200620000"
62
62
  },
63
63
  {
64
64
  "description": "bad symbol length: longer than rest of document",
65
- "bson": "120000000200FFFFFF00666F6F6261720000"
65
+ "bson": "120000000E00FFFFFF00666F6F6261720000"
66
66
  },
67
67
  {
68
68
  "description": "symbol is not null-terminated",
69
- "bson": "1000000002610004000000616263FF00"
69
+ "bson": "100000000E610004000000616263FF00"
70
70
  },
71
71
  {
72
72
  "description": "empty symbol, but extra null",
73
- "bson": "0E00000002610001000000000000"
73
+ "bson": "0E0000000E610001000000000000"
74
74
  },
75
75
  {
76
76
  "description": "invalid UTF-8",
77
- "bson": "0E00000002610002000000E90000"
77
+ "bson": "0E0000000E610002000000E90000"
78
78
  }
79
79
  ]
80
80
  }
@@ -3,9 +3,24 @@
3
3
  "bson_type": "0x00",
4
4
  "valid": [
5
5
  {
6
- "description": "Document with keys that start with $",
6
+ "description": "Dollar-prefixed key in top-level document",
7
7
  "canonical_bson": "0F00000010246B6579002A00000000",
8
8
  "canonical_extjson": "{\"$key\": {\"$numberInt\": \"42\"}}"
9
+ },
10
+ {
11
+ "description": "Dollar as key in top-level document",
12
+ "canonical_bson": "0E00000002240002000000610000",
13
+ "canonical_extjson": "{\"$\": \"a\"}"
14
+ },
15
+ {
16
+ "description": "Dotted key in top-level document",
17
+ "canonical_bson": "1000000002612E620002000000630000",
18
+ "canonical_extjson": "{\"a.b\": \"c\"}"
19
+ },
20
+ {
21
+ "description": "Dot as key in top-level document",
22
+ "canonical_bson": "0E000000022E0002000000610000",
23
+ "canonical_extjson": "{\".\": \"a\"}"
9
24
  }
10
25
  ],
11
26
  "decodeErrors": [
@@ -77,11 +92,11 @@
77
92
  },
78
93
  {
79
94
  "description": "Bad $regularExpression (pattern is number, not string)",
80
- "string": "{\"x\" : {\"$regularExpression\" : { \"pattern\": 42, \"$options\" : \"\"}}}"
95
+ "string": "{\"x\" : {\"$regularExpression\" : { \"pattern\": 42, \"options\" : \"\"}}}"
81
96
  },
82
97
  {
83
98
  "description": "Bad $regularExpression (options are number, not string)",
84
- "string": "{\"x\" : {\"$regularExpression\" : { \"pattern\": \"a\", \"$options\" : 0}}}"
99
+ "string": "{\"x\" : {\"$regularExpression\" : { \"pattern\": \"a\", \"options\" : 0}}}"
85
100
  },
86
101
  {
87
102
  "description" : "Bad $regularExpression (missing pattern field)",
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -63,6 +64,28 @@ shared_examples_for "a JSON serializable object" do
63
64
  end
64
65
  end
65
66
 
67
+ shared_examples_for "an Extended JSON serializable object" do
68
+
69
+ it "serializes the Extended JSON from #as_extended_json" do
70
+ expect(object.to_extended_json).to eq(object.as_extended_json.to_json)
71
+ end
72
+ end
73
+
74
+ shared_examples_for '#as_extended_json returns self' do
75
+
76
+ it 'returns self' do
77
+ expect(object.as_extended_json).to eq(object)
78
+ end
79
+ end
80
+
81
+ shared_examples_for '#as_json calls #as_extended_json' do
82
+
83
+ it 'calls #as_extended_json' do
84
+ expect(object).to receive(:as_extended_json).with(no_args)
85
+ object.as_json
86
+ end
87
+ end
88
+
66
89
  shared_examples_for "immutable when frozen" do |block|
67
90
 
68
91
  context "when the document is frozen" do
@@ -122,7 +145,7 @@ shared_examples_for "a validated BSON key" do
122
145
  end
123
146
  end
124
147
 
125
- context "when the string is invalid" do
148
+ context "when the string has dots/dollars" do
126
149
 
127
150
  context "when the string starts with $" do
128
151
 
@@ -130,10 +153,10 @@ shared_examples_for "a validated BSON key" do
130
153
  "$testing"
131
154
  end
132
155
 
133
- it "raises an exception" do
156
+ it "does not raise an exception" do
134
157
  expect {
135
158
  validated
136
- }.to raise_error(BSON::String::IllegalKey)
159
+ }.to_not raise_error
137
160
  end
138
161
  end
139
162
 
@@ -143,10 +166,10 @@ shared_examples_for "a validated BSON key" do
143
166
  "testing.testing"
144
167
  end
145
168
 
146
- it "raises an exception" do
169
+ it "does not raise an exception" do
147
170
  expect {
148
171
  validated
149
- }.to raise_error(BSON::String::IllegalKey)
172
+ }.to_not raise_error
150
173
  end
151
174
  end
152
175
  end
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  require 'singleton'
2
3
 
3
4
  class SpecConfig
@@ -1,10 +1,58 @@
1
+ # rubocop:todo all
1
2
  module Utils
3
+ extend self
4
+
2
5
  # JRuby chokes when strings like "\xfe\x00\xff", which are not valid UTF-8,
3
6
  # appear in the source. Use this method to build such strings.
4
7
  # char_array is an array of byte values to use for the string.
5
- module_function def make_byte_string(char_array, encoding = 'BINARY')
8
+ def make_byte_string(char_array, encoding = 'BINARY')
6
9
  char_array.map do |char|
7
10
  char.chr.force_encoding('BINARY')
8
11
  end.join.force_encoding(encoding)
9
12
  end
13
+
14
+ # Forks the current process and executes the given block in the child.
15
+ # The value returned by the block is then returned in the parent process
16
+ # by this method.
17
+ #
18
+ # @return [ Object ] the value returned by the block
19
+ def perform_in_child(&block)
20
+ reader, writer = IO.pipe
21
+
22
+ if fork
23
+ parent_worker(reader, writer)
24
+ else
25
+ child_worker(reader, writer, &block)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ # A utility method for #perform_in_child, to handle tasks for the parent
32
+ # side of the fork.
33
+ #
34
+ # @param [ IO ] reader The reader IO for the pipe
35
+ # @param [ IO ] writer The writer IO for the pipe
36
+ #
37
+ # @return [ Object ] the value returned by the child process
38
+ def parent_worker(reader, writer)
39
+ writer.close
40
+ blob = reader.read
41
+ reader.close
42
+ Process.wait
43
+ Marshal.load(blob)
44
+ end
45
+
46
+ # A utility method for #perform_in_child, to handle tasks for the child
47
+ # side of the fork.
48
+ #
49
+ # @param [ IO ] reader The reader IO for the pipe
50
+ # @param [ IO ] writer The writer IO for the pipe
51
+ def child_worker(reader, writer, &block)
52
+ reader.close
53
+ result = block.call
54
+ writer.write Marshal.dump(result)
55
+ writer.close
56
+ exit! 0
57
+ end
10
58
  end
data.tar.gz.sig CHANGED
Binary file