tconvert.c - vaccinewars - be a doctor and try to vaccinate the world
HTML git clone git://src.adamsgaard.dk/vaccinewars
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
tconvert.c (3880B)
---
1 /************************************************************************
2 * convert.c Codeset conversion functions *
3 * Copyright (C) 2002-2004 Ben Webb *
4 * Email: benwebb@users.sf.net *
5 * WWW: https://dopewars.sourceforge.io/ *
6 * *
7 * This program is free software; you can redistribute it and/or *
8 * modify it under the terms of the GNU General Public License *
9 * as published by the Free Software Foundation; either version 2 *
10 * of the License, or (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., 59 Temple Place - Suite 330, Boston, *
20 * MA 02111-1307, USA. *
21 ************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include <string.h>
28 #include <glib.h>
29
30 #include "convert.h"
31
32 static gchar *int_codeset = NULL;
33
34 static const gchar *FixedCodeset(const gchar *codeset)
35 {
36 if (strcmp(codeset, "ANSI_X3.4-1968") == 0
37 || strcmp(codeset, "ASCII") == 0) {
38 return "ISO-8859-1";
39 } else {
40 return codeset;
41 }
42 }
43
44 void Conv_SetInternalCodeset(const gchar *codeset)
45 {
46 g_free(int_codeset);
47 int_codeset = g_strdup(FixedCodeset(codeset));
48 }
49
50 static const gchar *GetLocaleCodeset(void)
51 {
52 const gchar *codeset;
53
54 g_get_charset(&codeset);
55 return FixedCodeset(codeset);
56 }
57
58 Converter *Conv_New(void)
59 {
60 Converter *conv;
61
62 conv = g_new(Converter, 1);
63 conv->ext_codeset = g_strdup(GetLocaleCodeset());
64 if (!int_codeset) {
65 int_codeset = g_strdup(GetLocaleCodeset());
66 }
67 return conv;
68 }
69
70 void Conv_Free(Converter *conv)
71 {
72 g_free(conv->ext_codeset);
73 g_free(conv);
74 }
75
76 void Conv_SetCodeset(Converter *conv, const gchar *codeset)
77 {
78 g_free(conv->ext_codeset);
79 conv->ext_codeset = g_strdup(FixedCodeset(codeset));
80 }
81
82 gboolean Conv_Needed(Converter *conv)
83 {
84 return (strcmp(conv->ext_codeset, int_codeset) != 0
85 || strcmp(int_codeset, "UTF-8") == 0);
86 }
87
88 static gchar *do_convert(const gchar *from_codeset, const gchar *to_codeset,
89 const gchar *from_str, int from_len)
90 {
91 gchar *to_str;
92
93 if (strcmp(to_codeset, "UTF-8") == 0 && strcmp(from_codeset, "UTF-8") == 0) {
94 const gchar *start, *end;
95
96 if (from_len == -1) {
97 to_str = g_strdup(from_str);
98 } else {
99 to_str = g_strndup(from_str, from_len);
100 }
101 start = to_str;
102 while (start && *start && !g_utf8_validate(start, -1, &end)
103 && end && *end) {
104 *((gchar *)end) = '?';
105 start = ++end;
106 }
107 return to_str;
108 } else {
109 to_str = g_convert_with_fallback(from_str, from_len, to_codeset,
110 from_codeset, "?", NULL, NULL, NULL);
111 if (to_str) {
112 return to_str;
113 } else {
114 return g_strdup("[?]");
115 }
116 }
117 }
118
119 gchar *Conv_ToExternal(Converter *conv, const gchar *int_str, int len)
120 {
121 return do_convert(int_codeset, conv->ext_codeset, int_str, len);
122 }
123
124 gchar *Conv_ToInternal(Converter *conv, const gchar *ext_str, int len)
125 {
126 return do_convert(conv->ext_codeset, int_codeset, ext_str, len);
127 }