1 /***************************************************************************
3 codesets.library - Amiga shared library for handling different codesets
4 Copyright (C) 2001-2005 by Alfonso [alfie] Ranieri <alforan@tin.it>.
5 Copyright (C) 2005-2007 by codesets.library Open Source Team
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 codesets.library project: http://sourceforge.net/projects/codesetslib/
21 ***************************************************************************/
26 #include "SDI_stdarg.h"
31 /****************************************************************************/
49 B64FLG_SourceFile
= 1<<0,
50 B64FLG_DestFile
= 1<<1,
54 /****************************************************************************/
62 /****************************************************************************/
64 static const UBYTE etable
[] =
66 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
67 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
68 85, 86, 87, 88, 89, 90, 97, 98, 99, 100,
69 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
70 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
71 121, 122, 48, 49, 50, 51, 52, 53, 54, 55,
72 56, 57, 43, 47, 0, 0, 0, 0, 0, 0,
73 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
82 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
83 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
87 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
88 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
89 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94 static const UBYTE dtable
[] =
96 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
97 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
98 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
99 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
100 128, 128, 128, 62, 128, 128, 128, 63, 52, 53,
101 54, 55, 56, 57, 58, 59, 60, 61, 128, 128,
102 128, 0, 128, 128, 128, 0, 1, 2, 3, 4,
103 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
104 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
105 25, 128, 128, 128, 128, 128, 128, 26, 27, 28,
106 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
107 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
108 49, 50, 51, 128, 128, 128, 128, 128, 128, 128,
109 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
110 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
111 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
112 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
113 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
114 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
115 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
116 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
117 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
118 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
119 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
120 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
121 128, 128, 128, 128, 128, 0
124 /****************************************************************************/
127 openIn(STRPTR name
, ULONG
* size
)
129 struct FileInfoBlock
*fib
;
134 if((fib
= AllocDosObject(DOS_FIB
,NULL
)))
136 if((file
= Open(name
,MODE_OLDFILE
)))
138 if(!ExamineFH(file
,fib
))
145 *size
= fib
->fib_Size
;
149 FreeDosObject(DOS_FIB
,fib
);
158 /****************************************************************************/
161 inchar(struct b64
*b64
)
167 if(b64
->flags
& B64FLG_SourceFile
)
169 if((c
= FGetC((BPTR
)b64
->in
))==EOF
)
172 b64
->error
= CSR_B64_ERROR_DOS
;
177 if(!b64
->inAvailable
)
183 c
= ((STRPTR
)b64
->in
)[b64
->inIndex
++];
191 /****************************************************************************/
194 ochar(struct b64
*b64
,int c
)
198 if(b64
->flags
& B64FLG_DestFile
)
202 if(b64
->maxLineLen
&& (b64
->lineCounter
>=b64
->maxLineLen
))
204 r
= FPuts((BPTR
)b64
->out
,b64
->eols
);
205 b64
->lineCounter
= 0;
210 r
= FPutC((BPTR
)b64
->out
,c
);
215 b64
->error
= CSR_B64_ERROR_DOS
;
225 ((STRPTR
)b64
->out
)[b64
->outIndex
++] = c
;
232 /****************************************************************************/
235 ostring(struct b64
*b64
,UBYTE
* buf
,int s
)
241 if(b64
->flags
& B64FLG_DestFile
)
245 for(r
= i
= 0; (r
!=EOF
) && (i
<s
); i
++)
247 r
= FPutC((BPTR
)b64
->out
,buf
[i
]);
252 b64
->error
= CSR_B64_ERROR_DOS
;
261 ((STRPTR
)b64
->out
)[b64
->outIndex
++] = buf
[i
];
268 /****************************************************************************/
271 insig(struct b64
*b64
)
279 if((c
==EOF
) || (c
>' '))
287 /****************************************************************************/
290 AROS_LH1(ULONG
, CodesetsEncodeB64A
,
291 AROS_LHA(struct TagItem
*, attrs
, A0
),
292 struct LibraryHeader
*, library
, 21, Codesets
298 CodesetsEncodeB64A(REG(a0
, struct TagItem
*attrs
))
305 ULONG totSize
, stop
, flags
;
307 int sourceLen
= 0, maxLineLen
;
311 if((tag
= FindTagItem(CSA_B64SourceFile
,attrs
)))
313 source
= (STRPTR
)tag
->ti_Data
;
314 flags
|= B64FLG_SourceFile
;
318 if((!(source
= (STRPTR
)GetTagData(CSA_B64SourceString
, 0, attrs
))))
320 RETURN(CSR_B64_ERROR_MEM
);
321 return CSR_B64_ERROR_MEM
;
324 if((tag
= FindTagItem(CSA_B64SourceLen
,attrs
)))
325 sourceLen
= tag
->ti_Data
;
327 sourceLen
= strlen(source
);
330 if((tag
= FindTagItem(CSA_B64DestFile
,attrs
)))
332 dest
= (APTR
)tag
->ti_Data
;
333 flags
|= B64FLG_DestFile
;
337 if((!(dest
= (APTR
)GetTagData(CSA_B64DestPtr
, 0, attrs
))))
339 RETURN(CSR_B64_ERROR_MEM
);
340 return CSR_B64_ERROR_MEM
;
344 maxLineLen
= GetTagData(CSA_B64MaxLineLen
,0,attrs
);
345 if(maxLineLen
<=0 || maxLineLen
>=256)
346 maxLineLen
= MAXLINELEN
;
348 if(GetTagData(CSA_B64Unix
,TRUE
,attrs
))
349 flags
|= B64FLG_Unix
;
352 if(flags
& B64FLG_SourceFile
)
354 if(!(in
= (APTR
)openIn(source
,&size
)))
356 RETURN(CSR_B64_ERROR_DOS
);
357 return CSR_B64_ERROR_DOS
;
366 b64
.inAvailable
= size
;
372 if(flags
& B64FLG_DestFile
)
374 if(!(out
= (APTR
)Open(dest
,MODE_NEWFILE
)))
376 RETURN(CSR_B64_ERROR_DOS
);
377 return CSR_B64_ERROR_DOS
;
385 if(!(out
= allocArbitrateVecPooled(totSize
)))
387 if(flags
& B64FLG_SourceFile
)
390 RETURN(CSR_B64_ERROR_MEM
);
391 return CSR_B64_ERROR_MEM
;
394 *((STRPTR
*)dest
) = out
;
403 b64
.maxLineLen
= maxLineLen
;
405 b64
.eols
= (flags
& B64FLG_Unix
) ? "\n" : "\r\n";
412 UBYTE igroup
[3], ogroup
[4];
415 igroup
[0] = igroup
[1] = igroup
[2] = 0;
426 igroup
[n
] = (UBYTE
) c
;
431 ogroup
[0] = etable
[igroup
[0]>>2];
432 ogroup
[1] = etable
[((igroup
[0] & 3)<<4) | (igroup
[1]>>4)];
433 ogroup
[2] = etable
[((igroup
[1] & 0xF)<<2) | (igroup
[2]>>6)];
434 ogroup
[3] = etable
[igroup
[2] & 0x3F];
445 c
= ochar(&b64
,ogroup
[i
]);
455 if(!(b64
.flags
& B64FLG_DestFile
))
456 ((STRPTR
)out
)[b64
.outIndex
] = 0;
459 if(flags
& B64FLG_SourceFile
)
462 /* flush and close dest */
463 if(flags
& B64FLG_DestFile
)
467 if(FPuts((BPTR
)out
,b64
.eols
)==EOF
)
468 b64
.error
= CSR_B64_ERROR_DOS
;
470 #if defined(__amigaos4__)
483 freeArbitratePooled(out
,totSize
);
487 RETURN((ULONG
)b64
.error
);
488 return (ULONG
)b64
.error
;
495 LIBSTUB(CodesetsEncodeB64A
, ULONG
, REG(a0
, struct TagItem
*attrs
))
498 return CodesetsEncodeB64A((struct TagItem
*)REG_A0
);
500 return CodesetsEncodeB64A(attrs
);
506 LIBSTUBVA(CodesetsEncodeB64
, ULONG
, ...)
511 VA_START(args
, self
);
512 res
= CodesetsEncodeB64A(VA_ARG(args
, struct TagItem
*));
519 /****************************************************************************/
522 AROS_LH1(ULONG
, CodesetsDecodeB64A
,
523 AROS_LHA(struct TagItem
*, attrs
, A0
),
524 struct LibraryHeader
*, library
, 22, Codesets
530 CodesetsDecodeB64A(REG(a0
, struct TagItem
*attrs
))
537 ULONG totSize
, flags
, errcheck
;
545 if((tag
= FindTagItem(CSA_B64SourceFile
,attrs
)))
547 source
= (STRPTR
)tag
->ti_Data
;
548 flags
|= B64FLG_SourceFile
;
552 if (!(source
= (STRPTR
)GetTagData(CSA_B64SourceString
,0,attrs
)))
554 RETURN(CSR_B64_ERROR_MEM
);
555 return CSR_B64_ERROR_MEM
;
558 if((tag
= FindTagItem(CSA_B64SourceLen
,attrs
)))
559 sourceLen
= tag
->ti_Data
;
561 sourceLen
= strlen(source
);
564 if((tag
= FindTagItem(CSA_B64DestFile
,attrs
)))
566 dest
= (APTR
)tag
->ti_Data
;
567 flags
|= B64FLG_DestFile
;
571 if(!(dest
= (APTR
)GetTagData(CSA_B64DestPtr
, 0, attrs
)))
573 RETURN(CSR_B64_ERROR_MEM
);
574 return CSR_B64_ERROR_MEM
;
579 if(flags
& B64FLG_SourceFile
)
581 if(!(in
= (APTR
)openIn(source
,&size
)))
583 RETURN(CSR_B64_ERROR_DOS
);
584 return CSR_B64_ERROR_DOS
;
593 b64
.inAvailable
= size
;
599 if(flags
& B64FLG_DestFile
)
601 if(!(out
= (APTR
)Open(dest
,MODE_NEWFILE
)))
603 RETURN(CSR_B64_ERROR_DOS
);
604 return CSR_B64_ERROR_DOS
;
612 if(!(out
= allocArbitrateVecPooled(totSize
)))
614 if(flags
& B64FLG_SourceFile
)
617 RETURN(CSR_B64_ERROR_MEM
);
618 return CSR_B64_ERROR_MEM
;
621 *((STRPTR
*)dest
) = out
;
634 /* parse error check */
635 errcheck
= !GetTagData(CSA_B64FLG_NtCheckErr
,FALSE
,attrs
);
640 UBYTE a
[4], b
[4], o
[3];
645 int c
= insig (&b64
);
649 if(!(b64
.flags
& B64FLG_DestFile
))
650 ((STRPTR
)out
)[b64
.outIndex
] = 0;
652 if(!b64
.error
&& errcheck
&& (i
>0))
653 b64
.error
= CSR_B64_ERROR_INCOMPLETE
;
662 b64
.error
= CSR_B64_ERROR_ILLEGAL
;
672 b
[i
] = (UBYTE
) dtable
[c
];
675 o
[0] = (b
[0]<<2) | (b
[1]>>4);
676 o
[1] = (b
[1]<<4) | (b
[2]>>2);
677 o
[2] = (b
[2]<<6) | b
[3];
679 i
= a
[2]=='=' ? 1 : (a
[3]=='=' ? 2 : 3);
681 if(ostring(&b64
,o
,i
)==EOF
|| i
< 3)
688 if(flags
& B64FLG_SourceFile
)
691 /* flush and close dest */
692 if(flags
& B64FLG_DestFile
)
696 if(FPuts((BPTR
)out
,b64
.eols
)==EOF
)
697 b64
.error
= CSR_B64_ERROR_DOS
;
699 #if defined(__amigaos4__)
712 freeArbitratePooled(out
,totSize
);
716 RETURN((ULONG
)b64
.error
);
717 return (ULONG
)b64
.error
;
724 LIBSTUB(CodesetsDecodeB64A
, ULONG
, REG(a0
, struct TagItem
*attrs
))
727 return CodesetsDecodeB64A((struct TagItem
*)REG_A0
);
729 return CodesetsDecodeB64A(attrs
);
735 LIBSTUBVA(CodesetsDecodeB64
, ULONG
, ...)
740 VA_START(args
, self
);
741 res
= CodesetsDecodeB64A(VA_ARG(args
, struct TagItem
*));
748 /****************************************************************************/