void totem_save_position (Totem *totem) { gint64 stream_length, position; char *pos_str; GFile *file; GError *error = NULL; if (totem->remember_position == FALSE) return; if (totem->mrl == NULL) return; stream_length = bacon_video_widget_get_stream_length (totem->bvw); position = bacon_video_widget_get_current_time (totem->bvw); file = g_file_new_for_uri (totem->mrl); /* Don't save if it's: * - a live stream * - too short to make saving useful * - too close to the beginning or end to make saving useful */ if (stream_length < SAVE_POSITION_THRESHOLD || (stream_length - position) < stream_length * SAVE_POSITION_END_THRESHOLD || position < stream_length * SAVE_POSITION_END_THRESHOLD) { g_debug ("not saving position because the video/track is too short"); /* Remove the attribute if it is currently set on the file; this ensures that if we start watching a stream and save the position * half-way through, then later continue watching it to the end, the mid-way saved position will be removed when we finish the * stream. Only do this for non-live streams. */ if (stream_length > 0) { g_file_set_attribute_string (file, SAVE_POSITION_FILE_ATTRIBUTE, "", G_FILE_QUERY_INFO_NONE, NULL, &error); if (error != NULL) { g_warning ("g_file_set_attribute_string failed: %s", error->message); g_error_free (error); } } g_object_unref (file); return; } g_debug ("saving position: %"G_GINT64_FORMAT, position); /* Save the position in the stream as a file attribute */ pos_str = g_strdup_printf ("%"G_GINT64_FORMAT, position); g_file_set_attribute_string (file, SAVE_POSITION_FILE_ATTRIBUTE, pos_str, G_FILE_QUERY_INFO_NONE, NULL, &error); g_free (pos_str); if (error != NULL) { g_warning ("g_file_set_attribute_string failed: %s", error->message); g_error_free (error); } g_object_unref (file); }
IOChannel::IOChannel(const String& filePath, Type type) : m_path(filePath) , m_type(type) { auto path = WebCore::fileSystemRepresentation(filePath); GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(path.data())); switch (m_type) { case Type::Create: { g_file_delete(file.get(), nullptr, nullptr); m_outputStream = adoptGRef(G_OUTPUT_STREAM(g_file_create(file.get(), static_cast<GFileCreateFlags>(G_FILE_CREATE_PRIVATE), nullptr, nullptr))); ASSERT(m_outputStream); GUniquePtr<char> birthtimeString(g_strdup_printf("%" G_GUINT64_FORMAT, std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()))); g_file_set_attribute_string(file.get(), "xattr::birthtime", birthtimeString.get(), G_FILE_QUERY_INFO_NONE, nullptr, nullptr); break; } case Type::Write: { m_ioStream = adoptGRef(g_file_open_readwrite(file.get(), nullptr, nullptr)); ASSERT(m_ioStream); break; } case Type::Read: m_inputStream = adoptGRef(G_INPUT_STREAM(g_file_read(file.get(), nullptr, nullptr))); ASSERT(m_inputStream); break; } }
static gboolean set_etag_xattr(const char *fn, CurlDownloadOptions *cdo) { gboolean result = FALSE; GFile *file; file = g_file_new_for_path(fn); result = g_file_set_attribute_string(file, VIKING_ETAG_XATTR, cdo->new_etag, G_FILE_QUERY_INFO_NONE, NULL, NULL); g_object_unref(file); if (result) g_debug("%s: Set etag (xattr) on %s: %s", __FUNCTION__, fn, cdo->new_etag); return result; }