📄 st-cache.c
字号:
char *buf; gsize size; gboolean status; pixbuf = g_value_get_object(value); if (pixbuf) { if (! gdk_pixbuf_save_to_buffer(pixbuf, &buf, &size, "png", err, NULL)) return FALSE; } else { buf = NULL; size = 0; } status = st_cache_write_buffer(channel, buf, size, err); g_free(buf); if (! status) return FALSE; break; } default: g_return_val_if_reached(FALSE); } return TRUE;}static char *st_cache_get_filename (const char *str){ int i; GString *filename; g_return_val_if_fail(str != NULL, NULL); filename = g_string_new(NULL); for (i = 0; str[i]; i++) if (g_ascii_isalnum(str[i])) g_string_append_c(filename, str[i]); else g_string_append_printf(filename, "%%%.2X", str[i]); return g_string_free(filename, FALSE);}static char *st_cache_get_handler_directory (STHandler *handler){ char *handler_filename; char *dir; g_return_val_if_fail(ST_IS_HANDLER(handler), NULL); handler_filename = st_cache_get_filename(st_handler_get_name(handler)); dir = g_build_filename(st_settings.cache_dir, handler_filename, NULL); g_free(handler_filename); return dir;}static char *st_cache_get_categories_filename (STHandler *handler){ char *dir; char *filename; g_return_val_if_fail(ST_IS_HANDLER(handler), NULL); dir = st_cache_get_handler_directory(handler); filename = g_build_filename(dir, "_categories", NULL); g_free(dir); return filename;}static char *st_cache_get_streams_filename (STHandler *handler, const char *category_name){ char *dir; char *category_filename; char *filename; g_return_val_if_fail(ST_IS_HANDLER(handler), NULL); dir = st_cache_get_handler_directory(handler); category_filename = st_cache_get_filename(category_name); filename = g_build_filename(dir, category_filename, NULL); g_free(dir); g_free(category_filename); return filename;}static GIOChannel *st_cache_io_channel_new_file (const char *filename, OpenMode mode, int magic, int version, int subversion, GError **err){ GIOChannel *channel; g_return_val_if_fail(filename != NULL, NULL); channel = g_io_channel_new_file(filename, mode == OPEN_MODE_READ ? "r" : "w", err); if (! channel) return NULL; if (g_io_channel_set_encoding(channel, NULL, err) != G_IO_STATUS_NORMAL) goto error; switch (mode) { case OPEN_MODE_READ: { int file_magic; int file_version; if (! st_cache_read_int(channel, &file_magic, err)) goto error; if (file_magic != magic) { g_set_error(err, 0, 0, _("invalid magic number")); goto error; } if (! st_cache_read_int(channel, &file_version, err)) goto error; if (file_version != version) { g_set_error(err, 0, 0, _("invalid version number")); goto error; } if (subversion != -1) { int file_subversion; if (! st_cache_read_int(channel, &file_subversion, err)) goto error; if (file_subversion != subversion) { g_set_error(err, 0, 0, _("invalid subversion number")); goto error; } } break; } case OPEN_MODE_WRITE: if (! st_cache_write(channel, "ii", magic, version, err)) goto error; if (subversion != -1 && ! st_cache_write(channel, "i", subversion, err)) goto error; break; default: g_return_val_if_reached(NULL); } return channel; error: g_io_channel_shutdown(channel, FALSE, NULL); g_io_channel_unref(channel); return NULL;}static GIOChannel *st_cache_io_channel_new_categories (const char *filename, OpenMode mode, GError **err){ g_return_val_if_fail(filename != NULL, NULL); return st_cache_io_channel_new_file(filename, mode, CATEGORIES_MAGIC, CATEGORIES_VERSION, -1, err);}static GIOChannel *st_cache_io_channel_new_streams (STHandler *handler, const char *filename, OpenMode mode, GError **err){ g_return_val_if_fail(ST_IS_HANDLER(handler), NULL); g_return_val_if_fail(filename != NULL, NULL); return st_cache_io_channel_new_file(filename, mode, STREAMS_MAGIC, STREAMS_VERSION, st_handler_get_stream_version(handler), err);}static gbooleanst_cache_write (GIOChannel *channel, const char *format, ...){ va_list args; int i; GError *err = NULL; GError **real_err; g_return_val_if_fail(channel != NULL, FALSE); g_return_val_if_fail(format != NULL, FALSE); va_start(args, format); for (i = 0; format[i]; i++) switch (format[i]) { case 'i': { int val = va_arg(args, int); if (! st_cache_write_int(channel, val, &err)) goto error; break; } case 's': { const char *val = va_arg(args, const char *); if (! st_cache_write_string(channel, val, &err)) goto error; break; } case 'b': { int len = va_arg(args, int); const char *val = va_arg(args, const char *); if (! st_cache_write_buffer(channel, val, len, &err)) goto error; break; } default: g_return_val_if_reached(FALSE); } va_end(args); return TRUE; error: real_err = va_arg(args, GError **); g_propagate_error(real_err, err); va_end(args); return FALSE;}static gbooleanst_cache_write_int (GIOChannel *channel, int i, GError **err){ g_return_val_if_fail(channel != NULL, FALSE); return g_io_channel_write_chars(channel, (const char *) &i, sizeof(i), NULL, err) == G_IO_STATUS_NORMAL;}static gbooleanst_cache_write_double (GIOChannel *channel, double d, GError **err){ g_return_val_if_fail(channel != NULL, FALSE); return g_io_channel_write_chars(channel, (const char *) &d, sizeof(d), NULL, err) == G_IO_STATUS_NORMAL;}static gbooleanst_cache_write_buffer (GIOChannel *channel, const char *buf, int len, GError **err){ g_return_val_if_fail(channel != NULL, FALSE); if (! st_cache_write_int(channel, len, err)) return FALSE; return g_io_channel_write_chars(channel, buf, len, NULL, err) == G_IO_STATUS_NORMAL;}static gbooleanst_cache_write_string (GIOChannel *channel, const char *str, GError **err){ g_return_val_if_fail(channel != NULL, FALSE); return st_cache_write_buffer(channel, str, str ? strlen(str) : 0, err);}gbooleanst_cache_has_categories (STHandler *handler){ char *filename; GIOChannel *channel; g_return_val_if_fail(ST_IS_HANDLER(handler), FALSE); filename = st_cache_get_categories_filename(handler); channel = st_cache_io_channel_new_categories(filename, OPEN_MODE_READ, NULL); g_free(filename); if (channel) { g_io_channel_shutdown(channel, FALSE, NULL); g_io_channel_unref(channel); return TRUE; } else return FALSE;}GNode *st_cache_load_categories (STHandler *handler, GError **err){ char *filename; GIOChannel *channel; GHashTable *parents; GNode *categories; STCategoryBag *category_bag = NULL; char *parent_name = NULL; CategoryAtom atom; GIOStatus io_status; g_return_val_if_fail(ST_IS_HANDLER(handler), NULL); filename = st_cache_get_categories_filename(handler); channel = st_cache_io_channel_new_categories(filename, OPEN_MODE_READ, err); g_free(filename); if (! channel) return FALSE; parents = g_hash_table_new(g_str_hash, g_str_equal); categories = g_node_new(NULL); while ((io_status = g_io_channel_read_chars(channel, (char *) &atom, sizeof(atom), NULL, err)) == G_IO_STATUS_NORMAL) switch (atom) { case ATOM_CATEGORY_NAME: { char *name; if (category_bag) { st_cache_append_category(handler, parents, categories, category_bag, parent_name); g_object_unref(category_bag); category_bag = NULL; g_free(parent_name); parent_name = NULL; } if (! st_cache_read_string(channel, &name, err)) goto error; if (ST_CATEGORY_BAG_NAME_IS_STOCK(name)) { category_bag = st_handler_get_stock_category(handler, name); if (category_bag) g_object_ref(category_bag); else st_handler_notice(handler, _("categories cache: no such stock category \"%s\""), name); g_free(name); } else { category_bag = st_category_bag_new(handler); ST_CATEGORY(category_bag)->name = name; } break; } case ATOM_CATEGORY_FLAGS: { unsigned int flags; if (! st_cache_read_int(channel, &flags, err)) goto error; if (category_bag) category_bag->flags = flags; break; } case ATOM_CATEGORY_PARENT: if (parent_name) { g_set_error(err, 0, 0, _("parent name (\"%s\") already specified"), parent_name); goto error; } if (! st_cache_read_string(channel, &parent_name, err)) goto error; break; case ATOM_CATEGORY_LABEL: { char *label; if (! st_cache_read_string(channel, &label, err)) goto error; if (category_bag) { if (ST_CATEGORY(category_bag)->label) { g_free(label); g_set_error(err, 0, 0, _("label (\"%s\") already specified"), ST_CATEGORY(category_bag)->label); goto error; } ST_CATEGORY(category_bag)->label = label; } else g_free(label); break; } case ATOM_CATEGORY_URL_POSTFIX: { char *url_postfix; if (! st_cache_read_string(channel, &url_postfix, err)) goto error; if (category_bag) { if (ST_CATEGORY(category_bag)->url_postfix) { g_free(url_postfix); g_set_error(err, 0, 0, _("URL postfix (\"%s\") already specified"), ST_CATEGORY(category_bag)->url_postfix); goto error; } ST_CATEGORY(category_bag)->url_postfix = url_postfix; } else g_free(url_postfix); break; } default: g_set_error(err, 0, 0, _("unknown atom %i"), atom); goto error; } if (io_status == G_IO_STATUS_EOF) { if (category_bag) st_cache_append_category(handler, parents, categories, category_bag,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -