Example #1
0
static bool_t id3v24_write_tag (const Tuple * tuple, VFSFile * f)
{
    int version, header_size, data_size, footer_size;
    bool_t syncsafe;
    int64_t offset;

    if (! read_header (f, & version, & syncsafe, & offset, & header_size,
     & data_size, & footer_size))
        return FALSE;

    //read all frames into generic frames;
    GHashTable * dict = g_hash_table_new_full (g_str_hash, g_str_equal,
     (GDestroyNotify) str_unref, (GDestroyNotify) free_frame_list);
    read_all_frames (f, version, syncsafe, data_size, dict);

    //make the new frames from tuple and replace in the dictionary the old frames with the new ones
    add_frameFromTupleStr (tuple, FIELD_TITLE, ID3_TITLE, dict);
    add_frameFromTupleStr (tuple, FIELD_ARTIST, ID3_ARTIST, dict);
    add_frameFromTupleStr (tuple, FIELD_ALBUM, ID3_ALBUM, dict);
    add_frameFromTupleInt (tuple, FIELD_YEAR, ID3_YEAR, dict);
    add_frameFromTupleInt (tuple, FIELD_TRACK_NUMBER, ID3_TRACKNR, dict);
    add_frameFromTupleStr (tuple, FIELD_GENRE, ID3_GENRE, dict);

    char * comment = tuple_get_str (tuple, FIELD_COMMENT);
    add_comment_frame (comment, dict);
    str_unref (comment);

    if (! offset)
    {
        if (! cut_beginning_tag (f, header_size + data_size + footer_size))
            goto ERR;
    }
    else
    {
        if (offset + header_size + data_size + footer_size != vfs_fsize (f))
            goto ERR;
        if (vfs_ftruncate (f, offset))
            goto ERR;
    }

    offset = vfs_fsize (f);

    if (offset < 0 || vfs_fseek (f, offset, SEEK_SET) || ! write_header (f, 0,
     FALSE))
        goto ERR;

    data_size = write_all_frames (f, dict);

    if (! write_header (f, data_size, TRUE) || vfs_fseek (f, offset, SEEK_SET)
     || ! write_header (f, data_size, FALSE))
        goto ERR;

    g_hash_table_destroy (dict);
    return TRUE;

ERR:
    g_hash_table_destroy (dict);
    return FALSE;
}
Example #2
0
static gboolean id3v24_write_tag (const Tuple * tuple, VFSFile * f)
{
    gint version, header_size, data_size, footer_size;
    gboolean syncsafe;
    gint64 offset;

    if (! read_header (f, & version, & syncsafe, & offset, & header_size,
     & data_size, & footer_size))
        return FALSE;

    //read all frames into generic frames;
    mowgli_dictionary_t * dict = mowgli_dictionary_create (strcasecmp);
    read_all_frames (f, version, syncsafe, data_size, dict);

    //make the new frames from tuple and replace in the dictionary the old frames with the new ones
    add_frameFromTupleStr (tuple, FIELD_TITLE, ID3_TITLE, dict);
    add_frameFromTupleStr (tuple, FIELD_ARTIST, ID3_ARTIST, dict);
    add_frameFromTupleStr (tuple, FIELD_ALBUM, ID3_ALBUM, dict);
    add_frameFromTupleInt (tuple, FIELD_YEAR, ID3_YEAR, dict);
    add_frameFromTupleInt (tuple, FIELD_TRACK_NUMBER, ID3_TRACKNR, dict);
    add_frameFromTupleStr (tuple, FIELD_GENRE, ID3_GENRE, dict);
    add_comment_frame (tuple_get_string (tuple, FIELD_COMMENT, NULL), dict);

    if (! offset)
    {
        if (! cut_beginning_tag (f, header_size + data_size + footer_size))
            goto ERR;
    }
    else
    {
        if (offset + header_size + data_size + footer_size != vfs_fsize (f))
            goto ERR;
        if (vfs_ftruncate (f, offset))
            goto ERR;
    }

    offset = vfs_fsize (f);

    if (offset < 0 || vfs_fseek (f, offset, SEEK_SET) || ! write_header (f, 0,
     FALSE))
        goto ERR;

    data_size = writeAllFramesToFile (f, dict);

    if (! write_header (f, data_size, TRUE) || vfs_fseek (f, offset, SEEK_SET)
     || ! write_header (f, data_size, FALSE))
        goto ERR;

    mowgli_dictionary_destroy (dict, free_frame_cb, NULL);
    return TRUE;

ERR:
    mowgli_dictionary_destroy (dict, free_frame_cb, NULL);
    return FALSE;
}
void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
{
    callback_info *info = (callback_info*) client_data;
    gsize size;

    if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO)
    {
        info->stream.samples = metadata->data.stream_info.total_samples;
        AUDDBG("total_samples=%lld\n", (long long) metadata->data.stream_info.total_samples);

        info->stream.bits_per_sample = metadata->data.stream_info.bits_per_sample;
        AUDDBG("bits_per_sample=%d\n", metadata->data.stream_info.bits_per_sample);

        info->stream.channels = metadata->data.stream_info.channels;
        AUDDBG("channels=%d\n", metadata->data.stream_info.channels);

        info->stream.samplerate = metadata->data.stream_info.sample_rate;
        AUDDBG("sample_rate=%d\n", metadata->data.stream_info.sample_rate);

        size = vfs_fsize(info->fd);

        if (size == -1 || info->stream.samples == 0)
            info->bitrate = 0;
        else
            info->bitrate = 8 * size * (gint64) info->stream.samplerate / info->stream.samples;

        AUDDBG("bitrate=%d\n", info->bitrate);

        info->metadata_changed = TRUE;
    }
}
Example #4
0
static gint64 seek_cb (void * file, gint64 offset, gint whence)
{
    if (whence == AVSEEK_SIZE)
        return vfs_fsize (file);
    if (vfs_fseek (file, offset, whence & ~(gint) AVSEEK_FORCE))
        return -1;
    return vfs_ftell (file);
}
Example #5
0
static uint32_t
wv_get_length(void *id)
{
    VFSFile *file = (VFSFile *) id;

    if (file == NULL)
        return 0;

    return vfs_fsize(file);
}
Example #6
0
/* Load a file to a buffer, return 0 on success, negative value on error
 */
