class Origami::Filter::A85

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

Public Instance Methods

decode(string) click to toggle source

Decodes the given data encoded in base85.

string

The data to decode.

# File lib/origami/filters/ascii.rb, line 116
def decode(string)
    input = filter_input(string)

    i = 0
    result = ''.b

    while i < input.size

        outblock = ""
        value = 0
        addend = 0

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

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

                addend = codelen - (input.length - i)
                input << "u" * addend
            end

            # Decode the 5 characters input block into a 32 bit integer.
            begin
                value = decode_block input[i, codelen]
            rescue InvalidASCII85StringError => error
                error.input_data = string
                error.decoded_data = result
                raise(error)
            end
        end

        outblock = [ value ].pack "L>"
        outblock = outblock[0, 4 - addend]

        result << outblock

        i = i + codelen
    end

    result
end
encode(stream) click to toggle source

Encodes given data into base85.

stream

The data to encode.

# 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

        # Encode the 4 bytes input value into a 5 character string.
        value = input[i, 4].unpack("L>")[0]
        outblock = encode_block(value)

        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

Private Instance Methods

decode_block(block) click to toggle source

Decodes a 5 character ASCII85 block into an integer value.

# File lib/origami/filters/ascii.rb, line 187
def decode_block(block)
    value = 0

    5.times do |i|
        byte = block[i].ord

        if byte > "u".ord or byte < "!".ord
            raise InvalidASCII85StringError, "Invalid character sequence: #{block.inspect}"
        else
            value += (byte - "!".ord) * 85 ** (4 - i)
        end
    end

    if value >= (1 << 32)
        raise InvalidASCII85StringError, "Invalid value (#{value}) for block #{block.inspect}"
    end

    value
end
encode_block(value) click to toggle source

Encodes an integer value into an ASCII85 block of 5 characters.

# File lib/origami/filters/ascii.rb, line 171
def encode_block(value)
    block = "".b

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

        value -= c * 85 ** (4 - p)
    end
    
    block
end
filter_input(string) click to toggle source
# File lib/origami/filters/ascii.rb, line 163
def filter_input(string)
    string = string[0, string.index(EOD)] if string.include?(EOD)
    string.delete(" \f\t\r\n\0")
end