mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
3202fbabe6
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6443 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
40 lines
1.1 KiB
Ruby
40 lines
1.1 KiB
Ruby
require 'yaml'
|
|
require 'strscan'
|
|
|
|
module ActiveSupport
|
|
module JSON
|
|
class ParseError < StandardError
|
|
end
|
|
|
|
class << self
|
|
# Converts a JSON string into a Ruby object.
|
|
def decode(json)
|
|
YAML.load(convert_json_to_yaml(json))
|
|
rescue ArgumentError => e
|
|
raise ParseError, "Invalid JSON string"
|
|
end
|
|
|
|
protected
|
|
# Ensure that ":" and "," are always followed by a space
|
|
def convert_json_to_yaml(json) #:nodoc:
|
|
scanner, quoting, marks = StringScanner.new(json), false, []
|
|
|
|
while scanner.scan_until(/(['":,]|\\.)/)
|
|
case char = scanner[1]
|
|
when '"', "'"
|
|
quoting = quoting == char ? false : char
|
|
when ":", ","
|
|
marks << scanner.pos - 1 unless quoting
|
|
end
|
|
end
|
|
|
|
if marks.empty?
|
|
json
|
|
else
|
|
ranges = ([0] + marks.map(&:succ)).zip(marks + [json.length])
|
|
ranges.map { |(left, right)| json[left..right] }.join(" ")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|