[easytag/wip/flac-vendor-string: 2/3] Split off shared FLAC code to a separate file



commit d907c83e674a64dff5d9472349eab32e7bab5ea8
Author: David King <amigadave amigadave com>
Date:   Sat Dec 6 23:57:24 2014 +0000

    Split off shared FLAC code to a separate file

 Makefile.am             |    2 +
 src/tags/flac_header.c  |  149 ++------------------------
 src/tags/flac_private.c |  256 +++++++++++++++++++++++++++++++++++++++++++++
 src/tags/flac_private.h |   76 ++++++++++++++
 src/tags/flac_tag.c     |  266 +----------------------------------------------
 5 files changed, 346 insertions(+), 403 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index d208a8f..57a832e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -71,6 +71,7 @@ easytag_SOURCES = \
        src/tags/libapetag/info_mpc.c \
        src/tags/ape_tag.c \
        src/tags/flac_header.c \
+       src/tags/flac_private.c \
        src/tags/flac_tag.c \
        src/tags/gio_wrapper.cc \
        src/tags/id3_tag.c \
@@ -123,6 +124,7 @@ easytag_headers = \
        src/tags/libapetag/info_mpc.h \
        src/tags/ape_tag.h \
        src/tags/flac_header.h \
+       src/tags/flac_private.h \
        src/tags/flac_tag.h \
        src/tags/gio_wrapper.h \
        src/tags/id3_tag.h \
diff --git a/src/tags/flac_header.c b/src/tags/flac_header.c
index f796c18..8750f89 100644
--- a/src/tags/flac_header.c
+++ b/src/tags/flac_header.c
@@ -23,144 +23,14 @@
 
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
-#include <FLAC/all.h>
 #include <errno.h>
 
 #include "et_core.h"
 #include "flac_header.h"
+#include "flac_private.h"
 #include "misc.h"
 
-typedef struct
-{
-    GFileInputStream *istream;
-    gboolean eof;
-    GError *error;
-} EtFlacState;
-
-/* FLAC__metadata_read_with_callbacks() IO callbacks. */
-static size_t
-et_flac_read_func (void *ptr,
-                   size_t size,
-                   size_t nmemb,
-                   FLAC__IOHandle handle)
-{
-    EtFlacState *state;
-    gssize bytes_read;
-
-    state = (EtFlacState *)handle;
-    state->eof = FALSE;
-
-    bytes_read = g_input_stream_read (G_INPUT_STREAM (state->istream), ptr,
-                                      size * nmemb, NULL, &state->error);
-
-    if (bytes_read == -1)
-    {
-        errno = EIO;
-        return 0;
-    }
-    else if (bytes_read == 0)
-    {
-        state->eof = TRUE;
-    }
-
-    return bytes_read;
-}
-
-static int
-et_flac_seek_func (FLAC__IOHandle handle,
-                   FLAC__int64 offset,
-                   int whence)
-{
-    EtFlacState *state;
-    GSeekable *seekable;
-    GSeekType seektype;
-
-    state = (EtFlacState *)handle;
-    seekable = G_SEEKABLE (state->istream);
-
-    if (!g_seekable_can_seek (seekable))
-    {
-        errno = EBADF;
-        return -1;
-    }
-    else
-    {
-        switch (whence)
-        {
-            case SEEK_SET:
-                seektype = G_SEEK_SET;
-                break;
-            case SEEK_CUR:
-                seektype = G_SEEK_CUR;
-                break;
-            case SEEK_END:
-                seektype = G_SEEK_END;
-                break;
-            default:
-                errno = EINVAL;
-                return -1;
-        }
-
-        if (!g_seekable_seek (seekable, offset, seektype, NULL, &state->error))
-        {
-            /* TODO: More suitable error. */
-            errno = EINVAL;
-            return -1;
-        }
-        else
-        {
-            return 0;
-        }
-    }
-}
-
-static FLAC__int64
-et_flac_tell_func (FLAC__IOHandle handle)
-{
-    EtFlacState *state;
-    GSeekable *seekable;
-
-    state = (EtFlacState *)handle;
-    seekable = G_SEEKABLE (state->istream);
-
-    if (!g_seekable_can_seek (seekable))
-    {
-        errno = EBADF;
-        return -1;
-    }
-    else
-    {
-        return g_seekable_tell (seekable);
-    }
-}
-
-static int
-et_flac_eof_func (FLAC__IOHandle handle)
-{
-    EtFlacState *state;
-
-    state = (EtFlacState *)handle;
-
-    /* EOF is not directly supported by GFileInputStream. */
-    return state->eof ? 1 : 0;
-}
-
-static int
-et_flac_close_func (FLAC__IOHandle handle)
-{
-    EtFlacState *state;
-
-    state = (EtFlacState *)handle;
-
-    g_clear_object (&state->istream);
-    g_clear_error (&state->error);
-
-    /* Always return success. */
-    return 0;
-}
-
 /* Header info of FLAC file */
