# # Author:: Tim Hinderliter () # Copyright:: Copyright 2010-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Wrapper class for interacting with JSON. require "ffi_yajl" unless defined?(FFI_Yajl) require_relative "exceptions" # We're requiring this to prevent breaking consumers using Hash.to_json require "json" class Chef class JSONCompat JSON_MAX_NESTING = 1000 class < e raise Chef::Exceptions::JSON::ParseError, e.message end # Just call the JSON gem's parse method with a modified :max_nesting field def from_json(source, opts = {}) obj = parse(source, opts) # JSON gem requires top level object to be a Hash or Array (otherwise # you get the "must contain two octets" error). Yajl doesn't impose the # same limitation. For compatibility, we re-impose this condition. unless obj.is_a?(Hash) || obj.is_a?(Array) raise Chef::Exceptions::JSON::ParseError, "Top level JSON object must be a Hash or Array. (actual: #{obj.class})" end obj end def to_json(obj, opts = nil) FFI_Yajl::Encoder.encode(obj, opts) rescue FFI_Yajl::EncodeError => e raise Chef::Exceptions::JSON::EncodeError, e.message end def to_json_pretty(obj, opts = nil) opts ||= {} options_map = {} options_map[:pretty] = true options_map[:indent] = opts[:indent] if opts.key?(:indent) to_json(obj, options_map).chomp end end end end