]> arthur.barton.de Git - netatalk.git/blob - libatalk/unicode/charsets/mac_hebrew.c
Move byteorder.h to include/atalk
[netatalk.git] / libatalk / unicode / charsets / mac_hebrew.c
1 /* 
2    Unix SMB/CIFS implementation.
3    minimal iconv implementation
4    Copyright (C) Andrew Tridgell 2001
5    Copyright (C) Jelmer Vernooij 2002,2003
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program 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
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21    From samba 3.0 beta and GNU libiconv-1.8
22    It's bad but most of the time we can't use libc iconv service:
23    - it doesn't round trip for most encoding
24    - it doesn't know about Apple extension
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif /* HAVE_CONFIG_H */
30 #include <stdlib.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <arpa/inet.h>
34
35 #include <atalk/unicode.h>
36 #include <atalk/logger.h>
37 #include <atalk/byteorder.h>
38
39 #include "mac_hebrew.h"
40
41 static size_t   mac_hebrew_pull(void *,char **, size_t *, char **, size_t *);
42 static size_t   mac_hebrew_push(void *,char **, size_t *, char **, size_t *);
43
44 struct charset_functions charset_mac_hebrew =
45 {
46         "MAC_HEBREW",
47         5,
48         mac_hebrew_pull,
49         mac_hebrew_push,
50         CHARSET_CLIENT | CHARSET_MULTIBYTE,
51         NULL,
52         NULL, NULL
53 };
54
55
56 /* ------------------------ 
57  * from unicode to mac hebrew code page
58 */
59 static int
60 char_ucs2_to_mac_hebrew ( unsigned char *r, ucs2_t wc)
61 {
62     unsigned char c = 0;
63     if (wc < 0x0080) {
64        *r = wc;
65        return 1;
66     }
67     else if (wc >= 0x00a0 && wc < 0x0100)
68         c = mac_hebrew_page00[wc-0x00a0];
69     else if (wc >= 0x05b0 && wc < 0x05f0)
70         c = mac_hebrew_page05[wc-0x05b0];
71     else if (wc >= 0x2010 && wc < 0x2028)
72         c = mac_hebrew_page20[wc-0x2010];
73     else if (wc == 0x20aa)
74         c = 0xa6;
75     else if (wc >= 0xfb18 && wc < 0xfb50)
76         c = mac_hebrew_pagefb[wc-0xfb18];
77     if (c != 0) {
78        *r = c;
79        return 1;
80     }
81     return 0;
82 }
83
84 static size_t mac_hebrew_push( void *cd _U_, char **inbuf, size_t *inbytesleft,
85                          char **outbuf, size_t *outbytesleft)
86 {
87     unsigned char c = 0;
88     int len = 0;
89     unsigned char *tmpptr = (unsigned char *) *outbuf;
90
91     while (*inbytesleft >= 2 && *outbytesleft >= 1) {
92         ucs2_t inptr = SVAL((*inbuf),0);
93         if (inptr == 0x05b8) {
94             (*inbuf) += 2;
95             (*inbytesleft)  -= 2;
96             if (*inbytesleft >= 2 && SVAL((*inbuf),0) == 0xf87f ) {
97                 (*inbuf) += 2;
98                 (*inbytesleft)  -= 2;
99                 c = 0xde;
100             }
101             else {
102                 c = 0xcb;
103             }
104             *tmpptr = c; 
105         }
106         else if (inptr == 0x05f2 && *inbytesleft >= 4 && SVAL((*inbuf),2) == 0x05b7) {
107             (*inbuf) += 4;
108             (*inbytesleft)  -= 4;
109             *tmpptr = 0x81;
110         }
111         else if (inptr == 0xf86a && *inbytesleft >= 6 && SVAL((*inbuf),2) == 0x05dc && SVAL((*inbuf),4) == 0x05b9) {
112             (*inbuf) += 6;
113             (*inbytesleft)  -= 6;
114             *tmpptr = 0xc0;
115         }
116         else if (char_ucs2_to_mac_hebrew ( tmpptr, inptr)) {
117             (*inbuf) += 2;
118             (*inbytesleft)  -= 2;
119         }
120         else {
121             errno = EILSEQ;
122             return (size_t) -1;
123         }
124         (*outbytesleft) -= 1;
125         tmpptr++;
126         len++;
127     }
128
129     if (*inbytesleft > 0) {
130         errno = E2BIG;
131         return -1;
132     }
133
134     return len;
135 }
136
137 /* ------------------------ */
138 static int
139 char_mac_hebrew_to_ucs2 (ucs2_t *pwc, const unsigned char *s)
140 {
141         unsigned char c = *s;
142         if (c < 0x80) {
143                 *pwc = (ucs2_t) c;
144                 return 1;
145         }
146         else {
147                 unsigned short wc = mac_hebrew_2uni[c-0x80];
148                 if (wc != 0xfffd) {
149                     *pwc = (ucs2_t) wc;
150                     return 1;
151                 }
152         }
153         return 0;
154 }
155
156 static size_t mac_hebrew_pull ( void *cd _U_, char **inbuf, size_t *inbytesleft,
157                          char **outbuf, size_t *outbytesleft)
158 {
159     ucs2_t         temp;
160     unsigned char  *inptr;
161     size_t         len = 0;
162
163     while (*inbytesleft >= 1 && *outbytesleft >= 2) {
164         inptr = (unsigned char *) *inbuf;
165         if (char_mac_hebrew_to_ucs2 ( &temp, inptr)) {
166             if (temp == 1) {       /* 0x81 --> 0x05f2+0x05b7 */
167                 if (*outbytesleft < 4) {
168                     errno = E2BIG;
169                     return (size_t) -1; 
170                 }
171                 SSVAL((*outbuf),0,0x05f2);
172                 SSVAL((*outbuf),2,0x05b7);
173                 (*outbuf)      +=4;
174                 (*outbytesleft)-=4;
175                 len += 2;
176             }
177             else if (temp == 2) { /* 0xc0 -> 0xf86a 0x05dc 0x05b9*/
178                 if (*outbytesleft < 6) {
179                     errno = E2BIG;
180                     return (size_t) -1; 
181                 }
182                 SSVAL((*outbuf),0,0xf86a);
183                 SSVAL((*outbuf),2,0x05dc);
184                 SSVAL((*outbuf),4,0x05b9);
185                 (*outbuf)      +=6;
186                 (*outbytesleft)-=6;
187                 len += 3;
188             }
189             else if (temp == 3) { /* 0xde --> 0x05b8 0xf87f */
190                 if (*outbytesleft < 4) {
191                     errno = E2BIG;
192                     return (size_t) -1; 
193                 }
194                 SSVAL((*outbuf),0,0x05b8);
195                 SSVAL((*outbuf),2,0xf87f);
196                 (*outbuf)      +=4;
197                 (*outbytesleft)-=4;
198                 len += 2;
199             }
200             else {
201                 SSVAL((*outbuf),0,temp);
202                 (*outbuf)      +=2;
203                 (*outbytesleft)-=2;
204                 len++;
205             }
206             (*inbuf)        +=1;
207             (*inbytesleft) -=1;
208         }
209         else    
210         {
211             errno = EILSEQ;
212             return (size_t) -1; 
213         }
214     }
215
216     if (*inbytesleft > 0) {
217         errno = E2BIG;
218         return (size_t) -1;
219     }
220     return len;
221 }
222