示例#1
0
static void
photos_glib_file_copy_splice (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
  GOutputStream *ostream = G_OUTPUT_STREAM (source_object);
  g_autoptr (GTask) task = G_TASK (user_data);
  PhotosGLibFileCopyData *data;

  data = (PhotosGLibFileCopyData *) g_task_get_task_data (task);

  g_assert_true (G_IS_FILE_OUTPUT_STREAM (ostream));
  g_assert_true (G_FILE_OUTPUT_STREAM (ostream) == data->ostream);

  {
    g_autoptr (GError) error = NULL;

    g_output_stream_splice_finish (ostream, res, &error);
    if (error != NULL)
      {
        g_task_return_error (task, g_steal_pointer (&error));
        goto out;
      }
  }

  g_task_return_pointer (task, g_object_ref (data->unique_file), g_object_unref);

 out:
  return;
}
示例#2
0
GFileOutputStream *
_g_local_file_output_stream_new (int fd)
{
  GLocalFileOutputStream *stream;

  stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL);
  stream->priv->fd = fd;
  return G_FILE_OUTPUT_STREAM (stream);
}
示例#3
0
GFileOutputStream *
_g_local_file_output_stream_create  (const char        *filename,
				     gboolean          readable,
				     GFileCreateFlags   flags,
				     GCancellable      *cancellable,
				     GError           **error)
{
  GLocalFileOutputStream *stream;
  int mode;
  int fd;
  int open_flags;

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return NULL;

  if (flags & G_FILE_CREATE_PRIVATE)
    mode = 0600;
  else
    mode = 0666;

  open_flags = O_CREAT | O_EXCL | O_BINARY;
  if (readable)
    open_flags |= O_RDWR;
  else
    open_flags |= O_WRONLY;

  fd = g_open (filename, open_flags, mode);
  if (fd == -1)
    {
      int errsv = errno;

      if (errsv == EINVAL)
	/* This must be an invalid filename, on e.g. FAT */
	g_set_error_literal (error, G_IO_ERROR,
                             G_IO_ERROR_INVALID_FILENAME,
                             _("Invalid filename"));
      else
	{
	  char *display_name = g_filename_display_name (filename);
	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error opening file '%s': %s"),
		       display_name, g_strerror (errsv));
	  g_free (display_name);
	}
      return NULL;
    }
  
  stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL);
  stream->priv->fd = fd;
  return G_FILE_OUTPUT_STREAM (stream);
}
示例#4
0
static GFileOutputStream *
output_stream_open (const char    *filename,
                    gint           open_flags,
                    guint          mode,
                    GCancellable  *cancellable,
                    GError       **error)
{
  GLocalFileOutputStream *stream;
  gint fd;

  fd = g_open (filename, open_flags, mode);
  if (fd == -1)
    {
      set_error_from_open_errno (filename, error);
      return NULL;
    }
  
  stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL);
  stream->priv->fd = fd;
  return G_FILE_OUTPUT_STREAM (stream);
}
示例#5
0
GFileOutputStream *
_g_local_file_output_stream_replace (const char        *filename,
				     const char        *etag,
				     gboolean           create_backup,
				     GFileCreateFlags   flags,
				     GCancellable      *cancellable,
				     GError           **error)
{
  GLocalFileOutputStream *stream;
  int mode;
  int fd;
  char *temp_file;

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return NULL;

  temp_file = NULL;

  if (flags & G_FILE_CREATE_PRIVATE)
    mode = 0600;
  else
    mode = 0666;

  /* If the file doesn't exist, create it */
  fd = g_open (filename, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode);

  if (fd == -1 && errno == EEXIST)
    {
      /* The file already exists */
      fd = handle_overwrite_open (filename, etag, create_backup, &temp_file,
				  cancellable, error);
      if (fd == -1)
	return NULL;
    }
  else if (fd == -1)
    {
      int errsv = errno;

      if (errsv == EINVAL)
	/* This must be an invalid filename, on e.g. FAT */
	g_set_error_literal (error, G_IO_ERROR,
                             G_IO_ERROR_INVALID_FILENAME,
                             _("Invalid filename"));
      else
	{
	  char *display_name = g_filename_display_name (filename);
	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error opening file '%s': %s"),
		       display_name, g_strerror (errsv));
	  g_free (display_name);
	}
      return NULL;
    }
  
 
  stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL);
  stream->priv->fd = fd;
  stream->priv->tmp_filename = temp_file;
  if (create_backup)
    stream->priv->backup_filename = create_backup_filename (filename);
  stream->priv->original_filename =  g_strdup (filename);
  
  return G_FILE_OUTPUT_STREAM (stream);
}
示例#6
0
文件: flac_tag.c 项目: GNOME/easytag
/*
 * Write Flac tag, using the level 2 flac interface
 */