gint xs_fload_buffer(const gchar *filename, guint8 **buf, size_t *bufSize)
{
    xs_file_t *f;
    glong seekPos;

    /* Open file, get file size */
    if ((f = xs_fopen(filename, "rb")) == NULL)
        return -1;

#ifdef __AUDACIOUS_NEWVFS__
    seekPos = vfs_fsize(f);
#else
    xs_fseek(f, 0L, SEEK_END);
    seekPos = xs_ftell(f);
#endif

    if (seekPos > 0) {
        size_t readSize = seekPos;
        if (readSize >= *bufSize || *buf == NULL) {
            /* Only re-allocate if the required size > current */
            if (*buf != NULL) {
                g_free(*buf);
                *buf = NULL;
            }

            *bufSize = seekPos;

            *buf = (guint8 *) g_malloc(*bufSize * sizeof(guint8));
            if (*buf == NULL) {
                xs_fclose(f);
                return -2;
            }
        }

        /* Read data */
        if (xs_fseek(f, 0, SEEK_SET))
            readSize = 0;
        else
            readSize = xs_fread(*buf, 1, *bufSize, f);

        xs_fclose(f);

        if (readSize != *bufSize)
            return -3;
        else
            return 0;
    } else {
        xs_fclose(f);
        return -4;
    }
}
Example #7
0
static char * read_win_text (VFSFile * file)
{
    int64_t size = vfs_fsize (file);
    if (size < 1)
        return NULL;

    char * raw = malloc (size + 1);
    size = vfs_fread (raw, 1, size, file);
    raw[size] = 0;

    strip_char (raw, '\r');
    char * text = str_to_utf8 (raw);
    free (raw);
    return text;
}
FLAC__StreamDecoderLengthStatus length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *length, void *client_data)
{
    callback_info *info = (callback_info*) client_data;

    if ((*length = vfs_fsize(info->fd)) == -1)
    {
        /*
         * Could not get the stream size. This is not necessarily an
         * error, maybe the stream has no fixed size (think streaming
         * audio)
         */
        AUDDBG("Stream length is unknown.\n");
        *length = 0;
        return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
    }

    AUDDBG ("Stream length is %d bytes\n", (gint) * length);

    return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
}
Example #9
0
EXPORT void vfs_file_read_all (VFSFile * file, void * * bufp, int64_t * sizep)
{
    char * buf = NULL;
    int64_t size = vfs_fsize (file);

    if (size >= 0)
    {
        size = MIN (size, SIZE_MAX - 1);
        buf = malloc (size + 1);
        size = vfs_fread (buf, 1, size, file);
    }
    else
    {
        size = 0;

        size_t bufsize = 4096;
        buf = malloc (bufsize);

        size_t readsize;
        while ((readsize = vfs_fread (buf + size, 1, bufsize - 1 - size, file)))
        {
            size += readsize;

            if (size == bufsize - 1)
            {
                if (bufsize > SIZE_MAX - 4096)
                    break;

                bufsize += 4096;
                buf = realloc (buf, bufsize);
            }
        }
    }

    buf[size] = 0; // nul-terminate

    * bufp = buf;
    if (sizep)
        * sizep = size;
}
Example #10
0
gchar * load_text_file (const gchar * filename)
{
    VFSFile * file;
    gint size;
    gchar * buffer;

    file = vfs_fopen (filename, "r");

    if (file == NULL)
        return NULL;

    size = vfs_fsize (file);
    size = MAX (0, size);
    buffer = g_malloc (size + 1);

    size = vfs_fread (buffer, 1, size, file);
    size = MAX (0, size);
    buffer[size] = 0;

    vfs_fclose (file);

    return buffer;
}
Example #11
0
static int64_t probe_buffer_fsize (VFSFile * file)
{
    return vfs_fsize (((ProbeBuffer *) vfs_get_handle (file))->file);
}
Example #12
0
Tuple *flac_probe_for_tuple(const char *filename, VFSFile *fd)
{
    AUDDBG("Probe for tuple.\n");

    Tuple *tuple = NULL;
    FLAC__Metadata_Iterator *iter;
    FLAC__Metadata_Chain *chain;
    FLAC__StreamMetadata *metadata = NULL;
    FLAC__Metadata_ChainStatus status;
    FLAC__StreamMetadata_VorbisComment_Entry *entry;
    char *key;
    char *value;

    tuple = tuple_new_from_filename(filename);

    tuple_set_str(tuple, FIELD_CODEC, NULL, "Free Lossless Audio Codec (FLAC)");
    tuple_set_str(tuple, FIELD_QUALITY, NULL, _("lossless"));

    chain = FLAC__metadata_chain_new();

    if (!FLAC__metadata_chain_read_with_callbacks(chain, fd, io_callbacks))
        goto ERR;

    iter = FLAC__metadata_iterator_new();

    FLAC__metadata_iterator_init(iter, chain);

    do
    {
        switch (FLAC__metadata_iterator_get_block_type(iter))
        {
            case FLAC__METADATA_TYPE_VORBIS_COMMENT:

                if (FLAC__metadata_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_VORBIS_COMMENT)
                {
                    metadata = FLAC__metadata_iterator_get_block(iter);

                    AUDDBG("Vorbis comment contains %d fields\n", metadata->data.vorbis_comment.num_comments);
                    AUDDBG("Vendor string: %s\n", metadata->data.vorbis_comment.vendor_string.entry);

                    entry = metadata->data.vorbis_comment.comments;

                    for (int i = 0; i < metadata->data.vorbis_comment.num_comments; i++, entry++)
                    {
                        if (FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(*entry, &key, &value) == false)
                            AUDDBG("Could not parse comment\n");
                        else
                        {
                            parse_comment(tuple, key, value);
                            free(key);
                            free(value);
                        }
                    }
                }
                break;

            case FLAC__METADATA_TYPE_STREAMINFO:
                metadata = FLAC__metadata_iterator_get_block(iter);

                /* Calculate the stream length (milliseconds) */
                if (metadata->data.stream_info.sample_rate == 0)
                {
                    FLACNG_ERROR("Invalid sample rate for stream!\n");
                    tuple_set_int(tuple, FIELD_LENGTH, NULL, -1);
                }
                else
                {
                    tuple_set_int(tuple, FIELD_LENGTH, NULL,
                        (metadata->data.stream_info.total_samples / metadata->data.stream_info.sample_rate) * 1000);
                    AUDDBG("Stream length: %d seconds\n", tuple_get_int(tuple, FIELD_LENGTH, NULL));
                }

                int64_t size = vfs_fsize(fd);

                if (size == -1 || metadata->data.stream_info.total_samples == 0)
                    tuple_set_int(tuple, FIELD_BITRATE, NULL, 0);
                else
                {
                    int bitrate = 8 * size *
                        (int64_t) metadata->data.stream_info.sample_rate / metadata->data.stream_info.total_samples;

                    tuple_set_int(tuple, FIELD_BITRATE, NULL, (bitrate + 500) / 1000);
                }
                break;

            default:
                ;
        }
    } while (FLAC__metadata_iterator_next(iter));

    FLAC__metadata_iterator_delete(iter);
    FLAC__metadata_chain_delete(chain);

    return tuple;

ERR:
    status = FLAC__metadata_chain_status(chain);
    FLAC__metadata_chain_delete(chain);

    FLACNG_ERROR("An error occured: %s\n", FLAC__Metadata_ChainStatusString[status]);
    return tuple;
}
Example #13
0
static bool_t read_header (VFSFile * handle, int * version, bool_t *
 syncsafe, int64_t * offset, int * header_size, int * data_size, int *
 footer_size)
{
    ID3v2Header header, footer;

    if (vfs_fseek (handle, 0, SEEK_SET))
        return FALSE;

    if (vfs_fread (& header, 1, sizeof (ID3v2Header), handle) != sizeof
     (ID3v2Header))
        return FALSE;

    if (validate_header (& header, FALSE))
    {
        * offset = 0;
        * version = header.version;
        * header_size = sizeof (ID3v2Header);
        * data_size = header.size;

        if (header.flags & ID3_HEADER_HAS_FOOTER)
        {
            if (vfs_fseek (handle, header.size, SEEK_CUR))
                return FALSE;

            if (vfs_fread (& footer, 1, sizeof (ID3v2Header), handle) != sizeof
             (ID3v2Header))
                return FALSE;

            if (! validate_header (& footer, TRUE))
                return FALSE;

            * footer_size = sizeof (ID3v2Header);
        }
        else
            * footer_size = 0;
    }
    else
    {
        int64_t end = vfs_fsize (handle);

        if (end < 0)
            return FALSE;

        if (vfs_fseek (handle, end - sizeof (ID3v2Header), SEEK_SET))
            return FALSE;

        if (vfs_fread (& footer, 1, sizeof (ID3v2Header), handle) != sizeof
         (ID3v2Header))
            return FALSE;

        if (! validate_header (& footer, TRUE))
            return FALSE;

        * offset = end - 2 * sizeof (ID3v2Header) - footer.size;
        * version = footer.version;
        * header_size = sizeof (ID3v2Header);
        * data_size = footer.size;
        * footer_size = sizeof (ID3v2Header);

        if (vfs_fseek (handle, * offset, SEEK_SET))
            return FALSE;

        if (vfs_fread (& header, 1, sizeof (ID3v2Header), handle) != sizeof
         (ID3v2Header))
            return FALSE;

        if (! validate_header (& header, FALSE))
            return FALSE;
    }

    * syncsafe = (header.flags & ID3_HEADER_SYNCSAFE) ? TRUE : FALSE;

    if (header.flags & ID3_HEADER_HAS_EXTENDED_HEADER)
    {
        int extended_size = 0;

        if (header.version == 3)
        {
            if (! skip_extended_header_3 (handle, & extended_size))
                return FALSE;
        }
        else if (header.version == 4)
        {
            if (! skip_extended_header_4 (handle, & extended_size))
                return FALSE;
        }

        * header_size += extended_size;
        * data_size -= extended_size;
    }

    TAGDBG ("Offset = %d, header size = %d, data size = %d, footer size = "
     "%d.\n", (int) * offset, * header_size, * data_size, * footer_size);

    return TRUE;
}
Example #14
0
INIFile * open_ini_file (VFSFile * file)
{
    GHashTable *ini_file = NULL;
    GHashTable *section = NULL;
    GString *section_name, *key_name, *value;
    gpointer section_hash, key_hash;
    gsize off = 0;

    gint64 filesize = vfs_fsize (file);
    if (filesize < 1)
        return NULL;

    gchar * buffer = g_malloc (filesize);
    filesize = vfs_fread (buffer, 1, filesize, file);

    section_name = g_string_new("");
    key_name = g_string_new(NULL);
    value = g_string_new(NULL);

    ini_file =
        g_hash_table_new_full(NULL, NULL, NULL, close_ini_file_free_section);
    section =
        g_hash_table_new_full(NULL, NULL, NULL, close_ini_file_free_value);
    /* make a nameless section which should store all entries that are not
     * embedded in a section */
    section_hash = GINT_TO_POINTER(g_string_hash(section_name));
    g_hash_table_insert(ini_file, section_hash, section);

    while (off < filesize)
    {
        /* ignore the following characters */
        if (buffer[off] == '\r' || buffer[off] == '\n' || buffer[off] == ' '
            || buffer[off] == '\t')
        {
            if (buffer[off] == '\n')
            {
                g_string_free(key_name, TRUE);
                g_string_free(value, TRUE);
                key_name = g_string_new(NULL);
                value = g_string_new(NULL);
            }

            off++;
            continue;
        }

        /* if we encounter a possible section statement */
        if (buffer[off] == '[')
        {
            g_string_free(section_name, TRUE);
            section_name = g_string_new(NULL);
            off++;

            if (off >= filesize)
                goto return_sequence;

            while (buffer[off] != ']')
            {
                /* if the section statement has not been closed before a
                 * linebreak */
                if (buffer[off] == '\n')
                    break;

                g_string_append_c(section_name, buffer[off]);
                off++;
                if (off >= filesize)
                    goto return_sequence;
            }
            if (buffer[off] == '\n')
                continue;
            if (buffer[off] == ']')
            {
                off++;
                if (off >= filesize)
                    goto return_sequence;

                strip_lower_string(section_name);
                section_hash = GINT_TO_POINTER(g_string_hash(section_name));

                /* if this section already exists, we don't make a new one,
                 * but reuse the old one */
                if (g_hash_table_lookup(ini_file, section_hash) != NULL)
                    section = g_hash_table_lookup(ini_file, section_hash);
                else
                {
                    section =
                        g_hash_table_new_full(NULL, NULL, NULL,
                                              close_ini_file_free_value);
                    g_hash_table_insert(ini_file, section_hash, section);
                }

                continue;
            }
        }

        if (buffer[off] == '=')
        {
            off++;
            if (off >= filesize)
                goto return_sequence;

            while (buffer[off] != '\n' && buffer[off] != '\r')
            {
                g_string_append_c(value, buffer[off]);
                off++;
                if (off >= filesize)
                    break;
            }

            strip_lower_string(key_name);
            key_hash = GINT_TO_POINTER(g_string_hash(key_name));
            strip_string(value);

            if (key_name->len > 0 && value->len > 0)
                g_hash_table_insert(section, key_hash, g_strdup(value->str));
        }
        else
        {
            g_string_append_c(key_name, buffer[off]);
            off++;
            if (off >= filesize)
                goto return_sequence;
        }
    }

  return_sequence:
    g_string_free(section_name, TRUE);
    g_string_free(key_name, TRUE);
    g_string_free(value, TRUE);
    g_free(buffer);
    return ini_file;
}
Example #15
0
static size_t get_size_vfs(VFSSTREAMFILE *streamfile)
{
  return vfs_fsize(streamfile->vfsFile);
}
Example #16
0
static gint64 probe_buffer_fsize (VFSFile * file)
{
    return vfs_fsize (((ProbeBuffer *) file->handle)->file);
}