ascii85_native 1.0.0
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 +7 -0
- data/ext/ascii85_native/ascii85_native.c +103 -0
- data/ext/ascii85_native/ascii85_native.h +27 -0
- data/ext/ascii85_native/extconf.rb +3 -0
- data/lib/ascii85_native.rb +69 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 29b779e3fe160aeafcecd06d79f661f9a4b0a992dd053af39515eacfa7e2f367
|
4
|
+
data.tar.gz: bbc6085d316adaea46f93095dbf738aea1441fb682c32736152c0674c33f7df2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0a4267955d024d17a5a540961e583bb498c4c70eddc9073d680925e3a8b9c10aeaed73a9ea07dbef6455c6dec62d308c61e465739312e67c5ff575f75de3bc4e
|
7
|
+
data.tar.gz: af7a04720ee115222ad4897af241ee305486bc2494aa9925acdddaefcb10aa8c5be8bcc723e92818237c04385207137a678cef777a8362dd8b7b9dff8db9c359
|
@@ -0,0 +1,103 @@
|
|
1
|
+
// a85.cpp
|
2
|
+
//
|
3
|
+
// Ascii85 C++ implementation pulled from https://github.com/larskholte/a85
|
4
|
+
// Original C++ Code License: Copy and use as you please. No attribution necessary.
|
5
|
+
//
|
6
|
+
// Adapted to C language
|
7
|
+
|
8
|
+
#include "ascii85_native.h"
|
9
|
+
|
10
|
+
int size_for_a85(int binlen, bool append_null) {
|
11
|
+
return (binlen * 5 + 3) / 4 + !!append_null;
|
12
|
+
}
|
13
|
+
|
14
|
+
void to_a85(const u8* data, int binlen, char* text, bool append_null) {
|
15
|
+
// Go to end of data and text buffers
|
16
|
+
data += binlen;
|
17
|
+
text += size_for_a85(binlen,append_null);
|
18
|
+
// Append null if requested
|
19
|
+
if (append_null) {
|
20
|
+
*(--text) = 0;
|
21
|
+
}
|
22
|
+
// If number of bytes is not divisible by 4, act as if null bytes were added to end of buffer
|
23
|
+
int rem = binlen & 3;
|
24
|
+
if (rem) {
|
25
|
+
u32 val = 0;
|
26
|
+
for (int i = 4 - rem; i < 4; i++) {
|
27
|
+
val |= *(--data) << (8 * i);
|
28
|
+
}
|
29
|
+
int i;
|
30
|
+
for (i = 0; i < 4 - rem; i++) {
|
31
|
+
val /= 85;
|
32
|
+
}
|
33
|
+
for (; i <= 4; i++) {
|
34
|
+
*(--text) = val % 85 + 33;
|
35
|
+
val /= 85;
|
36
|
+
}
|
37
|
+
binlen &= ~3;
|
38
|
+
}
|
39
|
+
while (binlen) {
|
40
|
+
// Process chunks of 4 bytes as 32-bit values
|
41
|
+
u32 val = *(--data);
|
42
|
+
val |= *(--data) << 8;
|
43
|
+
val |= *(--data) << 16;
|
44
|
+
val |= *(--data) << 24;
|
45
|
+
// Convert to base 85
|
46
|
+
*(--text) = val % 85 + 33;
|
47
|
+
val /= 85;
|
48
|
+
*(--text) = val % 85 + 33;
|
49
|
+
val /= 85;
|
50
|
+
*(--text) = val % 85 + 33;
|
51
|
+
val /= 85;
|
52
|
+
*(--text) = val % 85 + 33;
|
53
|
+
val /= 85;
|
54
|
+
*(--text) = val % 85 + 33;
|
55
|
+
binlen -= 4;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
int size_for_bin(int textlen) {
|
60
|
+
return (textlen * 4) / 5;
|
61
|
+
}
|
62
|
+
|
63
|
+
void from_a85(const char* text, int textlen, u8* data) {
|
64
|
+
while (textlen) {
|
65
|
+
|
66
|
+
while (*text == 0 || (*text >= 10 && *text <= 13)) { text++; textlen--; }
|
67
|
+
|
68
|
+
if (textlen < 5) {
|
69
|
+
// Determine represented value in base 85
|
70
|
+
u32 val = 0;
|
71
|
+
int factor = 52200625; // 85^4
|
72
|
+
int i;
|
73
|
+
for (i = 0; i < textlen; i++) {
|
74
|
+
val += (*(text++) - 33) * factor;
|
75
|
+
factor /= 85;
|
76
|
+
}
|
77
|
+
for (; i < 5; i++) {
|
78
|
+
val += 'u' * factor;
|
79
|
+
factor /= 85;
|
80
|
+
}
|
81
|
+
int shift = 24;
|
82
|
+
for (i = 0; i < textlen - 1; i++) {
|
83
|
+
*(data++) = val >> shift;
|
84
|
+
shift -= 8;
|
85
|
+
}
|
86
|
+
break;
|
87
|
+
}
|
88
|
+
|
89
|
+
// Determine represented value in base 85
|
90
|
+
u32 val = (*(text++) - 33) * 52200625; // 85^4
|
91
|
+
val += (*(text++) - 33) * 614125; // 85^3
|
92
|
+
val += (*(text++) - 33) * 7225; // 85^2
|
93
|
+
val += (*(text++) - 33) * 85; // 85^1
|
94
|
+
val += (*(text++) - 33); // 85^0
|
95
|
+
|
96
|
+
// Write out in big-endian order
|
97
|
+
*(data++) = val >> 24;
|
98
|
+
*(data++) = val >> 16;
|
99
|
+
*(data++) = val >> 8;
|
100
|
+
*(data++) = val;
|
101
|
+
textlen -= 5;
|
102
|
+
}
|
103
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
// a85.h
|
2
|
+
//
|
3
|
+
// Ascii85 C++ implementation pulled from https://github.com/larskholte/a85
|
4
|
+
// Original C++ Code License: Copy and use as you please. No attribution necessary.
|
5
|
+
//
|
6
|
+
// Adapted to C language
|
7
|
+
|
8
|
+
#include <stdint.h>
|
9
|
+
|
10
|
+
typedef _Bool bool;
|
11
|
+
typedef uint8_t u8;
|
12
|
+
typedef uint32_t u32;
|
13
|
+
|
14
|
+
// Returns size of buffer required for to_a85 function.
|
15
|
+
int size_for_a85(int binlen, bool append_null);
|
16
|
+
|
17
|
+
// Translates the given binary data of the given size to Ascii85.
|
18
|
+
// Can translate in-place.
|
19
|
+
// Optionally appends a null character.
|
20
|
+
void to_a85(const u8* data, int binlen, char* text, bool append_null);
|
21
|
+
|
22
|
+
// Returns the size of buffer required for from_a85 function.
|
23
|
+
int size_for_bin(int textlen);
|
24
|
+
|
25
|
+
// Translates the given Ascii85 text to binary data.
|
26
|
+
// Can translate in-place.
|
27
|
+
void from_a85(const char* text, int textlen, u8* data);
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
module Ascii85Native
|
6
|
+
extend FFI::Library
|
7
|
+
|
8
|
+
ffi_lib File.join(File.dirname(__FILE__), 'ascii85_native.so')
|
9
|
+
|
10
|
+
#void to_a85(const u8* data, int binlen, char* text, bool append_null);
|
11
|
+
attach_function :to_a85, [:buffer_in, :int, :buffer_out, :bool], :void
|
12
|
+
|
13
|
+
#int size_for_a85(int binlen, bool append_null);
|
14
|
+
attach_function :size_for_a85, [:int, :bool], :int
|
15
|
+
|
16
|
+
#void from_a85(const char* text, int textlen, u8* data);
|
17
|
+
attach_function :from_a85, [:buffer_in, :int, :buffer_out], :void
|
18
|
+
|
19
|
+
#int size_for_bin(int textlen)
|
20
|
+
attach_function :size_for_bin, [:int], :int
|
21
|
+
|
22
|
+
|
23
|
+
def self.encode(input, include_delimiter=false)
|
24
|
+
if input.nil?
|
25
|
+
return '<~~>' if include_delimiter
|
26
|
+
return ''
|
27
|
+
end
|
28
|
+
|
29
|
+
if input.class == String
|
30
|
+
input_data = []
|
31
|
+
input.each_byte { |byte| input_data << byte }
|
32
|
+
else
|
33
|
+
input_data = input
|
34
|
+
end
|
35
|
+
|
36
|
+
FFI::MemoryPointer.new(:uint8, input_data.size) do |in_uint8|
|
37
|
+
in_uint8.write_array_of_type(FFI::TYPE_UINT8, :put_uint8, input_data)
|
38
|
+
out_size = self.size_for_a85(input_data.size, true)
|
39
|
+
|
40
|
+
FFI::MemoryPointer.new(:uint8, out_size) do |output|
|
41
|
+
self.to_a85(in_uint8, input_data.size, output, true)
|
42
|
+
if include_delimiter
|
43
|
+
return '<~' + (output.read_string() || '') + '~>'
|
44
|
+
else
|
45
|
+
return output.read_string()
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def self.decode(input)
|
53
|
+
return "" if input.nil?
|
54
|
+
|
55
|
+
if input[0] == '<' && input[1] == '~' && input[-2] == '~' && input[-1] == '>'
|
56
|
+
input = input[2..-3]
|
57
|
+
end
|
58
|
+
|
59
|
+
FFI::MemoryPointer.new(:char, input.size) do |in_char|
|
60
|
+
in_char.write_string(input)
|
61
|
+
out_size = self.size_for_bin(input.size)
|
62
|
+
|
63
|
+
FFI::MemoryPointer.new(:uint8, out_size) do |output|
|
64
|
+
self.from_a85(in_char, input.size, output)
|
65
|
+
return output.read_string()
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ascii85_native
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jason Crossfield
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-05-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.15'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.15.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.15'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.15.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rake
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '13.0'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 13.0.1
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '13.0'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 13.0.1
|
53
|
+
description: A faster implementation of the Ascii85 Encode & Decode methods using
|
54
|
+
native C extensions to do the heavy lifting.
|
55
|
+
email: jason.crossfield@gmail.com
|
56
|
+
executables: []
|
57
|
+
extensions:
|
58
|
+
- ext/ascii85_native/extconf.rb
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- ext/ascii85_native/ascii85_native.c
|
62
|
+
- ext/ascii85_native/ascii85_native.h
|
63
|
+
- ext/ascii85_native/extconf.rb
|
64
|
+
- lib/ascii85_native.rb
|
65
|
+
homepage: https://github.com/AnomalousBit/ascii85_native
|
66
|
+
licenses:
|
67
|
+
- MIT
|
68
|
+
metadata: {}
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
- ext/ascii85_native
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubygems_version: 3.1.2
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: Ascii85 Encoder / Decoder with Native C Extensions
|
89
|
+
test_files: []
|