Packer.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:5k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: Packer.c,v 1.11 1999/01/19 02:24:20 wessels Exp $
  3.  *
  4.  * DEBUG: section 60    Packer: A uniform interface to store-like modules
  5.  * AUTHOR: Alex Rousskov
  6.  *
  7.  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
  8.  * ----------------------------------------------------------
  9.  *
  10.  *  Squid is the result of efforts by numerous individuals from the
  11.  *  Internet community.  Development is led by Duane Wessels of the
  12.  *  National Laboratory for Applied Network Research and funded by the
  13.  *  National Science Foundation.  Squid is Copyrighted (C) 1998 by
  14.  *  Duane Wessels and the University of California San Diego.  Please
  15.  *  see the COPYRIGHT file for full details.  Squid incorporates
  16.  *  software developed and/or copyrighted by other sources.  Please see
  17.  *  the CREDITS file for full details.
  18.  *
  19.  *  This program is free software; you can redistribute it and/or modify
  20.  *  it under the terms of the GNU General Public License as published by
  21.  *  the Free Software Foundation; either version 2 of the License, or
  22.  *  (at your option) any later version.
  23.  *  
  24.  *  This program is distributed in the hope that it will be useful,
  25.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  26.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27.  *  GNU General Public License for more details.
  28.  *  
  29.  *  You should have received a copy of the GNU General Public License
  30.  *  along with this program; if not, write to the Free Software
  31.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
  32.  *
  33.  */
  34. /*
  35.  * Rationale:
  36.  * ----------
  37.  * 
  38.  * OK, we have to major interfaces comm.c and store.c.
  39.  * 
  40.  * Store.c has a nice storeAppend[Printf] capability which makes "storing"
  41.  * things easy and painless. 
  42.  * 
  43.  * Comm.c lacks commAppend[Printf] because comm does not handle its own
  44.  * buffers (no mem_obj equivalent for comm.c).
  45.  * 
  46.  * Thus, if one wants to be able to store _and_ comm_write an object, s/he
  47.  * has to implement two almost identical functions.
  48.  * 
  49.  * Packer
  50.  * ------
  51.  * 
  52.  * Packer provides for a more uniform interface to store and comm modules.
  53.  * Packer has its own append and printf routines that "know" where to send
  54.  * incoming data. In case of store interface, Packer sends data to
  55.  * storeAppend.  Otherwise, Packer uses a MemBuf that can be flushed later to
  56.  * comm_write.
  57.  * 
  58.  * Thus, one can write just one function that will either "pack" things for
  59.  * comm_write or "append" things to store, depending on actual packer
  60.  * supplied.
  61.  * 
  62.  * It is amazing how much work a tiny object can save. :)
  63.  * 
  64.  */
  65. /*
  66.  * To-Do:
  67.  */
  68. #include "squid.h"
  69. /* local types */
  70. /* local routines */
  71. /* local constants and vars */
  72. /*
  73.  * We do have one potential problem here. Both append_f and vprintf_f types
  74.  * cannot match real functions precisely (at least because of the difference in
  75.  * the type of the first parameter). Thus, we have to use type cast. If somebody
  76.  * changes the prototypes of real functions, Packer will not notice that because
  77.  * of the type cast.
  78.  *
  79.  * Solution: we use the constants below to *hard code* current prototypes of
  80.  * real functions. If real prototypes change, these constants will produce a
  81.  * warning (e.g., "warning: assignment from incompatible pointer type").
  82.  */
  83. /* append()'s */
  84. static void (*const store_append) (StoreEntry *, const char *, int) = &storeAppend;
  85. static void (*const memBuf_append) (MemBuf *, const char *, mb_size_t) = &memBufAppend;
  86. /* vprintf()'s */
  87. static void (*const store_vprintf) (StoreEntry *, const char *, va_list ap) = &storeAppendVPrintf;
  88. static void (*const memBuf_vprintf) (MemBuf *, const char *, va_list ap) = &memBufVPrintf;
  89. /* init/clean */
  90. /* init with this to forward data to StoreEntry */
  91. void
  92. packerToStoreInit(Packer * p, StoreEntry * e)
  93. {
  94.     assert(p && e);
  95.     p->append = (append_f) store_append;
  96.     p->vprintf = (vprintf_f) store_vprintf;
  97.     p->real_handler = e;
  98. }
  99. /* init with this to accumulate data in MemBuf */
  100. void
  101. packerToMemInit(Packer * p, MemBuf * mb)
  102. {
  103.     assert(p && mb);
  104.     p->append = (append_f) memBuf_append;
  105.     p->vprintf = (vprintf_f) memBuf_vprintf;
  106.     p->real_handler = mb;
  107. }
  108. /* call this when you are done */
  109. void
  110. packerClean(Packer * p)
  111. {
  112.     assert(p);
  113.     /* it is not really necessary to do this, but, just in case... */
  114.     p->append = NULL;
  115.     p->vprintf = NULL;
  116.     p->real_handler = NULL;
  117. }
  118. void
  119. packerAppend(Packer * p, const char *buf, int sz)
  120. {
  121.     assert(p);
  122.     assert(p->real_handler && p->append);
  123.     p->append(p->real_handler, buf, sz);
  124. }
  125. #if STDC_HEADERS
  126. void
  127. packerPrintf(Packer * p, const char *fmt,...)
  128. {
  129.     va_list args;
  130.     va_start(args, fmt);
  131. #else
  132. void
  133. packerPrintf(va_alist)
  134.      va_dcl
  135. {
  136.     va_list args;
  137.     Packer *p = NULL;
  138.     const char *fmt = NULL;
  139.     int sz = 0;
  140.     va_start(args);
  141.     p = va_arg(args, Packer *);
  142.     fmt = va_arg(args, char *);
  143. #endif
  144.     assert(p);
  145.     assert(p->real_handler && p->vprintf);
  146.     p->vprintf(p->real_handler, fmt, args);
  147.     va_end(args);
  148. }