1/* Conversion from UTF-8 to legacy encodings. 2 Copyright (C) 2002, 2006-2007, 2009-2010 Free Software Foundation, Inc. 3 4 This program is free software: you can redistribute it and/or modify it 5 under the terms of the GNU Lesser General Public License as published 6 by the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17/* Written by Bruno Haible <bruno@clisp.org>. */ 18 19#include <config.h> 20 21/* Specification. */ 22#include "uniconv.h" 23 24#include <errno.h> 25#include <stdlib.h> 26#include <string.h> 27 28#include "c-strcaseeq.h" 29#include "striconveha.h" 30#include "unistr.h" 31 32char * 33u8_conv_to_encoding (const char *tocode, 34 enum iconv_ilseq_handler handler, 35 const uint8_t *src, size_t srclen, 36 size_t *offsets, 37 char *resultbuf, size_t *lengthp) 38{ 39 if (STRCASEEQ (tocode, "UTF-8", 'U','T','F','-','8',0,0,0,0)) 40 { 41 char *result; 42 43 /* Conversion from UTF-8 to UTF-8. No need to go through iconv(). */ 44#if CONFIG_UNICODE_SAFETY 45 if (u8_check (src, srclen)) 46 { 47 errno = EILSEQ; 48 return NULL; 49 } 50#endif 51 52 /* Memory allocation. */ 53 if (resultbuf != NULL && *lengthp >= srclen) 54 result = resultbuf; 55 else 56 { 57 result = (char *) malloc (srclen > 0 ? srclen : 1); 58 if (result == NULL) 59 { 60 errno = ENOMEM; 61 return NULL; 62 } 63 } 64 65 memcpy (result, (const char *) src, srclen); 66 *lengthp = srclen; 67 return result; 68 } 69 else 70 { 71 char *result = resultbuf; 72 size_t length = *lengthp; 73 74 if (mem_iconveha ((const char *) src, srclen, 75 "UTF-8", tocode, 76 handler == iconveh_question_mark, handler, 77 offsets, &result, &length) < 0) 78 return NULL; 79 80 if (result == NULL) /* when (resultbuf == NULL && length == 0) */ 81 { 82 result = (char *) malloc (1); 83 if (result == NULL) 84 { 85 errno = ENOMEM; 86 return NULL; 87 } 88 } 89 *lengthp = length; 90 return result; 91 } 92} 93