summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2008-11-13 00:27:09 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2008-11-13 00:27:09 +0000
commitdb524b69d0cc2d982c3d9f8496a33d7bff9308b8 (patch)
tree3cc721513b8614a0e596d03dea2b38caed88c2c3
parentcb6e6ec79557e3bea950e4abb6ba01dc5c1ec251 (diff)
downloadiconv-db524b69d0cc2d982c3d9f8496a33d7bff9308b8.tar.gz
iconv-db524b69d0cc2d982c3d9f8496a33d7bff9308b8.tar.bz2
Correctly reset codecs, including restoring their endianness/BOM flags.
Add support for UCS-4-INTERNAL, which is a platform-endian UCS4 variant. svn path=/trunk/iconv/; revision=5689
-rw-r--r--src/iconv.c29
-rw-r--r--src/internal.h2
2 files changed, 24 insertions, 7 deletions
diff --git a/src/iconv.c b/src/iconv.c
index 537f30b..f2792e1 100644
--- a/src/iconv.c
+++ b/src/iconv.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include <stdbool.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -128,6 +129,10 @@ iconv_t iconv_open(const char *tocode, const char *fromcode)
to_force_le = true;
break;
}
+ } else if (strcasecmp(totemp, "UCS-4-INTERNAL") == 0) {
+ uint32_t test = 0x55aa55aa;
+ to = csUCS4;
+ to_force_le = ((const uint8_t *) &test)[0] == 0xaa;
}
}
@@ -150,6 +155,10 @@ iconv_t iconv_open(const char *tocode, const char *fromcode)
from_force_le = true;
break;
}
+ } else if (strcasecmp(fromtemp, "UCS-4-INTERNAL") == 0) {
+ uint32_t test = 0x55aa55aa;
+ from = csUCS4;
+ from_force_le = ((const uint8_t *) &test)[0] == 0xaa;
}
}
@@ -173,12 +182,12 @@ iconv_t iconv_open(const char *tocode, const char *fromcode)
if (from_force_le)
flags |= encoding_FLAG_LITTLE_ENDIAN;
- c = alias_canonicalise(fromtemp);
- if (c && (c->mib_enum == csUCS4 ||
- c->mib_enum == csUnicode))
+ if (from == csUCS4 || from == csUnicode)
flags |= encoding_FLAG_NO_HEADER;
encoding_set_flags(e->in, flags, flags);
+
+ e->inflags = flags;
}
}
@@ -200,12 +209,12 @@ iconv_t iconv_open(const char *tocode, const char *fromcode)
if (to_force_le)
flags |= encoding_FLAG_LITTLE_ENDIAN;
- c = alias_canonicalise(totemp);
- if (c && (c->mib_enum == csUCS4 ||
- c->mib_enum == csUnicode))
+ if (to == csUCS4 || to == csUnicode)
flags |= encoding_FLAG_NO_HEADER;
encoding_set_flags(e->out, flags, flags);
+
+ e->outflags = flags;
}
}
@@ -247,8 +256,14 @@ size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf,
}
if (inbuf == NULL || *inbuf == NULL) {
- if (e->in)
+ if (e->in) {
encoding_reset(e->in);
+ encoding_set_flags(e->in, e->inflags, e->inflags);
+ }
+ if (e->out) {
+ encoding_reset(e->out);
+ encoding_set_flags(e->out, e->outflags, e->outflags);
+ }
return 0;
}
diff --git a/src/internal.h b/src/internal.h
index 9d27882..929d906 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -16,7 +16,9 @@
struct encoding_context {
Encoding *in;
+ unsigned int inflags;
Encoding *out;
+ unsigned int outflags;
unsigned short *intab, *outtab;
char **outbuf;
size_t *outbytesleft;