1/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ 2 3/* 4 * This file is part of The Croco Library 5 * 6 * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of version 2.1 of the GNU Lesser General Public 10 * License as published by the Free Software Foundation. 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 Lesser General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 20 * USA 21 */ 22 23/* 24 *$Id: cr-enc-handler.c,v 1.8 2005/05/10 19:48:56 dodji Exp $ 25 */ 26 27/** 28 *@file 29 *The definition of the #CREncHandler class. 30 */ 31 32#include <config.h> 33#include "cr-enc-handler.h" 34#include "cr-utils.h" 35 36#include <string.h> 37 38struct CREncAlias { 39 const gchar *name; 40 enum CREncoding encoding; 41}; 42 43static struct CREncAlias gv_default_aliases[] = { 44 {"UTF-8", CR_UTF_8}, 45 {"UTF_8", CR_UTF_8}, 46 {"UTF8", CR_UTF_8}, 47 {"UTF-16", CR_UTF_16}, 48 {"UTF_16", CR_UTF_16}, 49 {"UTF16", CR_UTF_16}, 50 {"UCS1", CR_UCS_1}, 51 {"UCS-1", CR_UCS_1}, 52 {"UCS_1", CR_UCS_1}, 53 {"ISO-8859-1", CR_UCS_1}, 54 {"ISO_8859-1", CR_UCS_1}, 55 {"UCS-1", CR_UCS_1}, 56 {"UCS_1", CR_UCS_1}, 57 {"UCS4", CR_UCS_4}, 58 {"UCS-4", CR_UCS_4}, 59 {"UCS_4", CR_UCS_4}, 60 {"ASCII", CR_ASCII}, 61 {0, 0} 62}; 63 64static CREncHandler gv_default_enc_handlers[] = { 65 {CR_UCS_1, cr_utils_ucs1_to_utf8, cr_utils_utf8_to_ucs1, 66 cr_utils_ucs1_str_len_as_utf8, cr_utils_utf8_str_len_as_ucs1}, 67 68 {CR_ISO_8859_1, cr_utils_ucs1_to_utf8, cr_utils_utf8_to_ucs1, 69 cr_utils_ucs1_str_len_as_utf8, cr_utils_utf8_str_len_as_ucs1}, 70 71 {CR_ASCII, cr_utils_ucs1_to_utf8, cr_utils_utf8_to_ucs1, 72 cr_utils_ucs1_str_len_as_utf8, cr_utils_utf8_str_len_as_ucs1}, 73 74 {0, NULL, NULL, NULL, NULL} 75}; 76 77/** 78 * cr_enc_handler_get_instance: 79 *@a_enc: the encoding of the Handler. 80 * 81 *Gets the instance of encoding handler. 82 *This function implements a singleton pattern. 83 * 84 *Returns the instance of #CREncHandler. 85 */ 86CREncHandler * 87cr_enc_handler_get_instance (enum CREncoding a_enc) 88{ 89 gulong i = 0; 90 91 for (i = 0; gv_default_enc_handlers[i].encoding; i++) { 92 if (gv_default_enc_handlers[i].encoding == a_enc) { 93 return (CREncHandler *) 94 & gv_default_enc_handlers[i].encoding; 95 } 96 } 97 98 return NULL; 99} 100 101/** 102 * cr_enc_handler_resolve_enc_alias: 103 *@a_alias_name: the encoding name. 104 *@a_enc: output param. The returned encoding type 105 *or 0 if the alias is not supported. 106 * 107 *Given an encoding name (called an alias name) 108 *the function returns the matching encoding type. 109 * 110 *Returns CR_OK upon successfull completion, an error code otherwise. 111 */ 112enum CRStatus 113cr_enc_handler_resolve_enc_alias (const guchar * a_alias_name, 114 enum CREncoding *a_enc) 115{ 116 gulong i = 0; 117 guchar *alias_name_up = NULL; 118 enum CRStatus status = CR_ENCODING_NOT_FOUND_ERROR; 119 120 g_return_val_if_fail (a_alias_name != NULL, CR_BAD_PARAM_ERROR); 121 122 alias_name_up = g_strdup (a_alias_name); 123 g_ascii_strup (alias_name_up, -1); 124 125 for (i = 0; gv_default_aliases[i].name; i++) { 126 if (!strcmp (gv_default_aliases[i].name, alias_name_up)) { 127 *a_enc = gv_default_aliases[i].encoding; 128 status = CR_OK; 129 break; 130 } 131 } 132 133 return status; 134} 135 136/** 137 * cr_enc_handler_convert_input: 138 *@a_this: the current instance of #CREncHandler. 139 *@a_in: the input buffer to convert. 140 *@a_in_len: in/out parameter. The len of the input 141 *buffer to convert. After return, contains the number of 142 *bytes actually consumed. 143 *@a_out: output parameter. The converted output buffer. 144 *Must be freed by the buffer. 145 *@a_out_len: output parameter. The length of the output buffer. 146 * 147 *Converts a raw input buffer into an utf8 buffer. 148 * 149 *Returns CR_OK upon successfull completion, an error code otherwise. 150 */ 151enum CRStatus 152cr_enc_handler_convert_input (CREncHandler * a_this, 153 const guchar * a_in, 154 gulong * a_in_len, 155 guchar ** a_out, gulong * a_out_len) 156{ 157 enum CRStatus status = CR_OK; 158 159 g_return_val_if_fail (a_this && a_in && a_in_len && a_out, 160 CR_BAD_PARAM_ERROR); 161 162 if (a_this->decode_input == NULL) 163 return CR_OK; 164 165 if (a_this->enc_str_len_as_utf8) { 166 status = a_this->enc_str_len_as_utf8 (a_in, 167 &a_in[*a_in_len - 1], 168 a_out_len); 169 170 g_return_val_if_fail (status == CR_OK, status); 171 } else { 172 *a_out_len = *a_in_len; 173 } 174 175 *a_out = g_malloc0 (*a_out_len); 176 177 status = a_this->decode_input (a_in, a_in_len, *a_out, a_out_len); 178 179 if (status != CR_OK) { 180 g_free (*a_out); 181 *a_out = NULL; 182 } 183 184 g_return_val_if_fail (status == CR_OK, status); 185 186 return CR_OK; 187} 188