[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r23121 - Extractor/src/plugins
From: |
gnunet |
Subject: |
[GNUnet-SVN] r23121 - Extractor/src/plugins |
Date: |
Sun, 5 Aug 2012 22:46:38 +0200 |
Author: grothoff
Date: 2012-08-05 22:46:38 +0200 (Sun, 05 Aug 2012)
New Revision: 23121
Modified:
Extractor/src/plugins/flac_extractor.c
Extractor/src/plugins/ogg_extractor.c
Log:
first hack at refactoring FLAC to new API
Modified: Extractor/src/plugins/flac_extractor.c
===================================================================
--- Extractor/src/plugins/flac_extractor.c 2012-08-05 20:01:02 UTC (rev
23120)
+++ Extractor/src/plugins/flac_extractor.c 2012-08-05 20:46:38 UTC (rev
23121)
@@ -1,10 +1,10 @@
/*
This file is part of libextractor.
- (C) 2007, 2009 Vidyut Samanta and Christian Grothoff
+ (C) 2007, 2009, 2012 Vidyut Samanta and Christian Grothoff
libextractor 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, or (at your
+ by the Free Software Foundation; either version 3, or (at your
option) any later version.
libextractor is distributed in the hope that it will be useful, but
@@ -18,99 +18,185 @@
Boston, MA 02111-1307, USA.
*/
+/**
+ * @file plugins/flac_extractor.c
+ * @brief plugin to support FLAC files
+ * @author Christian Grothoff
+ */
#include "platform.h"
#include "extractor.h"
+#include <FLAC/all.h>
+
+/**
+ * Bytes each FLAC file must begin with (not used, but we might
+ * choose to add this back in the future to improve performance
+ * for non-ogg files).
+ */
#define FLAC_HEADER "fLaC"
-#if HAVE_FLAC_ALL_H
-#include <FLAC/all.h>
-#else
-#error You must install the libflac header files!
-#endif
-
-struct Context {
- const char * data;
- size_t size;
- size_t pos;
- EXTRACTOR_MetaDataProcessor proc;
- void *proc_cls;
- int ret;
-};
-
+/**
+ * Custom read function for flac.
+ *
+ * @param decoder unused
+ * @param buffer where to write the data
+ * @param bytes how many bytes to read, set to how many bytes were read
+ * @param client_data our 'struct EXTRACTOR_ExtractContxt*'
+ * @return status code (error, end-of-file or success)
+ */
static FLAC__StreamDecoderReadStatus
flac_read (const FLAC__StreamDecoder *decoder,
FLAC__byte buffer[],
size_t *bytes,
void *client_data)
{
- struct Context * ctx = client_data;
-
- if (*bytes <= 0)
+ struct EXTRACTOR_ExtractContext *ec = client_data;
+ void *data;
+ ssize_t ret;
+
+ data = NULL;
+ ret = ec->read (ec->cls,
+ &data,
+ *bytes);
+ if (-1 == ret)
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
- if (*bytes > ctx->size - ctx->pos)
- *bytes = ctx->size - ctx->pos;
- if (*bytes == 0)
- return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
- memcpy(buffer,
- &ctx->data[ctx->pos],
- *bytes);
- ctx->pos += *bytes;
+ if (0 == ret)
+ {
+ errno = 0;
+ return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+ }
+ memcpy (buffer, data, ret);
+ *bytes = ret;
+ errno = 0;
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
}
+
+/**
+ * Seek to a particular position in the file.
+ *
+ * @param decoder unused
+ * @param absolute_byte_offset where to seek
+ * @param client_data the 'struct EXTRACTOR_ExtractContext'
+ * @return status code (error or success)
+ */
static FLAC__StreamDecoderSeekStatus
-flac_seek(const FLAC__StreamDecoder *decoder,
- FLAC__uint64 absolute_byte_offset, void *client_data)
+flac_seek (const FLAC__StreamDecoder *decoder,
+ FLAC__uint64 absolute_byte_offset,
+ void *client_data)
{
- struct Context * ctx = client_data;
-
- if (absolute_byte_offset > ctx->size)
+ struct EXTRACTOR_ExtractContext *ec = client_data;
+
+ if (absolute_byte_offset !=
+ ec->seek (ec->cls, (int64_t) absolute_byte_offset, SEEK_SET))
return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
- ctx->pos = (size_t) absolute_byte_offset;
return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
}
+
+/**
+ * Tell FLAC about our current position in the file.
+ *
+ * @param decoder unused
+ * @param absolute_byte_offset location to store the current offset
+ * @param client_data the 'struct EXTRACTOR_ExtractContext'
+ * @return status code (error or success)
+ */
static FLAC__StreamDecoderTellStatus
-flac_tell(const FLAC__StreamDecoder *decoder, FLAC__uint64
*absolute_byte_offset, void *client_data)
+flac_tell (const FLAC__StreamDecoder *decoder,
+ FLAC__uint64 *absolute_byte_offset,
+ void *client_data)
{
- struct Context * ctx = client_data;
-
- *absolute_byte_offset = ctx->pos;
+ struct EXTRACTOR_ExtractContext *ec = client_data;
+
+ *absolute_byte_offset = ec->seek (ec->cls,
+ 0,
+ SEEK_CUR);
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
}
+
+/**
+ * Tell FLAC the size of the file.
+ *
+ * @param decoder unused
+ * @param stream_length where to store the file size
+ * @param client_data the 'struct EXTRACTOR_ExtractContext'
+ * @return true at EOF, false if not
+ */
static FLAC__StreamDecoderLengthStatus
-flac_length(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length,
void *client_data)
+flac_length (const FLAC__StreamDecoder *decoder,
+ FLAC__uint64 *stream_length,
+ void *client_data)
{
- struct Context * ctx = client_data;
+ struct EXTRACTOR_ExtractContext *ec = client_data;
- ctx->pos = *stream_length;
+ *stream_length = ec->get_size (ec->cls);
return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
}
+
+/**
+ * Tell FLAC if we are at the end of the file.
+ *
+ * @param decoder unused
+ * @param absolute_byte_offset location to store the current offset
+ * @param client_data the 'struct EXTRACTOR_ExtractContext'
+ * @return true at EOF, false if not
+ */
static FLAC__bool
-flac_eof(const FLAC__StreamDecoder *decoder, void *client_data)
+flac_eof (const FLAC__StreamDecoder *decoder,
+ void *client_data)
{
- struct Context * ctx = client_data;
+ struct EXTRACTOR_ExtractContext *ec = client_data;
- return (ctx->pos == ctx->size) ? true : false;
+ return (ec->get_size (ec->cls) ==
+ ec->seek (ec->cls, 0, SEEK_CUR)) ? true : false;
}
+
+/**
+ * FLAC wants to write. Always succeeds but does nothing.
+ *
+ * @param decoder unused
+ * @param frame unused
+ * @param buffer unused
+ * @param client_data the 'struct EXTRACTOR_ExtractContext'
+ * @return always claims success
+ */
static FLAC__StreamDecoderWriteStatus
-flac_write(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const
FLAC__int32 *const buffer[], void *client_data)
+flac_write (const FLAC__StreamDecoder *decoder,
+ const FLAC__Frame *frame,
+ const FLAC__int32 *const buffer[],
+ void *client_data)
{
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
-typedef struct
+
+/**
+ * A mapping from FLAC meta data strings to extractor types.
+ */
+struct Matches
{
+ /**
+ * FLAC Meta data description text.
+ */
const char *text;
+
+ /**
+ * Corresponding LE type.
+ */
enum EXTRACTOR_MetaType type;
-} Matches;
+};
-static Matches tmap[] = {
+
+/**
+ * Mapping of FLAC meta data description texts to LE types.
+ * NULL-terminated.
+ */
+static struct Matches tmap[] = {
{"TITLE", EXTRACTOR_METATYPE_TITLE},
{"VERSION", EXTRACTOR_METATYPE_SONG_VERSION},
{"ALBUM", EXTRACTOR_METATYPE_ALBUM},
@@ -126,72 +212,97 @@
{"CONTACT", EXTRACTOR_METATYPE_CONTACT_INFORMATION},
{"TRACKNUMBER", EXTRACTOR_METATYPE_TRACK_NUMBER},
{"ISRC", EXTRACTOR_METATYPE_ISRC},
- {NULL, 0},
+ {NULL, 0}
};
-static char * xstrndup(const char * s, size_t n){
+/**
+ * FIXME.
+ */
+#define ADD (t,s) do { if (ctx->ret == 0) ctx->ret = ctx->proc (ctx->proc_cls,
"flac", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen(s)+1); } while (0)
+
+
+/**
+ * Create 0-terminated version of n-character string.
+ *
+ * @param s input string (non 0-terminated)
+ * @param n number of bytes in 's'
+ * @return NULL on error, otherwise 0-terminated version of 's'
+ */
+static char *
+xstrndup (const char *s,
+ size_t n)
+{
char * d;
- d= malloc(n+1);
- if (d == NULL)
+ if (NULL == (d = malloc(n+1)))
return NULL;
- memcpy(d,s,n);
- d[n]='\0';
+ memcpy (d, s, n);
+ d[n] = '\0';
return d;
}
-#define ADD(t,s) do { if (ctx->ret == 0) ctx->ret = ctx->proc (ctx->proc_cls,
"flac", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen(s)+1); } while (0)
-
+/**
+ * FIXME.
+ */
static void
-check(const char * type,
- unsigned int type_length,
- const char * value,
- unsigned int value_length,
- struct Context *ctx)
+check (const char *type,
+ unsigned int type_length,
+ const char *value,
+ unsigned int value_length,
+ struct EXTRACTOR_ExtractContext *ec)
{
unsigned int i;
char *tmp;
- i = 0;
- while (tmap[i].text != NULL)
+ for (i=0; NULL != tmap[i].text; i++)
{
- if ( (type_length == strlen(tmap[i].text)) &&
- (0 == strncasecmp(tmap[i].text,
- type,
- type_length)) )
- {
- tmp = xstrndup(value,
- value_length);
- if (tmp != NULL)
- {
- ADD (tmap[i].type, tmp);
- free (tmp);
- }
- break;
- }
- i++;
+ if ( (type_length != strlen (tmap[i].text)) ||
+ (0 != strncasecmp (tmap[i].text,
+ type,
+ type_length)) )
+ continue;
+ if (NULL ==
+ (tmp = xstrndup (value,
+ value_length)))
+ continue;
+ ADD (tmap[i].type, tmp);
+ free (tmp);
}
}
+/**
+ * Function called whenever FLAC finds meta data.
+ *
+ * @param decoder unused
+ * @param metadata meta data that was found
+ * @param client_data the 'struct EXTRACTOR_ExtractContext'
+ */
static void
-flac_metadata(const FLAC__StreamDecoder *decoder,
- const FLAC__StreamMetadata *metadata,
- void *client_data)
+flac_metadata (const FLAC__StreamDecoder *decoder,
+ const FLAC__StreamMetadata *metadata,
+ void *client_data)
{
- struct Context * ctx = client_data;
+ struct EXTRACTOR_ExtractContext *ec = client_data;
+ enum EXTRACTOR_MetaType type;
+ const FLAC__StreamMetadata_VorbisComment * vc;
+ unsigned int count;
+ const FLAC__StreamMetadata_VorbisComment_Entry * entry;
+ const char * eq;
+ unsigned int len;
+ unsigned int ilen;
switch (metadata->type)
{
case FLAC__METADATA_TYPE_STREAMINFO:
{
char buf[512];
- snprintf(buf, 512,
- _("%u Hz, %u channels"),
- metadata->data.stream_info.sample_rate,
- metadata->data.stream_info.channels);
+ snprintf (buf, sizeof (buf),
+ _("%u Hz, %u channels"),
+ metadata->data.stream_info.sample_rate,
+ metadata->data.stream_info.channels);
ADD (EXTRACTOR_METATYPE_RESOURCE_TYPE, buf);
break;
}
@@ -203,13 +314,8 @@
break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
{
- const FLAC__StreamMetadata_VorbisComment * vc =
&metadata->data.vorbis_comment;
- unsigned int count = vc->num_comments;
- const FLAC__StreamMetadata_VorbisComment_Entry * entry;
- const char * eq;
- unsigned int len;
- unsigned int ilen;
-
+ vc = &metadata->data.vorbis_comment;
+ count = vc->num_comments;
while (count-- > 0)
{
entry = &vc->comments[count];
@@ -226,64 +332,62 @@
(ilen == len) )
break;
eq++;
- check((const char*) entry->entry,
- ilen,
- eq,
- len - ilen,
- ctx);
+ check ((const char*) entry->entry,
+ ilen,
+ eq,
+ len - ilen,
+ ctx);
}
break;
}
case FLAC__METADATA_TYPE_PICTURE:
{
- if (ctx->ret == 0)
+ if (0 != ctx->ret)
+ break;
+ switch (metadata->data.picture.type)
{
- enum EXTRACTOR_MetaType type;
- switch (metadata->data.picture.type)
- {
- case FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON:
- type = EXTRACTOR_METATYPE_THUMBNAIL;
- break;
- case FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER:
- type = EXTRACTOR_METATYPE_COVER_PICTURE;
- break;
- case FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_BAND:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST:
- type = EXTRACTOR_METATYPE_CONTRIBUTOR_PICTURE;
- break;
- case FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE:
- type = EXTRACTOR_METATYPE_EVENT_PICTURE;
- break;
- case FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE:
- type = EXTRACTOR_METATYPE_LOGO;
- break;
- case FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_FISH:
- case FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION:
- default:
- type = EXTRACTOR_METATYPE_PICTURE;
- break;
- }
- ctx->ret = ctx->proc (ctx->proc_cls,
- "flac",
- type,
- EXTRACTOR_METAFORMAT_BINARY,
- metadata->data.picture.mime_type,
- (const char*) metadata->data.picture.data,
- metadata->data.picture.data_length);
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON:
+ type = EXTRACTOR_METATYPE_THUMBNAIL;
+ break;
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER:
+ type = EXTRACTOR_METATYPE_COVER_PICTURE;
+ break;
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_BAND:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST:
+ type = EXTRACTOR_METATYPE_CONTRIBUTOR_PICTURE;
+ break;
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE:
+ type = EXTRACTOR_METATYPE_EVENT_PICTURE;
+ break;
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE:
+ type = EXTRACTOR_METATYPE_LOGO;
+ break;
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_FISH:
+ case FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION:
+ default:
+ type = EXTRACTOR_METATYPE_PICTURE;
+ break;
}
+ ec->proc (ec->cls,
+ "flac",
+ type,
+ EXTRACTOR_METAFORMAT_BINARY,
+ metadata->data.picture.mime_type,
+ (const char*) metadata->data.picture.data,
+ metadata->data.picture.data_length))
break;
}
case FLAC__METADATA_TYPE_PADDING:
@@ -294,81 +398,73 @@
}
}
+
+/**
+ * Function called whenever FLAC decoder has trouble. Does nothing.
+ *
+ * @param decoder the decoder handle
+ * @param status type of the error
+ * @param client_data our 'struct EXTRACTOR_ExtractContext'
+ */
static void
-flac_error(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus
status, void *client_data)
+flac_error (const FLAC__StreamDecoder *decoder,
+ FLAC__StreamDecoderErrorStatus status,
+ void *client_data)
{
-#if 0
- fprintf(stderr,
- "Got error: %u\n", status);
-#endif
+ /* ignore errors */
}
-/* mimetype = audio/flac */
-int
-EXTRACTOR_flac_extract (const char *data,
- size_t size,
- EXTRACTOR_MetaDataProcessor proc,
- void *proc_cls,
- const char *options)
+
+/**
+ * Main entry method for the 'audio/flac' extraction plugin.
+ *
+ * @param ec extraction context provided to the plugin
+ */
+void
+EXTRACTOR_flac_extract_method (struct EXTRACTOR_ExtractContext *ec)
{
FLAC__StreamDecoder * decoder;
- struct Context le_cls;
- struct Context *ctx;
- if (size < strlen(FLAC_HEADER) + sizeof (int))
- return 0;
- if (0 != memcmp(FLAC_HEADER,
- data,
- strlen(FLAC_HEADER)))
- return 0;
- decoder = FLAC__stream_decoder_new();
- if (NULL == decoder)
- return 0;
- FLAC__stream_decoder_set_md5_checking(decoder, false);
- FLAC__stream_decoder_set_metadata_ignore_all(decoder);
- if (false == FLAC__stream_decoder_set_metadata_respond_all(decoder))
+ if (NULL == (decoder = FLAC__stream_decoder_new ()))
+ return;
+ FLAC__stream_decoder_set_md5_checking (decoder, false);
+ FLAC__stream_decoder_set_metadata_ignore_all (decoder);
+ if (false == FLAC__stream_decoder_set_metadata_respond_all (decoder))
{
- FLAC__stream_decoder_delete(decoder);
- return 0;
+ FLAC__stream_decoder_delete (decoder);
+ return;
}
- le_cls.ret = 0;
- le_cls.size = size;
- le_cls.data = data;
- le_cls.proc = proc;
- le_cls.proc_cls = proc_cls;
- le_cls.pos = 0;
if (FLAC__STREAM_DECODER_INIT_STATUS_OK !=
- FLAC__stream_decoder_init_stream(decoder,
- &flac_read,
- &flac_seek,
- &flac_tell,
- &flac_length,
- &flac_eof,
- &flac_write,
- &flac_metadata,
- &flac_error,
- &le_cls))
+ FLAC__stream_decoder_init_stream (decoder,
+ &flac_read,
+ &flac_seek,
+ &flac_tell,
+ &flac_length,
+ &flac_eof,
+ &flac_write,
+ &flac_metadata,
+ &flac_error,
+ ec))
{
- FLAC__stream_decoder_delete(decoder);
- return le_cls.ret;
+ FLAC__stream_decoder_delete (decoder);
+ return;
}
- if (FLAC__stream_decoder_get_state(decoder) !=
FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
+ if (FLAC__STREAM_DECODER_SEARCH_FOR_METADATA !=
FLAC__stream_decoder_get_state(decoder))
{
- FLAC__stream_decoder_delete(decoder);
- return le_cls.ret;
+ FLAC__stream_decoder_delete (decoder);
+ return;
}
if (! FLAC__stream_decoder_process_until_end_of_metadata(decoder))
{
- FLAC__stream_decoder_delete(decoder);
- return le_cls.ret;
+ FLAC__stream_decoder_delete (decoder);
+ return;
}
- switch (FLAC__stream_decoder_get_state(decoder))
+ switch (FLAC__stream_decoder_get_state (decoder))
{
case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
case FLAC__STREAM_DECODER_READ_METADATA:
case FLAC__STREAM_DECODER_END_OF_STREAM:
case FLAC__STREAM_DECODER_READ_FRAME:
- ctx = &le_cls;
ADD (EXTRACTOR_METATYPE_MIMETYPE, "audio/flac");
break;
default:
@@ -376,6 +472,8 @@
break;
}
FLAC__stream_decoder_finish (decoder);
- FLAC__stream_decoder_delete(decoder);
- return le_cls.ret;
+ FLAC__stream_decoder_delete (decoder);
}
+
+/* end of flac_extractor.c */
+
Modified: Extractor/src/plugins/ogg_extractor.c
===================================================================
--- Extractor/src/plugins/ogg_extractor.c 2012-08-05 20:01:02 UTC (rev
23120)
+++ Extractor/src/plugins/ogg_extractor.c 2012-08-05 20:46:38 UTC (rev
23121)
@@ -82,7 +82,9 @@
int whence)
{
struct EXTRACTOR_ExtractContext *ec = datasource;
- int64_t new_position = ec->seek (ec->cls, (int64_t) offset, whence);
+ int64_t new_position;
+
+ new_position = ec->seek (ec->cls, (int64_t) offset, whence);
return (long) new_position;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r23121 - Extractor/src/plugins,
gnunet <=