aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-file-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/camel-file-utils.c')
-rw-r--r--camel/camel-file-utils.c283
1 files changed, 283 insertions, 0 deletions
diff --git a/camel/camel-file-utils.c b/camel/camel-file-utils.c
new file mode 100644
index 0000000000..1b0fe65dbb
--- /dev/null
+++ b/camel/camel-file-utils.c
@@ -0,0 +1,283 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * Authors:
+ * Michael Zucchi <notzed@ximian.com>
+ * Dan Winship <danw@ximian.com>
+ *
+ * Copyright (C) 2000, 2001 Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+
+#include "camel-file-utils.h"
+
+#include <netinet/in.h>
+
+/**
+ * camel_file_util_encode_uint32:
+ * @out: file to output to
+ * @value: value to output
+ *
+ * Utility function to save an uint32 to a file.
+ *
+ * Return value: 0 on success, -1 on error.
+ **/
+int
+camel_file_util_encode_uint32 (FILE *out, guint32 value)
+{
+ int i;
+
+ for (i = 28; i > 0; i -= 7) {
+ if (value >= (1 << i)) {
+ unsigned int c = (value >> i) & 0x7f;
+ if (fputc (c, out) == -1)
+ return -1;
+ }
+ }
+ return fputc (value | 0x80, out);
+}
+
+/**
+ * camel_file_util_decode_uint32:
+ * @in: file to read from
+ * @dest: pointer to a variable to store the value in
+ *
+ * Retrieve an encoded uint32 from a file.
+ *
+ * Return value: 0 on success, -1 on error. @*dest will contain the
+ * decoded value.
+ **/
+int
+camel_file_util_decode_uint32 (FILE *in, guint32 *dest)
+{
+ guint32 value = 0;
+ int v;
+
+ /* until we get the last byte, keep decoding 7 bits at a time */
+ while ( ((v = fgetc (in)) & 0x80) == 0 && v!=EOF) {
+ value |= v;
+ value <<= 7;
+ }
+ if (v == EOF) {
+ *dest = value >> 7;
+ return -1;
+ }
+ *dest = value | (v & 0x7f);
+
+ return 0;
+}
+
+/**
+ * camel_file_util_encode_fixed_int32:
+ * @out: file to output to
+ * @value: value to output
+ *
+ * Encode a gint32, performing no compression, but converting
+ * to network order.
+ *
+ * Return value: 0 on success, -1 on error.
+ **/
+int
+camel_file_util_encode_fixed_int32 (FILE *out, gint32 value)
+{
+ guint32 save;
+
+ save = htonl (value);
+ if (fwrite (&save, sizeof (save), 1, out) != 1)
+ return -1;
+ return 0;
+}
+
+/**
+ * camel_file_util_decode_fixed_int32:
+ * @in: file to read from
+ * @dest: pointer to a variable to store the value in
+ *
+ * Retrieve a gint32.
+ *
+ * Return value: 0 on success, -1 on error.
+ **/
+int
+camel_file_util_decode_fixed_int32 (FILE *in, gint32 *dest)
+{
+ guint32 save;
+
+ if (fread (&save, sizeof (save), 1, in) == 1) {
+ *dest = ntohl (save);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+/**
+ * camel_file_util_encode_time_t:
+ * @out: file to output to
+ * @value: value to output
+ *
+ * Encode a time_t value to the file.
+ *
+ * Return value: 0 on success, -1 on error.
+ **/
+int
+camel_file_util_encode_time_t(FILE *out, time_t value)
+{
+ int i;
+
+ for (i = sizeof (time_t) - 1; i >= 0; i--) {
+ if (fputc((value >> (i * 8)) & 0xff, out) == -1)
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * camel_file_util_decode_time_t:
+ * @in: file to read from
+ * @dest: pointer to a variable to store the value in
+ *
+ * Decode a time_t value.
+ *
+ * Return value: 0 on success, -1 on error.
+ **/
+int
+camel_file_util_decode_time_t (FILE *in, time_t *dest)
+{
+ time_t save = 0;
+ int v, i = sizeof (time_t) - 1;
+
+ while (i >= 0 && (v = fgetc (in)) != EOF) {
+ save |= ((time_t)v) << (i * 8);
+ i--;
+ }
+ *dest = save;
+ if (v == EOF)
+ return -1;
+ return 0;
+}
+
+/**
+ * camel_file_util_encode_off_t:
+ * @out: file to output to
+ * @value: value to output
+ *
+ * Encode an off_t type.
+ *
+ * Return value: 0 on success, -1 on error.
+ **/
+int
+camel_file_util_encode_off_t (FILE *out, off_t value)
+{
+ int i;
+
+ for (i = sizeof (off_t) - 1; i >= 0; i--) {
+ if (fputc ((value >> (i * 8)) & 0xff, out) == -1)
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * camel_file_util_decode_off_t:
+ * @in: file to read from
+ * @dest: pointer to a variable to put the value in
+ *
+ * Decode an off_t type.
+ *
+ * Return value: 0 on success, -1 on failure.
+ **/
+int
+camel_file_util_decode_off_t (FILE *in, off_t *dest)
+{
+ off_t save = 0;
+ int v, i = sizeof(off_t) - 1;
+
+ while (i >= 0 && (v = fgetc (in)) != EOF) {
+ save |= ((off_t)v) << (i * 8);
+ i--;
+ }
+ *dest = save;
+ if (v == EOF)
+ return -1;
+ return 0;
+}
+
+/**
+ * camel_file_util_encode_string:
+ * @out: file to output to
+ * @str: value to output
+ *
+ * Encode a normal string and save it in the output file.
+ *
+ * Return value: 0 on success, -1 on error.
+ **/
+int
+camel_file_util_encode_string (FILE *out, const char *str)
+{
+ register int len;
+
+ if (str == NULL)
+ return camel_file_util_encode_uint32 (out, 0);
+
+ len = strlen (str);
+ if (camel_file_util_encode_uint32 (out, len+1) == -1)
+ return -1;
+ if (fwrite (str, len, 1, out) == 1)
+ return 0;
+ return -1;
+}
+
+/**
+ * camel_file_util_decode_string:
+ * @in: file to read from
+ * @str: pointer to a variable to store the value in
+ *
+ * Decode a normal string from the input file.
+ *
+ * Return value: 0 on success, -1 on error.
+ **/
+int
+camel_file_util_decode_string (FILE *in, char **str)
+{
+ guint32 len;
+ register char *ret;
+
+ if (camel_file_util_decode_uint32 (in, &len) == -1) {
+ *str = NULL;
+ return -1;
+ }
+
+ len--;
+ if (len > 65536) {
+ *str = NULL;
+ return -1;
+ }
+
+ ret = g_malloc (len+1);
+ if (fread (ret, len, 1, in) != 1) {
+ g_free (ret);
+ *str = NULL;
+ return -1;
+ }
+
+ ret[len] = 0;
+ *str = ret;
+ return 0;
+}
+
+