st-cache.c
来自「linux下网络收音机的源码」· C语言 代码 · 共 1,444 行 · 第 1/3 页
C
1,444 行
parent_name); } else goto error; end: g_hash_table_destroy(parents); if (category_bag) g_object_unref(category_bag); g_free(parent_name); if (categories) { if (g_io_channel_shutdown(channel, TRUE, err) != G_IO_STATUS_NORMAL) { sg_objects_free_node(categories); categories = NULL; } } else g_io_channel_shutdown(channel, FALSE, NULL); g_io_channel_unref(channel); return categories; error: sg_objects_free_node(categories); categories = NULL; goto end;}static voidst_cache_append_category (STHandler *handler, GHashTable *parents, GNode *categories, STCategoryBag *category_bag, const char *parent_name){ g_return_if_fail(ST_IS_HANDLER(handler)); g_return_if_fail(parents != NULL); g_return_if_fail(categories != NULL); g_return_if_fail(ST_IS_CATEGORY_BAG(category_bag)); if (! ST_CATEGORY_BAG_IS_STOCK(category_bag)) { GNode *parent = NULL; GNode *node = NULL; if (parent_name) { parent = g_hash_table_lookup(parents, parent_name); if (! parent) { st_handler_notice(handler, _("categories cache: parent category \"%s\" not found"), parent_name); return; } } if (! parent) parent = categories; node = g_node_append_data(parent, g_object_ref(category_bag)); g_hash_table_insert(parents, ST_CATEGORY(category_bag)->name, node); }}gbooleanst_cache_has_streams (STHandler *handler, const char *category_name){ char *filename; GIOChannel *channel; g_return_val_if_fail(ST_IS_HANDLER(handler), FALSE); g_return_val_if_fail(category_name != NULL, FALSE); filename = st_cache_get_streams_filename(handler, category_name); channel = st_cache_io_channel_new_streams(handler, 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;}STStreamStore *st_cache_load_streams (STHandler *handler, const char *category_name, STCacheLoadStreamsProgressCallback progress_cb, gpointer progress_data, GError **err){ char *filename; GIOChannel *channel; STStreamStore *streams; STStreamBag *stream_bag = NULL; StreamAtom atom; int n_streams; int n = 0; GIOStatus io_status; g_return_val_if_fail(ST_IS_HANDLER(handler), NULL); g_return_val_if_fail(category_name != NULL, NULL); filename = st_cache_get_streams_filename(handler, category_name); channel = st_cache_io_channel_new_streams(handler, filename, OPEN_MODE_READ, err); g_free(filename); if (! channel) return NULL; streams = st_stream_store_new(handler); if (! st_cache_read_int(channel, &n_streams, err)) goto error; while ((io_status = g_io_channel_read_chars(channel, (char *) &atom, sizeof(atom), NULL, err)) == G_IO_STATUS_NORMAL) { switch (atom) { case ATOM_STREAM_NAME: { char *name; if (progress_cb) { if (progress_cb(++n, n_streams, progress_data)) goto error; /* aborted by callback */ } if (stream_bag) { st_stream_store_append(streams, stream_bag); g_object_unref(stream_bag); stream_bag = NULL; } if (! st_cache_read_string(channel, &name, err)) goto error; stream_bag = st_stream_bag_new(handler); ST_STREAM(stream_bag)->name = name; break; } case ATOM_STREAM_FIELDS: if (stream_bag) { int n_fields; GSList *iter; int i; if (! st_cache_read_int(channel, &n_fields, err)) goto error; iter = st_handler_get_fields(stream_bag->handler); for (i = 0; i < n_fields; i++) { STHandlerField *field = NULL; while (! field && iter) { if (! ST_HANDLER_FIELD_IS_VOLATILE(iter->data)) field = iter->data; iter = iter->next; } if (field) { GValue value = { 0, }; if (! st_cache_load_value(channel, &value, err)) goto error; if (G_IS_VALUE(&value)) { if (G_VALUE_HOLDS(&value, st_handler_field_get_type(field))) st_stream_bag_set_field(stream_bag, field, &value); else st_handler_notice(handler, _("streams cache of category \"%s\": invalid value type"), category_name); g_value_unset(&value); } } else st_handler_notice(handler, _("streams cache of category \"%s\": too many stream fields"), category_name); } } else { g_set_error(err, 0, 0, _("orphan stream fields")); goto error; } break; default: g_set_error(err, 0, 0, _("unknown atom %i"), atom); goto error; } } if (io_status == G_IO_STATUS_EOF) { if (stream_bag) st_stream_store_append(streams, stream_bag); } else goto error; end: if (stream_bag) g_object_unref(stream_bag); if (streams) { if (g_io_channel_shutdown(channel, TRUE, err) != G_IO_STATUS_NORMAL) { g_object_unref(streams); streams = NULL; } } else g_io_channel_shutdown(channel, FALSE, NULL); g_io_channel_unref(channel); return streams; error: g_object_unref(streams); streams = NULL; goto end;}static gbooleanst_cache_load_value (GIOChannel *channel, GValue *value, GError **err){ int type; g_return_val_if_fail(channel != NULL, FALSE); g_return_val_if_fail(value != NULL, FALSE); if (! st_cache_read_int(channel, &type, err)) return FALSE; switch (type) { case VALUE_TYPE_BOOLEAN: { gboolean val; if (! st_cache_read_int(channel, &val, err)) return FALSE; g_value_init(value, G_TYPE_BOOLEAN); g_value_set_boolean(value, val); return TRUE; } case VALUE_TYPE_INT: { int val; if (! st_cache_read_int(channel, &val, err)) return FALSE; g_value_init(value, G_TYPE_INT); g_value_set_int(value, val); return TRUE; } case VALUE_TYPE_UINT: { int val; if (! st_cache_read_int(channel, &val, err)) return FALSE; g_value_init(value, G_TYPE_UINT); g_value_set_uint(value, val); return TRUE; } case VALUE_TYPE_DOUBLE: { double val; if (! st_cache_read_double(channel, &val, err)) return FALSE; g_value_init(value, G_TYPE_DOUBLE); g_value_set_double(value, val); return TRUE; } case VALUE_TYPE_STRING: { char *val; if (! st_cache_read_string(channel, &val, err)) return FALSE; g_value_init(value, G_TYPE_STRING); g_value_take_string(value, val); return TRUE; } case VALUE_TYPE_VALUE_ARRAY: { int n_values; GValueArray *value_array; int i; if (! st_cache_read_int(channel, &n_values, err)) return FALSE; value_array = g_value_array_new(n_values); for (i = 0; i < n_values; i++) { GValue this_value = { 0, }; if (! st_cache_load_value(channel, &this_value, err)) { g_value_array_free(value_array); return FALSE; } g_value_array_append(value_array, &this_value); g_value_unset(&this_value); } g_value_init(value, G_TYPE_VALUE_ARRAY); g_value_take_boxed(value, value_array); return TRUE; } case VALUE_TYPE_PIXBUF: { char *buf; int len; gboolean status = TRUE; if (! st_cache_read_buffer(channel, &buf, &len, err)) return FALSE; if (len > 0) { GdkPixbufLoader *loader; loader = gdk_pixbuf_loader_new(); status = gdk_pixbuf_loader_write(loader, buf, len, err); if (status) { GdkPixbuf *pixbuf; pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); if (pixbuf) { g_value_init(value, GDK_TYPE_PIXBUF); g_value_set_object(value, pixbuf); } } gdk_pixbuf_loader_close(loader, NULL); } else g_value_init(value, GDK_TYPE_PIXBUF); g_free(buf); return status; } default: g_set_error(err, 0, 0, _("unknown value type %i"), type); return FALSE; }}static gbooleanst_cache_read_any (GIOChannel *channel, gpointer ptr, int len, GError **err){ char buf[len]; GIOStatus status; gsize bytes_read; g_return_val_if_fail(channel != NULL, FALSE); g_return_val_if_fail(ptr != NULL, FALSE); status = g_io_channel_read_chars(channel, buf, len, &bytes_read, err); if (status == G_IO_STATUS_NORMAL || status == G_IO_STATUS_EOF) { if (bytes_read == len) { memcpy(ptr, buf, len); return TRUE; } else g_set_error(err, 0, 0, _("unexpected end of file")); } return FALSE;}static gbooleanst_cache_read_buffer (GIOChannel *channel, char **buf, int *len, GError **err){ GIOStatus status; gsize bytes_read; int _len; char *_buf; g_return_val_if_fail(channel != NULL, FALSE); g_return_val_if_fail(buf != NULL, FALSE); if (! st_cache_read_int(channel, &_len, err)) return FALSE; _buf = g_new(char, _len + 1); status = g_io_channel_read_chars(channel, _buf, _len, &bytes_read, err); if (status == G_IO_STATUS_NORMAL || status == G_IO_STATUS_EOF) { if (bytes_read == _len) { *buf = _buf; if (len) *len = _len; _buf[_len] = 0; return TRUE; } else g_set_error(err, 0, 0, _("unexpected end of file")); } g_free(_buf); return FALSE;}static gbooleanst_cache_read_string (GIOChannel *channel, char **str, GError **err){ char *buf; g_return_val_if_fail(channel != NULL, FALSE); g_return_val_if_fail(str != NULL, FALSE); if (! st_cache_read_buffer(channel, &buf, NULL, err)) return FALSE; *str = buf; return TRUE;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?