[gnumeric] xls: improve handling of long strings in formulas.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] xls: improve handling of long strings in formulas.
- Date: Fri, 21 Feb 2014 21:14:09 +0000 (UTC)
commit 03266296fe1c0d681f826b4b61a1c97be8e1ea24
Author: Morten Welinder <terra gnome org>
Date: Fri Feb 21 16:13:28 2014 -0500
xls: improve handling of long strings in formulas.
The format cannot handle strings longer than 255 characters so do a creative
rewrite with "&".
NEWS | 1 +
plugins/excel/ChangeLog | 11 +++++++++++
plugins/excel/ms-biff.c | 1 +
plugins/excel/ms-excel-write.c | 28 +++++++++++++++++++++-------
plugins/excel/ms-formula-write.c | 33 ++++++++++++++++++++++++++++++++-
5 files changed, 66 insertions(+), 8 deletions(-)
---
diff --git a/NEWS b/NEWS
index e02b1fb..7a8762c 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,7 @@ Morten:
* Fix xlsx export of underlines.
* Fix BIFF8 export of diagonal borders.
* Export headers and footers to xlsx. [Part of #724516]
+ * Fix xls export of long strings in formulas.
--------------------------------------------------------------------------
Gnumeric 1.12.11
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 42cdc10..e6ba7ba 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,3 +1,14 @@
+2014-02-21 Morten Welinder <terra gnome org>
+
+ * ms-biff.c (ms_biff_query_next): Handle CONTINUE record for
+ BIFF_FORMULA_v0 too.
+
+ * ms-excel-write.c (excel_write_string): Improve handling of
+ string overflow.
+
+ * ms-formula-write.c (write_string): Split long strings into 255
+ character chunks: ("s1"&"s2"&...)
+
2014-02-20 Morten Welinder <terra gnome org>
* xlsx-write.c (xlsx_write_print_info): First stab at exporting
diff --git a/plugins/excel/ms-biff.c b/plugins/excel/ms-biff.c
index 52a8739..eda7b90 100644
--- a/plugins/excel/ms-biff.c
+++ b/plugins/excel/ms-biff.c
@@ -508,6 +508,7 @@ ms_biff_query_next (BiffQuery *q)
switch (q->opcode) {
case BIFF_LABEL_v0:
case BIFF_LABEL_v2:
+ case BIFF_FORMULA_v0:
auto_continue = TRUE;
break;
case BIFF_CONTINUE:
diff --git a/plugins/excel/ms-excel-write.c b/plugins/excel/ms-excel-write.c
index 5a0fba9..6c6323f 100644
--- a/plugins/excel/ms-excel-write.c
+++ b/plugins/excel/ms-excel-write.c
@@ -313,10 +313,6 @@ excel_write_string (BiffPut *bp, WriteStringFlags flags,
if (char_len != byte_len || (flags & STR_SUPPRESS_HEADER)) {
char *tmp;
- /* TODO : think about what to do with LEN_IN_BYTES */
- if ((flags & STR_LENGTH_MASK) == STR_ONE_BYTE_LENGTH &&
- char_len > 0xff)
- char_len = 0xff;
out_bytes = char_len * 2;
/* 2 in case we null terminate, and up to 4 for the length */
@@ -358,9 +354,27 @@ excel_write_string (BiffPut *bp, WriteStringFlags flags,
g_warning (_("This is somewhat corrupt.\n"
"We already wrote a length for a string that is being truncated
due to encoding problems."));
break;
- case STR_ONE_BYTE_LENGTH: GSF_LE_SET_GUINT8 (bp->buf, output_len); break;
- case STR_TWO_BYTE_LENGTH: GSF_LE_SET_GUINT16 (bp->buf, output_len); break;
- case STR_FOUR_BYTE_LENGTH: GSF_LE_SET_GUINT32 (bp->buf, output_len); break;
+ case STR_ONE_BYTE_LENGTH:
+ if (output_len > 255) {
+ g_printerr ("Truncating string of %u %s\n",
+ output_len,
+ (flags & STR_LEN_IN_BYTES) ? "bytes" : "characters");
+ output_len = 255;
+ }
+ GSF_LE_SET_GUINT8 (bp->buf, output_len);
+ break;
+ case STR_TWO_BYTE_LENGTH:
+ if (output_len > 65535) {
+ g_printerr ("Truncating string of %u %s\n",
+ output_len,
+ (flags & STR_LEN_IN_BYTES) ? "bytes" : "characters");
+ output_len = 65535;
+ }
+ GSF_LE_SET_GUINT16 (bp->buf, output_len);
+ break;
+ case STR_FOUR_BYTE_LENGTH:
+ GSF_LE_SET_GUINT32 (bp->buf, output_len);
+ break;
}
output_len = out_bytes;
diff --git a/plugins/excel/ms-formula-write.c b/plugins/excel/ms-formula-write.c
index 000cb09..10df2d8 100644
--- a/plugins/excel/ms-formula-write.c
+++ b/plugins/excel/ms-formula-write.c
@@ -357,13 +357,44 @@ write_cellref_v8 (PolishData *pd, GnmCellRef const *ref,
}
static void
-write_string (PolishData *pd, gchar const *txt)
+write_string1 (PolishData *pd, gchar const *txt)
{
push_guint8 (pd, FORMULA_PTG_STR);
excel_write_string (pd->ewb->bp, STR_ONE_BYTE_LENGTH, txt);
}
static void
+write_string (PolishData *pd, gchar const *txt)
+{
+ size_t i, n = 0, len = g_utf8_strlen (txt, -1);
+ const char *p = txt;
+
+ for (i = 0; n == 0 || i < len; ) {
+ if (len - i <= 255) {
+ write_string1 (pd, p);
+ i = len;
+ } else {
+ const char *endcut = g_utf8_offset_to_pointer (p, 255);
+ size_t cutlen = endcut - p;
+ char *cut = g_memdup (p, cutlen + 1);
+ cut[cutlen] = 0;
+ write_string1 (pd, cut);
+ g_free (cut);
+
+ p = endcut;
+ i += 255;
+ }
+
+ if (n > 0)
+ push_guint8 (pd, FORMULA_PTG_CONCAT);
+ n++;
+ }
+
+ if (n > 1)
+ push_guint8 (pd, FORMULA_PTG_PAREN);
+}
+
+static void
excel_formula_write_CELLREF (PolishData *pd, GnmCellRef const *ref,
Sheet *sheet_b, XLOpType target_type)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]