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 28#ifdef HAVE_CONFIG_H 29#include "config.h" 30#endif /* HAVE_CONFIG_H */ 31#include <stdlib.h> 32#include <netatalk/endian.h> 33#include <atalk/unicode.h> 34 35#include "mac_roman.h" 36#include "generic_mb.h" 37 38static size_t mac_roman_pull(void *,char **, size_t *, char **, size_t *); 39static size_t mac_roman_push(void *,char **, size_t *, char **, size_t *); 40 41struct charset_functions charset_mac_roman = 42{ 43 "MAC_ROMAN", 44 0, 45 mac_roman_pull, 46 mac_roman_push, 47 CHARSET_CLIENT | CHARSET_MULTIBYTE | CHARSET_PRECOMPOSED, 48 NULL, 49 NULL, NULL 50}; 51 52/* ------------------------ */ 53static int 54char_ucs2_to_mac_roman ( unsigned char *r, ucs2_t wc) 55{ 56 unsigned char c = 0; 57 if (wc < 0x0080) { 58 *r = wc; 59 return 1; 60 } 61 else if (wc >= 0x00a0 && wc < 0x0100) 62 c = mac_roman_page00[wc-0x00a0]; 63 else if (wc >= 0x0130 && wc < 0x0198) 64 c = mac_roman_page01[wc-0x0130]; 65 else if (wc >= 0x02c0 && wc < 0x02e0) 66 c = mac_roman_page02[wc-0x02c0]; 67 else if (wc == 0x03c0) 68 c = 0xb9; 69 else if (wc >= 0x2010 && wc < 0x2048) 70 c = mac_roman_page20[wc-0x2010]; 71 else if (wc >= 0x2120 && wc < 0x2128) 72 c = mac_roman_page21[wc-0x2120]; 73 else if (wc >= 0x2200 && wc < 0x2268) 74 c = mac_roman_page22[wc-0x2200]; 75 else if (wc == 0x25ca) 76 c = 0xd7; 77 else if (wc >= 0xfb00 && wc < 0xfb08) 78 c = mac_roman_pagefb[wc-0xfb00]; 79 else if (wc == 0xf8ff) 80 c = 0xf0; 81 82 if (c != 0) { 83 *r = c; 84 return 1; 85 } 86 return 0; 87} 88 89static size_t mac_roman_push( void *cd, char **inbuf, size_t *inbytesleft, 90 char **outbuf, size_t *outbytesleft) 91{ 92 /* No special handling required */ 93 return (size_t) mb_generic_push( char_ucs2_to_mac_roman, cd, inbuf, inbytesleft, outbuf, outbytesleft); 94} 95 96/* ------------------------ */ 97static int 98char_mac_roman_to_ucs2 (ucs2_t *pwc, const unsigned char *s) 99{ 100 unsigned char c = *s; 101 if (c < 0x80) { 102 *pwc = (ucs2_t) c; 103 return 1; 104 } 105 else { 106 unsigned short wc = mac_roman_2uni[c-0x80]; 107 *pwc = (ucs2_t) wc; 108 return 1; 109 } 110 return 0; 111} 112 113static size_t mac_roman_pull ( void *cd, char **inbuf, size_t *inbytesleft, 114 char **outbuf, size_t *outbytesleft) 115{ 116 return (size_t) mb_generic_pull( char_mac_roman_to_ucs2, cd, inbuf, inbytesleft, outbuf, outbytesleft); 117} 118