aboutsummaryrefslogtreecommitdiff
path: root/iconvdata/iso646.c
diff options
context:
space:
mode:
Diffstat (limited to 'iconvdata/iso646.c')
-rw-r--r--iconvdata/iso646.c67
1 files changed, 56 insertions, 11 deletions
diff --git a/iconvdata/iso646.c b/iconvdata/iso646.c
index db0c0893e7..3b4864ef11 100644
--- a/iconvdata/iso646.c
+++ b/iconvdata/iso646.c
@@ -18,6 +18,19 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* The implementation of the conversion which can be performed by this
+ module are not very sophisticated and not tuned at all. There are
+ zillions of ISO 646 derivates and supporting them all in a separate
+ module is overkill since these coded character sets are hardly ever
+ used anymore (except ANSI_X3.4-1968 == ASCII, which is compatible
+ with ISO 8859-1). The European variants are superceded by the
+ various ISO 8859-? standards and the Asian variants are embedded in
+ larger character sets. Therefore this implementation is simply
+ here to make it possible to do the conversion if it is necessary.
+ The cost in the gconv-modules file is set to `2' and therefore
+ allows one to easily provide a tuned implementation in case this
+ proofs to be necessary. */
+
#include <gconv.h>
#include <stdlib.h>
#include <string.h>
@@ -25,13 +38,14 @@
/* Direction of the transformation. */
enum direction
{
- illegal,
+ illegal_dir,
to_iso646,
from_iso646
};
enum variant
{
+ illegal_var,
US, /* ANSI_X3.4-1968 */
GB, /* BS_4730 */
};
@@ -73,10 +87,13 @@ gconv_init (struct gconv_step *step, struct gconv_step_data *data)
var = GB;
}
else
- dir = illegal;
+ {
+ dir = illegal_dir;
+ var = illegal_var;
+ }
result = GCONV_NOCONV;
- if (dir != illegal
+ if (dir != illegal_dir
&& ((new_data
= (struct iso646_data *) malloc (sizeof (struct iso646_data)))
!= NULL))
@@ -167,11 +184,16 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
default:
*((wchar_t *) (outbuf + outwchars)) =
(unsigned char) inbuf[cnt];
+ case '\x80' ... '\xff':
+ /* Illegal character. */
+ result = GCONV_ILLEGAL_INPUT;
+ goto out_from;
}
++do_write;
outwchars += sizeof (wchar_t);
++cnt;
}
+ out_from:
*inbufsize -= cnt;
data->outbufavail = outwchars;
}
@@ -179,24 +201,47 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
{
size_t inwchars = *inbufsize;
size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
+ unsigned char *outbuf = data->outbuf;
size_t cnt = 0;
while (inwchars >= cnt + sizeof (wchar_t)
&& outchars < data->outbufsize)
{
- if (*((wchar_t *) (inbuf + cnt)) >= L'\0'
- && *((wchar_t *) (inbuf + cnt)) <= L'\177')
- outbuf[outchars] = *((wchar_t *) (inbuf + cnt));
- else
- /* Here is where the transliteration would enter the
- scene. */
- break;
+ switch (*((wchar_t *) (inbuf + cnt)))
+ {
+ case 0x23:
+ if (var == GB)
+ goto out_to;
+ outbuf[outchars] = 0x23;
+ break;
+ case 0x75:
+ if (var == GB)
+ goto out_to;
+ outbuf[outchars] = 0x75;
+ break;
+ case 0xa3:
+ if (var != GB)
+ goto out_to;
+ outbuf[outchars] = 0x23;
+ break;
+ case 0x203e:
+ if (var != GB)
+ goto out_to;
+ outbuf[outchars] = 0x75;
+ break;
+ default:
+ if (*((wchar_t *) (inbuf + cnt)) > 0x7f)
+ goto out_to;
+ outbuf[outchars] =
+ (unsigned char) *((wchar_t *) (inbuf + cnt));
+ break;
+ }
++do_write;
++outchars;
cnt += sizeof (wchar_t);
}
+ out_to:
*inbufsize -= cnt;
data->outbufavail = outchars;