📄 packer.c
字号:
/* * $Id: Packer.c,v 1.11 1999/01/19 02:24:20 wessels Exp $ * * DEBUG: section 60 Packer: A uniform interface to store-like modules * AUTHOR: Alex Rousskov * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * * Squid is the result of efforts by numerous individuals from the * Internet community. Development is led by Duane Wessels of the * National Laboratory for Applied Network Research and funded by the * National Science Foundation. Squid is Copyrighted (C) 1998 by * Duane Wessels and the University of California San Diego. Please * see the COPYRIGHT file for full details. Squid incorporates * software developed and/or copyrighted by other sources. Please see * the CREDITS file for full details. * * This program 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 of the License, or * (at your option) any later version. * * This program 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 program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * *//* * Rationale: * ---------- * * OK, we have to major interfaces comm.c and store.c. * * Store.c has a nice storeAppend[Printf] capability which makes "storing" * things easy and painless. * * Comm.c lacks commAppend[Printf] because comm does not handle its own * buffers (no mem_obj equivalent for comm.c). * * Thus, if one wants to be able to store _and_ comm_write an object, s/he * has to implement two almost identical functions. * * Packer * ------ * * Packer provides for a more uniform interface to store and comm modules. * Packer has its own append and printf routines that "know" where to send * incoming data. In case of store interface, Packer sends data to * storeAppend. Otherwise, Packer uses a MemBuf that can be flushed later to * comm_write. * * Thus, one can write just one function that will either "pack" things for * comm_write or "append" things to store, depending on actual packer * supplied. * * It is amazing how much work a tiny object can save. :) * *//* * To-Do: */#include "squid.h"/* local types *//* local routines *//* local constants and vars *//* * We do have one potential problem here. Both append_f and vprintf_f types * cannot match real functions precisely (at least because of the difference in * the type of the first parameter). Thus, we have to use type cast. If somebody * changes the prototypes of real functions, Packer will not notice that because * of the type cast. * * Solution: we use the constants below to *hard code* current prototypes of * real functions. If real prototypes change, these constants will produce a * warning (e.g., "warning: assignment from incompatible pointer type"). *//* append()'s */static void (*const store_append) (StoreEntry *, const char *, int) = &storeAppend;static void (*const memBuf_append) (MemBuf *, const char *, mb_size_t) = &memBufAppend;/* vprintf()'s */static void (*const store_vprintf) (StoreEntry *, const char *, va_list ap) = &storeAppendVPrintf;static void (*const memBuf_vprintf) (MemBuf *, const char *, va_list ap) = &memBufVPrintf;/* init/clean *//* init with this to forward data to StoreEntry */voidpackerToStoreInit(Packer * p, StoreEntry * e){ assert(p && e); p->append = (append_f) store_append; p->vprintf = (vprintf_f) store_vprintf; p->real_handler = e;}/* init with this to accumulate data in MemBuf */voidpackerToMemInit(Packer * p, MemBuf * mb){ assert(p && mb); p->append = (append_f) memBuf_append; p->vprintf = (vprintf_f) memBuf_vprintf; p->real_handler = mb;}/* call this when you are done */voidpackerClean(Packer * p){ assert(p); /* it is not really necessary to do this, but, just in case... */ p->append = NULL; p->vprintf = NULL; p->real_handler = NULL;}voidpackerAppend(Packer * p, const char *buf, int sz){ assert(p); assert(p->real_handler && p->append); p->append(p->real_handler, buf, sz);}#if STDC_HEADERSvoidpackerPrintf(Packer * p, const char *fmt,...){ va_list args; va_start(args, fmt);#elsevoidpackerPrintf(va_alist) va_dcl{ va_list args; Packer *p = NULL; const char *fmt = NULL; int sz = 0; va_start(args); p = va_arg(args, Packer *); fmt = va_arg(args, char *);#endif assert(p); assert(p->real_handler && p->vprintf); p->vprintf(p->real_handler, fmt, args); va_end(args);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -