]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/Packer.cc
5 * DEBUG: section 60 Packer: A uniform interface to store-like modules
6 * AUTHOR: Alex Rousskov
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
40 * OK, we have to major interfaces comm.c and store.c.
42 * Store.c has a nice storeAppend[Printf] capability which makes "storing"
43 * things easy and painless.
45 * Comm.c lacks commAppend[Printf] because comm does not handle its own
46 * buffers (no mem_obj equivalent for comm.c).
48 * Thus, if one wants to be able to store _and_ Comm::Write an object, s/he
49 * has to implement two almost identical functions.
54 * Packer provides for a more uniform interface to store and comm modules.
55 * Packer has its own append and printf routines that "know" where to send
56 * incoming data. In case of store interface, Packer sends data to
57 * storeAppend. Otherwise, Packer uses a MemBuf that can be flushed later to
60 * Thus, one can write just one function that will either "pack" things for
61 * Comm::Write or "append" things to store, depending on actual packer
64 * It is amazing how much work a tiny object can save. :)
82 /* local constants and vars */
85 * We do have one potential problem here. Both append_f and vprintf_f types
86 * cannot match real functions precisely (at least because of the difference in
87 * the type of the first parameter). Thus, we have to use type cast. If somebody
88 * changes the prototypes of real functions, Packer will not notice that because
91 * Solution: we use the constants below to *hard code* current prototypes of
92 * real functions. If real prototypes change, these constants will produce a
93 * warning (e.g., "warning: assignment from incompatible pointer type").
97 memBufAppend(MemBuf
*mb
, const char *buf
, mb_size_t len
)
103 memBufVPrintf(MemBuf
* mb
, const char *fmt
, va_list vargs
)
105 mb
->vPrintf(fmt
, vargs
);
109 storeEntryAppend(StoreEntry
*e
, const char *buf
, int len
)
116 static void (*const store_append
) (StoreEntry
*, const char *, int) = &storeEntryAppend
;
117 static void (*const memBuf_append
) (MemBuf
*, const char *, mb_size_t
) = &memBufAppend
;
120 static void (*const store_vprintf
) (StoreEntry
*, const char *, va_list ap
) = &storeAppendVPrintf
;
121 static void (*const memBuf_vprintf
) (MemBuf
*, const char *, va_list ap
) = &memBufVPrintf
;
126 /* init with this to forward data to StoreEntry */
128 packerToStoreInit(Packer
* p
, StoreEntry
* e
)
131 p
->append
= (append_f
) store_append
;
132 p
->packer_vprintf
= (vprintf_f
) store_vprintf
;
137 /* init with this to accumulate data in MemBuf */
139 packerToMemInit(Packer
* p
, MemBuf
* mb
)
142 p
->append
= (append_f
) memBuf_append
;
143 p
->packer_vprintf
= (vprintf_f
) memBuf_vprintf
;
144 p
->real_handler
= mb
;
147 /* call this when you are done */
149 packerClean(Packer
* p
)
153 if (p
->append
== (append_f
) store_append
&& p
->real_handler
)
154 static_cast<StoreEntry
*>(p
->real_handler
)->flush();
156 /* it is not really necessary to do this, but, just in case... */
158 p
->packer_vprintf
= NULL
;
159 p
->real_handler
= NULL
;
163 packerAppend(Packer
* p
, const char *buf
, int sz
)
166 assert(p
->real_handler
&& p
->append
);
167 p
->append(p
->real_handler
, buf
, sz
);
171 packerPrintf(Packer
* p
, const char *fmt
,...)
177 assert(p
->real_handler
&& p
->packer_vprintf
);
178 p
->packer_vprintf(p
->real_handler
, fmt
, args
);