[gmime: 1/5] Rewrote GMimeFilterStrip to handle DOS line endings
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime: 1/5] Rewrote GMimeFilterStrip to handle DOS line endings
- Date: Tue, 21 Mar 2017 11:58:23 +0000 (UTC)
commit c65a09b014e98af36b3a59a0eafc1364cc141857
Author: Jeffrey Stedfast <jestedfa microsoft com>
Date: Mon Mar 20 20:22:42 2017 -0400
Rewrote GMimeFilterStrip to handle DOS line endings
gmime/gmime-filter-strip.c | 89 +++++++++++++++++++++++++------------
gmime/gmime-filter-strip.h | 2 +
util/Makefile.am | 2 +
util/packed.c | 105 ++++++++++++++++++++++++++++++++++++++++++++
util/packed.h | 47 ++++++++++++++++++++
5 files changed, 217 insertions(+), 28 deletions(-)
---
diff --git a/gmime/gmime-filter-strip.c b/gmime/gmime-filter-strip.c
index e98a064..5b0c964 100644
--- a/gmime/gmime-filter-strip.c
+++ b/gmime/gmime-filter-strip.c
@@ -27,6 +27,8 @@
#include <string.h>
#include "gmime-filter-strip.h"
+#include "gmime-table-private.h"
+#include "packed.h"
/**
@@ -99,12 +101,16 @@ g_mime_filter_strip_class_init (GMimeFilterStripClass *klass)
static void
g_mime_filter_strip_init (GMimeFilterStrip *filter, GMimeFilterStripClass *klass)
{
- /* no-op */
+ filter->lwsp = packed_byte_array_new ();
}
static void
g_mime_filter_strip_finalize (GObject *object)
{
+ GMimeFilterStrip *filter = (GMimeFilterStrip *) object;
+
+ packed_byte_array_free (filter->lwsp);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -116,56 +122,83 @@ filter_copy (GMimeFilter *filter)
}
static void
-filter_filter (GMimeFilter *filter, char *in, size_t len, size_t prespace,
- char **out, size_t *outlen, size_t *outprespace)
+convert (GMimeFilter *filter, char *in, size_t len, size_t prespace,
+ char **out, size_t *outlen, size_t *outprespace, gboolean flush)
{
- register unsigned char *inptr, *last;
- unsigned char *inend, *start;
- char *outptr;
+ GMimeFilterStrip *strip = (GMimeFilterStrip *) filter;
+ PackedByteArray *lwsp = (PackedByteArray *) strip->lwsp;
+ register char *inptr, *outptr;
+ char *inend, *outbuf;
- g_mime_filter_set_size (filter, len, FALSE);
+ if (len == 0) {
+ if (flush)
+ packed_byte_array_clear (lwsp);
+
+ *outprespace = prespace;
+ *outlen = len;
+ *out = in;
+
+ return;
+ }
- last = inptr = (unsigned char *) in;
- inend = (unsigned char *) in + len;
+ g_mime_filter_set_size (filter, len + lwsp->len, FALSE);
+ outptr = outbuf = filter->outbuf;
+ inend = in + len;
+ inptr = in;
- outptr = filter->outbuf;
+ if (flush)
+ packed_byte_array_clear (strip->lwsp);
while (inptr < inend) {
- start = inptr;
- while (inptr < inend && *inptr != '\n') {
- if (*inptr != ' ' && *inptr != '\t')
- last = inptr + 1;
- inptr++;
+ if (is_blank (*inptr)) {
+ packed_byte_array_add (lwsp, *inptr);
+ } else if (*inptr == '\r') {
+ packed_byte_array_clear (lwsp);
+ *outptr++ = *inptr;
+ } else if (*inptr == '\n') {
+ packed_byte_array_clear (lwsp);
+ *outptr++ = *inptr;
+ } else {
+ if (lwsp->len > 0) {
+ packed_byte_array_copy_to (lwsp, outptr);
+ outptr += lwsp->len;
+ packed_byte_array_clear (lwsp);
+ }
+
+ *outptr++ = *inptr;
}
- memcpy (outptr, start, last - start);
- outptr += (last - start);
- if (inptr < inend) {
- /* write the newline */
- *outptr++ = (char) *inptr++;
- last = inptr;
- }
+ inptr++;
}
- g_mime_filter_backup (filter, (char *) last, inptr - last);
+ if (flush)
+ packed_byte_array_clear (lwsp);
- *out = filter->outbuf;
- *outlen = outptr - filter->outbuf;
*outprespace = filter->outpre;
+ *outlen = (outptr - filter->outbuf);
+ *out = filter->outbuf;
+}
+
+static void
+filter_filter (GMimeFilter *filter, char *in, size_t len, size_t prespace,
+ char **out, size_t *outlen, size_t *outprespace)
+{
+ convert (filter, in, len, prespace, out, outlen, outprespace, FALSE);
}
static void
filter_complete (GMimeFilter *filter, char *in, size_t len, size_t prespace,
char **out, size_t *outlen, size_t *outprespace)
{
- if (len)
- filter_filter (filter, in, len, prespace, out, outlen, outprespace);
+ convert (filter, in, len, prespace, out, outlen, outprespace, TRUE);
}
static void
filter_reset (GMimeFilter *filter)
{
- /* no-op */
+ GMimeFilterStrip *strip = (GMimeFilterStrip *) filter;
+
+ packed_byte_array_clear (strip->lwsp);
}
diff --git a/gmime/gmime-filter-strip.h b/gmime/gmime-filter-strip.h
index 6e9151b..fd64174 100644
--- a/gmime/gmime-filter-strip.h
+++ b/gmime/gmime-filter-strip.h
@@ -45,6 +45,8 @@ typedef struct _GMimeFilterStripClass GMimeFilterStripClass;
struct _GMimeFilterStrip {
GMimeFilter parent_object;
+ /* < private > */
+ void *lwsp;
};
struct _GMimeFilterStripClass {
diff --git a/util/Makefile.am b/util/Makefile.am
index cedddca..37535c4 100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -19,6 +19,8 @@ libutil_la_SOURCES = \
list.h \
md5-utils.c \
md5-utils.h \
+ packed.c \
+ packed.h \
url-scanner.c \
url-scanner.h
diff --git a/util/packed.c b/util/packed.c
new file mode 100644
index 0000000..187f26c
--- /dev/null
+++ b/util/packed.c
@@ -0,0 +1,105 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* GMime
+ * Copyright (C) 2000-2017 Jeffrey Stedfast
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "packed.h"
+
+
+PackedByteArray *
+packed_byte_array_new (void)
+{
+ PackedByteArray *packed;
+
+ packed = g_slice_new (PackedByteArray);
+ packed->buffer = g_malloc (sizeof (guint16) * 64);
+ packed->allocated = 64;
+ packed->cur = -1;
+ packed->len = 0;
+}
+
+
+void
+packed_byte_array_free (PackedByteArray *packed)
+{
+ g_free (packed->buffer);
+ g_slice_free (PackedByteArray, packed);
+}
+
+
+void
+packed_byte_array_clear (PackedByteArray *packed)
+{
+ packed->cur = -1;
+ packed->len = 0;
+}
+
+
+static guint16 *
+ensure_buffer_size (PackedByteArray *packed, int size)
+{
+ if (packed->allocated > size)
+ return packed->buffer;
+
+ size_t ideal = (size + 63) & ~63;
+
+ packed->buffer = g_realloc (packed->buffer, sizeof (guint16) * ideal);
+ packed->allocated = ideal;
+
+ return packed->buffer;
+}
+
+
+void
+packed_byte_array_add (PackedByteArray *packed, char c)
+{
+ guint16 *buffer = packed->buffer;
+ int cur = packed->cur;
+
+ if (cur < 0 || c != (char) (buffer[cur] & 0xff) || (buffer[cur] & 0xff00) == 0xff00) {
+ buffer = ensure_buffer_size (packed, cur + 2);
+ buffer[++cur] = (guint16) ((1 << 8) | (unsigned char) c);
+ } else {
+ buffer[cur] += (1 << 8);
+ }
+
+ packed->cur = cur;
+ packed->len++;
+}
+
+
+void
+packed_byte_array_copy_to (PackedByteArray *packed, char *outbuf)
+{
+ register char *outptr = outbuf;
+ int count, i, n;
+ char c;
+
+ for (i = 0; i <= packed->cur; i++) {
+ count = (packed->buffer[i] >> 8) & 0xff;
+ c = (char) (packed->buffer[i] & 0xff);
+
+ for (n = 0; n < count; n++)
+ *outptr++ = c;
+ }
+}
diff --git a/util/packed.h b/util/packed.h
new file mode 100644
index 0000000..f7a8b2c
--- /dev/null
+++ b/util/packed.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* GMime
+ * Copyright (C) 2000-2017 Jeffrey Stedfast
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+
+#ifndef __PACKED_BYTE_ARRAY_H__
+#define __PACKED_BYTE_ARRAY_H__
+
+#include <glib.h>
+#include <sys/types.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ guint16 *buffer;
+ int allocated;
+ int cur, len;
+} PackedByteArray;
+
+G_GNUC_INTERNAL PackedByteArray *packed_byte_array_new (void);
+G_GNUC_INTERNAL void packed_byte_array_free (PackedByteArray *packed);
+
+G_GNUC_INTERNAL void packed_byte_array_clear (PackedByteArray *packed);
+
+G_GNUC_INTERNAL void packed_byte_array_add (PackedByteArray *packed, char c);
+
+G_GNUC_INTERNAL void packed_byte_array_copy_to (PackedByteArray *packed, char *outbuf);
+
+G_END_DECLS
+
+#endif /* __PACKED_BYTE_ARRAY_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]