Class: SteamCodec::KeyValues::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/steam_codec/key_values.rb

Class Method Summary collapse

Class Method Details

.getQuoteList(data) ⇒ Object

Raises:

  • (RuntimeError)


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/steam_codec/key_values.rb', line 37

def self.getQuoteList(data)
    indexes = []
    quoted = false
    length = data.length
    length.times do |index|
        if data[index] == '"'
            escaped = false
            escaped = self.isEscaped(data, index) if quoted
            if not escaped
                indexes << index
                quoted = !quoted
            end
        end
    end
    raise RuntimeError, "Unmatched quotes" if quoted
    indexes
end

.isEscaped(data, index, char = '\\') ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/steam_codec/key_values.rb', line 24

def self.isEscaped(data, index, char = '\\')
    return false if index == 0
    escaped = false
    (index - 1).downto(0) do |num|
        if data[num] == char
            escaped = !escaped
        else
            break
        end
    end
    escaped
end

.proccess(data, last = true) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/steam_codec/key_values.rb', line 11

def self.proccess(data, last = true)
    token = /"[^"]*"/
    data = data.gsub(/(?<=^|[\s{}])(\s*)([^"{}\s\n\r]+)(\s*)(?=[\s{}]|\z)/, '\1"\2"\3')
    if last
        data.gsub!(/(#{token}:\s*#{token}|})(?=\s*")/, '\1,')
        data.gsub!(/(#{token})(?=\s*{|[ \t\f]+")/, '\1:')
    else
        data.gsub!(/(#{token}:\s*#{token}|})(?=\s*"|\s*\z)/, '\1,')
        data.gsub!(/(#{token})(?=\s*{|[ \t\f]+"|\s*\z)/, '\1:')
    end
    data
end

.toJSON(data) ⇒ Object

Raises:

  • (ArgumentError)


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/steam_codec/key_values.rb', line 55

def self.toJSON(data)
    raise ArgumentError, "data must be String" unless data.is_a?(String)
    str = ''
    previous = 0
    data.gsub!(/^#(include|base).*$/, '') # include and base not supported so just ignore
    quoteList = self.getQuoteList(data)
    quoteList.each_index  do |index|
        quoted = index % 2 == 1
        part = data[previous...quoteList[index]]
        previous = quoteList[index] + 1
        next if part.empty? and not quoted
        if quoted
            str += '"' + part.gsub(/\n/,'\n') + '"'
            lastIndex = data.length
            lastIndex = quoteList[index + 1] if index + 1 < quoteList.length
            nextPart = data[previous...lastIndex].gsub(/\\\\.*$/,'') # remove comments
            nextPart = self.proccess(nextPart, true)
            case nextPart
            when /\A(\s*{|[ \t]+\z)/
                str += ':'
            when /\A\s+\z/
                str += ','
            end
        else
            part = part.gsub(/\\\\[^\n]*$/,'') # remove comments
            str += self.proccess(part, index + 1 >= quoteList.length)
        end
    end
    lastIndex = data.length
    part = data[previous...lastIndex]
    str += self.proccess(part, true) if part
    '{' + str + '}'
end