class JSON::TruffleRuby::Generator::State
while generating a JSON text from a Ruby data structure.
This class is used to create State instances, that are use to hold data
def self.from_state(opts)
an unconfigured instance. If _opts_ is a State object, it is just
a new State instance configured by _opts_, something else to create
Creates a State object from _opts_, which ought to be Hash to create
def self.from_state(opts) case when self === opts opts when opts.respond_to?(:to_hash) new(opts.to_hash) when opts.respond_to?(:to_h) new(opts.to_h) else SAFE_STATE_PROTOTYPE.dup end end
def self.generate(obj, opts = nil)
def self.generate(obj, opts = nil) new(opts).generate(obj) end
def [](name)
def [](name) if respond_to?(name) __send__(name) else instance_variable_get("@#{name}") if instance_variables.include?("@#{name}".to_sym) # avoid warning end end
def []=(name, value)
def []=(name, value) if respond_to?(name_writer = "#{name}=") __send__ name_writer, value else instance_variable_set "@#{name}", value end end
def allow_nan?
Returns true if NaN, Infinity, and -Infinity should be considered as
def allow_nan? @allow_nan end
def ascii_only?
Returns true, if only ASCII characters should be generated. Otherwise
def ascii_only? @ascii_only end
def buffer_initial_length=(length)
def buffer_initial_length=(length) if length > 0 @buffer_initial_length = length end end
def check_circular?
Returns true, if circular data structures are checked,
def check_circular? !@max_nesting.zero? end
def check_max_nesting # :nodoc:
def check_max_nesting # :nodoc: return if @max_nesting.zero? current_nesting = depth + 1 current_nesting > @max_nesting and raise NestingError, "nesting of #{current_nesting} is too deep" end
def configure(opts)
Configure this State instance with the Hash _opts_, and return
def configure(opts) if opts.respond_to?(:to_hash) opts = opts.to_hash elsif opts.respond_to?(:to_h) opts = opts.to_h else raise TypeError, "can't convert #{opts.class} into Hash" end opts.each do |key, value| instance_variable_set "@#{key}", value end # NOTE: If adding new instance variables here, check whether #generate should check them for #generate_json @indent = opts[:indent] || '' if opts.key?(:indent) @space = opts[:space] || '' if opts.key?(:space) @space_before = opts[:space_before] || '' if opts.key?(:space_before) @object_nl = opts[:object_nl] || '' if opts.key?(:object_nl) @array_nl = opts[:array_nl] || '' if opts.key?(:array_nl) @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan) @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only) @depth = opts[:depth] || 0 @buffer_initial_length ||= opts[:buffer_initial_length] @script_safe = if opts.key?(:script_safe) !!opts[:script_safe] elsif opts.key?(:escape_slash) !!opts[:escape_slash] else false end @strict = !!opts[:strict] if opts.key?(:strict) if !opts.key?(:max_nesting) # defaults to 100 @max_nesting = 100 elsif opts[:max_nesting] @max_nesting = opts[:max_nesting] else @max_nesting = 0 end self end
def fast_serialize_string(string, buf) # :nodoc:
Assumes !@ascii_only, !@script_safe
def fast_serialize_string(string, buf) # :nodoc: '"' string.encoding == ::Encoding::UTF_8 n ring = string.encode(::Encoding::UTF_8) ue Encoding::UndefinedConversionError => error ise GeneratorError, error.message GeneratorError, "source sequence is illegal/malformed utf-8" unless string.valid_encoding? \\\x0-\x1f]/n.match?(string) << string.gsub(/["\\\x0-\x1f]/n, MAP) << string '"'
def generate(obj)
created this method raises a
returns the result. If no valid JSON document can be
Generates a valid JSON document from object +obj+ and
def generate(obj) if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and !@ascii_only and !@script_safe and @max_nesting == 0 and !@strict result = generate_json(obj, ''.dup) else result = obj.to_json(self) end JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError, "source sequence #{result.inspect} is illegal/malformed utf-8" result end
def generate_json(obj, buf)
def generate_json(obj, buf) bj ash << '{' t = true each_pair do |k,v| f << ',' unless first y_str = k.to_s key_str.class == String fast_serialize_string(key_str, buf) sif key_str.is_a?(String) generate_json(key_str, buf) se raise TypeError, "#{k.class}#to_s returns an instance of #{key_str.class}, expected a String" d f << ':' nerate_json(v, buf) rst = false << '}' rray << '[' t = true each do |e| f << ',' unless first nerate_json(e, buf) rst = false << ']' tring bj.class == String st_serialize_string(obj, buf) f << obj.to_json(self) nteger << obj.to_s te: Float is handled this way since Float#to_s is slow anyway << obj.to_json(self)
def initialize(opts = nil)
generated, otherwise an exception is thrown, if these values are
* *allow_nan*: true if NaN, Infinity, and -Infinity should be
the generated JSON, max_nesting = 0 if no maximum should be checked.
* *max_nesting*: sets the maximum level of data structure nesting in
* *check_circular*: is deprecated now, use the :max_nesting option instead,
as to make the JSON object safe to interpolate in a script tag (default: false).
* *script_safe*: true if U+2028, U+2029 and forward slash (/) should be escaped
* *array_nl*: a string that is put at the end of a JSON array (default: ''),
* *object_nl*: a string that is put at the end of a JSON object (default: ''),
* *space_before*: a string that is put before a : pair delimiter (default: ''),
* *space*: a string that is put after, a : or , delimiter (default: ''),
* *indent*: a string used to indent levels (default: ''),
_opts_ can have the following keys:
Instantiates a new State object, configured by _opts_.
def initialize(opts = nil) @indent = '' @space = '' @space_before = '' @object_nl = '' @array_nl = '' @allow_nan = false @ascii_only = false @depth = 0 @buffer_initial_length = 1024 @script_safe = false @strict = false @max_nesting = 100 configure(opts) if opts end
def script_safe?
def script_safe? @script_safe end
def strict?
Strict mode only allow serializing JSON native types: Hash, Array,
Returns true, if strict mode is enabled. Otherwise returns false.
def strict? @strict end
def to_h
Returns the configuration instance variables as a hash, that can be
def to_h result = {} instance_variables.each do |iv| iv = iv.to_s[1..-1] result[iv.to_sym] = self[iv] end result end