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 35#include <netatalk/endian.h> 36#include <atalk/unicode.h> 37#include <atalk/logger.h> 38 39#include "generic_mb.h" 40#include "../byteorder.h" 41 42 43/* ------------------------ */ 44 45size_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 79size_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} 113