json 2.3.1 → 2.5.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +22 -0
  3. data/LICENSE +56 -0
  4. data/VERSION +1 -1
  5. data/ext/json/ext/generator/generator.c +60 -11
  6. data/ext/json/ext/generator/generator.h +5 -2
  7. data/ext/json/ext/parser/extconf.rb +25 -0
  8. data/ext/json/ext/parser/parser.c +110 -68
  9. data/ext/json/ext/parser/parser.h +1 -0
  10. data/ext/json/ext/parser/parser.rl +67 -25
  11. data/ext/json/extconf.rb +1 -0
  12. data/json.gemspec +11 -77
  13. data/lib/json.rb +171 -0
  14. data/lib/json/add/complex.rb +0 -1
  15. data/lib/json/add/rational.rb +0 -1
  16. data/lib/json/common.rb +240 -228
  17. data/lib/json/pure/generator.rb +28 -8
  18. data/lib/json/pure/parser.rb +20 -2
  19. data/lib/json/version.rb +1 -1
  20. data/tests/fixtures/fail29.json +1 -0
  21. data/tests/fixtures/fail30.json +1 -0
  22. data/tests/fixtures/fail31.json +1 -0
  23. data/tests/fixtures/fail32.json +1 -0
  24. data/tests/json_addition_test.rb +0 -4
  25. data/tests/json_common_interface_test.rb +43 -0
  26. data/tests/json_fixtures_test.rb +3 -0
  27. data/tests/json_generator_test.rb +16 -38
  28. data/tests/json_parser_test.rb +25 -0
  29. data/tests/lib/core_assertions.rb +763 -0
  30. data/tests/lib/envutil.rb +365 -0
  31. data/tests/lib/find_executable.rb +22 -0
  32. data/tests/lib/helper.rb +4 -0
  33. data/tests/ractor_test.rb +30 -0
  34. data/tests/test_helper.rb +3 -3
  35. metadata +16 -37
  36. data/.gitignore +0 -18
  37. data/.travis.yml +0 -26
  38. data/README-json-jruby.md +0 -33
  39. data/Rakefile +0 -334
  40. data/diagrams/.keep +0 -0
  41. data/install.rb +0 -23
  42. data/java/src/json/ext/ByteListTranscoder.java +0 -166
  43. data/java/src/json/ext/Generator.java +0 -466
  44. data/java/src/json/ext/GeneratorMethods.java +0 -231
  45. data/java/src/json/ext/GeneratorService.java +0 -42
  46. data/java/src/json/ext/GeneratorState.java +0 -490
  47. data/java/src/json/ext/OptionsReader.java +0 -113
  48. data/java/src/json/ext/Parser.java +0 -2362
  49. data/java/src/json/ext/Parser.rl +0 -893
  50. data/java/src/json/ext/ParserService.java +0 -34
  51. data/java/src/json/ext/RuntimeInfo.java +0 -116
  52. data/java/src/json/ext/StringDecoder.java +0 -166
  53. data/java/src/json/ext/StringEncoder.java +0 -111
  54. data/java/src/json/ext/Utils.java +0 -88
  55. data/json-java.gemspec +0 -37
  56. data/json_pure.gemspec +0 -33
  57. data/references/rfc7159.txt +0 -899
  58. data/tools/diff.sh +0 -18
  59. data/tools/fuzz.rb +0 -131
  60. data/tools/server.rb +0 -62
