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-2009 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 /****************************************************************************/
44 B64FLG_SourceFile
= 1<<0,
45 B64FLG_DestFile
= 1<<1,
49 /****************************************************************************/
57 /****************************************************************************/
59 static const UBYTE etable
[] =
61 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
62 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
63 85, 86, 87, 88, 89, 90, 97, 98, 99, 100,
64 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
65 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
66 121, 122, 48, 49, 50, 51, 52, 53, 54, 55,
67 56, 57, 43, 47, 0, 0, 0, 0, 0, 0,
68 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72 0, 0, 0, 0, 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,
89 static const UBYTE dtable
[] =
91 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
92 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
93 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
94 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
95 128, 128, 128, 62, 128, 128, 128, 63, 52, 53,
96 54, 55, 56, 57, 58, 59, 60, 61, 128, 128,
97 128, 0, 128, 128, 128, 0, 1, 2, 3, 4,
98 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
99 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
100 25, 128, 128, 128, 128, 128, 128, 26, 27, 28,
101 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
102 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
103 49, 50, 51, 128, 128, 128, 128, 128, 128, 128,
104 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
105 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
106 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
107 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
108 128, 128, 128, 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, 0
119 /****************************************************************************/
121 #if defined(__amigaos4__)
123 openIn(STRPTR name
, int64
*size
)
126 struct ExamineData
*exd
;
130 if((exd
= ExamineObjectTags(EX_StringNameInput
, name
, TAG_END
)) != NULL
)
134 if((file
= Open(name
, MODE_OLDFILE
)))
135 *size
= exd
->FileSize
;
138 FreeDosObject(DOS_EXAMINEDATA
, exd
);
145 #elif defined(__MORPHOS__)
147 openIn(STRPTR name
, ULONG
* size
)
149 struct FileInfoBlock fib
;
154 if((file
= Open(name
,MODE_OLDFILE
)))
156 if(!ExamineFH(file
,&fib
))
163 *size
= fib
.fib_Size
;
172 openIn(STRPTR name
, ULONG
* size
)
174 struct FileInfoBlock
*fib
;
179 if((fib
= AllocDosObject(DOS_FIB
,NULL
)))
181 if((file
= Open(name
,MODE_OLDFILE
)))
183 if(!ExamineFH(file
,fib
))
190 *size
= fib
->fib_Size
;
194 FreeDosObject(DOS_FIB
,fib
);
204 /****************************************************************************/
207 inchar(struct b64
*b64
)
213 if(b64
->flags
& B64FLG_SourceFile
)
215 if((c
= FGetC((BPTR
)b64
->in
))==EOF
)
218 b64
->error
= CSR_B64_ERROR_DOS
;
223 if(!b64
->inAvailable
)
229 c
= ((STRPTR
)b64
->in
)[b64
->inIndex
++];
237 /****************************************************************************/
240 ochar(struct b64
*b64
,int c
)
244 if(b64
->flags
& B64FLG_DestFile
)
248 if(b64
->maxLineLen
&& (b64
->lineCounter
>=b64
->maxLineLen
))
250 r
= FPuts((BPTR
)b64
->out
,b64
->eols
);
251 b64
->lineCounter
= 0;
256 r
= FPutC((BPTR
)b64
->out
,c
);
261 b64
->error
= CSR_B64_ERROR_DOS
;
271 ((STRPTR
)b64
->out
)[b64
->outIndex
++] = c
;
278 /****************************************************************************/
281 ostring(struct b64
*b64
,UBYTE
* buf
,int s
)
287 if(b64
->flags
& B64FLG_DestFile
)
291 for(r
= i
= 0; (r
!=EOF
) && (i
<s
); i
++)
293 r
= FPutC((BPTR
)b64
->out
,buf
[i
]);
298 b64
->error
= CSR_B64_ERROR_DOS
;
307 ((STRPTR
)b64
->out
)[b64
->outIndex
++] = buf
[i
];
314 /****************************************************************************/
317 insig(struct b64
*b64
)
325 if((c
==EOF
) || (c
>' '))
333 /****************************************************************************/
336 CodesetsEncodeB64A(REG(a0
, struct TagItem
*attrs
))
342 ULONG totSize
, stop
, flags
;
343 #if defined(__amigaos4__)
348 int sourceLen
= 0, maxLineLen
;
352 if((tag
= FindTagItem(CSA_B64SourceFile
,attrs
)))
354 source
= (STRPTR
)tag
->ti_Data
;
355 flags
|= B64FLG_SourceFile
;
359 if((!(source
= (STRPTR
)GetTagData(CSA_B64SourceString
, 0, attrs
))))
361 RETURN(CSR_B64_ERROR_MEM
);
362 return CSR_B64_ERROR_MEM
;
365 if((tag
= FindTagItem(CSA_B64SourceLen
,attrs
)))
366 sourceLen
= tag
->ti_Data
;
368 sourceLen
= strlen(source
);
371 if((tag
= FindTagItem(CSA_B64DestFile
,attrs
)))
373 dest
= (APTR
)tag
->ti_Data
;
374 flags
|= B64FLG_DestFile
;
378 if((!(dest
= (APTR
)GetTagData(CSA_B64DestPtr
, 0, attrs
))))
380 RETURN(CSR_B64_ERROR_MEM
);
381 return CSR_B64_ERROR_MEM
;
385 maxLineLen
= GetTagData(CSA_B64MaxLineLen
,0,attrs
);
386 if(maxLineLen
<=0 || maxLineLen
>=256)
387 maxLineLen
= MAXLINELEN
;
389 if(GetTagData(CSA_B64Unix
,TRUE
,attrs
))
390 flags
|= B64FLG_Unix
;
393 if(flags
& B64FLG_SourceFile
)
395 if(!(in
= (APTR
)openIn(source
,&size
)))
397 RETURN(CSR_B64_ERROR_DOS
);
398 return CSR_B64_ERROR_DOS
;
407 b64
.inAvailable
= size
;
413 if(flags
& B64FLG_DestFile
)
415 if(!(out
= (APTR
)Open(dest
,MODE_NEWFILE
)))
417 RETURN(CSR_B64_ERROR_DOS
);
418 return CSR_B64_ERROR_DOS
;
426 if(!(out
= allocArbitrateVecPooled(totSize
)))
428 if(flags
& B64FLG_SourceFile
)
431 RETURN(CSR_B64_ERROR_MEM
);
432 return CSR_B64_ERROR_MEM
;
435 *((STRPTR
*)dest
) = out
;
444 b64
.maxLineLen
= maxLineLen
;
446 b64
.eols
= (flags
& B64FLG_Unix
) ? "\n" : "\r\n";
453 UBYTE igroup
[3], ogroup
[4];
456 igroup
[0] = igroup
[1] = igroup
[2] = 0;
467 igroup
[n
] = (UBYTE
) c
;
472 ogroup
[0] = etable
[igroup
[0]>>2];
473 ogroup
[1] = etable
[((igroup
[0] & 3)<<4) | (igroup
[1]>>4)];
474 ogroup
[2] = etable
[((igroup
[1] & 0xF)<<2) | (igroup
[2]>>6)];
475 ogroup
[3] = etable
[igroup
[2] & 0x3F];
486 c
= ochar(&b64
,ogroup
[i
]);
496 if(!(b64
.flags
& B64FLG_DestFile
))
497 ((STRPTR
)out
)[b64
.outIndex
] = 0;
500 if(flags
& B64FLG_SourceFile
)
503 /* flush and close dest */
504 if(flags
& B64FLG_DestFile
)
508 if(FPuts((BPTR
)out
,b64
.eols
)==EOF
)
509 b64
.error
= CSR_B64_ERROR_DOS
;
511 #if defined(__amigaos4__)
523 freeArbitrateVecPooled(out
);
526 RETURN((ULONG
)b64
.error
);
527 return (ULONG
)b64
.error
;
530 /****************************************************************************/
533 CodesetsDecodeB64A(REG(a0
, struct TagItem
*attrs
))
539 ULONG totSize
, flags
, errcheck
;
540 #if defined(__amigaos4__)
551 if((tag
= FindTagItem(CSA_B64SourceFile
,attrs
)))
553 source
= (STRPTR
)tag
->ti_Data
;
554 flags
|= B64FLG_SourceFile
;
558 if (!(source
= (STRPTR
)GetTagData(CSA_B64SourceString
,0,attrs
)))
560 RETURN(CSR_B64_ERROR_MEM
);
561 return CSR_B64_ERROR_MEM
;
564 if((tag
= FindTagItem(CSA_B64SourceLen
,attrs
)))
565 sourceLen
= tag
->ti_Data
;
567 sourceLen
= strlen(source
);
570 if((tag
= FindTagItem(CSA_B64DestFile
,attrs
)))
572 dest
= (APTR
)tag
->ti_Data
;
573 flags
|= B64FLG_DestFile
;
577 if(!(dest
= (APTR
)GetTagData(CSA_B64DestPtr
, 0, attrs
)))
579 RETURN(CSR_B64_ERROR_MEM
);
580 return CSR_B64_ERROR_MEM
;
585 if(flags
& B64FLG_SourceFile
)
587 if(!(in
= (APTR
)openIn(source
,&size
)))
589 RETURN(CSR_B64_ERROR_DOS
);
590 return CSR_B64_ERROR_DOS
;
599 b64
.inAvailable
= size
;
605 if(flags
& B64FLG_DestFile
)
607 if(!(out
= (APTR
)Open(dest
,MODE_NEWFILE
)))
609 RETURN(CSR_B64_ERROR_DOS
);
610 return CSR_B64_ERROR_DOS
;
618 if(!(out
= allocArbitrateVecPooled(totSize
)))
620 if(flags
& B64FLG_SourceFile
)
623 RETURN(CSR_B64_ERROR_MEM
);
624 return CSR_B64_ERROR_MEM
;
627 *((STRPTR
*)dest
) = out
;
640 /* parse error check */
641 errcheck
= !GetTagData(CSA_B64FLG_NtCheckErr
,FALSE
,attrs
);
646 UBYTE a
[4], b
[4], o
[3];
651 int c
= insig (&b64
);
655 if(!(b64
.flags
& B64FLG_DestFile
))
656 ((STRPTR
)out
)[b64
.outIndex
] = 0;
658 if(!b64
.error
&& errcheck
&& (i
>0))
659 b64
.error
= CSR_B64_ERROR_INCOMPLETE
;
668 b64
.error
= CSR_B64_ERROR_ILLEGAL
;
678 b
[i
] = (UBYTE
) dtable
[c
];
681 o
[0] = (b
[0]<<2) | (b
[1]>>4);
682 o
[1] = (b
[1]<<4) | (b
[2]>>2);
683 o
[2] = (b
[2]<<6) | b
[3];
685 i
= a
[2]=='=' ? 1 : (a
[3]=='=' ? 2 : 3);
687 if(ostring(&b64
,o
,i
)==EOF
|| i
< 3)
694 if(flags
& B64FLG_SourceFile
)
697 /* flush and close dest */
698 if(flags
& B64FLG_DestFile
)
702 if(FPuts((BPTR
)out
,b64
.eols
)==EOF
)
703 b64
.error
= CSR_B64_ERROR_DOS
;
705 #if defined(__amigaos4__)
717 freeArbitrateVecPooled(out
);
720 RETURN((ULONG
)b64
.error
);
721 return (ULONG
)b64
.error
;
724 /****************************************************************************/