Class: Origami::Filter::ASCII85

Inherits:
Object
  • Object
show all
Includes:
Origami::Filter
Defined in:
lib/origami/filters/ascii.rb

Overview

Class representing a filter used to encode and decode data written in base85 encoding.

Constant Summary collapse

EOD =

:nodoc:

"~>"

Constants included from Origami::Filter

A85, AHx, CCF, Fl, RL

Instance Method Summary collapse

Methods included from Origami::Filter

included, #initialize

Instance Method Details

#decode(string) ⇒ Object

Decodes the given data encoded in base85.

string

The data to decode.



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/origami/filters/ascii.rb', line 125

def decode(string)
    input = (string.include?(EOD) ? string[0..string.index(EOD) - 1] : string).delete(" \f\t\r\n\0")

    i = 0
    result = "".b
    while i < input.size do

        outblock = ""

        if input[i] == "z"
            inblock = 0
            codelen = 1
        else
            inblock = 0
            codelen = 5

            if input.length - i < 5
                raise InvalidASCII85StringError.new("Invalid length", input_data: string, decoded_data: result) if input.length - i == 1

                addend = 5 - (input.length - i)
                input << "u" * addend
            else
                addend = 0
            end

            # Checking if this string is in base85
            5.times do |j|
                if input[i+j].ord > "u".ord or input[i+j].ord < "!".ord
                    raise InvalidASCII85StringError.new(
                            "Invalid character sequence: #{input[i,5].inspect}",
                            input_data: string,
                            decoded_data: result
                    )
                else
                    inblock += (input[i+j].ord - "!".ord) * 85 ** (4 - j)
                end
            end

            raise InvalidASCII85StringError.new(
                    "Invalid value (#{inblock}) for block #{input[i,5].inspect}",
                    input_data: string,
                    decoded_data: result
            ) if inblock >= 2**32
        end

        4.times do |p|
            c = inblock / 256 ** (3 - p)
            outblock << c.chr

            inblock -= c * 256 ** (3 - p)
        end

        if addend != 0
            outblock = outblock[0, 4 - addend]
        end

        result << outblock

        i = i + codelen
    end

    result
end

#encode(stream) ⇒ Object

Encodes given data into base85.

stream

The data to encode.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/origami/filters/ascii.rb', line 80

def encode(stream)
    i = 0
    code = "".b
    input = stream.dup

    while i < input.size do

        if input.length - i < 4
            addend = 4 - (input.length - i)
            input << "\0" * addend
        else
            addend = 0
        end

        inblock = (input[i].ord * 256**3 +
                   input[i+1].ord * 256**2 +
                   input[i+2].ord * 256 +
                   input[i+3].ord)
        outblock = ""

        5.times do |p|
            c = inblock / 85 ** (4 - p)
            outblock << ("!".ord + c).chr

            inblock -= c * 85 ** (4 - p)
        end

        outblock = "z" if outblock == "!!!!!" and addend == 0

        if addend != 0
            outblock = outblock[0,(4 - addend) + 1]
        end

        code << outblock

        i = i + 4
    end

    code
end