data/.gitignore DELETED
@@ -1,18 +0,0 @@
1
- .*.sw[pon]
2
- *.bundle
3
- coverage
4
- tags
5
- pkg
6
- .nfs.*
7
- .idea
8
- java/Json.iml
9
- Gemfile.lock
10
- .rvmrc
11
- *.rbc
12
- .rbx
13
- .AppleDouble
14
- .DS_Store
15
- */**/Makefile
16
- */**/*.o
17
- .byebug_history
18
- *.log
@@ -1,26 +0,0 @@
1
- # Passes arguments to bundle install (http://gembundler.com/man/bundle-install.1.html)
2
- #bundler_args: --binstubs
3
- language: ruby
4
-
5
- # Specify which ruby versions you wish to run your tests on, each version will be used
6
- rvm:
7
- - 2.0.0
8
- - 2.1
9
- - 2.2
10
- - 2.3
11
- - 2.4
12
- - 2.5
13
- - 2.6
14
- - 2.7.0-preview3
15
- - ruby-head
16
- - jruby
17
- - jruby-9.2.7.0
18
- - truffleruby
19
- matrix:
20
- allow_failures:
21
- - rvm: ruby-head
22
- - rvm: jruby
23
- - rvm: jruby-9.2.7.0
24
- - rvm: truffleruby
25
- script: "bundle exec rake"
26
- sudo: false
@@ -1,33 +0,0 @@
1
- JSON-JRuby
2
- ==========
3
-
4
- JSON-JRuby is a port of Florian Frank's native
5
- [`json` library](http://json.rubyforge.org/) to JRuby.
6
- It aims to be a perfect drop-in replacement for `json_pure`.
7
-
8
-
9
- Development version
10
- ===================
11
-
12
- The latest version is available from the
13
- [Git repository](http://github.com/mernen/json-jruby/tree):
14
-
15
- git clone git://github.com/mernen/json-jruby.git
16
-
17
-
18
- Compiling
19
- =========
20
-
21
- You'll need JRuby version 1.2 or greater to build JSON-JRuby.
22
- Its path must be set on the `jruby.dir` property of
23
- `nbproject/project.properties` (defaults to `../jruby`).
24
-
25
- Additionally, you'll need [Ant](http://ant.apache.org/), and
26
- [Ragel](http://www.cs.queensu.ca/~thurston/ragel/) 6.4 or greater.
27
-
28
- Then, from the folder where the sources are located, type:
29
-
30
- ant clean jar
31
-
32
- to clean any leftovers from previous builds and generate the `.jar` files.
33
- To generate a RubyGem, specify the `gem` action rather than `jar`.
data/Rakefile DELETED
@@ -1,334 +0,0 @@
1
- begin
2
- require 'rubygems/package_task'
3
- rescue LoadError
4
- end
5
-
6
- require 'rbconfig'
7
- include\
8
- begin
9
- RbConfig
10
- rescue NameError
11
- Config
12
- end
13
-
14
- require 'rake/clean'
15
- CLOBBER.include 'doc', 'Gemfile.lock'
16
- CLEAN.include FileList['diagrams/*.*'], 'doc', 'coverage', 'tmp',
17
- FileList["ext/**/{Makefile,mkmf.log}"], 'build', 'dist', FileList['**/*.rbc'],
18
- FileList["{ext,lib}/**/*.{so,bundle,#{CONFIG['DLEXT']},o,obj,pdb,lib,manifest,exp,def,jar,class,dSYM}"],
19
- FileList['java/src/**/*.class']
20
-
21
- require 'rake/testtask'
22
- class UndocumentedTestTask < Rake::TestTask
23
- def desc(*) end
24
- end
25
-
26
- which = lambda { |c|
27
- w = `which #{c}`
28
- break w.chomp unless w.empty?
29
- }
30
-
31
- MAKE = ENV['MAKE'] || %w[gmake make].find(&which)
32
- BUNDLE = ENV['BUNDLE'] || %w[bundle].find(&which)
33
- PKG_NAME = 'json'
34
- PKG_TITLE = 'JSON Implementation for Ruby'
35
- PKG_VERSION = File.read('VERSION').chomp
36
- PKG_FILES = FileList[`git ls-files`.split(/\n/)]
37
-
38
- EXT_ROOT_DIR = 'ext/json/ext'
39
- EXT_PARSER_DIR = "#{EXT_ROOT_DIR}/parser"
40
- EXT_PARSER_DL = "#{EXT_PARSER_DIR}/parser.#{CONFIG['DLEXT']}"
41
- RAGEL_PATH = "#{EXT_PARSER_DIR}/parser.rl"
42
- EXT_PARSER_SRC = "#{EXT_PARSER_DIR}/parser.c"
43
- EXT_GENERATOR_DIR = "#{EXT_ROOT_DIR}/generator"
44
- EXT_GENERATOR_DL = "#{EXT_GENERATOR_DIR}/generator.#{CONFIG['DLEXT']}"
45
- EXT_GENERATOR_SRC = "#{EXT_GENERATOR_DIR}/generator.c"
46
-
47
- JAVA_DIR = "java/src/json/ext"
48
- JAVA_RAGEL_PATH = "#{JAVA_DIR}/Parser.rl"
49
- JAVA_PARSER_SRC = "#{JAVA_DIR}/Parser.java"
50
- JAVA_SOURCES = FileList["#{JAVA_DIR}/*.java"]
51
- JAVA_CLASSES = []
52
- JRUBY_PARSER_JAR = File.expand_path("lib/json/ext/parser.jar")
53
- JRUBY_GENERATOR_JAR = File.expand_path("lib/json/ext/generator.jar")
54
-
55
- RAGEL_CODEGEN = %w[rlcodegen rlgen-cd ragel].find(&which)
56
- RAGEL_DOTGEN = %w[rlgen-dot rlgen-cd ragel].find(&which)
57
-
58
- desc "Installing library (pure)"
59
- task :install_pure => :version do
60
- ruby 'install.rb'
61
- end
62
-
63
- task :install_ext_really do
64
- sitearchdir = CONFIG["sitearchdir"]
65
- cd 'ext' do
66
- for file in Dir["json/ext/*.#{CONFIG['DLEXT']}"]
67
- d = File.join(sitearchdir, file)
68
- mkdir_p File.dirname(d)
69
- install(file, d)
70
- end
71
- warn " *** Installed EXT ruby library."
72
- end
73
- end
74
-
75
- desc "Installing library (extension)"
76
- task :install_ext => [ :compile, :install_pure, :install_ext_really ]
77
-
78
- desc "Installing library (extension)"
79
- task :install => :install_ext
80
-
81
- desc m = "Writing version information for #{PKG_VERSION}"
82
- task :version do
83
- puts m
84
- File.open(File.join('lib', 'json', 'version.rb'), 'w') do |v|
85
- v.puts <<EOT
86
- # frozen_string_literal: false
87
- module JSON
88
- # JSON version
89
- VERSION = '#{PKG_VERSION}'
90
- VERSION_ARRAY = VERSION.split(/\\./).map { |x| x.to_i } # :nodoc:
91
- VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
92
- VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
93
- VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
94
- end
95
- EOT
96
- end
97
- end
98
-
99
- task :check_env do
100
- ENV.key?('JSON') or fail "JSON env var is required"
101
- end
102
-
103
- desc "Testing library (pure ruby)"
104
- task :test_pure => [ :set_env_pure, :check_env, :do_test_pure ]
105
- task(:set_env_pure) { ENV['JSON'] = 'pure' }
106
-
107
- UndocumentedTestTask.new do |t|
108
- t.name = 'do_test_pure'
109
- t.libs << 'lib' << 'tests'
110
- t.test_files = FileList['tests/*_test.rb']
111
- t.verbose = true
112
- t.options = '-v'
113
- end
114
-
115
- desc "Testing library (pure ruby and extension)"
116
- task :test => [ :test_pure, :test_ext ]
117
-
118
- namespace :gems do
119
- desc 'Install all development gems'
120
- task :install do
121
- sh "#{BUNDLE}"
122
- end
123
- end
124
-
125
- if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
126
- ENV['JAVA_HOME'] ||= [
127
- '/usr/local/java/jdk',
128
- '/usr/lib/jvm/java-6-openjdk',
129
- '/Library/Java/Home',
130
- ].find { |c| File.directory?(c) }
131
- if ENV['JAVA_HOME']
132
- warn " *** JAVA_HOME is set to #{ENV['JAVA_HOME'].inspect}"
133
- ENV['PATH'] = ENV['PATH'].split(/:/).unshift(java_path = "#{ENV['JAVA_HOME']}/bin") * ':'
134
- warn " *** java binaries are assumed to be in #{java_path.inspect}"
135
- else
136
- warn " *** JAVA_HOME was not set or could not be guessed!"
137
- exit 1
138
- end
139
-
140
- file JAVA_PARSER_SRC => JAVA_RAGEL_PATH do
141
- cd JAVA_DIR do
142
- if RAGEL_CODEGEN == 'ragel'
143
- sh "ragel Parser.rl -J -o Parser.java"
144
- else
145
- sh "ragel -x Parser.rl | #{RAGEL_CODEGEN} -J"
146
- end
147
- end
148
- end
149
-
150
- desc "Generate parser for java with ragel"
151
- task :ragel => JAVA_PARSER_SRC
152
-
153
- desc "Delete the ragel generated Java source"
154
- task :ragel_clean do
155
- rm_rf JAVA_PARSER_SRC
156
- end
157
-
158
- JRUBY_JAR = File.join(CONFIG["libdir"], "jruby.jar")
159
- if File.exist?(JRUBY_JAR)
160
- JAVA_SOURCES.each do |src|
161
- classpath = (Dir['java/lib/*.jar'] << 'java/src' << JRUBY_JAR) * ':'
162
- obj = src.sub(/\.java\Z/, '.class')
163
- file obj => src do
164
- sh 'javac', '-classpath', classpath, '-source', '1.6', '-target', '1.6', src
165
- end
166
- JAVA_CLASSES << obj
167
- end
168
- else
169
- warn "WARNING: Cannot find jruby in path => Cannot build jruby extension!"
170
- end
171
-
172
- desc "Compiling jruby extension"
173
- task :compile => JAVA_CLASSES
174
-
175
- desc "Package the jruby gem"
176
- task :jruby_gem => :create_jar do
177
- sh 'gem build json-java.gemspec'
178
- mkdir_p 'pkg'
179
- mv "json-#{PKG_VERSION}-java.gem", 'pkg'
180
- end
181
-
182
- desc "Testing library (jruby)"
183
- task :test_ext => [ :set_env_ext, :create_jar, :check_env, :do_test_ext ]
184
- task(:set_env_ext) { ENV['JSON'] = 'ext' }
185
-
186
- UndocumentedTestTask.new do |t|
187
- t.name = 'do_test_ext'
188
- t.libs << 'lib' << 'tests'
189
- t.test_files = FileList['tests/*_test.rb']
190
- t.verbose = true
191
- t.options = '-v'
192
- end
193
-
194
- file JRUBY_PARSER_JAR => :compile do
195
- cd 'java/src' do
196
- parser_classes = FileList[
197
- "json/ext/ByteListTranscoder*.class",
198
- "json/ext/OptionsReader*.class",
199
- "json/ext/Parser*.class",
200
- "json/ext/RuntimeInfo*.class",
201
- "json/ext/StringDecoder*.class",
202
- "json/ext/Utils*.class"
203
- ]
204
- sh 'jar', 'cf', File.basename(JRUBY_PARSER_JAR), *parser_classes
205
- mv File.basename(JRUBY_PARSER_JAR), File.dirname(JRUBY_PARSER_JAR)
206
- end
207
- end
208
-
209
- desc "Create parser jar"
210
- task :create_parser_jar => JRUBY_PARSER_JAR
211
-
212
- file JRUBY_GENERATOR_JAR => :compile do
213
- cd 'java/src' do
214
- generator_classes = FileList[
215
- "json/ext/ByteListTranscoder*.class",
216
- "json/ext/OptionsReader*.class",
217
- "json/ext/Generator*.class",
218
- "json/ext/RuntimeInfo*.class",
219
- "json/ext/StringEncoder*.class",
220
- "json/ext/Utils*.class"
221
- ]
222
- sh 'jar', 'cf', File.basename(JRUBY_GENERATOR_JAR), *generator_classes
223
- mv File.basename(JRUBY_GENERATOR_JAR), File.dirname(JRUBY_GENERATOR_JAR)
224
- end
225
- end
226
-
227
- desc "Create generator jar"
228
- task :create_generator_jar => JRUBY_GENERATOR_JAR
229
-
230
- desc "Create parser and generator jars"
231
- task :create_jar => [ :create_parser_jar, :create_generator_jar ]
232
-
233
- desc "Build all gems and archives for a new release of the jruby extension."
234
- task :build => [ :clean, :version, :jruby_gem ]
235
-
236
- task :release => :build
237
- else
238
- desc "Compiling extension"
239
- task :compile => [ EXT_PARSER_DL, EXT_GENERATOR_DL ]
240
-
241
- file EXT_PARSER_DL => EXT_PARSER_SRC do
242
- cd EXT_PARSER_DIR do
243
- ruby 'extconf.rb'
244
- sh MAKE
245
- end
246
- cp "#{EXT_PARSER_DIR}/parser.#{CONFIG['DLEXT']}", EXT_ROOT_DIR
247
- end
248
-
249
- file EXT_GENERATOR_DL => EXT_GENERATOR_SRC do
250
- cd EXT_GENERATOR_DIR do
251
- ruby 'extconf.rb'
252
- sh MAKE
253
- end
254
- cp "#{EXT_GENERATOR_DIR}/generator.#{CONFIG['DLEXT']}", EXT_ROOT_DIR
255
- end
256
-
257
- desc "Testing library (extension)"
258
- task :test_ext => [ :check_env, :compile, :do_test_ext ]
259
-
260
- UndocumentedTestTask.new do |t|
261
- t.name = 'do_test_ext'
262
- t.libs << 'ext' << 'lib' << 'tests'
263
- t.test_files = FileList['tests/*_test.rb']
264
- t.verbose = true
265
- t.options = '-v'
266
- end
267
-
268
- desc "Generate parser with ragel"
269
- task :ragel => EXT_PARSER_SRC
270
-
271
- desc "Delete the ragel generated C source"
272
- task :ragel_clean do
273
- rm_rf EXT_PARSER_SRC
274
- end
275
-
276
- desc "Update the tags file"
277
- task :tags do
278
- system 'ctags', *Dir['**/*.{rb,c,h,java}']
279
- end
280
-
281
- file EXT_PARSER_SRC => RAGEL_PATH do
282
- cd EXT_PARSER_DIR do
283
- if RAGEL_CODEGEN == 'ragel'
284
- sh "ragel parser.rl -G2 -o parser.c"
285
- else
286
- sh "ragel -x parser.rl | #{RAGEL_CODEGEN} -G2"
287
- end
288
- src = File.read("parser.c").gsub(/[ \t]+$/, '')
289
- src.gsub!(/^static const int (JSON_.*=.*);$/, 'enum {\1};')
290
- src.gsub!(/0 <= \(\*p\) && \(\*p\) <= 31/, "0 <= (signed char)(*p) && (*p) <= 31")
291
- src[0, 0] = "/* This file is automatically generated from parser.rl by using ragel */"
292
- File.open("parser.c", "w") {|f| f.print src}
293
- end
294
- end
295
-
296
- desc "Generate diagrams of ragel parser (ps)"
297
- task :ragel_dot_ps do
298
- root = 'diagrams'
299
- specs = []
300
- File.new(RAGEL_PATH).grep(/^\s*machine\s*(\S+);\s*$/) { specs << $1 }
301
- for s in specs
302
- if RAGEL_DOTGEN == 'ragel'
303
- sh "ragel #{RAGEL_PATH} -S#{s} -p -V | dot -Tps -o#{root}/#{s}.ps"
304
- else
305
- sh "ragel -x #{RAGEL_PATH} -S#{s} | #{RAGEL_DOTGEN} -p|dot -Tps -o#{root}/#{s}.ps"
306
- end
307
- end
308
- end
309
-
310
- desc "Generate diagrams of ragel parser (png)"
311
- task :ragel_dot_png do
312
- root = 'diagrams'
313
- specs = []
314
- File.new(RAGEL_PATH).grep(/^\s*machine\s*(\S+);\s*$/) { specs << $1 }
315
- for s in specs
316
- if RAGEL_DOTGEN == 'ragel'
317
- sh "ragel #{RAGEL_PATH} -S#{s} -p -V | dot -Tpng -o#{root}/#{s}.png"
318
- else
319
- sh "ragel -x #{RAGEL_PATH} -S#{s} | #{RAGEL_DOTGEN} -p|dot -Tpng -o#{root}/#{s}.png"
320
- end
321
- end
322
- end
323
-
324
- desc "Generate diagrams of ragel parser"
325
- task :ragel_dot => [ :ragel_dot_png, :ragel_dot_ps ]
326
-
327
- desc "Build all gems and archives for a new release of json and json_pure."
328
- task :build => [ :clean, :gemspec, :package ]
329
-
330
- task :release => :build
331
- end
332
-
333
- desc "Compile in the the source directory"
334
- task :default => [ :clean, :test ]
File without changes
data/install.rb DELETED
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'fileutils'
4
- include FileUtils::Verbose
5
- require 'rbconfig'
6
- include\
7
- begin
8
- RbConfig
9
- rescue NameError
10
- Config
11
- end
12
-
13
- sitelibdir = CONFIG["sitelibdir"]
14
- cd 'lib' do
15
- install('json.rb', sitelibdir)
16
- mkdir_p File.join(sitelibdir, 'json')
17
- for file in Dir['json/**/*}']
18
- d = File.join(sitelibdir, file)
19
- mkdir_p File.dirname(d)
20
- install(file, d)
21
- end
22
- end
23
- warn " *** Installed PURE ruby library."
@@ -1,166 +0,0 @@
1
- /*
2
- * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
- *
4
- * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
5
- */
6
- package json.ext;
7
-
8
- import org.jruby.exceptions.RaiseException;
9
- import org.jruby.runtime.ThreadContext;
10
- import org.jruby.util.ByteList;
11
-
12
- /**
13
- * A class specialized in transcoding a certain String format into another,
14
- * using UTF-8 ByteLists as both input and output.
15
- */
16
- abstract class ByteListTranscoder {
17
- protected final ThreadContext context;
18
-
19
- protected ByteList src;
20
- protected int srcEnd;
21
- /** Position where the last read character started */
22
- protected int charStart;
23
- /** Position of the next character to read */
24
- protected int pos;
25
-
26
- private ByteList out;
27
- /**
28
- * When a character that can be copied straight into the output is found,
29
- * its index is stored on this variable, and copying is delayed until
30
- * the sequence of characters that can be copied ends.
31
- *
32
- * <p>The variable stores -1 when not in a plain sequence.
33
- */
34
- private int quoteStart = -1;
35
-
36
- protected ByteListTranscoder(ThreadContext context) {
37
- this.context = context;
38
- }
39
-
40
- protected void init(ByteList src, ByteList out) {
41
- this.init(src, 0, src.length(), out);
42
- }
43
-
44
- protected void init(ByteList src, int start, int end, ByteList out) {
45
- this.src = src;
46
- this.pos = start;
47
- this.charStart = start;
48
- this.srcEnd = end;
49
- this.out = out;
50
- }
51
-
52
- /**
53
- * Returns whether there are any characters left to be read.
54
- */
55
- protected boolean hasNext() {
56
- return pos < srcEnd;
57
- }
58
-
59
- /**
60
- * Returns the next character in the buffer.
61
- */
62
- private char next() {
63
- return src.charAt(pos++);
64
- }
65
-
66
- /**
67
- * Reads an UTF-8 character from the input and returns its code point,
68
- * while advancing the input position.
69
- *
70
- * <p>Raises an {@link #invalidUtf8()} exception if an invalid byte
71
- * is found.
72
- */
73
- protected int readUtf8Char() {
74
- charStart = pos;
75
- char head = next();
76
- if (head <= 0x7f) { // 0b0xxxxxxx (ASCII)
77
- return head;
78
- }
79
- if (head <= 0xbf) { // 0b10xxxxxx
80
- throw invalidUtf8(); // tail byte with no head
81
- }
82
- if (head <= 0xdf) { // 0b110xxxxx
83
- ensureMin(1);
84
- int cp = ((head & 0x1f) << 6)
85
- | nextPart();
86
- if (cp < 0x0080) throw invalidUtf8();
87
- return cp;
88
- }
89
- if (head <= 0xef) { // 0b1110xxxx
90
- ensureMin(2);
91
- int cp = ((head & 0x0f) << 12)
92
- | (nextPart() << 6)
93
- | nextPart();
94
- if (cp < 0x0800) throw invalidUtf8();
95
- return cp;
96
- }
97
- if (head <= 0xf7) { // 0b11110xxx
98
- ensureMin(3);
99
- int cp = ((head & 0x07) << 18)
100
- | (nextPart() << 12)
101
- | (nextPart() << 6)
102
- | nextPart();
103
- if (!Character.isValidCodePoint(cp)) throw invalidUtf8();
104
- return cp;
105
- }
106
- // 0b11111xxx?
107
- throw invalidUtf8();
108
- }
109
-
110
- /**
111
- * Throws a GeneratorError if the input list doesn't have at least this
112
- * many bytes left.
113
- */
114
- protected void ensureMin(int n) {
115
- if (pos + n > srcEnd) throw incompleteUtf8();
116
- }
117
-
118
- /**
119
- * Reads the next byte of a multi-byte UTF-8 character and returns its
120
- * contents (lower 6 bits).
121
- *
122
- * <p>Throws a GeneratorError if the byte is not a valid tail.
123
- */
124
- private int nextPart() {
125
- char c = next();
126
- // tail bytes must be 0b10xxxxxx
127
- if ((c & 0xc0) != 0x80) throw invalidUtf8();
128
- return c & 0x3f;
129
- }
130
-
131
-
132
- protected void quoteStart() {
133
- if (quoteStart == -1) quoteStart = charStart;
134
- }
135
-
136
- /**
137
- * When in a sequence of characters that can be copied directly,
138
- * interrupts the sequence and copies it to the output buffer.
139
- *
140
- * @param endPos The offset until which the direct character quoting should
141
- * occur. You may pass {@link #pos} to quote until the most
142
- * recently read character, or {@link #charStart} to quote
143
- * until the character before it.
144
- */
145
- protected void quoteStop(int endPos) {
146
- if (quoteStart != -1) {
147
- out.append(src, quoteStart, endPos - quoteStart);
148
- quoteStart = -1;
149
- }
150
- }
151
-
152
- protected void append(int b) {
153
- out.append(b);
154
- }
155
-
156
- protected void append(byte[] origin, int start, int length) {
157
- out.append(origin, start, length);
158
- }
159
-
160
-
161
- protected abstract RaiseException invalidUtf8();
162
-
163
- protected RaiseException incompleteUtf8() {
164
- return invalidUtf8();
165
- }
166
- }