]> git.ipfire.org Git - thirdparty/squid.git/blob - src/Packer.cc
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / src / Packer.cc
1
2 /*
3 * $Id$
4 *
5 * DEBUG: section 60 Packer: A uniform interface to store-like modules
6 * AUTHOR: Alex Rousskov
7 *
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
10 *
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.
19 *
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.
24 *
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.
29 *
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.
33 *
34 */
35
36 /*
37 * Rationale:
38 * ----------
39 *
40 * OK, we have to major interfaces comm.c and store.c.
41 *
42 * Store.c has a nice storeAppend[Printf] capability which makes "storing"
43 * things easy and painless.
44 *
45 * Comm.c lacks commAppend[Printf] because comm does not handle its own
46 * buffers (no mem_obj equivalent for comm.c).
47 *
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.
50 *
51 * Packer
52 * ------
53 *
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
58 * Comm::Write.
59 *
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
62 * supplied.
63 *
64 * It is amazing how much work a tiny object can save. :)
65 *
66 */
67
68
69 /*
70 * To-Do:
71 */
72
73
74 #include "squid-old.h"
75 #include "Store.h"
76 #include "MemBuf.h"
77
78 /* local types */
79
80 /* local routines */
81
82 /* local constants and vars */
83
84 /*
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
89 * of the type cast.
90 *
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").
94 */
95
96 static void
97 memBufAppend(MemBuf *mb, const char *buf, mb_size_t len)
98 {
99 mb->append(buf, len);
100 }
101
102 static void
103 memBufVPrintf(MemBuf * mb, const char *fmt, va_list vargs)
104 {
105 mb->vPrintf(fmt, vargs);
106 }
107
108 static void
109 storeEntryAppend(StoreEntry *e, const char *buf, int len)
110 {
111 e->append(buf, len);
112 }
113
114
115 /* append()'s */
116 static void (*const store_append) (StoreEntry *, const char *, int) = &storeEntryAppend;
117 static void (*const memBuf_append) (MemBuf *, const char *, mb_size_t) = &memBufAppend;
118
119 /* vprintf()'s */
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;
122
123
124 /* init/clean */
125
126 /* init with this to forward data to StoreEntry */
127 void
128 packerToStoreInit(Packer * p, StoreEntry * e)
129 {
130 assert(p && e);
131 p->append = (append_f) store_append;
132 p->packer_vprintf = (vprintf_f) store_vprintf;
133 p->real_handler = e;
134 e->buffer();
135 }
136
137 /* init with this to accumulate data in MemBuf */
138 void
139 packerToMemInit(Packer * p, MemBuf * mb)
140 {
141 assert(p && mb);
142 p->append = (append_f) memBuf_append;
143 p->packer_vprintf = (vprintf_f) memBuf_vprintf;
144 p->real_handler = mb;
145 }
146
147 /* call this when you are done */
148 void
149 packerClean(Packer * p)
150 {
151 assert(p);
152
153 if (p->append == (append_f) store_append && p->real_handler)
154 static_cast<StoreEntry*>(p->real_handler)->flush();
155
156 /* it is not really necessary to do this, but, just in case... */
157 p->append = NULL;
158 p->packer_vprintf = NULL;
159 p->real_handler = NULL;
160 }
161
162 void
163 packerAppend(Packer * p, const char *buf, int sz)
164 {
165 assert(p);
166 assert(p->real_handler && p->append);
167 p->append(p->real_handler, buf, sz);
168 }
169
170 void
171 packerPrintf(Packer * p, const char *fmt,...)
172 {
173 va_list args;
174 va_start(args, fmt);
175
176 assert(p);
177 assert(p->real_handler && p->packer_vprintf);
178 p->packer_vprintf(p->real_handler, fmt, args);
179 va_end(args);
180 }