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 + -
显示快捷键?