Module: Z85

Defined in:
lib/z85.rb,
lib/z85/version.rb,
ext/z85/z85.c

Overview

This function has a special name and it is invoked by Ruby to initialize the extension.

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =
"0.7"

Class Method Summary collapse

Class Method Details

._decode(rstring) ⇒ Object



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
120
# File 'ext/z85/z85.c', line 92

static VALUE Z85_decode(VALUE _mod, VALUE rstring)
{
    char* string = StringValuePtr(rstring);
    long strlen = RSTRING_LEN(rstring);
    if (strlen % 5)
      strlen--; /* It is padded, ignore the counter */

    size_t decoded_size = strlen * 4 / 5;
    byte* decoded = malloc(decoded_size);

    uint byte_nbr = 0;
    uint char_nbr = 0;
    uint32_t value = 0;
    while (char_nbr < strlen) {
        value = value * 85 + decoder[(byte) string[char_nbr++] - 32];
        if (char_nbr % 5 == 0) {
            uint divisor = 256 * 256 * 256;
            while (divisor) {
                decoded[byte_nbr++] = value / divisor % 256;
                divisor /= 256;
            }
            value = 0;
        }
    }

    VALUE out = rb_str_new((const char*) decoded, decoded_size);
    free(decoded);
    return out;
}

._encode(string) ⇒ Object



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
88
89
90
# File 'ext/z85/z85.c', line 63

static VALUE Z85_encode(VALUE _mod, VALUE string)
{
    byte* data = (byte*) StringValuePtr(string);
    long size = RSTRING_LEN(string);

    size_t encoded_len = size * 5 / 4;
    char *encoded = malloc(encoded_len + 1);
    uint char_nbr = 0;
    uint byte_nbr = 0;
    uint32_t value = 0;

    while (byte_nbr < size) {
        value = value * 256 + data[byte_nbr++];
        if (byte_nbr % 4 == 0) {
            uint divisor = 85 * 85 * 85 * 85;
            while (divisor) {
                encoded[char_nbr++] = encoder[value / divisor % 85];
                divisor /= 85;
            }
            value = 0;
        }
    }
    encoded[char_nbr] = 0;

    VALUE out = rb_usascii_str_new_cstr(encoded);
    free(encoded);
    return out;
}

.decode(string) ⇒ Object



29
30
31
32
33
34
# File 'lib/z85.rb', line 29

def decode(string)
  if string.bytesize % 5 != 0
    err "Input length should be 0 mod 5. Please, check Z85.decode_with_padding."
  end
  _decode(string)
end

.decode_with_padding(string) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/z85.rb', line 36

def decode_with_padding(string)
  err "Input length should be 1 mod 5" if string.bytesize % 5 != 1

  counter = string[-1]
  err "Invalid counter: #{counter}" if counter < "0" || counter > "3"

  decoded = _decode(string)
  size = decoded.bytesize - counter.to_i
  err "String too short for counter #{counter}" if size < 0

  decoded.slice!(0, size)
end

.encode(string) ⇒ Object



17
18
19
20
21
22
# File 'lib/z85.rb', line 17

def encode(string)
  if string.bytesize % 4 != 0
    err "Input length should be 0 mod 4. Please, check Z85.encode_with_padding."
  end
  _encode(string)
end

.encode_with_padding(string) ⇒ Object



24
25
26
27
# File 'lib/z85.rb', line 24

def encode_with_padding(string)
  counter = 4 - (string.bytesize % 4)
  counter == 4 ? _encode(string) + "0" : _encode(string + PADDINGS[counter]) + counter.to_s
end