]> arthur.barton.de Git - netatalk.git/blob - libatalk/unicode/charsets/generic_mb.c
7b36997d804a035a4f6b86f1d0686d95df9b6759
[netatalk.git] / libatalk / unicode / charsets / generic_mb.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 <unistd.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <arpa/inet.h>
35
36 #include <atalk/unicode.h>
37 #include <atalk/logger.h>
38
39 #include "generic_mb.h"
40 #include "../byteorder.h"
41
42
43 /* ------------------------ */
44
45 size_t mb_generic_push( int (*char_func)(unsigned char *, ucs2_t), void *cd _U_, char **inbuf, 
46                         size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
47 {
48         int len = 0;
49         unsigned char *tmpptr = (unsigned char *) *outbuf;
50         ucs2_t inval;
51
52         while (*inbytesleft >= 2 && *outbytesleft >= 1) {
53
54                 inval = SVAL((*inbuf),0);
55                 if ( (char_func)( tmpptr, inval)) {
56                         (*inbuf) += 2;
57                         tmpptr++;
58                         len++;
59                         (*inbytesleft)  -= 2;
60                         (*outbytesleft) -= 1;
61                 }
62                 else    
63                 {
64                         errno = EILSEQ;
65                         return (size_t) -1;     
66                 }
67         }
68
69         if (*inbytesleft > 0) {
70                 errno = E2BIG;
71                 return -1;
72         }
73
74         return len;
75 }
76
77 /* ------------------------ */
78
79 size_t mb_generic_pull ( int (*char_func)(ucs2_t *, const unsigned char *), void *cd _U_, 
80                         char **inbuf, size_t *inbytesleft,char **outbuf, size_t *outbytesleft)
81 {
82         ucs2_t          temp;
83         unsigned char   *inptr;
84         size_t  len = 0;
85
86         while (*inbytesleft >= 1 && *outbytesleft >= 2) {
87
88                 inptr = (unsigned char *) *inbuf;
89                 if (char_func ( &temp, inptr)) {
90                         SSVAL((*outbuf), 0, temp);
91                         (*inbuf)        +=1;
92                         (*outbuf)       +=2;
93                         (*inbytesleft) -=1;
94                         (*outbytesleft)-=2;
95                         len++;
96                         
97                 }
98                 else    
99                 {
100                         errno = EILSEQ;
101                         return (size_t) -1;     
102                 }
103         }
104
105         if (*inbytesleft > 0) {
106                 errno = E2BIG;
107                 return (size_t) -1;
108         }
109
110         return len;
111
112 }