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, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 module iv
.ascii85
/*is aliced*/;
25 /// returns input range
26 auto ascii85Decoder(RI
) (auto ref RI src
)
27 if (isInputRange
!RI
&&
28 (isSomeChar
!(ElementType
!RI
)) ||
29 is(ElementType
!RI
: ubyte) ||
30 is(ElementType
!RI
: byte))
34 static immutable uint[5] pow85
= [85*85*85*85u, 85*85*85u, 85*85u, 85u, 1u];
38 static if (isInfinite
!RI
) {
39 enum bool empty
= false;
46 this() (auto ref RI sr
) {
48 static if (!isInfinite
!RI
) isEmpty
= true;
52 popFront
; // populate curCh
56 static if (!isInfinite
!RI
) {
57 @property bool empty () const pure nothrow @nogc { return isEmpty
; }
59 @property ubyte front () const pure nothrow @nogc { return curCh
; }
61 static if (isForwardRange
!RI
) {
62 @property auto save() () {
64 if (!empty
) res
.rng
= rng
.save();
69 // template to allow autodeducing attributes
71 static if (!isInfinite
!RI
) {
72 if (isEmpty
) { curCh
= 0; return; }
79 uint b
= cast(uint)rng
.front
;
81 if (count
== 0 && b
== 'z') {
84 } else if (count
== 0 && b
== 'y') {
88 } else if (b
>= '!' && b
<= 'u') {
89 btuple
+= (b
-'!')*pow85
[count
++];
93 static if (isInfinite
!RI
) {
102 // we have some bytes ready
103 btuple
+= pow85
[--count
];
105 // we have 4 bytes ready
110 curCh
= (btuple
>>24)&0xff;
119 version(test_ascii85
)
122 import std
.utf
: byChar
;
124 immutable e
= `:Ms_p+EVgG/0IE&ARo=s-Z^D?Df'3+B-:f)EZfXGFT`;
125 immutable s
= cast(string
)array(ascii85Decoder(e
.byChar
));
126 //import iv.writer; writeln(s);
127 assert(s
== "One, two, Freddy's coming for you");
131 ":Ms_p+EVgG/0IE&ARo=s-Z^D?Df'3+B-:f)EZfXGFU\n"~
132 "D)]Eb/f5+D,P7E\\&>\"ATW$*EZf1:@r!34Dfp(CA8cC\n"~
133 ",$:\\`QALnsFBm;0OB6%Ei+CQC&Eckl+AncKB$<(MZA\n"~
134 "Ss%AASGdjF=\\P)Df0H$+EMX5Gp%6K+DbJ.AM+<bBl7\n"~
135 "K5+EV14/0I]!G%G\\:F)5E!E$/S%@;0U3/hRJ";
136 immutable s
= cast(string
)array(ascii85Decoder(e
.byChar
));
137 //import iv.writer; writeln(s);
139 "One, two, Freddy's coming for you\n"~
140 "Three, four, Better lock your door\n"~
141 "Five, six, grab a crucifix.\n"~
142 "Seven, eight, Gonna stay up late.\n"~
143 "Nine, ten, Never sleep again...\n");
148 /// returns input range
149 auto ascii85Encoder(RI
) (auto ref RI src
)
150 if (isInputRange
!RI
&&
151 (is(ElementType
!RI
: char) ||
152 is(ElementType
!RI
: ubyte) ||
153 is(ElementType
!RI
: byte)))
160 static if (isInfinite
!RI
) {
161 enum bool empty
= false;
163 bool isEmpty
= false;
168 this() (auto ref RI sr
) {
170 static if (!isInfinite
!RI
) isEmpty
= true;
174 popFront
; // populate curCh
178 static if (!isInfinite
!RI
) {
179 @property bool empty () const pure nothrow @nogc { return isEmpty
; }
180 @property char front () const pure nothrow @nogc { return (isEmpty ?
0 : cast(char)buf
[bpos
]); }
182 @property char front () const pure nothrow @nogc { return cast(char)buf
[bpos
]; }
185 static if (isForwardRange
!RI
) {
186 @property auto save() () {
188 if (!empty
) res
.rng
= rng
.save();
193 // template to allow autodeducing attributes
195 static if (!isInfinite
!RI
) {
203 // read at most 4 bytes and encode 'em
207 if (rng
.empty
) break;
208 auto b
= cast(uint)rng
.front
;
210 btuple |
= b
<<((3-count
)*8);
214 static if (isInfinite
!RI
) {
221 if (count
== 4 && btuple
== 0) {
227 for (bpos
= 0; bpos
< 5; ++bpos
) {
228 buf
[bpos
] = btuple
%85+'!';
231 --bpos
; // current char
239 version(test_ascii85
)
242 import std
.utf
: byChar
;
244 immutable s
= "One, two, Freddy's coming for you";
245 immutable e
= cast(string
)array(ascii85Encoder(s
.byChar
));
246 assert(e
== `:Ms_p+EVgG/0IE&ARo=s-Z^D?Df'3+B-:f)EZfXGFT`);
247 //import iv.writer; writeln(e);
251 "One, two, Freddy's coming for you\n"~
252 "Three, four, Better lock your door\n"~
253 "Five, six, grab a crucifix.\n"~
254 "Seven, eight, Gonna stay up late.\n"~
255 "Nine, ten, Never sleep again...\n";
256 immutable e
= cast(string
)array(ascii85Encoder(s
.byChar
));
258 ":Ms_p+EVgG/0IE&ARo=s-Z^D?Df'3+B-:f)EZfXGFU"~
259 "D)]Eb/f5+D,P7E\\&>\"ATW$*EZf1:@r!34Dfp(CA8cC"~
260 ",$:\\`QALnsFBm;0OB6%Ei+CQC&Eckl+AncKB$<(MZA"~
261 "Ss%AASGdjF=\\P)Df0H$+EMX5Gp%6K+DbJ.AM+<bBl7"~
262 "K5+EV14/0I]!G%G\\:F)5E!E$/S%@;0U3/hRJ");
263 //import iv.writer; writeln(e);