gboolean
flac_tag_write_file_tag (const ET_File *ETFile,
                         GError **error)
{
    const File_Tag *FileTag;
    GFile *file;
    GFileIOStream *iostream;
    EtFlacWriteState state;
    FLAC__IOCallbacks callbacks = { et_flac_read_func, et_flac_write_func,
                                    et_flac_seek_func, et_flac_tell_func,
                                    et_flac_eof_func,
                                    et_flac_write_close_func
                                  };
    const gchar *filename;
    const gchar *filename_utf8;
    const gchar *flac_error_msg;
    FLAC__Metadata_Chain *chain;
    FLAC__Metadata_Iterator *iter;
    FLAC__StreamMetadata_VorbisComment_Entry vce_field_vendor_string; // To save vendor string
    gboolean vce_field_vendor_string_found = FALSE;

    g_return_val_if_fail (ETFile != NULL && ETFile->FileTag != NULL, FALSE);
    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

    FileTag       = (File_Tag *)ETFile->FileTag->data;
    filename      = ((File_Name *)ETFile->FileNameCur->data)->value;
    filename_utf8 = ((File_Name *)ETFile->FileNameCur->data)->value_utf8;

    /* libFLAC is able to detect (and skip) ID3v2 tags by itself */

    /* Create a new chain instance to get all blocks in one time. */
    chain = FLAC__metadata_chain_new ();

    if (chain == NULL)
    {
        flac_error_msg = FLAC__Metadata_ChainStatusString[FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR];

        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                     _("Error while opening file ‘%s’ as FLAC: %s"),
                     filename_utf8, flac_error_msg);
        return FALSE;
    }

    file = g_file_new_for_path (filename);

    state.file = file;
    state.error = NULL;
    /* TODO: Fallback to an in-memory copy of the file for non-local files,
     * where creation of the GFileIOStream may fail. */
    iostream = g_file_open_readwrite (file, NULL, &state.error);

    if (iostream == NULL)
    {
        FLAC__metadata_chain_delete (chain);
        g_propagate_error (error, state.error);
        g_object_unref (file);
        return FALSE;
    }

    state.istream = G_FILE_INPUT_STREAM (g_io_stream_get_input_stream (G_IO_STREAM (iostream)));
    state.ostream = G_FILE_OUTPUT_STREAM (g_io_stream_get_output_stream (G_IO_STREAM (iostream)));
    state.seekable = G_SEEKABLE (iostream);
    state.iostream = iostream;

    if (!FLAC__metadata_chain_read_with_callbacks (chain, &state, callbacks))
    {
        const FLAC__Metadata_ChainStatus status = FLAC__metadata_chain_status (chain);
        flac_error_msg = FLAC__Metadata_ChainStatusString[status];
        FLAC__metadata_chain_delete (chain);

        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                     _("Error while opening file ‘%s’ as FLAC: %s"),
                     filename_utf8, flac_error_msg);
        et_flac_write_close_func (&state);
        return FALSE;
    }

    /* Create a new iterator instance for the chain. */
    iter = FLAC__metadata_iterator_new ();

    if (iter == NULL)
    {
        flac_error_msg = FLAC__Metadata_ChainStatusString[FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR];

        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                     _("Error while opening file ‘%s’ as FLAC: %s"),
                     filename_utf8, flac_error_msg);
        FLAC__metadata_chain_delete (chain);
        et_flac_write_close_func (&state);
        return FALSE;
    }

    FLAC__metadata_iterator_init (iter, chain);

    while (FLAC__metadata_iterator_next (iter))
    {
        const FLAC__MetadataType block_type = FLAC__metadata_iterator_get_block_type (iter);

        /* TODO: Modify the blocks directly, rather than deleting and
         * recreating. */
        if (block_type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
        {
            // Delete the VORBIS_COMMENT block and convert to padding. But before, save the original vendor string.
            /* Get block data. */
            FLAC__StreamMetadata *block = FLAC__metadata_iterator_get_block(iter);
            FLAC__StreamMetadata_VorbisComment *vc = &block->data.vorbis_comment;

            if (vc->vendor_string.entry != NULL)
            {
                // Get initial vendor string, to don't alterate it by FLAC__VENDOR_STRING when saving file
                vce_field_vendor_string.entry = (FLAC__byte *)g_strdup ((gchar *)vc->vendor_string.entry);
                vce_field_vendor_string.length = strlen ((gchar *)vce_field_vendor_string.entry);
                vce_field_vendor_string_found = TRUE;
            }

            /* Free block data. */
            FLAC__metadata_iterator_delete_block (iter, true);
        }
        else if (block_type == FLAC__METADATA_TYPE_PICTURE)
        {
            /* Delete all the PICTURE blocks, and convert to padding. */
            FLAC__metadata_iterator_delete_block (iter, true);
        }
    }


    //
    // Create and insert a new VORBISCOMMENT block
    //
    {
        FLAC__StreamMetadata *vc_block; // For vorbis comments
        GList *l;

        // Allocate a block for Vorbis comments
        vc_block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);

        // Set the original vendor string, else will be use the version of library
        if (vce_field_vendor_string_found)
        {
            // must set 'copy' param to false, because the API will reuse the  pointer of an empty
            // string (yet still return 'true', indicating it was copied); the string is free'd during
            // metadata_chain_delete routine
            FLAC__metadata_object_vorbiscomment_set_vendor_string(vc_block, vce_field_vendor_string, /*copy=*/false);
        }


        /*********
         * Title *
         *********/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_TITLE,
                             FileTag->title,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-title"));

        /**********
         * Artist *
         **********/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_ARTIST,
                             FileTag->artist,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-artist"));

        /****************
         * Album Artist *
         ****************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_ALBUM_ARTIST,
                             FileTag->album_artist,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-artist"));

        /*********
         * Album *
         *********/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_ALBUM,
                             FileTag->album,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-album"));

        /******************************
         * Disc Number and Disc Total *
         ******************************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_DISC_NUMBER,
                             FileTag->disc_number, FALSE);
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_DISC_TOTAL,
                             FileTag->disc_total, FALSE);

        /********
         * Year *
         ********/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_DATE,
                             FileTag->year, FALSE);

        /*************************
         * Track and Total Track *
         *************************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_TRACK_NUMBER,
                             FileTag->track, FALSE);
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_TRACK_TOTAL,
                             FileTag->track_total, FALSE);

        /*********
         * Genre *
         *********/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_GENRE,
                             FileTag->genre,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-genre"));

        /***********
         * Comment *
         ***********/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_DESCRIPTION,
                             FileTag->comment,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-comment"));

        /************
         * Composer *
         ************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_COMPOSER,
                             FileTag->composer,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-composer"));

        /*******************
         * Original artist *
         *******************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_PERFORMER,
                             FileTag->orig_artist,
                             g_settings_get_boolean (MainSettings,
                                     "ogg-split-original-artist"));

        /*************
         * Copyright *
         *************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_COPYRIGHT,
                             FileTag->copyright, FALSE);

        /*******
         * URL *
         *******/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_CONTACT,
                             FileTag->url, FALSE);

        /**************
         * Encoded by *
         **************/
        vc_block_append_tag (vc_block, ET_VORBIS_COMMENT_FIELD_ENCODED_BY,
                             FileTag->encoded_by, FALSE);


        /**************************
         * Set unsupported fields *
         **************************/
        for (l = FileTag->other; l != NULL; l = g_list_next (l))
        {
            vc_block_append_other_tag (vc_block, (gchar *)l->data);
        }

        // Add the block to the the chain (so we don't need to free the block)
        FLAC__metadata_iterator_insert_block_after(iter, vc_block);
    }



    //
    // Create and insert PICTURE blocks
    //

    /***********
     * Picture *
     ***********/
    {
        EtPicture *pic = FileTag->picture;

        while (pic)
        {
            /* TODO: Can this ever be NULL? */
            if (pic->bytes)
            {
                const gchar *violation;
                FLAC__StreamMetadata *picture_block; // For picture data
                Picture_Format format;
                gconstpointer data;
                gsize data_size;

                // Allocate block for picture data
                picture_block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE);

                // Type
                picture_block->data.picture.type = pic->type;

                // Mime type
                format = Picture_Format_From_Data(pic);
                /* Safe to pass a const string, according to the FLAC API
                 * reference. */
                FLAC__metadata_object_picture_set_mime_type(picture_block, (gchar *)Picture_Mime_Type_String(format), TRUE);

                // Description
                if (pic->description)
                {
                    FLAC__metadata_object_picture_set_description(picture_block, (FLAC__byte *)pic->description, TRUE);
                }

                // Resolution
                picture_block->data.picture.width  = pic->width;
                picture_block->data.picture.height = pic->height;
                picture_block->data.picture.depth  = 0;

                /* Picture data. */
                data = g_bytes_get_data (pic->bytes, &data_size);
                /* Safe to pass const data, if the last argument (copy) is
                 * TRUE, according the the FLAC API reference. */
                FLAC__metadata_object_picture_set_data (picture_block,
                                                        (FLAC__byte *)data,
                                                        (FLAC__uint32)data_size,
                                                        true);

                if (!FLAC__metadata_object_picture_is_legal (picture_block,
                        &violation))
                {
                    g_critical ("Created an invalid picture block: ‘%s’",
                                violation);
                    FLAC__metadata_object_delete (picture_block);
                }
                else
                {
                    // Add the block to the the chain (so we don't need to free the block)
                    FLAC__metadata_iterator_insert_block_after(iter, picture_block);
                }
            }

            pic = pic->next;
        }
    }

    FLAC__metadata_iterator_delete (iter);

    //
    // Prepare for writing tag
    //

    FLAC__metadata_chain_sort_padding (chain);

    /* Write tag. */
    if (FLAC__metadata_chain_check_if_tempfile_needed (chain, true))
    {
        EtFlacWriteState temp_state;
        GFile *temp_file;
        GFileIOStream *temp_iostream;
        GError *temp_error = NULL;

        temp_file = g_file_new_tmp ("easytag-XXXXXX", &temp_iostream,
                                    &temp_error);

        if (temp_file == NULL)
        {
            FLAC__metadata_chain_delete (chain);
            g_propagate_error (error, temp_error);
            et_flac_write_close_func (&state);
            return FALSE;
        }

        temp_state.file = temp_file;
        temp_state.error = NULL;
        temp_state.istream = G_FILE_INPUT_STREAM (g_io_stream_get_input_stream (G_IO_STREAM (temp_iostream)));
        temp_state.ostream = G_FILE_OUTPUT_STREAM (g_io_stream_get_output_stream (G_IO_STREAM (temp_iostream)));
        temp_state.seekable = G_SEEKABLE (temp_iostream);
        temp_state.iostream = temp_iostream;

        if (!FLAC__metadata_chain_write_with_callbacks_and_tempfile (chain,
                true,
                &state,
                callbacks,
                &temp_state,
                callbacks))
        {
            const FLAC__Metadata_ChainStatus status = FLAC__metadata_chain_status (chain);
            flac_error_msg = FLAC__Metadata_ChainStatusString[status];

            FLAC__metadata_chain_delete (chain);
            et_flac_write_close_func (&temp_state);
            et_flac_write_close_func (&state);

            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                         _("Failed to write comments to file ‘%s’: %s"),
                         filename_utf8, flac_error_msg);
            return FALSE;
        }

        if (!g_file_move (temp_file, file, G_FILE_COPY_OVERWRITE, NULL, NULL,
                          NULL, &state.error))
        {
            FLAC__metadata_chain_delete (chain);
            et_flac_write_close_func (&temp_state);

            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                         _("Failed to write comments to file ‘%s’: %s"),
                         filename_utf8, state.error->message);
            et_flac_write_close_func (&state);
            return FALSE;
        }

        et_flac_write_close_func (&temp_state);
    }
    else
    {
        if (!FLAC__metadata_chain_write_with_callbacks (chain, true, &state,
                callbacks))
        {
            const FLAC__Metadata_ChainStatus status = FLAC__metadata_chain_status (chain);
            flac_error_msg = FLAC__Metadata_ChainStatusString[status];

            FLAC__metadata_chain_delete (chain);
            et_flac_write_close_func (&state);

            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                         _("Failed to write comments to file ‘%s’: %s"),
                         filename_utf8, flac_error_msg);
            return FALSE;
        }
    }

    FLAC__metadata_chain_delete (chain);
    et_flac_write_close_func (&state);

