aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--transcode.c33
-rw-r--r--transcode_data.h2
3 files changed, 33 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 5bbc89be33..f16780a32c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Sat Aug 9 16:33:21 2008 Tanaka Akira <akr@fsij.org>
+
+ * transcode_data.h (rb_transcoding): new fields: next_info and next_byte.
+
+ * transcode.c (transcode_restartable): save/restore next_info and
+ next_byte.
+ sync readlen and in_p when invalid.
+
Sat Aug 9 15:10:15 2008 Tanaka Akira <akr@fsij.org>
* transcode.c (transcode_restartable): my_transcoder argument removed.
diff --git a/transcode.c b/transcode.c
index c1323e3ac7..dd57f0809d 100644
--- a/transcode.c
+++ b/transcode.c
@@ -368,6 +368,8 @@ transcode_restartable(const unsigned char **in_pos, unsigned char **out_pos,
unsigned char *out_p;
int readlen;
const BYTE_LOOKUP *next_table;
+ VALUE next_info;
+ unsigned char next_byte;
unsigned char empty_buf;
unsigned char *empty_ptr = &empty_buf;
@@ -386,6 +388,8 @@ transcode_restartable(const unsigned char **in_pos, unsigned char **out_pos,
out_p = *out_pos;
readlen = my_transcoding->readlen;
next_table = my_transcoding->next_table;
+ next_info = my_transcoding->next_info;
+ next_byte = my_transcoding->next_byte;
#define SUSPEND(ret, num) \
do { \
@@ -399,6 +403,8 @@ transcode_restartable(const unsigned char **in_pos, unsigned char **out_pos,
*out_pos = out_p; \
my_transcoding->readlen = readlen; \
my_transcoding->next_table = next_table; \
+ my_transcoding->next_info = next_info; \
+ my_transcoding->next_byte = next_byte; \
return ret; \
resume_label ## num:; \
} while (0)
@@ -422,9 +428,6 @@ transcode_restartable(const unsigned char **in_pos, unsigned char **out_pos,
}
while (1) {
- unsigned char next_byte;
- VALUE next_info;
-
if (in_stop <= in_p) {
if (!(opt & PARTIAL_INPUT))
break;
@@ -460,7 +463,6 @@ transcode_restartable(const unsigned char **in_pos, unsigned char **out_pos,
readlen++;
next_table = (const BYTE_LOOKUP *)next_info;
goto follow_byte;
- /* maybe rewrite the following cases to use fallthrough???? */
case ZERObt: /* drop input */
continue;
case ONEbt:
@@ -509,21 +511,32 @@ transcode_restartable(const unsigned char **in_pos, unsigned char **out_pos,
}
case INVALID:
{
+ int step;
if (readlen <= unitlen) {
while ((opt & PARTIAL_INPUT) && readlen + (in_stop - in_p) < unitlen) {
- readlen += in_stop - in_p;
+ step = in_stop - in_p;
+ readlen += step;
in_p = in_stop;
SUSPEND(transcode_ibuf_empty, 8);
}
- if (readlen + (in_stop - in_p) <= unitlen)
+ if (readlen + (in_stop - in_p) <= unitlen) {
+ step = in_stop - in_p;
+ readlen += step;
in_p = in_stop;
- else
- in_p += unitlen - readlen;
+ }
+ else {
+ step = unitlen - readlen;
+ readlen = unitlen;
+ in_p += step;
+ }
}
else {
- /* xxx: possibly in_p is lesser than *in_pos
+ /* xxx: step may be negative.
+ * possibly in_p is lesser than *in_pos.
* caller may want to access readbuf. */
- in_p += ((readlen - 1) / unitlen) * unitlen - readlen;
+ step = ((readlen - 1) / unitlen) * unitlen - readlen;
+ in_p += step;
+ readlen += step;
}
goto invalid;
}
diff --git a/transcode_data.h b/transcode_data.h
index 3801c38ec8..12e24e71eb 100644
--- a/transcode_data.h
+++ b/transcode_data.h
@@ -66,6 +66,8 @@ typedef struct rb_transcoding {
int resume_position;
const BYTE_LOOKUP *next_table;
+ VALUE next_info;
+ unsigned char next_byte;
int readlen;
union {
unsigned char ary[8]; /* max_input <= sizeof(ary) */