Module: HTTParty::Parsers::JSON

Defined in:
lib/httparty/parsers/json.rb

Overview

:nodoc:

Defined Under Namespace

Classes: ParseError

Class Method Summary collapse

Class Method Details

.convert_json_to_yaml(json) ⇒ Object

Ensure that “:” and “,” are always followed by a space



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/httparty/parsers/json.rb', line 33

def self.convert_json_to_yaml(json) #:nodoc:
  scanner, quoting, marks, pos, times = StringScanner.new(json), false, [], nil, []
  while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
    case char = scanner[1]
    when '"', "'"
      if !quoting
        quoting = char
        pos = scanner.pos
      elsif quoting == char
        if json[pos..scanner.pos-2] =~ DATE_REGEX
          # found a date, track the exact positions of the quotes so we can remove them later.
          # oh, and increment them for each current mark, each one is an extra padded space that bumps
          # the position in the final YAML output
          total_marks = marks.size
          times << pos+total_marks << scanner.pos+total_marks
        end
        quoting = false
      end
    when ":",","
      marks << scanner.pos - 1 unless quoting
    end
  end

  if marks.empty?
    json.gsub(/\\\//, '/')
  else
    left_pos  = [-1].push(*marks)
    right_pos = marks << json.length
    output    = []
    left_pos.each_with_index do |left, i|
      output << json[left.succ..right_pos[i]]
    end
    output = output * " "

    times.each { |i| output[i-1] = ' ' }
    output.gsub!(/\\\//, '/')
    output
  end
end

.decode(json) ⇒ Object



15
16
17
18
19
# File 'lib/httparty/parsers/json.rb', line 15

def self.decode(json)
  YAML.load(unescape(convert_json_to_yaml(json)))
rescue ArgumentError => e
  raise ParseError, "Invalid JSON string"
end

.unescape(str) ⇒ Object



23
24
25
26
27
# File 'lib/httparty/parsers/json.rb', line 23

def self.unescape(str)
  str.gsub(/\\u([0-9a-f]{4})/) {
    [$1.hex].pack("U")
  }
end