-
 gboolean
 et_flac_header_read_file_info (GFile *file,
                                ET_File_Info *ETFileInfo,
@@ -168,11 +38,14 @@ et_flac_header_read_file_info (GFile *file,
 {
     GFileInfo *info;
     FLAC__Metadata_Chain *chain;
-    EtFlacState state;
+    EtFlacReadState state;
     GFileInputStream *istream;
-    FLAC__IOCallbacks callbacks = { et_flac_read_func, NULL, et_flac_seek_func,
-                                    et_flac_tell_func, et_flac_eof_func,
-                                    et_flac_close_func };
+    FLAC__IOCallbacks callbacks = { et_flac_read_read_func,
+                                    NULL, /* Do not set a write callback. */
+                                    et_flac_read_seek_func,
+                                    et_flac_read_tell_func,
+                                    et_flac_read_eof_func,
+                                    et_flac_read_close_func };
     FLAC__Metadata_Iterator *iter;
     gsize metadata_len;
 
@@ -211,7 +84,7 @@ et_flac_header_read_file_info (GFile *file,
         /* TODO: Provide a dedicated error enum corresponding to status. */
         g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s",
                      _("Error opening FLAC file"));
-        et_flac_close_func (&state);
+        et_flac_read_close_func (&state);
         return FALSE;
     }
 
@@ -219,7 +92,7 @@ et_flac_header_read_file_info (GFile *file,
 
     if (iter == NULL)
     {
-        et_flac_close_func (&state);
+        et_flac_read_close_func (&state);
         g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM, "%s",
                      g_strerror (ENOMEM));
         return FALSE;
@@ -257,7 +130,7 @@ et_flac_header_read_file_info (GFile *file,
 
     FLAC__metadata_iterator_delete (iter);
     FLAC__metadata_chain_delete (chain);
-    et_flac_close_func (&state);
+    et_flac_read_close_func (&state);
     /* End of decoding FLAC file */
 
     info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE,
diff --git a/src/tags/flac_private.c b/src/tags/flac_private.c
new file mode 100644
index 0000000..c29c91f
--- /dev/null
+++ b/src/tags/flac_private.c
@@ -0,0 +1,256 @@
+/* EasyTAG - tag editor for audio files
+ * Copyright (C) 2014 David King <amigadave amigadave com>
+ *
+ * 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., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "flac_private.h"
+
+#include <errno.h>
+
+static size_t
+read_func (GInputStream *istream,
+           void *buffer,
+           gsize count,
+           gboolean *eof,
+           GError **error)
+{
+    gssize bytes_read;
+
+    *eof = FALSE;
+
+    bytes_read = g_input_stream_read (istream, buffer, count, NULL, error);
+
+    if (bytes_read == -1)
+    {
+        errno = EIO;
+        return 0;
+    }
+    else if (bytes_read == 0)
+    {
+        *eof = TRUE;
+    }
+
+    return bytes_read;
+}
+
+size_t
+et_flac_read_read_func (void *ptr,
+                        size_t size,
+                        size_t nmemb,
+                        FLAC__IOHandle handle)
+{
+    EtFlacReadState *state;
+
+    state = (EtFlacReadState *)handle;
+
+    return read_func (G_INPUT_STREAM (state->istream), ptr, size * nmemb,
+                      &state->eof, &state->error);
+}
+
+size_t
+et_flac_write_read_func (void *ptr,
+                         size_t size,
+                         size_t nmemb,
+                         FLAC__IOHandle handle)
+{
+    EtFlacWriteState *state;
+
+    state = (EtFlacWriteState *)handle;
+
+    return read_func (G_INPUT_STREAM (state->istream), ptr, size * nmemb,
+                      &state->eof, &state->error);
+}
+
+size_t
+et_flac_write_write_func (const void *ptr,
+                          size_t size,
+                          size_t nmemb,
+                          FLAC__IOHandle handle)
+{
+    EtFlacWriteState *state;
+    gsize bytes_written;
+
+    state = (EtFlacWriteState *)handle;
+
+    if (!g_output_stream_write_all (G_OUTPUT_STREAM (state->ostream), ptr,
+                                    size * nmemb, &bytes_written, NULL,
+                                    &state->error))
+    {
+        g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %" G_GSIZE_FORMAT
+                 " bytes of data were written", bytes_written,
+                 size);
+        errno = EIO;
+    }
+
+    return bytes_written;
+}
+
+static gint
+seek_func (GSeekable *seekable,
+           goffset offset,
+           gint whence,
+           GError **error)
+{
+    GSeekType seektype;
+
+    if (!g_seekable_can_seek (seekable))
+    {
+        errno = EBADF;
+        return -1;
+    }
+    else
+    {
+        switch (whence)
+        {
+            case SEEK_SET:
+                seektype = G_SEEK_SET;
+                break;
+            case SEEK_CUR:
+                seektype = G_SEEK_CUR;
+                break;
+            case SEEK_END:
+                seektype = G_SEEK_END;
+                break;
+            default:
+                errno = EINVAL;
+                return -1;
+        }
+
+        if (g_seekable_seek (seekable, offset, seektype, NULL, error))
+        {
+            return 0;
+        }
+        else
+        {
+            /* TODO: More suitable error. */
+            errno = EINVAL;
+            return -1;
+        }
+    }
+}
+
+int
+et_flac_read_seek_func (FLAC__IOHandle handle,
+                        FLAC__int64 offset,
+                        int whence)
+{
+    EtFlacReadState *state;
+
+    state = (EtFlacReadState *)handle;
+
+    return seek_func (G_SEEKABLE (state->istream), offset, whence,
+                      &state->error);
+}
+
+int
+et_flac_write_seek_func (FLAC__IOHandle handle,
+                         FLAC__int64 offset,
+                         int whence)
+{
+    EtFlacWriteState *state;
+
+    state = (EtFlacWriteState *)handle;
+
+    /* Seeking on the IOStream causes both the input and output stream to have
+     * the same offset. */
+    return seek_func (G_SEEKABLE (state->iostream), offset, whence,
+                      &state->error);
+}
+
+static FLAC__int64
+tell_func (GSeekable *seekable)
+{
+    if (!g_seekable_can_seek (seekable))
+    {
+        errno = EBADF;
+        return -1;
+    }
+    else
+    {
+        return g_seekable_tell (seekable);
+    }
+}
+
+FLAC__int64
+et_flac_read_tell_func (FLAC__IOHandle handle)
+{
+    EtFlacReadState *state;
+
+    state = (EtFlacReadState *)handle;
+
+    return tell_func (G_SEEKABLE (state->istream));
+}
+
+FLAC__int64
+et_flac_write_tell_func (FLAC__IOHandle handle)
+{
+    EtFlacWriteState *state;
+
+    state = (EtFlacWriteState *)handle;
+
+    return tell_func (G_SEEKABLE (state->iostream));
+}
+
+int
+et_flac_read_eof_func (FLAC__IOHandle handle)
+{
+    EtFlacReadState *state;
+
+    state = (EtFlacReadState *)handle;
+
+    /* EOF is not directly supported by GFileInputStream. */
+    return state->eof ? 1 : 0;
+}
+
+int
+et_flac_write_eof_func (FLAC__IOHandle handle)
+{
+    EtFlacWriteState *state;
+
+    state = (EtFlacWriteState *)handle;
+
+    /* EOF is not directly supported by GFileInputStream. */
+    return state->eof ? 1 : 0;
+}
+
+int
+et_flac_read_close_func (FLAC__IOHandle handle)
+{
+    EtFlacReadState *state;
+
+    state = (EtFlacReadState *)handle;
+
+    g_clear_object (&state->istream);
+    g_clear_error (&state->error);
+
+    /* Always return success. */
+    return 0;
+}
+
+int
+et_flac_write_close_func (FLAC__IOHandle handle)
+{
+    EtFlacWriteState *state;
+
+    state = (EtFlacWriteState *)handle;
+
+    g_clear_object (&state->file);
+    g_clear_object (&state->iostream);
+    g_clear_error (&state->error);
+
+    /* Always return success. */
+    return 0;
+}
diff --git a/src/tags/flac_private.h b/src/tags/flac_private.h
new file mode 100644
index 0000000..e009495
--- /dev/null
+++ b/src/tags/flac_private.h
@@ -0,0 +1,76 @@
+/* EasyTAG - tag editor for audio files
+ * Copyright (C) 2014 David King <amigadave amigadave com>
+ *
+ * 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., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef ET_FLAC_PRIVATE_H_
+#define ET_FLAC_PRIVATE_H_
+
+#include "config.h"
+
+#ifdef ENABLE_FLAC
+
+#include <gio/gio.h>
+#include <FLAC/metadata.h>
+
+G_BEGIN_DECLS
+
+/*
+ * EtFlacReadState:
+ *
+ * Used as a FLAC__IOHandle for FLAC__metadata_chain_read_with_callbacks().
+ */
+typedef struct
+{
+    GFileInputStream *istream;
+    gboolean eof;
+    GError *error;
+} EtFlacReadState;
+
+/*
+ * EtFlacWriteState:
+ *
+ * Used as a FLAC__IOHandle for FLAC__metadata_chain_write_with_callbacks() and
+ * FLAC__metadata_chain_write_with_callbacks_and_tempfile().
+ */
+typedef struct
+{
+    GFile *file;
+    GFileInputStream *istream;
+    GFileOutputStream *ostream;
+    GFileIOStream *iostream;
+    gboolean eof;
+    GError *error;
+} EtFlacWriteState;
+
+size_t et_flac_read_read_func (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
+int et_flac_read_seek_func (FLAC__IOHandle handle, FLAC__int64 offset, int whence);
+FLAC__int64 et_flac_read_tell_func (FLAC__IOHandle handle);
+int et_flac_read_eof_func (FLAC__IOHandle handle);
+int et_flac_read_close_func (FLAC__IOHandle handle);
+
+size_t et_flac_write_read_func (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
+size_t et_flac_write_write_func (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
+int et_flac_write_seek_func (FLAC__IOHandle handle, FLAC__int64 offset, int whence);
+FLAC__int64 et_flac_write_tell_func (FLAC__IOHandle handle);
+int et_flac_write_eof_func (FLAC__IOHandle handle);
+int et_flac_write_close_func (FLAC__IOHandle handle);
+
+G_END_DECLS
+
+#endif /* ENABLE_FLAC */
+
+#endif /* ET_FLAC_PRIVATE_H_ */
diff --git a/src/tags/flac_tag.c b/src/tags/flac_tag.c
index b90be90..6672796 100644
--- a/src/tags/flac_tag.c
+++ b/src/tags/flac_tag.c
@@ -28,10 +28,10 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <FLAC/metadata.h>
 #include <unistd.h>
 
 #include "easytag.h"
+#include "flac_private.h"
 #include "flac_tag.h"
 #include "vcedit.h"
 #include "et_core.h"
@@ -41,34 +41,6 @@
 #include "picture.h"
 #include "charset.h"
 
-/*
- * EtFlacReadState:
- *
- * Used as a FLAC__IOHandle for FLAC__metadata_chain_read_with_callbacks().
- */
-typedef struct
-{
-    GFileInputStream *istream;
-    gboolean eof;
-    GError *error;
-} EtFlacReadState;
-
-/*
- * EtFlacWriteState:
- *
- * Used as a FLAC__IOHandle for FLAC__metadata_chain_write_with_callbacks() and
- * FLAC__metadata_chain_write_with_callbacks_and_tempfile().
- */
-typedef struct
-{
-    GFile *file;
-    GFileInputStream *istream;
-    GFileOutputStream *ostream;
-    GFileIOStream *iostream;
-    gboolean eof;
-    GError *error;
-} EtFlacWriteState;
-
 #define MULTIFIELD_SEPARATOR " - "
 
 /* FLAC uses Ogg Vorbis comments
@@ -102,242 +74,6 @@ static gboolean Flac_Write_Delimetered_Tag (FLAC__StreamMetadata *vc_block, cons
 static gboolean Flac_Write_Tag (FLAC__StreamMetadata *vc_block, const gchar *tag_name, gchar *value);
 static gboolean Flac_Set_Tag (FLAC__StreamMetadata *vc_block, const gchar *tag_name, gchar *value, gboolean 
split);
 
-
-static size_t
-read_func (GInputStream *istream,
-           void *buffer,
-           gsize count,
-           gboolean *eof,
-           GError **error)
-{
-    gssize bytes_read;
-
-    *eof = FALSE;
-
-    bytes_read = g_input_stream_read (istream, buffer, count, NULL, error);
-
-    if (bytes_read == -1)
-    {
-        errno = EIO;
-        return 0;
-    }
-    else if (bytes_read == 0)
-    {
-        *eof = TRUE;
-    }
-
-    return bytes_read;
-}
-
-static size_t
-et_flac_read_read_func (void *ptr,
-                        size_t size,
-                        size_t nmemb,
-                        FLAC__IOHandle handle)
-{
-    EtFlacReadState *state;
-
-    state = (EtFlacReadState *)handle;
-
-    return read_func (G_INPUT_STREAM (state->istream), ptr, size * nmemb,
-                      &state->eof, &state->error);
-}
-
-static size_t
-et_flac_write_read_func (void *ptr,
-                         size_t size,
-                         size_t nmemb,
-                         FLAC__IOHandle handle)
-{
-    EtFlacWriteState *state;
-
-    state = (EtFlacWriteState *)handle;
-
-    return read_func (G_INPUT_STREAM (state->istream), ptr, size * nmemb,
-                      &state->eof, &state->error);
-}
-
-static size_t
-et_flac_write_write_func (const void *ptr,
-                          size_t size,
-                          size_t nmemb,
-                          FLAC__IOHandle handle)
-{
-    EtFlacWriteState *state;
-    gsize bytes_written;
-
-    state = (EtFlacWriteState *)handle;
-
-    if (!g_output_stream_write_all (G_OUTPUT_STREAM (state->ostream), ptr,
-                                    size * nmemb, &bytes_written, NULL,
-                                    &state->error))
-    {
-        g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %" G_GSIZE_FORMAT
-                 " bytes of data were written", bytes_written,
-                 size);
-        errno = EIO;
-    }
-
-    return bytes_written;
-}
-
-static gint
-seek_func (GSeekable *seekable,
-           goffset offset,
-           gint whence,
-           GError **error)
-{
-    GSeekType seektype;
-
-    if (!g_seekable_can_seek (seekable))
-    {
-        errno = EBADF;
-        return -1;
-    }
-    else
-    {
-        switch (whence)
-        {
-            case SEEK_SET:
-                seektype = G_SEEK_SET;
-                break;
-            case SEEK_CUR:
-                seektype = G_SEEK_CUR;
-                break;
-            case SEEK_END:
-                seektype = G_SEEK_END;
-                break;
-            default:
-                errno = EINVAL;
-                return -1;
-        }
-
-        if (g_seekable_seek (seekable, offset, seektype, NULL, error))
-        {
-            return 0;
-        }
-        else
-        {
-            /* TODO: More suitable error. */
-            errno = EINVAL;
-            return -1;
-        }
-    }
-}
-
-static int
-et_flac_read_seek_func (FLAC__IOHandle handle,
-                        FLAC__int64 offset,
-                        int whence)
-{
-    EtFlacReadState *state;
-
-    state = (EtFlacReadState *)handle;
-
-    return seek_func (G_SEEKABLE (state->istream), offset, whence,
-                      &state->error);
-}
-
-static int
-et_flac_write_seek_func (FLAC__IOHandle handle,
-                         FLAC__int64 offset,
-                         int whence)
-{
-    EtFlacWriteState *state;
-
-    state = (EtFlacWriteState *)handle;
-
-    /* Seeking on the IOStream causes both the input and output stream to have
-     * the same offset. */
-    return seek_func (G_SEEKABLE (state->iostream), offset, whence,
-                      &state->error);
-}
-
-static FLAC__int64
-tell_func (GSeekable *seekable)
-{
-    if (!g_seekable_can_seek (seekable))
-    {
-        errno = EBADF;
-        return -1;
-    }
-    else
-    {
-        return g_seekable_tell (seekable);
-    }
-}
-
-static FLAC__int64
-et_flac_read_tell_func (FLAC__IOHandle handle)
-{
-    EtFlacReadState *state;
-
-    state = (EtFlacReadState *)handle;
-
-    return tell_func (G_SEEKABLE (state->istream));
-}
-
-static FLAC__int64
-et_flac_write_tell_func (FLAC__IOHandle handle)
-{
-    EtFlacWriteState *state;
-
-    state = (EtFlacWriteState *)handle;
-
-    return tell_func (G_SEEKABLE (state->iostream));
-}
-
-static int
-et_flac_read_eof_func (FLAC__IOHandle handle)
-{
-    EtFlacReadState *state;
-
-    state = (EtFlacReadState *)handle;
-
-    /* EOF is not directly supported by GFileInputStream. */
-    return state->eof ? 1 : 0;
-}
-
-static int
-et_flac_write_eof_func (FLAC__IOHandle handle)
-{
-    EtFlacWriteState *state;
-
-    state = (EtFlacWriteState *)handle;
-
-    /* EOF is not directly supported by GFileInputStream. */
-    return state->eof ? 1 : 0;
-}
-
-static int
-et_flac_read_close_func (FLAC__IOHandle handle)
-{
-    EtFlacReadState *state;
-
-    state = (EtFlacReadState *)handle;
-
-    g_clear_object (&state->istream);
-    g_clear_error (&state->error);
-
-    /* Always return success. */
-    return 0;
-}
-
-static int
-et_flac_write_close_func (FLAC__IOHandle handle)
-{
-    EtFlacWriteState *state;
-
-    state = (EtFlacWriteState *)handle;
-
-    g_clear_object (&state->file);
-    g_clear_object (&state->iostream);
-    g_clear_error (&state->error);
-
-    /* Always return success. */
-    return 0;
-}
-
 /*
  * Read tag data from a FLAC file using the level 2 flac interface,
  * Note:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]