#ifdef ENABLE_MP3
    {
        // Delete the ID3 tags (create a dummy ETFile for the Id3tag_... function)
        ET_File   *ETFile_tmp    = ET_File_Item_New();
        File_Name *FileName_tmp = et_file_name_new ();
        File_Tag  *FileTag_tmp = et_file_tag_new ();
        // Same file...
        FileName_tmp->value      = g_strdup(filename);
        FileName_tmp->value_utf8 = g_strdup(filename_utf8); // Not necessary to fill 'value_ck'
        ETFile_tmp->FileNameList = g_list_append(NULL,FileName_tmp);
        ETFile_tmp->FileNameCur  = ETFile_tmp->FileNameList;
        // With empty tag...
        ETFile_tmp->FileTagList  = g_list_append(NULL,FileTag_tmp);
        ETFile_tmp->FileTag      = ETFile_tmp->FileTagList;
        id3tag_write_file_tag (ETFile_tmp, NULL);
        ET_Free_File_List_Item(ETFile_tmp);
    }
#endif

    return TRUE;
}
示例#7
0
GFileOutputStream *
_g_local_file_output_stream_replace (const char        *filename,
				     gboolean          readable,
				     const char        *etag,
				     gboolean           create_backup,
				     GFileCreateFlags   flags,
                                     GFileInfo         *reference_info,
				     GCancellable      *cancellable,
				     GError           **error)
{
  GLocalFileOutputStream *stream;
  int mode;
  int fd;
  char *temp_file;
  gboolean sync_on_close;
  int open_flags;

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return NULL;

  temp_file = NULL;

  mode = mode_from_flags_or_info (flags, reference_info);
  sync_on_close = FALSE;

  /* If the file doesn't exist, create it */
  open_flags = O_CREAT | O_EXCL | O_BINARY;
  if (readable)
    open_flags |= O_RDWR;
  else
    open_flags |= O_WRONLY;
  fd = g_open (filename, open_flags, mode);

  if (fd == -1 && errno == EEXIST)
    {
      /* The file already exists */
      fd = handle_overwrite_open (filename, readable, etag,
                                  create_backup, &temp_file,
                                  flags, reference_info,
                                  cancellable, error);
      if (fd == -1)
	return NULL;

      /* If the final destination exists, we want to sync the newly written
       * file to ensure the data is on disk when we rename over the destination.
       * otherwise if we get a system crash we can lose both the new and the
       * old file on some filesystems. (I.E. those that don't guarantee the
       * data is written to the disk before the metadata.)
       */
      sync_on_close = TRUE;
    }
  else if (fd == -1)
    {
      set_error_from_open_errno (filename, error);
      return NULL;
    }
  
 
  stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL);
  stream->priv->fd = fd;
  stream->priv->sync_on_close = sync_on_close;
  stream->priv->tmp_filename = temp_file;
  if (create_backup)
    stream->priv->backup_filename = create_backup_filename (filename);
  stream->priv->original_filename =  g_strdup (filename);
  
  return G_FILE_OUTPUT_STREAM (stream);
}
示例#8
0
gboolean
wavpack_tag_write_file_tag (const ET_File *ETFile,
                            GError **error)
{
    WavpackStreamReader writer = { wavpack_read_bytes, wavpack_get_pos,
                                   wavpack_set_pos_abs, wavpack_set_pos_rel,
                                   wavpack_push_back_byte, wavpack_get_length,
                                   wavpack_can_seek, wavpack_write_bytes };
    GFile *file;
    EtWavpackWriteState state;
    const gchar *filename;
    const File_Tag *FileTag;
    WavpackContext *wpc;
    gchar message[80];
    gchar *buffer;

    g_return_val_if_fail (ETFile != NULL && ETFile->FileTag != NULL, FALSE);
    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

    filename = ((File_Name *)((GList *)ETFile->FileNameCur)->data)->value;
    FileTag = (File_Tag *)ETFile->FileTag->data;

    file = g_file_new_for_path (filename);
    state.error = NULL;
    state.iostream = g_file_open_readwrite (file, NULL, &state.error);
    g_object_unref (file);

    if (!state.iostream)
    {
        g_propagate_error (error, state.error);
        return FALSE;
    }

    state.istream = G_FILE_INPUT_STREAM (g_io_stream_get_input_stream (G_IO_STREAM (state.iostream)));
    state.ostream = G_FILE_OUTPUT_STREAM (g_io_stream_get_output_stream (G_IO_STREAM (state.iostream)));
    state.seekable = G_SEEKABLE (state.iostream);

    /* NULL for the WavPack correction file. */
    wpc = WavpackOpenFileInputEx (&writer, &state, NULL, message,
                                  OPEN_EDIT_TAGS, 0);

    if (wpc == NULL)
    {
        if (state.error)
        {
            g_propagate_error (error, state.error);
        }
        else
        {
            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s",
                         message);
        }

        g_object_unref (state.iostream);
        return FALSE;
    }

    /* Title. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "title", FileTag->title))
    {
        goto err;
    }

    /* Artist. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "artist", FileTag->artist))
    {
        goto err;
    }

    /* Album artist. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "album artist",
                                               FileTag->album_artist))
    {
        goto err;
    }

    /* Album. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "album", FileTag->album))
    {
        goto err;
    }

    /* Discnumber. */
    if (FileTag->disc_number && FileTag->disc_total)
    {
        buffer = g_strdup_printf ("%s/%s", FileTag->disc_number,
                                  FileTag->disc_total);

        if (!et_wavpack_append_or_delete_tag_item (wpc, "part", buffer))
        {
            g_free (buffer);
            goto err;
        }
        else
        {
            g_free (buffer);
        }
    }
    else
    {
        if (!et_wavpack_append_or_delete_tag_item (wpc, "part",
                                                   FileTag->disc_number))
        {
            goto err;
        }
    }

    /* Year. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "year", FileTag->year))
    {
        goto err;
    }

    /* Tracknumber + tracktotal. */
    if (FileTag->track_total)
    {
        buffer = g_strdup_printf ("%s/%s", FileTag->track,
                                  FileTag->track_total);

        if (!et_wavpack_append_or_delete_tag_item (wpc, "track", buffer))
        {
            g_free (buffer);
            goto err;
        }
        else
        {
            g_free (buffer);
        }
    }
    else
    {
        if (!et_wavpack_append_or_delete_tag_item (wpc, "track",
                                                   FileTag->track))
        {
            goto err;
        }
    }

    /* Genre. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "genre", FileTag->genre))
    {
        goto err;
    }

    /* Comment. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "comment", FileTag->comment))
    {
        goto err;
    }

    /* Composer. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "composer",
                                               FileTag->composer))
    {
        goto err;
    }

    /* Original artist. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "original artist",
                                               FileTag->orig_artist))
    {
        goto err;
    }

    /* Copyright. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "copyright",
                                               FileTag->copyright))
    {
        goto err;
    }

    /* URL. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "copyright url",
                                               FileTag->url))
    {
        goto err;
    }

    /* Encoded by. */
    if (!et_wavpack_append_or_delete_tag_item (wpc, "encoded by",
                                               FileTag->encoded_by))
    {
        goto err;
    }

    if (WavpackWriteTag (wpc) == 0)
    {
        goto err;
    }

    WavpackCloseFile (wpc);

    g_object_unref (state.iostream);

    return TRUE;

