⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codec.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * codec.c - basic codec interface implementation * * Copyright (C) 2001 Stefan Jahn <stefan@lkcc.org> * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. *  * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this package; see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA.   * * $Id: codec.c,v 1.2 2001/10/08 13:02:54 ela Exp $ * */#if HAVE_CONFIG_H# include <config.h>#endif#define _GNU_SOURCE#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "libserveez/alloc.h"#include "libserveez/util.h"#include "libserveez/array.h"#include "libserveez/socket.h"#include "libserveez/codec/codec.h"/* Include codec headers if any. */#if HAVE_ZLIB#include "libserveez/codec/gzlib.h"#endif/* Collection of available encoder and decoder provided by the libcodec   archive or by external (shared) libraries. */static svz_array_t *svz_codecs = NULL;/* Find an appropriate codec for the given @var{description} and @var{type}   which can be either @code{SVZ_CODEC_ENCODER} or @code{SVZ_CODEC_DECODER}.   The function returns @code{NULL} if there is no such codec registered. */svz_codec_t *svz_codec_get (char *description, int type){  int i;  svz_codec_t *codec;  if (description == NULL)    return NULL;  svz_array_foreach (svz_codecs, codec, i)    {      if (strcmp (description, codec->description) == 0 &&	  type == codec->type)	return codec;    }  return NULL;}/* Prints the text representation of the list of known codecs registered    within the core library. This includes all encoder and decoder once ran   through @code{svz_codec_register()}. */voidsvz_codec_list (void){  int n;  svz_codec_t *codec;  fprintf (stderr, "--- list of available codecs ---");  /* Print encoder list. */  fprintf (stderr, "\n\tencoder:");  svz_array_foreach (svz_codecs, codec, n)    if (codec->type == SVZ_CODEC_ENCODER)      fprintf (stderr, " %s", codec->description);  /* Print decoder list. */  fprintf (stderr, "\n\tdecoder:");  svz_array_foreach (svz_codecs, codec, n)    if (codec->type == SVZ_CODEC_DECODER)      fprintf (stderr, " %s", codec->description);  fprintf (stderr, "\n");}/* This routine is called by @code{svz_boot()} and registers the builtin   codecs. */intsvz_codec_init (void){#if HAVE_ZLIB  svz_codec_register (&zlib_encoder);  svz_codec_register (&zlib_decoder);#endif /* HAVE_ZLIB */  return 0;}/* This routine is called by @code{svz_halt()} and destroys the list of   known codecs. */intsvz_codec_finalize (void){  if (svz_codecs)    {      svz_array_destroy (svz_codecs);      svz_codecs = NULL;    }  return 0;}/* Checks the given codec for validity. Return zero on success. */static intsvz_codec_check (svz_codec_t *codec){  if (codec == NULL || codec->description == NULL ||      (codec->type != SVZ_CODEC_DECODER && codec->type != SVZ_CODEC_ENCODER))    return -1;  return 0;}/* Register the given codec @var{codec}. Does not register invalid or    duplicate codecs. Returns zero on success, non-zero otherwise. */intsvz_codec_register (svz_codec_t *codec){  svz_codec_t *c;  int i;  /* Check validity of the codec. */  if (svz_codec_check (codec))    {      svz_log (LOG_ERROR, "cannot register invalid codec\n");      return -1;    }  /* Check for duplicate codecs. */  svz_array_foreach (svz_codecs, c, i)    {      if (strcmp (c->description, codec->description) == 0 &&	  c->type == codec->type)	{	  svz_log (LOG_ERROR, "cannot register duplicate codec `%s'\n",		   codec->description);	  return -1;	}    }  /* Add this codec to the list of known codecs. */  if (svz_codecs == NULL)    svz_codecs = svz_array_create (2);  svz_array_add (svz_codecs, codec);  svz_log (LOG_NOTICE, "registered `%s' %s\n", codec->description,	   codec->type == SVZ_CODEC_ENCODER ? "encoder" : "decoder");  return 0;}/* Removes the given codec @var{codec} from the list of known codecs. Returns   zero if the codec could be successfully removed, non-zero otherwise. */intsvz_codec_unregister (svz_codec_t *codec){  svz_codec_t *c;  int i;  /* Check validity of the codec. */  if (svz_codec_check (codec))    {      svz_log (LOG_ERROR, "cannot unregister invalid codec\n");      return -1;    }  /* Find codec within the list of known codecs. */  svz_array_foreach (svz_codecs, c, i)    {      if (strcmp (c->description, codec->description) == 0 &&	  c->type == codec->type)	{	  svz_array_del (svz_codecs, i);	  svz_log (LOG_NOTICE, "unregistered `%s' %s\n", codec->description,		   codec->type == SVZ_CODEC_ENCODER ? "encoder" : "decoder");	  return 0;	}    }  svz_log (LOG_ERROR, "cannot unregister codec `%s'\n",	   codec->description);  return -1;}/* The following four (4) macros are receive buffer switcher used in order   to apply the output buffer of the codec to the receive buffer of a socket   structure and to revert these changes. */#define svz_codec_set_recv_buffer(sock, data) \  do {                                        \    sock->recv_buffer = data->out_buffer;     \    sock->recv_buffer_size = data->out_size;  \    sock->recv_buffer_fill = data->out_fill;  \  } while (0)#define svz_codec_unset_recv_buffer(sock, data) \  do {                                          \    data->out_buffer = sock->recv_buffer;       \    data->out_size = sock->recv_buffer_size;    \    data->out_fill = sock->recv_buffer_fill;    \  } while (0)#define svz_codec_save_recv_buffer(sock, data) \  do {                                         \    data->in_buffer = sock->recv_buffer;       \    data->in_fill = sock->recv_buffer_fill;    \    data->in_size = sock->recv_buffer_size;    \  } while (0)#define svz_codec_restore_recv_buffer(sock, data) \  do {                                            \    sock->recv_buffer = data->in_buffer;          \    sock->recv_buffer_size = data->in_size;       \    sock->recv_buffer_fill = data->in_fill;       \  } while (0)/* Reverts the changes made in @code{svz_codec_sock_receive_setup()}. */static voidsvz_codec_sock_recv_revert (svz_socket_t *sock){  svz_codec_data_t *data = (svz_codec_data_t *) sock->recv_codec;  svz_codec_restore_recv_buffer (sock, data);  sock->check_request = data->check_request;  sock->disconnected_socket = data->disconnected_socket;  svz_free (data->out_buffer);  svz_free (sock->recv_codec);  sock->recv_codec = NULL;}/* Setup the given socket structure @var{sock} to decode or encode its   receive data via the codec @var{codec}. Therefore you must have setup   the @code{check_request} method previously. The function returns zero   on success, non-zero otherwise. */intsvz_codec_sock_receive_setup (svz_socket_t *sock, svz_codec_t *codec){  svz_codec_data_t *data;  if (sock->recv_codec != NULL)    return 0;  /* Setup internal codec data. */  data = svz_malloc (sizeof (svz_codec_data_t));  data->codec = codec;  data->flag = SVZ_CODEC_INIT;  data->config = data->data = NULL;  sock->recv_codec = data;  /* Save the given sockets receive buffer, @code{check_request} callback     and @code{disconnected_socket} callback if necessary. */  svz_codec_save_recv_buffer (sock, data);  data->check_request = sock->check_request;  sock->check_request = svz_codec_sock_receive;  if (sock->disconnected_socket != svz_codec_sock_disconnect)    {      data->disconnected_socket = sock->disconnected_socket;      sock->disconnected_socket = svz_codec_sock_disconnect;    }  /* Apply new receive buffer which is the output buffer of the codec. */  data->out_fill = 0;  data->out_size = sock->recv_buffer_size;  data->out_buffer = svz_malloc (data->out_size);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -