]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/Packer.cc
541ef04b11b43f5aef387b0396f0bd612ef1e50f
3 * DEBUG: section 60 Packer: A uniform interface to store-like modules
4 * AUTHOR: Alex Rousskov
6 * SQUID Web Proxy Cache http://www.squid-cache.org/
7 * ----------------------------------------------------------
9 * Squid is the result of efforts by numerous individuals from
10 * the Internet community; see the CONTRIBUTORS file for full
11 * details. Many organizations have provided support for Squid's
12 * development; see the SPONSORS file for full details. Squid is
13 * Copyrighted (C) 2001 by the Regents of the University of
14 * California; see the COPYRIGHT file for full details. Squid
15 * incorporates software developed and/or copyrighted by other
16 * sources; see the CREDITS file for full details.
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
38 * OK, we have to major interfaces comm.c and store.c.
40 * Store.c has a nice storeAppend[Printf] capability which makes "storing"
41 * things easy and painless.
43 * Comm.c lacks commAppend[Printf] because comm does not handle its own
44 * buffers (no mem_obj equivalent for comm.c).
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.
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
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
62 * It is amazing how much work a tiny object can save. :)
78 /* local constants and vars */
81 * We do have one potential problem here. Both append_f and vprintf_f types
82 * cannot match real functions precisely (at least because of the difference in
83 * the type of the first parameter). Thus, we have to use type cast. If somebody
84 * changes the prototypes of real functions, Packer will not notice that because
87 * Solution: we use the constants below to *hard code* current prototypes of
88 * real functions. If real prototypes change, these constants will produce a
89 * warning (e.g., "warning: assignment from incompatible pointer type").
93 memBufAppend(MemBuf
*mb
, const char *buf
, mb_size_t len
)
99 memBufVPrintf(MemBuf
* mb
, const char *fmt
, va_list vargs
)
101 mb
->vPrintf(fmt
, vargs
);
105 storeEntryAppend(StoreEntry
*e
, const char *buf
, int len
)
111 static void (*const store_append
) (StoreEntry
*, const char *, int) = &storeEntryAppend
;
112 static void (*const memBuf_append
) (MemBuf
*, const char *, mb_size_t
) = &memBufAppend
;
115 static void (*const store_vprintf
) (StoreEntry
*, const char *, va_list ap
) = &storeAppendVPrintf
;
116 static void (*const memBuf_vprintf
) (MemBuf
*, const char *, va_list ap
) = &memBufVPrintf
;
120 /* init with this to forward data to StoreEntry */
122 packerToStoreInit(Packer
* p
, StoreEntry
* e
)
125 p
->append
= (append_f
) store_append
;
126 p
->packer_vprintf
= (vprintf_f
) store_vprintf
;
131 /* init with this to accumulate data in MemBuf */
133 packerToMemInit(Packer
* p
, MemBuf
* mb
)
136 p
->append
= (append_f
) memBuf_append
;
137 p
->packer_vprintf
= (vprintf_f
) memBuf_vprintf
;
138 p
->real_handler
= mb
;
141 /* call this when you are done */
143 packerClean(Packer
* p
)
147 if (p
->append
== (append_f
) store_append
&& p
->real_handler
)
148 static_cast<StoreEntry
*>(p
->real_handler
)->flush();
150 /* it is not really necessary to do this, but, just in case... */
152 p
->packer_vprintf
= NULL
;
153 p
->real_handler
= NULL
;
157 packerAppend(Packer
* p
, const char *buf
, int sz
)
160 assert(p
->real_handler
&& p
->append
);
161 p
->append(p
->real_handler
, buf
, sz
);
165 packerPrintf(Packer
* p
, const char *fmt
,...)
171 assert(p
->real_handler
&& p
->packer_vprintf
);
172 p
->packer_vprintf(p
->real_handler
, fmt
, args
);