err:
    g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s",
                 WavpackGetErrorMessage (wpc));
    WavpackCloseFile (wpc);
    return FALSE;
}
示例#9
0
文件: gvfs-save.c 项目: vikoadi/gvfs
static gboolean
save (GFile *file)
{
  GOutputStream *out;
  GFileCreateFlags flags;
  char buffer[1025];
  char *p;
  gssize res;
  gboolean close_res;
  GError *error;
  gboolean save_res;

  error = NULL;

  flags = priv ? G_FILE_CREATE_PRIVATE : G_FILE_CREATE_NONE;
  flags |= replace_dest ? G_FILE_CREATE_REPLACE_DESTINATION : 0;

  if (create)
    out = (GOutputStream *)g_file_create (file, flags, NULL, &error);
  else if (append)
    out = (GOutputStream *)g_file_append_to (file, flags, NULL, &error);
  else
    out = (GOutputStream *)g_file_replace (file, etag, backup, flags, NULL, &error);
  if (out == NULL)
    {
      g_printerr (_("Error opening file: %s\n"), error->message);
      g_error_free (error);
      return FALSE;
    }

  save_res = TRUE;

  while (1)
    {
      res = read (STDIN_FILENO, buffer, 1024);
      if (res > 0)
	{
	  ssize_t written;

	  p = buffer;
	  while (res > 0)
	    {
	      error = NULL;
	      written = g_output_stream_write (out, p, res, NULL, &error);
	      if (written == -1)
		{
		  save_res = FALSE;
		  g_printerr ("Error writing to stream: %s", error->message);
		  g_error_free (error);
		  goto out;
		}
	      res -= written;
	      p += written;
	    }
	}
      else if (res < 0)
	{
	  save_res = FALSE;
	  perror (_("Error reading stdin"));
	  break;
	}
      else if (res == 0)
	break;
    }

 out:

  close_res = g_output_stream_close (out, NULL, &error);
  if (!close_res)
    {
      save_res = FALSE;
      g_printerr (_("Error closing: %s\n"), error->message);
      g_error_free (error);
    }

  if (close_res && print_etag)
    {
      char *etag;
      etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (out));

      if (etag)
	g_print ("Etag: %s\n", etag);
      else
	/* Translators: The "etag" is a token allowing to verify whether a file has been modified */
	g_print (_("Etag not available\n"));
      g_free (etag);
    }

  g_object_unref (out);

  return save_res;
}
示例#10
0
GFileOutputStream *
_g_local_file_output_stream_replace (const char        *filename,
				     gboolean          readable,
				     const char        *etag,
				     gboolean           create_backup,
				     GFileCreateFlags   flags,
				     GCancellable      *cancellable,
				     GError           **error)
{
  GLocalFileOutputStream *stream;
  int mode;
  int fd;
  char *temp_file;
  gboolean sync_on_close;
  int open_flags;

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return NULL;

  temp_file = NULL;

  if (flags & G_FILE_CREATE_PRIVATE)
    mode = 0600;
  else
    mode = 0666;
  sync_on_close = FALSE;

  /* If the file doesn't exist, create it */
  open_flags = O_CREAT | O_EXCL | O_BINARY;
  if (readable)
    open_flags |= O_RDWR;
  else
    open_flags |= O_WRONLY;
  fd = g_open (filename, open_flags, mode);

  if (fd == -1 && errno == EEXIST)
    {
      /* The file already exists */
      fd = handle_overwrite_open (filename, readable, etag,
				  create_backup, &temp_file,
				  flags, cancellable, error);
      if (fd == -1)
	return NULL;

      /* If the final destination exists, we want to sync the newly written
       * file to ensure the data is on disk when we rename over the destination.
       * otherwise if we get a system crash we can lose both the new and the
       * old file on some filesystems. (I.E. those that don't guarantee the
       * data is written to the disk before the metadata.)
       */
      sync_on_close = TRUE;
    }
  else if (fd == -1)
    {
      int errsv = errno;

      if (errsv == EINVAL)
	/* This must be an invalid filename, on e.g. FAT */
	g_set_error_literal (error, G_IO_ERROR,
                             G_IO_ERROR_INVALID_FILENAME,
                             _("Invalid filename"));
      else
	{
	  char *display_name = g_filename_display_name (filename);
	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error opening file '%s': %s"),
		       display_name, g_strerror (errsv));
	  g_free (display_name);
	}
      return NULL;
    }
  
 
  stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL);
  stream->priv->fd = fd;
  stream->priv->sync_on_close = sync_on_close;
  stream->priv->tmp_filename = temp_file;
  if (create_backup)
    stream->priv->backup_filename = create_backup_filename (filename);
  stream->priv->original_filename =  g_strdup (filename);
  
  return G_FILE_OUTPUT_STREAM (stream);
}