egeditor: more VaVoom C highlighting
[iv.d.git] / a85ct.d
blob232d35aafe027344eb057759076da982737aae46
1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 // ASCII85 codec
19 module iv.a85ct /*is aliced*/;
20 import iv.alice;
23 // very slow and enifficient ascii85 decoder
24 string decodeAscii85(T) (const(T)[] src) {
25 static immutable uint[5] pow85 = [85*85*85*85u, 85*85*85u, 85*85u, 85u, 1u];
26 auto data = cast(const(ubyte)[])src;
27 uint tuple = 0;
28 int count = 0;
29 string res = "";
31 void decodeTuple (int bytes) @safe nothrow {
32 while (bytes-- > 0) {
33 res ~= (tuple>>24)&0xff;
34 tuple <<= 8;
38 foreach (immutable b; data) {
39 if (b <= 32 || b > 126) continue; // skip blanks
40 if (b == 'z') {
41 // zero tuple
42 if (count != 0) return null; // alas
43 res ~= "\0\0\0\0";
44 } else {
45 if (b < '!' || b > 'u') return null; // alas
46 tuple += (b-'!')*pow85[count++];
47 if (count == 5) {
48 decodeTuple(4);
49 tuple = 0;
50 count = 0;
54 // write last (possibly incomplete) tuple
55 if (count > 1) {
56 tuple += pow85[--count];
57 decodeTuple(count);
59 return res;
63 string encodeAscii85(T) (const(T)[] src, int width=76) {
64 auto data = cast(const(ubyte)[])src;
65 uint tuple = 0;
66 int count = 0, pos = 0;
67 string res;
69 void encodeTuple () @safe nothrow {
70 int tmp = 5;
71 ubyte[5] buf;
72 usize bpos = 0;
73 do {
74 buf[bpos++] = tuple%85;
75 tuple /= 85;
76 } while (--tmp > 0);
77 tmp = count;
78 do {
79 if (width > 0 && pos >= width) { res ~= '\n'; pos = 0; }
80 res ~= cast(char)(buf[--bpos]+'!');
81 ++pos;
82 } while (tmp-- > 0);
85 foreach (immutable b; data) {
86 switch (count++) {
87 case 0: tuple |= b<<24; break;
88 case 1: tuple |= b<<16; break;
89 case 2: tuple |= b<<8; break;
90 case 3:
91 tuple |= b;
92 if (tuple == 0) {
93 // special case
94 if (width > 0 && pos >= width) { res ~= '\n'; pos = 0; }
95 res ~= 'z';
96 ++pos;
97 } else {
98 encodeTuple();
100 tuple = 0;
101 count = 0;
102 break;
103 default: assert(0);
106 if (count > 0) encodeTuple();
107 return res;
111 // for mixin
112 template a85enc(string s) {
113 private static enum qstr(string s) = s.stringof;
114 enum a85enc = qstr!(encodeAscii85(s, 0));
118 // fox mixin
119 template a85dec(string s) {
120 private static enum qstr(string s) = s.stringof;
121 enum a85dec = qstr!(decodeAscii85(s));
125 version(none) {
126 enum e = encodeAscii85("One, two, Freddy's coming for you");
127 enum s = decodeAscii85(`:Ms_p+EVgG/0IE&ARo=s-Z^D?Df'3+B-:f)EZfXGFT`);
129 void main () {
130 import iv.writer;
131 writeln(s);
132 writeln(decodeAscii85(e) == s);