ascii85_native 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/ascii85_native/ascii85_native.c +21 -28
- data/ext/ascii85_native/ascii85_native.h +0 -4
- data/lib/ascii85_native.rb +14 -22
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9c131b0e45806651154e7787963fcf0b66caf3c0d178262fc23fc148bd8f5f8
|
4
|
+
data.tar.gz: 824b411d00c8ef1f02d8cda1073f7f12c705599cd2280a60669f8cd268915cf7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b659d5d91700f63b9a04df578b8748047cca28a89a5d0105e781c8e0adb8d3f7838c139f394226dbd27612f97a8f2e2986851bcc639e7d2628f6d1883fa508f3
|
7
|
+
data.tar.gz: e299f89e5df890f1294b6fc8d461a265a155f4285767f87e8cc51459003efc2543e73caf5a6260870df42f6e6322ce3da8ee47024fd4eed6a08eb97760d19070
|
@@ -2,27 +2,31 @@
|
|
2
2
|
|
3
3
|
#include "stdlib.h"
|
4
4
|
#include "ascii85_native.h"
|
5
|
+
#include "stdio.h"
|
6
|
+
#include "string.h"
|
5
7
|
|
6
8
|
int a85_encoded_size(int input_length, bool append_null) {
|
7
9
|
return (input_length * 5 + 3) / 4 + !!append_null;
|
8
10
|
}
|
9
11
|
|
10
12
|
void a85_encode(const u8* input, int input_length, char* output, bool append_null) {
|
13
|
+
|
11
14
|
// Go to end of input and output buffers
|
12
15
|
input += input_length;
|
13
16
|
output += a85_encoded_size(input_length,append_null);
|
17
|
+
|
14
18
|
// Append null if requested
|
15
|
-
if (append_null) {
|
16
|
-
|
17
|
-
}
|
19
|
+
if (append_null) { *(--output) = 0; }
|
20
|
+
|
18
21
|
// If number of bytes is not divisible by 4, act as if null bytes were added to end of buffer
|
19
22
|
int rem = input_length & 3;
|
20
23
|
if (rem) {
|
21
24
|
u32 val = 0;
|
22
|
-
|
25
|
+
|
26
|
+
int i;
|
27
|
+
for (i = 4 - rem; i < 4; i++) {
|
23
28
|
val |= *(--input) << (8 * i);
|
24
29
|
}
|
25
|
-
int i;
|
26
30
|
for (i = 0; i < 4 - rem; i++) {
|
27
31
|
val /= 85;
|
28
32
|
}
|
@@ -30,14 +34,17 @@ void a85_encode(const u8* input, int input_length, char* output, bool append_nul
|
|
30
34
|
*(--output) = val % 85 + 33;
|
31
35
|
val /= 85;
|
32
36
|
}
|
37
|
+
|
33
38
|
input_length &= ~3;
|
34
39
|
}
|
40
|
+
|
35
41
|
while (input_length) {
|
36
42
|
// Process chunks of 4 bytes as 32-bit values
|
37
43
|
u32 val = *(--input);
|
38
44
|
val |= *(--input) << 8;
|
39
45
|
val |= *(--input) << 16;
|
40
46
|
val |= *(--input) << 24;
|
47
|
+
|
41
48
|
// Convert to base 85
|
42
49
|
*(--output) = val % 85 + 33;
|
43
50
|
val /= 85;
|
@@ -56,36 +63,16 @@ int a85_decoded_size(int input_length) {
|
|
56
63
|
return ((input_length * 4) / 5);
|
57
64
|
}
|
58
65
|
|
59
|
-
void a85_filter_before_decode(const char* input, int input_length, char* output) {
|
60
|
-
int input_remaining = input_length;
|
61
|
-
while (input_remaining) {
|
62
|
-
if ( !(*input == 0 || (*input >= 10 && *input <= 13)) ) {
|
63
|
-
*output = *input;
|
64
|
-
output++;
|
65
|
-
}
|
66
|
-
input++;
|
67
|
-
input_remaining--;
|
68
|
-
}
|
69
|
-
//*output = '\0';
|
70
|
-
}
|
71
|
-
|
72
66
|
void a85_decode(const char* input, int input_length, u8* output) {
|
73
|
-
// this is now done from the ruby side
|
74
|
-
//char* filtered_input;
|
75
|
-
//filtered_input = (char*)malloc(input_length*sizeof(char));
|
76
|
-
//a85_filter_before_decode(input, input_length, filtered_input);
|
77
|
-
//int filtered_length = strlen(filtered_input);
|
78
|
-
|
79
67
|
while (input_length) {
|
80
68
|
|
81
|
-
|
82
|
-
|
83
|
-
if (*input >= 10 && *input <= 13) { input++; input_length--; continue; }
|
69
|
+
while ((*input >= 9 && *input <= 13) || *input == 32) { input++; input_length--;}
|
84
70
|
|
85
71
|
if (input_length < 5) {
|
86
72
|
// Determine represented value in base 85
|
87
73
|
u32 val = 0;
|
88
74
|
int factor = 52200625; // 85^4
|
75
|
+
|
89
76
|
int i;
|
90
77
|
for (i = 0; i < input_length; i++) {
|
91
78
|
val += (*(input++) - 33) * factor;
|
@@ -103,11 +90,16 @@ void a85_decode(const char* input, int input_length, u8* output) {
|
|
103
90
|
break;
|
104
91
|
}
|
105
92
|
|
106
|
-
// Determine represented value in base 85
|
93
|
+
// Determine represented value in base 85 while throwing out invalid ascii85 characters
|
94
|
+
while ((*input >= 9 && *input <= 13) || *input == 32) { input++; input_length--;}
|
107
95
|
u32 val = (*(input++) - 33) * 52200625; // 85^4
|
96
|
+
while ((*input >= 9 && *input <= 13) || *input == 32) { input++; input_length--;}
|
108
97
|
val += (*(input++) - 33) * 614125; // 85^3
|
98
|
+
while ((*input >= 9 && *input <= 13) || *input == 32) { input++; input_length--;}
|
109
99
|
val += (*(input++) - 33) * 7225; // 85^2
|
100
|
+
while ((*input >= 9 && *input <= 13) || *input == 32) { input++; input_length--;}
|
110
101
|
val += (*(input++) - 33) * 85; // 85^1
|
102
|
+
while ((*input >= 9 && *input <= 13) || *input == 32) { input++; input_length--;}
|
111
103
|
val += (*(input++) - 33); // 85^0
|
112
104
|
|
113
105
|
// Write out in big-endian order
|
@@ -117,4 +109,5 @@ void a85_decode(const char* input, int input_length, u8* output) {
|
|
117
109
|
*(output++) = val;
|
118
110
|
input_length -= 5;
|
119
111
|
}
|
112
|
+
*(output++) = 0;
|
120
113
|
}
|
@@ -22,7 +22,3 @@ int a85_decoded_size(int input_length);
|
|
22
22
|
// Translates the given Ascii85 input to binary output.
|
23
23
|
// Can translate in-place.
|
24
24
|
void a85_decode(const char* input, int input_length, u8* output);
|
25
|
-
|
26
|
-
// Removes unused / ignored characters from the ascii85 input
|
27
|
-
// TODO: identify and remove <~ and ~> delimiters
|
28
|
-
void a85_filter_before_decode(const char* input, int input_length, char* output);
|
data/lib/ascii85_native.rb
CHANGED
@@ -17,13 +17,10 @@ module Ascii85Native
|
|
17
17
|
#int a85_decoded_size(int textlen)
|
18
18
|
attach_function :a85_decoded_size, [:int], :int
|
19
19
|
|
20
|
-
#void a85_decode(const char* text, int textlen, u8* data);
|
21
|
-
attach_function :a85_filter_before_decode, [:buffer_in, :int, :buffer_out], :void
|
22
|
-
|
23
20
|
#void a85_decode(const char* text, int textlen, u8* data);
|
24
21
|
attach_function :a85_decode, [:buffer_in, :int, :buffer_out], :void
|
25
22
|
|
26
|
-
attach_function :strlen, [:
|
23
|
+
attach_function :strlen, [:buffer_in], :int
|
27
24
|
|
28
25
|
def self.encode(input, include_delimiter=false)
|
29
26
|
if input.nil? || input.size == 0
|
@@ -54,36 +51,31 @@ module Ascii85Native
|
|
54
51
|
end
|
55
52
|
|
56
53
|
|
57
|
-
def self.decode(input, force_delimiter=
|
54
|
+
def self.decode(input, force_delimiter=false)
|
58
55
|
return "" if input.nil? || input.size == 0
|
59
56
|
|
57
|
+
# Array slicing in ruby 3.0.1 appears to be constant time O(1): no performance hit based on array size.
|
58
|
+
# No reason to implement this code segment in C if this holds true.
|
60
59
|
if force_delimiter
|
61
60
|
input = input[2..-3]
|
62
61
|
else
|
63
|
-
|
64
|
-
|
65
|
-
input = input[
|
62
|
+
stream_start = find_stream_start(input)
|
63
|
+
stream_end = find_stream_end(input)
|
64
|
+
input = input[stream_start..stream_end] if stream_start != 0 || stream_end != -1
|
66
65
|
end
|
67
66
|
|
68
67
|
FFI::MemoryPointer.new(:char, input.size) do |in_char|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
self.a85_filter_before_decode(in_char, input.size, filtered_char)
|
73
|
-
filtered_length = self.strlen(filtered_char.read_string())
|
74
|
-
puts "filtered_length: #{filtered_length}"
|
75
|
-
|
76
|
-
out_size = self.a85_decoded_size(filtered_length)
|
68
|
+
in_char.write_string(input)
|
69
|
+
out_size = self.a85_decoded_size(input.size)
|
77
70
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
71
|
+
FFI::MemoryPointer.new(:uint8, out_size) do |output|
|
72
|
+
self.a85_decode(in_char, strlen(in_char), output)
|
73
|
+
return output.read_string()
|
82
74
|
end
|
83
75
|
end
|
84
76
|
end
|
85
77
|
|
86
|
-
def self.
|
78
|
+
def self.find_stream_start(input)
|
87
79
|
start_slice = 0
|
88
80
|
cursor = 0
|
89
81
|
|
@@ -102,7 +94,7 @@ module Ascii85Native
|
|
102
94
|
return start_slice
|
103
95
|
end
|
104
96
|
|
105
|
-
def self.
|
97
|
+
def self.find_stream_end(input)
|
106
98
|
end_slice = -1
|
107
99
|
cursor = -1
|
108
100
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ascii85_native
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Crossfield
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-06-
|
11
|
+
date: 2021-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|