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

📄 codec.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* Initialize the codec. */  if (codec->init (data) == SVZ_CODEC_ERROR)    {      svz_log (LOG_ERROR, "%s: init: %s\n", 	       codec->description, codec->error (data));      svz_codec_sock_recv_revert (sock);      return -1;    }  return 0;}/* This routine is the new @code{check_request} callback for reading codecs.   It is applied in the above @code{svz_codec_sock_receive_setup()} function.    Usually it gets called whenever there is data in the receive buffer. It    lets the current receive buffer be the input of the codec. The output    buffer of the codec gets the new receive buffer buffer of the socket    structure @var{sock}. The old @code{check_request} callback of @var{sock}   gets called afterwards. When leaving this functions the receive buffer    gets restored again with the bytes snipped consumed by the codec itself. */intsvz_codec_sock_receive (svz_socket_t *sock){  svz_codec_data_t *data = (svz_codec_data_t *) sock->recv_codec;  svz_codec_t *codec = data->codec;  int ret;  /* Run the encoder / decoder of the applied codec. */  data->flag = SVZ_CODEC_CODE;  if (sock->flags & SOCK_FLAG_FLUSH)    data->flag = SVZ_CODEC_FINISH;  svz_codec_save_recv_buffer (sock, data);  while ((ret = codec->code (data)) == SVZ_CODEC_MORE_OUT)    {      /* Resize output buffer if necessary. */      data->flag = SVZ_CODEC_FLUSH;      data->out_size *= 2;      data->out_buffer = svz_realloc (data->out_buffer, data->out_size);    }  /* Evaluate the return value of the codec. */  switch (ret)    {    case SVZ_CODEC_ERROR:    /* Error occurred. */      svz_log (LOG_ERROR, "%s: code: %s\n", 	       codec->description, codec->error (data));      return -1;    case SVZ_CODEC_FINISHED: /* Codec finished. */      if (codec->finalize (data) != SVZ_CODEC_OK)	{	  svz_log (LOG_ERROR, "%s: finalize: %s\n", 		   codec->description, codec->error (data));	}      break;    case SVZ_CODEC_OK:       /* No error. */      break;    case SVZ_CODEC_MORE_IN:  /* Needs more input data to continue. */      break;    default:                 /* Unhandled. */      svz_log (LOG_ERROR, "%s: code: invalid return value: %d\n",	       codec->description, ret);      break;    }  /* Call the saved @code{check_request} callback with the new receive      buffer which is the output buffer of the codec. */  svz_codec_set_recv_buffer (sock, data);  if ((ret = data->check_request (sock)))    {      svz_codec_unset_recv_buffer (sock, data);      return ret;    }  /* Save back changes made to the current receive buffer. */  svz_codec_unset_recv_buffer (sock, data);  /* Restore old receive buffer. */  svz_codec_restore_recv_buffer (sock, data);  return 0;}/* These are send buffer switcher used to apply the output buffer of a   sending codec to the send buffer of a socket structure and vice-versa. */#define svz_codec_set_send_buffer(sock, data) \  do {                                        \    sock->send_buffer = data->out_buffer;     \    sock->send_buffer_size = data->out_size;  \    sock->send_buffer_fill = data->out_fill;  \  } while (0)#define svz_codec_unset_send_buffer(sock, data) \  do {                                          \    data->out_buffer = sock->send_buffer;       \    data->out_size = sock->send_buffer_size;    \    data->out_fill = sock->send_buffer_fill;    \  } while (0)#define svz_codec_save_send_buffer(sock, data) \  do {                                         \    data->in_buffer = sock->send_buffer;       \    data->in_fill = sock->send_buffer_fill;    \    data->in_size = sock->send_buffer_size;    \  } while (0)#define svz_codec_restore_send_buffer(sock, data) \  do {                                            \    sock->send_buffer = data->in_buffer;          \    sock->send_buffer_size = data->in_size;       \    sock->send_buffer_fill = data->in_fill;       \  } while (0)/* Reverts the changes made in @code{svz_codec_sock_send_setup()}. */static voidsvz_codec_sock_send_revert (svz_socket_t *sock){  svz_codec_data_t *data = (svz_codec_data_t *) sock->send_codec;  svz_codec_restore_send_buffer (sock, data);  sock->check_request = data->check_request;  sock->disconnected_socket = data->disconnected_socket;  svz_free (data->out_buffer);  svz_free (sock->send_codec);  sock->send_codec = NULL;}/* Setup the socket structure @var{sock} for encoding or decoding its send   buffer via the given codec @var{codec}. Therefore you previously need to   assign the @code{write_socket} member of @var{sock} properly. The function   returns zero on success, non-zero otherwise. */intsvz_codec_sock_send_setup (svz_socket_t *sock, svz_codec_t *codec){  svz_codec_data_t *data;  /* Return here if there is already a codec registered. */  if (sock->send_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->send_codec = data;  /* Save the given sockets send buffer, the @code{write_socket} callback     and the @code{disconnected_socket} callback if necessary. */  svz_codec_save_send_buffer (sock, data);  data->write_socket = sock->write_socket;  sock->write_socket = svz_codec_sock_send;  if (sock->disconnected_socket != svz_codec_sock_disconnect)    {      data->disconnected_socket = sock->disconnected_socket;      sock->disconnected_socket = svz_codec_sock_disconnect;    }  /* Apply new send buffer which is the output buffer of the codec. */  data->out_fill = 0;  data->out_size = sock->send_buffer_size;  data->out_buffer = svz_malloc (data->out_size);  /* Initialize the codec. */  if (codec->init (data) == SVZ_CODEC_ERROR)    {      svz_log (LOG_ERROR, "%s: init: %s\n", 	       codec->description, codec->error (data));      svz_codec_sock_send_revert (sock);      return -1;    }  return 0;}/* This is a codec socket structures @var{sock} new @code{write_socket}   callback which is called whenever there is data within the send buffer   available and @var{sock} is scheduled for writing. It uses the current   send buffer as input buffer for the codec. The output buffer of the codec   is used to invoke the @code{write_socket} callback saved within   @code{svz_codec_sock_send_setup()}. After this the send buffer is    restored again without the bytes consumed by the codec. */intsvz_codec_sock_send (svz_socket_t *sock){  svz_codec_data_t *data = (svz_codec_data_t *) sock->send_codec;  svz_codec_t *codec = data->codec;  int ret;  /* Run the encoder / decoder of the applied codec. */  data->flag = SVZ_CODEC_CODE;  if (sock->flags & SOCK_FLAG_FLUSH)    data->flag = SVZ_CODEC_FINISH;  svz_codec_save_send_buffer (sock, data);  while ((ret = codec->code (data)) == SVZ_CODEC_MORE_OUT)    {      /* Resize output buffer if necessary. */      data->flag = SVZ_CODEC_FLUSH;      data->out_size *= 2;      data->out_buffer = svz_realloc (data->out_buffer, data->out_size);    }  /* Evaluate the return value of the codec. */  switch (ret)    {    case SVZ_CODEC_ERROR:    /* Error occurred. */      svz_log (LOG_ERROR, "%s: code: %s\n", 	       codec->description, codec->error (data));      return -1;    case SVZ_CODEC_FINISHED: /* Codec finished. */      if (codec->finalize (data) != SVZ_CODEC_OK)	{	  svz_log (LOG_ERROR, "%s: finalize: %s\n", 		   codec->description, codec->error (data));	}      break;    case SVZ_CODEC_OK:       /* No error. */      break;    case SVZ_CODEC_MORE_IN:  /* Needs more input data to continue. */      break;    default:                 /* Unhandled. */      svz_log (LOG_ERROR, "%s: code: invalid return value: %d\n",	       codec->description, ret);      break;    }  /* Call the saved @code{write_socket} callback with the new send      buffer which is the output buffer of the codec. */  svz_codec_set_send_buffer (sock, data);  if ((ret = data->write_socket (sock)))    {      svz_codec_unset_send_buffer (sock, data);      return ret;    }  /* Save back changes made to the current send buffer. */  svz_codec_unset_send_buffer (sock, data);  /* Restore old send buffer. */  svz_codec_restore_send_buffer (sock, data);  return 0;}/* This callback is used as the @code{disconnected_socket} callback of the   socket structure @var{sock}. It tries to release the resources of both   the receiving and sending codec of @var{sock}. The routine is called by   default if the codec socket structure @var{sock} gets disconnected for    some external reason. */intsvz_codec_sock_disconnect (svz_socket_t *sock){  svz_codec_data_t *data;  int (* disconnected) (svz_socket_t *);  disconnected = NULL;  /* Check and release receiving codec. */  if ((data = (svz_codec_data_t *) sock->recv_codec) != NULL)    {      disconnected = data->disconnected_socket;      data->codec->finalize (data);      svz_codec_sock_recv_revert (sock);    }  /* Check and release sending codec. */  if ((data = (svz_codec_data_t *) sock->send_codec) != NULL)    {      disconnected = data->disconnected_socket;      data->codec->finalize (data);      svz_codec_sock_send_revert (sock);    }  /* Run old @code{disconnected_socket} callback. */  if (disconnected != NULL)    return disconnected (sock);  return 0;}

⌨️ 快捷键说明

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