---------------------
PatchSet 5297 
Date: 2002/10/08 04:06:34
Author: rbcollins
Branch: rbcollins_cxxtest
Tag: (none) 
Log:
more conversions

Members: 
	src/CacheDigest.c:1.5.10.1->1.5.10.2(DEAD) 
	src/CacheDigest.cc:1.1->1.1.2.1 
	src/ETag.c:1.4->1.4.94.1(DEAD) 
	src/ETag.cc:1.1->1.1.2.1 
	src/HttpBody.c:1.4->1.4.96.1(DEAD) 
	src/HttpBody.cc:1.1->1.1.2.1 
	src/HttpHdrCc.c:1.5.96.2->1.5.96.3(DEAD) 
	src/HttpHdrCc.cc:1.1->1.1.2.1 
	src/HttpHeader.c:1.16.10.2->1.16.10.3 
	src/HttpHeader.h:1.1->1.1.2.1 
	src/HttpHeaderTools.c:1.7->1.7.48.1 
	src/Makefile.am:1.29.2.11->1.29.2.12 
	src/enums.h:1.40.2.4->1.40.2.5 
	src/structs.h:1.70.2.5->1.70.2.6 

--- squid/src/CacheDigest.c	Wed Feb 14 01:07:36 2007
+++ /dev/null	Wed Feb 14 01:07:22 2007
@@ -1,326 +0,0 @@
-
-/*
- * $Id: CacheDigest.c,v 1.5.10.1 2002/10/04 07:07:19 rbcollins Exp $
- *
- * DEBUG: section 70    Cache Digest
- * AUTHOR: Alex Rousskov
- *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; 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.
- *
- */
-
-#include "squid.h"
-#include "Store.h"
-
-#if USE_CACHE_DIGESTS
-
-/* local types */
-typedef struct {
-    int bit_count;		/* total number of bits */
-    int bit_on_count;		/* #bits turned on */
-    int bseq_len_sum;		/* sum of all bit seq length */
-    int bseq_count;		/* number of bit seqs */
-} CacheDigestStats;
-
-/* local functions */
-static void cacheDigestHashKey(const CacheDigest * cd, const cache_key * key);
-
-/* static array used by cacheDigestHashKey for optimization purposes */
-static u_int32_t hashed_keys[4];
-
-static void
-cacheDigestInit(CacheDigest * cd, int capacity, int bpe)
-{
-    const size_t mask_size = cacheDigestCalcMaskSize(capacity, bpe);
-    assert(cd);
-    assert(capacity > 0 && bpe > 0);
-    assert(mask_size > 0);
-    cd->capacity = capacity;
-    cd->bits_per_entry = bpe;
-    cd->mask_size = mask_size;
-    cd->mask = xcalloc(cd->mask_size, 1);
-    debug(70, 2) ("cacheDigestInit: capacity: %d entries, bpe: %d; size: %d bytes\n",
-	cd->capacity, cd->bits_per_entry, cd->mask_size);
-}
-
-CacheDigest *
-cacheDigestCreate(int capacity, int bpe)
-{
-    CacheDigest *cd = memAllocate(MEM_CACHE_DIGEST);
-    assert(MD5_DIGEST_CHARS == 16);	/* our hash functions rely on 16 byte keys */
-    cacheDigestInit(cd, capacity, bpe);
-    return cd;
-}
-
-static void
-cacheDigestClean(CacheDigest * cd)
-{
-    assert(cd);
-    xfree(cd->mask);
-    cd->mask = NULL;
-}
-
-void
-cacheDigestDestroy(CacheDigest * cd)
-{
-    assert(cd);
-    cacheDigestClean(cd);
-    memFree(cd, MEM_CACHE_DIGEST);
-}
-
-CacheDigest *
-cacheDigestClone(const CacheDigest * cd)
-{
-    CacheDigest *clone;
-    assert(cd);
-    clone = cacheDigestCreate(cd->capacity, cd->bits_per_entry);
-    clone->count = cd->count;
-    clone->del_count = cd->del_count;
-    assert(cd->mask_size == clone->mask_size);
-    xmemcpy(clone->mask, cd->mask, cd->mask_size);
-    return clone;
-}
-
-void
-cacheDigestClear(CacheDigest * cd)
-{
-    assert(cd);
-    cd->count = cd->del_count = 0;
-    memset(cd->mask, 0, cd->mask_size);
-}
-
-/* changes mask size, resets bits to 0, preserves "cd" pointer */
-void
-cacheDigestChangeCap(CacheDigest * cd, int new_cap)
-{
-    assert(cd);
-    cacheDigestClean(cd);
-    cacheDigestInit(cd, new_cap, cd->bits_per_entry);
-}
-
-/* returns true if the key belongs to the digest */
-int
-cacheDigestTest(const CacheDigest * cd, const cache_key * key)
-{
-    assert(cd && key);
-    /* hash */
-    cacheDigestHashKey(cd, key);
-    /* test corresponding bits */
-    return
-	CBIT_TEST(cd->mask, hashed_keys[0]) &&
-	CBIT_TEST(cd->mask, hashed_keys[1]) &&
-	CBIT_TEST(cd->mask, hashed_keys[2]) &&
-	CBIT_TEST(cd->mask, hashed_keys[3]);
-}
-
-void
-cacheDigestAdd(CacheDigest * cd, const cache_key * key)
-{
-    assert(cd && key);
-    /* hash */
-    cacheDigestHashKey(cd, key);
-    /* turn on corresponding bits */
-#if CD_FAST_ADD
-    CBIT_SET(cd->mask, hashed_keys[0]);
-    CBIT_SET(cd->mask, hashed_keys[1]);
-    CBIT_SET(cd->mask, hashed_keys[2]);
-    CBIT_SET(cd->mask, hashed_keys[3]);
-#else
-    {
-	int on_xition_cnt = 0;
-	if (!CBIT_TEST(cd->mask, hashed_keys[0])) {
-	    CBIT_SET(cd->mask, hashed_keys[0]);
-	    on_xition_cnt++;
-	}
-	if (!CBIT_TEST(cd->mask, hashed_keys[1])) {
-	    CBIT_SET(cd->mask, hashed_keys[1]);
-	    on_xition_cnt++;
-	}
-	if (!CBIT_TEST(cd->mask, hashed_keys[2])) {
-	    CBIT_SET(cd->mask, hashed_keys[2]);
-	    on_xition_cnt++;
-	}
-	if (!CBIT_TEST(cd->mask, hashed_keys[3])) {
-	    CBIT_SET(cd->mask, hashed_keys[3]);
-	    on_xition_cnt++;
-	}
-	statHistCount(&statCounter.cd.on_xition_count, on_xition_cnt);
-    }
-#endif
-    cd->count++;
-}
-
-void
-cacheDigestDel(CacheDigest * cd, const cache_key * key)
-{
-    assert(cd && key);
-    cd->del_count++;
-    /* we do not support deletions from the digest */
-}
-
-/* returns mask utilization parameters */
-static void
-cacheDigestStats(const CacheDigest * cd, CacheDigestStats * stats)
-{
-    int on_count = 0;
-    int pos = cd->mask_size * 8;
-    int seq_len_sum = 0;
-    int seq_count = 0;
-    int cur_seq_len = 0;
-    int cur_seq_type = 1;
-    assert(stats);
-    memset(stats, 0, sizeof(*stats));
-    while (pos-- > 0) {
-	const int is_on = 0 != CBIT_TEST(cd->mask, pos);
-	if (is_on)
-	    on_count++;
-	if (is_on != cur_seq_type || !pos) {
-	    seq_len_sum += cur_seq_len;
-	    seq_count++;
-	    cur_seq_type = is_on;
-	    cur_seq_len = 0;
-	}
-	cur_seq_len++;
-    }
-    stats->bit_count = cd->mask_size * 8;
-    stats->bit_on_count = on_count;
-    stats->bseq_len_sum = seq_len_sum;
-    stats->bseq_count = seq_count;
-}
-
-int
-cacheDigestBitUtil(const CacheDigest * cd)
-{
-    CacheDigestStats stats;
-    assert(cd);
-    cacheDigestStats(cd, &stats);
-    return xpercentInt(stats.bit_on_count, stats.bit_count);
-}
-
-void
-cacheDigestGuessStatsUpdate(cd_guess_stats * stats, int real_hit, int guess_hit)
-{
-    assert(stats);
-    if (real_hit) {
-	if (guess_hit)
-	    stats->true_hits++;
-	else
-	    stats->false_misses++;
-    } else {
-	if (guess_hit)
-	    stats->false_hits++;
-	else
-	    stats->true_misses++;
-    }
-}
-
-void
-cacheDigestGuessStatsReport(const cd_guess_stats * stats, StoreEntry * sentry, const char *label)
-{
-    const int true_count = stats->true_hits + stats->true_misses;
-    const int false_count = stats->false_hits + stats->false_misses;
-    const int hit_count = stats->true_hits + stats->false_hits;
-    const int miss_count = stats->true_misses + stats->false_misses;
-    const int tot_count = true_count + false_count;
-
-    assert(label);
-    assert(tot_count == hit_count + miss_count);	/* paranoid */
-
-    if (!tot_count) {
-	storeAppendPrintf(sentry, "no guess stats for %s available\n", label);
-	return;
-    }
-    storeAppendPrintf(sentry, "Digest guesses stats for %s:\n", label);
-    storeAppendPrintf(sentry, "guess\t hit\t\t miss\t\t total\t\t\n");
-    storeAppendPrintf(sentry, " \t #\t %%\t #\t %%\t #\t %%\t\n");
-    storeAppendPrintf(sentry, "true\t %d\t %.2f\t %d\t %.2f\t %d\t %.2f\n",
-	stats->true_hits, xpercent(stats->true_hits, tot_count),
-	stats->true_misses, xpercent(stats->true_misses, tot_count),
-	true_count, xpercent(true_count, tot_count));
-    storeAppendPrintf(sentry, "false\t %d\t %.2f\t %d\t %.2f\t %d\t %.2f\n",
-	stats->false_hits, xpercent(stats->false_hits, tot_count),
-	stats->false_misses, xpercent(stats->false_misses, tot_count),
-	false_count, xpercent(false_count, tot_count));
-    storeAppendPrintf(sentry, "all\t %d\t %.2f\t %d\t %.2f\t %d\t %.2f\n",
-	hit_count, xpercent(hit_count, tot_count),
-	miss_count, xpercent(miss_count, tot_count),
-	tot_count, xpercent(tot_count, tot_count));
-    storeAppendPrintf(sentry, "\tclose_hits: %d ( %d%%) /* cd said hit, doc was in the peer cache, but we got a miss */\n",
-	stats->close_hits, xpercentInt(stats->close_hits, stats->false_hits));
-}
-
-void
-cacheDigestReport(CacheDigest * cd, const char *label, StoreEntry * e)
-{
-    CacheDigestStats stats;
-    assert(cd && e);
-    cacheDigestStats(cd, &stats);
-    storeAppendPrintf(e, "%s digest: size: %d bytes\n",
-	label ? label : "", stats.bit_count / 8
-	);
-    storeAppendPrintf(e, "\t entries: count: %d capacity: %d util: %d%%\n",
-	cd->count,
-	cd->capacity,
-	xpercentInt(cd->count, cd->capacity)
-	);
-    storeAppendPrintf(e, "\t deletion attempts: %d\n",
-	cd->del_count
-	);
-    storeAppendPrintf(e, "\t bits: per entry: %d on: %d capacity: %d util: %d%%\n",
-	cd->bits_per_entry,
-	stats.bit_on_count, stats.bit_count,
-	xpercentInt(stats.bit_on_count, stats.bit_count)
-	);
-    storeAppendPrintf(e, "\t bit-seq: count: %d avg.len: %.2f\n",
-	stats.bseq_count,
-	xdiv(stats.bseq_len_sum, stats.bseq_count)
-	);
-}
-
-size_t
-cacheDigestCalcMaskSize(int cap, int bpe)
-{
-    return (size_t) (cap * bpe + 7) / 8;
-}
-
-static void
-cacheDigestHashKey(const CacheDigest * cd, const cache_key * key)
-{
-    const unsigned int bit_count = cd->mask_size * 8;
-    unsigned int tmp_keys[4];
-    /* we must memcpy to ensure alignment */
-    xmemcpy(tmp_keys, key, sizeof(tmp_keys));
-    hashed_keys[0] = htonl(tmp_keys[0]) % bit_count;
-    hashed_keys[1] = htonl(tmp_keys[1]) % bit_count;
-    hashed_keys[2] = htonl(tmp_keys[2]) % bit_count;
-    hashed_keys[3] = htonl(tmp_keys[3]) % bit_count;
-    debug(70, 9) ("cacheDigestHashKey: %s -(%d)-> %d %d %d %d\n",
-	storeKeyText(key), bit_count,
-	hashed_keys[0], hashed_keys[1], hashed_keys[2], hashed_keys[3]);
-}
-
-#endif
--- /dev/null	Wed Feb 14 01:07:22 2007
+++ squid/src/CacheDigest.cc	Wed Feb 14 01:07:36 2007
@@ -0,0 +1,326 @@
+
+/*
+ * $Id: CacheDigest.cc,v 1.1.2.1 2002/10/08 04:06:34 rbcollins Exp $
+ *
+ * DEBUG: section 70    Cache Digest
+ * AUTHOR: Alex Rousskov
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; 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.
+ *
+ */
+
+#include "squid.h"
+#include "Store.h"
+
+#if USE_CACHE_DIGESTS
+
+/* local types */
+typedef struct {
+    int bit_count;		/* total number of bits */
+    int bit_on_count;		/* #bits turned on */
+    int bseq_len_sum;		/* sum of all bit seq length */
+    int bseq_count;		/* number of bit seqs */
+} CacheDigestStats;
+
+/* local functions */
+static void cacheDigestHashKey(const CacheDigest * cd, const cache_key * key);
+
+/* static array used by cacheDigestHashKey for optimization purposes */
+static u_int32_t hashed_keys[4];
+
+static void
+cacheDigestInit(CacheDigest * cd, int capacity, int bpe)
+{
+    const size_t mask_size = cacheDigestCalcMaskSize(capacity, bpe);
+    assert(cd);
+    assert(capacity > 0 && bpe > 0);
+    assert(mask_size > 0);
+    cd->capacity = capacity;
+    cd->bits_per_entry = bpe;
+    cd->mask_size = mask_size;
+    cd->mask = (char *)xcalloc(cd->mask_size, 1);
+    debug(70, 2) ("cacheDigestInit: capacity: %d entries, bpe: %d; size: %d bytes\n",
+	cd->capacity, cd->bits_per_entry, cd->mask_size);
+}
+
+CacheDigest *
+cacheDigestCreate(int capacity, int bpe)
+{
+    CacheDigest *cd = (CacheDigest *)memAllocate(MEM_CACHE_DIGEST);
+    assert(MD5_DIGEST_CHARS == 16);	/* our hash functions rely on 16 byte keys */
+    cacheDigestInit(cd, capacity, bpe);
+    return cd;
+}
+
+static void
+cacheDigestClean(CacheDigest * cd)
+{
+    assert(cd);
+    xfree(cd->mask);
+    cd->mask = NULL;
+}
+
+void
+cacheDigestDestroy(CacheDigest * cd)
+{
+    assert(cd);
+    cacheDigestClean(cd);
+    memFree(cd, MEM_CACHE_DIGEST);
+}
+
+CacheDigest *
+cacheDigestClone(const CacheDigest * cd)
+{
+    CacheDigest *clone;
+    assert(cd);
+    clone = cacheDigestCreate(cd->capacity, cd->bits_per_entry);
+    clone->count = cd->count;
+    clone->del_count = cd->del_count;
+    assert(cd->mask_size == clone->mask_size);
+    xmemcpy(clone->mask, cd->mask, cd->mask_size);
+    return clone;
+}
+
+void
+cacheDigestClear(CacheDigest * cd)
+{
+    assert(cd);
+    cd->count = cd->del_count = 0;
+    memset(cd->mask, 0, cd->mask_size);
+}
+
+/* changes mask size, resets bits to 0, preserves "cd" pointer */
+void
+cacheDigestChangeCap(CacheDigest * cd, int new_cap)
+{
+    assert(cd);
+    cacheDigestClean(cd);
+    cacheDigestInit(cd, new_cap, cd->bits_per_entry);
+}
+
+/* returns true if the key belongs to the digest */
+int
+cacheDigestTest(const CacheDigest * cd, const cache_key * key)
+{
+    assert(cd && key);
+    /* hash */
+    cacheDigestHashKey(cd, key);
+    /* test corresponding bits */
+    return
+	CBIT_TEST(cd->mask, hashed_keys[0]) &&
+	CBIT_TEST(cd->mask, hashed_keys[1]) &&
+	CBIT_TEST(cd->mask, hashed_keys[2]) &&
+	CBIT_TEST(cd->mask, hashed_keys[3]);
+}
+
+void
+cacheDigestAdd(CacheDigest * cd, const cache_key * key)
+{
+    assert(cd && key);
+    /* hash */
+    cacheDigestHashKey(cd, key);
+    /* turn on corresponding bits */
+#if CD_FAST_ADD
+    CBIT_SET(cd->mask, hashed_keys[0]);
+    CBIT_SET(cd->mask, hashed_keys[1]);
+    CBIT_SET(cd->mask, hashed_keys[2]);
+    CBIT_SET(cd->mask, hashed_keys[3]);
+#else
+    {
+	int on_xition_cnt = 0;
+	if (!CBIT_TEST(cd->mask, hashed_keys[0])) {
+	    CBIT_SET(cd->mask, hashed_keys[0]);
+	    on_xition_cnt++;
+	}
+	if (!CBIT_TEST(cd->mask, hashed_keys[1])) {
+	    CBIT_SET(cd->mask, hashed_keys[1]);
+	    on_xition_cnt++;
+	}
+	if (!CBIT_TEST(cd->mask, hashed_keys[2])) {
+	    CBIT_SET(cd->mask, hashed_keys[2]);
+	    on_xition_cnt++;
+	}
+	if (!CBIT_TEST(cd->mask, hashed_keys[3])) {
+	    CBIT_SET(cd->mask, hashed_keys[3]);
+	    on_xition_cnt++;
+	}
+	statHistCount(&statCounter.cd.on_xition_count, on_xition_cnt);
+    }
+#endif
+    cd->count++;
+}
+
+void
+cacheDigestDel(CacheDigest * cd, const cache_key * key)
+{
+    assert(cd && key);
+    cd->del_count++;
+    /* we do not support deletions from the digest */
+}
+
+/* returns mask utilization parameters */
+static void
+cacheDigestStats(const CacheDigest * cd, CacheDigestStats * stats)
+{
+    int on_count = 0;
+    int pos = cd->mask_size * 8;
+    int seq_len_sum = 0;
+    int seq_count = 0;
+    int cur_seq_len = 0;
+    int cur_seq_type = 1;
+    assert(stats);
+    memset(stats, 0, sizeof(*stats));
+    while (pos-- > 0) {
+	const int is_on = 0 != CBIT_TEST(cd->mask, pos);
+	if (is_on)
+	    on_count++;
+	if (is_on != cur_seq_type || !pos) {
+	    seq_len_sum += cur_seq_len;
+	    seq_count++;
+	    cur_seq_type = is_on;
+	    cur_seq_len = 0;
+	}
+	cur_seq_len++;
+    }
+    stats->bit_count = cd->mask_size * 8;
+    stats->bit_on_count = on_count;
+    stats->bseq_len_sum = seq_len_sum;
+    stats->bseq_count = seq_count;
+}
+
+int
+cacheDigestBitUtil(const CacheDigest * cd)
+{
+    CacheDigestStats stats;
+    assert(cd);
+    cacheDigestStats(cd, &stats);
+    return xpercentInt(stats.bit_on_count, stats.bit_count);
+}
+
+void
+cacheDigestGuessStatsUpdate(cd_guess_stats * stats, int real_hit, int guess_hit)
+{
+    assert(stats);
+    if (real_hit) {
+	if (guess_hit)
+	    stats->true_hits++;
+	else
+	    stats->false_misses++;
+    } else {
+	if (guess_hit)
+	    stats->false_hits++;
+	else
+	    stats->true_misses++;
+    }
+}
+
+void
+cacheDigestGuessStatsReport(const cd_guess_stats * stats, StoreEntry * sentry, const char *label)
+{
+    const int true_count = stats->true_hits + stats->true_misses;
+    const int false_count = stats->false_hits + stats->false_misses;
+    const int hit_count = stats->true_hits + stats->false_hits;
+    const int miss_count = stats->true_misses + stats->false_misses;
+    const int tot_count = true_count + false_count;
+
+    assert(label);
+    assert(tot_count == hit_count + miss_count);	/* paranoid */
+
+    if (!tot_count) {
+	storeAppendPrintf(sentry, "no guess stats for %s available\n", label);
+	return;
+    }
+    storeAppendPrintf(sentry, "Digest guesses stats for %s:\n", label);
+    storeAppendPrintf(sentry, "guess\t hit\t\t miss\t\t total\t\t\n");
+    storeAppendPrintf(sentry, " \t #\t %%\t #\t %%\t #\t %%\t\n");
+    storeAppendPrintf(sentry, "true\t %d\t %.2f\t %d\t %.2f\t %d\t %.2f\n",
+	stats->true_hits, xpercent(stats->true_hits, tot_count),
+	stats->true_misses, xpercent(stats->true_misses, tot_count),
+	true_count, xpercent(true_count, tot_count));
+    storeAppendPrintf(sentry, "false\t %d\t %.2f\t %d\t %.2f\t %d\t %.2f\n",
+	stats->false_hits, xpercent(stats->false_hits, tot_count),
+	stats->false_misses, xpercent(stats->false_misses, tot_count),
+	false_count, xpercent(false_count, tot_count));
+    storeAppendPrintf(sentry, "all\t %d\t %.2f\t %d\t %.2f\t %d\t %.2f\n",
+	hit_count, xpercent(hit_count, tot_count),
+	miss_count, xpercent(miss_count, tot_count),
+	tot_count, xpercent(tot_count, tot_count));
+    storeAppendPrintf(sentry, "\tclose_hits: %d ( %d%%) /* cd said hit, doc was in the peer cache, but we got a miss */\n",
+	stats->close_hits, xpercentInt(stats->close_hits, stats->false_hits));
+}
+
+void
+cacheDigestReport(CacheDigest * cd, const char *label, StoreEntry * e)
+{
+    CacheDigestStats stats;
+    assert(cd && e);
+    cacheDigestStats(cd, &stats);
+    storeAppendPrintf(e, "%s digest: size: %d bytes\n",
+	label ? label : "", stats.bit_count / 8
+	);
+    storeAppendPrintf(e, "\t entries: count: %d capacity: %d util: %d%%\n",
+	cd->count,
+	cd->capacity,
+	xpercentInt(cd->count, cd->capacity)
+	);
+    storeAppendPrintf(e, "\t deletion attempts: %d\n",
+	cd->del_count
+	);
+    storeAppendPrintf(e, "\t bits: per entry: %d on: %d capacity: %d util: %d%%\n",
+	cd->bits_per_entry,
+	stats.bit_on_count, stats.bit_count,
+	xpercentInt(stats.bit_on_count, stats.bit_count)
+	);
+    storeAppendPrintf(e, "\t bit-seq: count: %d avg.len: %.2f\n",
+	stats.bseq_count,
+	xdiv(stats.bseq_len_sum, stats.bseq_count)
+	);
+}
+
+size_t
+cacheDigestCalcMaskSize(int cap, int bpe)
+{
+    return (size_t) (cap * bpe + 7) / 8;
+}
+
+static void
+cacheDigestHashKey(const CacheDigest * cd, const cache_key * key)
+{
+    const unsigned int bit_count = cd->mask_size * 8;
+    unsigned int tmp_keys[4];
+    /* we must memcpy to ensure alignment */
+    xmemcpy(tmp_keys, key, sizeof(tmp_keys));
+    hashed_keys[0] = htonl(tmp_keys[0]) % bit_count;
+    hashed_keys[1] = htonl(tmp_keys[1]) % bit_count;
+    hashed_keys[2] = htonl(tmp_keys[2]) % bit_count;
+    hashed_keys[3] = htonl(tmp_keys[3]) % bit_count;
+    debug(70, 9) ("cacheDigestHashKey: %s -(%d)-> %d %d %d %d\n",
+	storeKeyText(key), bit_count,
+	hashed_keys[0], hashed_keys[1], hashed_keys[2], hashed_keys[3]);
+}
+
+#endif
--- squid/src/ETag.c	Wed Feb 14 01:07:36 2007
+++ /dev/null	Wed Feb 14 01:07:22 2007
@@ -1,68 +0,0 @@
-
-/*
- * $Id: ETag.c,v 1.4 2001/01/12 08:20:32 hno Exp $
- *
- * DEBUG: none          ETag parsing support
- * AUTHOR: Alex Rousskov
- *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; 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.
- *
- */
-
-#include "squid.h"
-
-/*
- * Note: ETag is not an http "field" like, for example HttpHdrRange. ETag is a
- * field-value that maybe used in many http fields.
- */
-
-/* parses a string as weak or strong entity-tag; returns true on success */
-/* note: we do not duplicate "str"! */
-int
-etagParseInit(ETag * etag, const char *str)
-{
-    int len;
-    assert(etag && str);
-    etag->str = NULL;
-    etag->weak = !strncmp(str, "W/", 2);
-    if (etag->weak)
-	str += 2;
-    /* check format (quoted-string) */
-    len = strlen(str);
-    if (len >= 2 && str[0] == '"' && str[len - 1] == '"')
-	etag->str = str;
-    return etag->str != NULL;
-}
-
-/* returns true if etags are equal */
-int
-etagIsEqual(const ETag * tag1, const ETag * tag2)
-{
-    assert(tag1 && tag2);
-    assert(!tag1->weak && !tag2->weak);		/* weak comparison not implemented yet */
-    return !strcmp(tag1->str, tag2->str);
-}
--- /dev/null	Wed Feb 14 01:07:22 2007
+++ squid/src/ETag.cc	Wed Feb 14 01:07:36 2007
@@ -0,0 +1,68 @@
+
+/*
+ * $Id: ETag.cc,v 1.1.2.1 2002/10/08 04:06:34 rbcollins Exp $
+ *
+ * DEBUG: none          ETag parsing support
+ * AUTHOR: Alex Rousskov
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; 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.
+ *
+ */
+
+#include "squid.h"
+
+/*
+ * Note: ETag is not an http "field" like, for example HttpHdrRange. ETag is a
+ * field-value that maybe used in many http fields.
+ */
+
+/* parses a string as weak or strong entity-tag; returns true on success */
+/* note: we do not duplicate "str"! */
+int
+etagParseInit(ETag * etag, const char *str)
+{
+    int len;
+    assert(etag && str);
+    etag->str = NULL;
+    etag->weak = !strncmp(str, "W/", 2);
+    if (etag->weak)
+	str += 2;
+    /* check format (quoted-string) */
+    len = strlen(str);
+    if (len >= 2 && str[0] == '"' && str[len - 1] == '"')
+	etag->str = str;
+    return etag->str != NULL;
+}
+
+/* returns true if etags are equal */
+int
+etagIsEqual(const ETag * tag1, const ETag * tag2)
+{
+    assert(tag1 && tag2);
+    assert(!tag1->weak && !tag2->weak);		/* weak comparison not implemented yet */
+    return !strcmp(tag1->str, tag2->str);
+}
--- squid/src/HttpBody.c	Wed Feb 14 01:07:36 2007
+++ /dev/null	Wed Feb 14 01:07:22 2007
@@ -1,76 +0,0 @@
-
-/*
- * $Id: HttpBody.c,v 1.4 2001/01/12 08:20:32 hno Exp $
- *
- * DEBUG: section 56    HTTP Message Body
- * AUTHOR: Alex Rousskov
- *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; 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.
- *
- */
-
-#include "squid.h"
-
-
-void
-httpBodyInit(HttpBody * body)
-{
-    body->mb = MemBufNull;
-}
-
-void
-httpBodyClean(HttpBody * body)
-{
-    assert(body);
-    if (!memBufIsNull(&body->mb))
-	memBufClean(&body->mb);
-}
-
-/* set body by absorbing mb */
-void
-httpBodySet(HttpBody * body, MemBuf * mb)
-{
-    assert(body);
-    assert(memBufIsNull(&body->mb));
-    body->mb = *mb;		/* absorb */
-}
-
-void
-httpBodyPackInto(const HttpBody * body, Packer * p)
-{
-    assert(body && p);
-    if (body->mb.size)
-	packerAppend(p, body->mb.buf, body->mb.size);
-}
-
-#if UNUSED_CODE
-const char *
-httpBodyPtr(const HttpBody * body)
-{
-    return body->mb.buf ? body->mb.buf : "";
-}
-#endif
--- /dev/null	Wed Feb 14 01:07:22 2007
+++ squid/src/HttpBody.cc	Wed Feb 14 01:07:36 2007
@@ -0,0 +1,76 @@
+
+/*
+ * $Id: HttpBody.cc,v 1.1.2.1 2002/10/08 04:06:34 rbcollins Exp $
+ *
+ * DEBUG: section 56    HTTP Message Body
+ * AUTHOR: Alex Rousskov
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; 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.
+ *
+ */
+
+#include "squid.h"
+
+
+void
+httpBodyInit(HttpBody * body)
+{
+    body->mb = MemBufNull;
+}
+
+void
+httpBodyClean(HttpBody * body)
+{
+    assert(body);
+    if (!memBufIsNull(&body->mb))
+	memBufClean(&body->mb);
+}
+
+/* set body by absorbing mb */
+void
+httpBodySet(HttpBody * body, MemBuf * mb)
+{
+    assert(body);
+    assert(memBufIsNull(&body->mb));
+    body->mb = *mb;		/* absorb */
+}
+
+void
+httpBodyPackInto(const HttpBody * body, Packer * p)
+{
+    assert(body && p);
+    if (body->mb.size)
+	packerAppend(p, body->mb.buf, body->mb.size);
+}
+
+#if UNUSED_CODE
+const char *
+httpBodyPtr(const HttpBody * body)
+{
+    return body->mb.buf ? body->mb.buf : "";
+}
+#endif
--- squid/src/HttpHdrCc.c	Wed Feb 14 01:07:36 2007
+++ /dev/null	Wed Feb 14 01:07:22 2007
@@ -1,263 +0,0 @@
-
-/*
- * $Id: HttpHdrCc.c,v 1.5.96.2 2002/10/04 07:07:19 rbcollins Exp $
- *
- * DEBUG: section 65    HTTP Cache Control Header
- * AUTHOR: Alex Rousskov
- *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; 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.
- *
- */
-
-#include "squid.h"
-#include "Store.h"
-
-/* this table is used for parsing cache control header */
-static const HttpHeaderFieldAttrs CcAttrs[CC_ENUM_END] =
-{
-    {"public", CC_PUBLIC},
-    {"private", CC_PRIVATE},
-    {"no-cache", CC_NO_CACHE},
-    {"no-store", CC_NO_STORE},
-    {"no-transform", CC_NO_TRANSFORM},
-    {"must-revalidate", CC_MUST_REVALIDATE},
-    {"proxy-revalidate", CC_PROXY_REVALIDATE},
-    {"only-if-cached", CC_ONLY_IF_CACHED},
-    {"max-age", CC_MAX_AGE},
-    {"s-maxage", CC_S_MAXAGE},
-    {"max-stale", CC_MAX_STALE},
-    {"Other,", CC_OTHER}	/* ',' will protect from matches */
-};
-HttpHeaderFieldInfo *CcFieldsInfo = NULL;
-
-/* local prototypes */
-static int httpHdrCcParseInit(HttpHdrCc * cc, const String * str);
-
-
-/* module initialization */
-
-void
-httpHdrCcInitModule(void)
-{
-    CcFieldsInfo = httpHeaderBuildFieldsInfo(CcAttrs, CC_ENUM_END);
-}
-
-void
-httpHdrCcCleanModule(void)
-{
-    httpHeaderDestroyFieldsInfo(CcFieldsInfo, CC_ENUM_END);
-    CcFieldsInfo = NULL;
-}
-
-/* implementation */
-
-HttpHdrCc *
-httpHdrCcCreate(void)
-{
-    HttpHdrCc *cc = memAllocate(MEM_HTTP_HDR_CC);
-    cc->max_age = cc->s_maxage = cc->max_stale = -1;
-    return cc;
-}
-
-/* creates an cc object from a 0-terminating string */
-HttpHdrCc *
-httpHdrCcParseCreate(const String * str)
-{
-    HttpHdrCc *cc = httpHdrCcCreate();
-    if (!httpHdrCcParseInit(cc, str)) {
-	httpHdrCcDestroy(cc);
-	cc = NULL;
-    }
-    return cc;
-}
-
-/* parses a 0-terminating string and inits cc */
-static int
-httpHdrCcParseInit(HttpHdrCc * cc, const String * str)
-{
-    const char *item;
-    const char *p;		/* '=' parameter */
-    const char *pos = NULL;
-    http_hdr_type type;
-    int ilen;
-    assert(cc && str);
-
-    /* iterate through comma separated list */
-    while (strListGetItem(str, ',', &item, &ilen, &pos)) {
-	/* strip '=' statements @?@ */
-	if ((p = strchr(item, '=')) && (p - item < ilen))
-	    ilen = p++ - item;
-	/* find type */
-	type = httpHeaderIdByName(item, ilen,
-	    CcFieldsInfo, CC_ENUM_END);
-	if (type < 0) {
-	    debug(65, 2) ("hdr cc: unknown cache-directive: near '%s' in '%s'\n", item, strBuf(*str));
-	    type = CC_OTHER;
-	}
-	if (EBIT_TEST(cc->mask, type)) {
-	    if (type != CC_OTHER)
-		debug(65, 2) ("hdr cc: ignoring duplicate cache-directive: near '%s' in '%s'\n", item, strBuf(*str));
-	    CcFieldsInfo[type].stat.repCount++;
-	    continue;
-	}
-	/* update mask */
-	EBIT_SET(cc->mask, type);
-	/* post-processing special cases */
-	switch (type) {
-	case CC_MAX_AGE:
-	    if (!p || !httpHeaderParseInt(p, &cc->max_age)) {
-		debug(65, 2) ("cc: invalid max-age specs near '%s'\n", item);
-		cc->max_age = -1;
-		EBIT_CLR(cc->mask, type);
-	    }
-	    break;
-	case CC_S_MAXAGE:
-	    if (!p || !httpHeaderParseInt(p, &cc->s_maxage)) {
-		debug(65, 2) ("cc: invalid s-maxage specs near '%s'\n", item);
-		cc->s_maxage = -1;
-		EBIT_CLR(cc->mask, type);
-	    }
-	    break;
-	case CC_MAX_STALE:
-	    if (!p || !httpHeaderParseInt(p, &cc->max_stale)) {
-		debug(65, 2) ("cc: max-stale directive is valid without value\n");
-		cc->max_stale = -1;
-	    }
-	    break;
-	default:
-	    /* note that we ignore most of '=' specs */
-	    break;
-	}
-    }
-    return cc->mask != 0;
-}
-
-void
-httpHdrCcDestroy(HttpHdrCc * cc)
-{
-    assert(cc);
-    memFree(cc, MEM_HTTP_HDR_CC);
-}
-
-HttpHdrCc *
-httpHdrCcDup(const HttpHdrCc * cc)
-{
-    HttpHdrCc *dup;
-    assert(cc);
-    dup = httpHdrCcCreate();
-    dup->mask = cc->mask;
-    dup->max_age = cc->max_age;
-    dup->s_maxage = cc->s_maxage;
-    dup->max_stale = cc->max_stale;
-    return dup;
-}
-
-void
-httpHdrCcPackInto(const HttpHdrCc * cc, Packer * p)
-{
-    http_hdr_cc_type flag;
-    int pcount = 0;
-    assert(cc && p);
-    for (flag = 0; flag < CC_ENUM_END; flag++) {
-	if (EBIT_TEST(cc->mask, flag) && flag != CC_OTHER) {
-
-	    /* print option name */
-	    packerPrintf(p, (pcount ? ", %s" : "%s"), strBuf(CcFieldsInfo[flag].name));
-
-	    /* handle options with values */
-	    if (flag == CC_MAX_AGE)
-		packerPrintf(p, "=%d", (int) cc->max_age);
-
-	    if (flag == CC_S_MAXAGE)
-		packerPrintf(p, "=%d", (int) cc->s_maxage);
-
-	    if (flag == CC_MAX_STALE)
-		packerPrintf(p, "=%d", (int) cc->max_stale);
-
-	    pcount++;
-	}
-    }
-}
-
-void
-httpHdrCcJoinWith(HttpHdrCc * cc, const HttpHdrCc * new_cc)
-{
-    assert(cc && new_cc);
-    if (cc->max_age < 0)
-	cc->max_age = new_cc->max_age;
-    if (cc->s_maxage < 0)
-	cc->s_maxage = new_cc->s_maxage;
-    if (cc->max_stale < 0)
-	cc->max_stale = new_cc->max_stale;
-    cc->mask |= new_cc->mask;
-}
-
-/* negative max_age will clean old max_Age setting */
-void
-httpHdrCcSetMaxAge(HttpHdrCc * cc, int max_age)
-{
-    assert(cc);
-    cc->max_age = max_age;
-    if (max_age >= 0)
-	EBIT_SET(cc->mask, CC_MAX_AGE);
-    else
-	EBIT_CLR(cc->mask, CC_MAX_AGE);
-}
-
-/* negative s_maxage will clean old s-maxage setting */
-void
-httpHdrCcSetSMaxAge(HttpHdrCc * cc, int s_maxage)
-{
-    assert(cc);
-    cc->s_maxage = s_maxage;
-    if (s_maxage >= 0)
-	EBIT_SET(cc->mask, CC_S_MAXAGE);
-    else
-	EBIT_CLR(cc->mask, CC_S_MAXAGE);
-}
-
-void
-httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist)
-{
-    http_hdr_cc_type c;
-    assert(cc);
-    for (c = 0; c < CC_ENUM_END; c++)
-	if (EBIT_TEST(cc->mask, c))
-	    statHistCount(hist, c);
-}
-
-void
-httpHdrCcStatDumper(StoreEntry * sentry, int idx, double val, double size, int count)
-{
-    extern const HttpHeaderStat *dump_stat;	/* argh! */
-    const int id = (int) val;
-    const int valid_id = id >= 0 && id < CC_ENUM_END;
-    const char *name = valid_id ? strBuf(CcFieldsInfo[id].name) : "INVALID";
-    if (count || valid_id)
-	storeAppendPrintf(sentry, "%2d\t %-20s\t %5d\t %6.2f\n",
-	    id, name, count, xdiv(count, dump_stat->ccParsedCount));
-}
--- /dev/null	Wed Feb 14 01:07:22 2007
+++ squid/src/HttpHdrCc.cc	Wed Feb 14 01:07:36 2007
@@ -0,0 +1,271 @@
+
+/*
+ * $Id: HttpHdrCc.cc,v 1.1.2.1 2002/10/08 04:06:34 rbcollins Exp $
+ *
+ * DEBUG: section 65    HTTP Cache Control Header
+ * AUTHOR: Alex Rousskov
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; 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.
+ *
+ */
+
+#include "squid.h"
+#include "Store.h"
+#include "HttpHeader.h"
+
+/* this table is used for parsing cache control header */
+static const HttpHeaderFieldAttrs CcAttrs[CC_ENUM_END] =
+{
+    {"public", (http_hdr_type)CC_PUBLIC},
+    {"private", (http_hdr_type)CC_PRIVATE},
+    {"no-cache", (http_hdr_type)CC_NO_CACHE},
+    {"no-store", (http_hdr_type)CC_NO_STORE},
+    {"no-transform", (http_hdr_type)CC_NO_TRANSFORM},
+    {"must-revalidate", (http_hdr_type)CC_MUST_REVALIDATE},
+    {"proxy-revalidate", (http_hdr_type)CC_PROXY_REVALIDATE},
+    {"only-if-cached", (http_hdr_type)CC_ONLY_IF_CACHED},
+    {"max-age", (http_hdr_type)CC_MAX_AGE},
+    {"s-maxage", (http_hdr_type)CC_S_MAXAGE},
+    {"max-stale", (http_hdr_type)CC_MAX_STALE},
+    {"Other,", (http_hdr_type)CC_OTHER}	/* ',' will protect from matches */
+};
+HttpHeaderFieldInfo *CcFieldsInfo = NULL;
+
+http_hdr_cc_type &operator++ (http_hdr_cc_type &aHeader)
+{
+    aHeader = (http_hdr_cc_type)(++(int)aHeader);
+    return aHeader;
+}
+
+
+/* local prototypes */
+static int httpHdrCcParseInit(HttpHdrCc * cc, const String * str);
+
+
+/* module initialization */
+
+void
+httpHdrCcInitModule(void)
+{
+    CcFieldsInfo = httpHeaderBuildFieldsInfo(CcAttrs, CC_ENUM_END);
+}
+
+void
+httpHdrCcCleanModule(void)
+{
+    httpHeaderDestroyFieldsInfo(CcFieldsInfo, CC_ENUM_END);
+    CcFieldsInfo = NULL;
+}
+
+/* implementation */
+
+HttpHdrCc *
+httpHdrCcCreate(void)
+{
+    HttpHdrCc *cc = (HttpHdrCc *)memAllocate(MEM_HTTP_HDR_CC);
+    cc->max_age = cc->s_maxage = cc->max_stale = -1;
+    return cc;
+}
+
+/* creates an cc object from a 0-terminating string */
+HttpHdrCc *
+httpHdrCcParseCreate(const String * str)
+{
+    HttpHdrCc *cc = httpHdrCcCreate();
+    if (!httpHdrCcParseInit(cc, str)) {
+	httpHdrCcDestroy(cc);
+	cc = NULL;
+    }
+    return cc;
+}
+
+/* parses a 0-terminating string and inits cc */
+static int
+httpHdrCcParseInit(HttpHdrCc * cc, const String * str)
+{
+    const char *item;
+    const char *p;		/* '=' parameter */
+    const char *pos = NULL;
+    http_hdr_cc_type type;
+    int ilen;
+    assert(cc && str);
+
+    /* iterate through comma separated list */
+    while (strListGetItem(str, ',', &item, &ilen, &pos)) {
+	/* strip '=' statements @?@ */
+	if ((p = strchr(item, '=')) && (p - item < ilen))
+	    ilen = p++ - item;
+	/* find type */
+	type = (http_hdr_cc_type ) httpHeaderIdByName(item, ilen,
+	    CcFieldsInfo, CC_ENUM_END);
+	if (type < 0) {
+	    debug(65, 2) ("hdr cc: unknown cache-directive: near '%s' in '%s'\n", item, strBuf(*str));
+	    type = CC_OTHER;
+	}
+	if (EBIT_TEST(cc->mask, type)) {
+	    if (type != CC_OTHER)
+		debug(65, 2) ("hdr cc: ignoring duplicate cache-directive: near '%s' in '%s'\n", item, strBuf(*str));
+	    CcFieldsInfo[type].stat.repCount++;
+	    continue;
+	}
+	/* update mask */
+	EBIT_SET(cc->mask, type);
+	/* post-processing special cases */
+	switch (type) {
+	case CC_MAX_AGE:
+	    if (!p || !httpHeaderParseInt(p, &cc->max_age)) {
+		debug(65, 2) ("cc: invalid max-age specs near '%s'\n", item);
+		cc->max_age = -1;
+		EBIT_CLR(cc->mask, type);
+	    }
+	    break;
+	case CC_S_MAXAGE:
+	    if (!p || !httpHeaderParseInt(p, &cc->s_maxage)) {
+		debug(65, 2) ("cc: invalid s-maxage specs near '%s'\n", item);
+		cc->s_maxage = -1;
+		EBIT_CLR(cc->mask, type);
+	    }
+	    break;
+	case CC_MAX_STALE:
+	    if (!p || !httpHeaderParseInt(p, &cc->max_stale)) {
+		debug(65, 2) ("cc: max-stale directive is valid without value\n");
+		cc->max_stale = -1;
+	    }
+	    break;
+	default:
+	    /* note that we ignore most of '=' specs */
+	    break;
+	}
+    }
+    return cc->mask != 0;
+}
+
+void
+httpHdrCcDestroy(HttpHdrCc * cc)
+{
+    assert(cc);
+    memFree(cc, MEM_HTTP_HDR_CC);
+}
+
+HttpHdrCc *
+httpHdrCcDup(const HttpHdrCc * cc)
+{
+    HttpHdrCc *dup;
+    assert(cc);
+    dup = httpHdrCcCreate();
+    dup->mask = cc->mask;
+    dup->max_age = cc->max_age;
+    dup->s_maxage = cc->s_maxage;
+    dup->max_stale = cc->max_stale;
+    return dup;
+}
+
+void
+httpHdrCcPackInto(const HttpHdrCc * cc, Packer * p)
+{
+    http_hdr_cc_type flag;
+    int pcount = 0;
+    assert(cc && p);
+    for (flag = CC_PUBLIC; flag < CC_ENUM_END; ++flag) {
+	if (EBIT_TEST(cc->mask, flag) && flag != CC_OTHER) {
+
+	    /* print option name */
+	    packerPrintf(p, (pcount ? ", %s" : "%s"), strBuf(CcFieldsInfo[flag].name));
+
+	    /* handle options with values */
+	    if (flag == CC_MAX_AGE)
+		packerPrintf(p, "=%d", (int) cc->max_age);
+
+	    if (flag == CC_S_MAXAGE)
+		packerPrintf(p, "=%d", (int) cc->s_maxage);
+
+	    if (flag == CC_MAX_STALE)
+		packerPrintf(p, "=%d", (int) cc->max_stale);
+
+	    pcount++;
+	}
+    }
+}
+
+void
+httpHdrCcJoinWith(HttpHdrCc * cc, const HttpHdrCc * new_cc)
+{
+    assert(cc && new_cc);
+    if (cc->max_age < 0)
+	cc->max_age = new_cc->max_age;
+    if (cc->s_maxage < 0)
+	cc->s_maxage = new_cc->s_maxage;
+    if (cc->max_stale < 0)
+	cc->max_stale = new_cc->max_stale;
+    cc->mask |= new_cc->mask;
+}
+
+/* negative max_age will clean old max_Age setting */
+void
+httpHdrCcSetMaxAge(HttpHdrCc * cc, int max_age)
+{
+    assert(cc);
+    cc->max_age = max_age;
+    if (max_age >= 0)
+	EBIT_SET(cc->mask, CC_MAX_AGE);
+    else
+	EBIT_CLR(cc->mask, CC_MAX_AGE);
+}
+
+/* negative s_maxage will clean old s-maxage setting */
+void
+httpHdrCcSetSMaxAge(HttpHdrCc * cc, int s_maxage)
+{
+    assert(cc);
+    cc->s_maxage = s_maxage;
+    if (s_maxage >= 0)
+	EBIT_SET(cc->mask, CC_S_MAXAGE);
+    else
+	EBIT_CLR(cc->mask, CC_S_MAXAGE);
+}
+
+void
+httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist)
+{
+    http_hdr_cc_type c;
+    assert(cc);
+    for (c = CC_PUBLIC; c < CC_ENUM_END; ++c)
+	if (EBIT_TEST(cc->mask, c))
+	    statHistCount(hist, c);
+}
+
+void
+httpHdrCcStatDumper(StoreEntry * sentry, int idx, double val, double size, int count)
+{
+    extern const HttpHeaderStat *dump_stat;	/* argh! */
+    const int id = (int) val;
+    const int valid_id = id >= 0 && id < CC_ENUM_END;
+    const char *name = valid_id ? strBuf(CcFieldsInfo[id].name) : "INVALID";
+    if (count || valid_id)
+	storeAppendPrintf(sentry, "%2d\t %-20s\t %5d\t %6.2f\n",
+	    id, name, count, xdiv(count, dump_stat->ccParsedCount));
+}
Index: squid/src/HttpHeader.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/HttpHeader.c,v
retrieving revision 1.16.10.2
retrieving revision 1.16.10.3
diff -u -r1.16.10.2 -r1.16.10.3
--- squid/src/HttpHeader.c	4 Oct 2002 07:07:19 -0000	1.16.10.2
+++ squid/src/HttpHeader.c	8 Oct 2002 04:06:34 -0000	1.16.10.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpHeader.c,v 1.16.10.2 2002/10/04 07:07:19 rbcollins Exp $
+ * $Id: HttpHeader.c,v 1.16.10.3 2002/10/08 04:06:34 rbcollins Exp $
  *
  * DEBUG: section 55    HTTP Header
  * AUTHOR: Alex Rousskov
@@ -35,6 +35,7 @@
 
 #include "squid.h"
 #include "Store.h"
+#include "HttpHeader.h"
 
 /*
  * On naming conventions:
--- /dev/null	Wed Feb 14 01:07:22 2007
+++ squid/src/HttpHeader.h	Wed Feb 14 01:07:36 2007
@@ -0,0 +1,47 @@
+
+/*
+ * $Id: HttpHeader.h,v 1.1.2.1 2002/10/08 04:06:35 rbcollins Exp $
+ *
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; 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.
+ *
+ */
+
+#ifndef SQUID_HTTPHEADER_H
+#define SQUID_HTTPHEADER_H
+
+#ifdef __cplusplus
+#endif
+
+/* constant attributes of http header fields */
+struct _HttpHeaderFieldAttrs {
+    const char *name;
+    http_hdr_type id;
+    field_type type;
+};
+
+#endif /* SQUID_HTTPHEADER_H */
Index: squid/src/HttpHeaderTools.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/HttpHeaderTools.c,v
retrieving revision 1.7
retrieving revision 1.7.48.1
diff -u -r1.7 -r1.7.48.1
--- squid/src/HttpHeaderTools.c	6 Sep 2001 21:19:46 -0000	1.7
+++ squid/src/HttpHeaderTools.c	8 Oct 2002 04:06:35 -0000	1.7.48.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpHeaderTools.c,v 1.7 2001/09/06 21:19:46 squidadm Exp $
+ * $Id: HttpHeaderTools.c,v 1.7.48.1 2002/10/08 04:06:35 rbcollins Exp $
  *
  * DEBUG: section 66    HTTP Header Tools
  * AUTHOR: Alex Rousskov
@@ -34,6 +34,7 @@
  */
 
 #include "squid.h"
+#include "HttpHeader.h"
 
 #if UNUSED_CODE
 static int httpHeaderStrCmp(const char *h1, const char *h2, int len);
Index: squid/src/Makefile.am
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Makefile.am,v
retrieving revision 1.29.2.11
retrieving revision 1.29.2.12
diff -u -r1.29.2.11 -r1.29.2.12
--- squid/src/Makefile.am	7 Oct 2002 09:21:04 -0000	1.29.2.11
+++ squid/src/Makefile.am	8 Oct 2002 04:06:35 -0000	1.29.2.12
@@ -121,7 +121,7 @@
 	asn.c \
 	authenticate.cc \
 	cache_cf.cc \
-	CacheDigest.c \
+	CacheDigest.cc \
 	cache_manager.c \
 	carp.c \
 	cbdata.c \
@@ -143,7 +143,7 @@
 	$(DNSSOURCE) \
 	enums.h \
 	errorpage.cc \
-	ETag.c \
+	ETag.cc \
 	event.c \
 	external_acl.cc \
 	fd.c \
@@ -157,12 +157,12 @@
 	$(HTCPSOURCE) \
 	http.cc \
 	HttpStatusLine.c \
-	HttpHdrCc.c \
+	HttpHdrCc.cc \
 	HttpHdrRange.c \
 	HttpHdrContRange.c \
 	HttpHeader.c \
 	HttpHeaderTools.c \
-	HttpBody.c \
+	HttpBody.cc \
 	HttpMsg.c \
 	HttpReply.c \
 	HttpRequest.cc \
Index: squid/src/enums.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/enums.h,v
retrieving revision 1.40.2.4
retrieving revision 1.40.2.5
diff -u -r1.40.2.4 -r1.40.2.5
--- squid/src/enums.h	4 Oct 2002 22:35:17 -0000	1.40.2.4
+++ squid/src/enums.h	8 Oct 2002 04:06:35 -0000	1.40.2.5
@@ -1,6 +1,6 @@
 
 /*
- * $Id: enums.h,v 1.40.2.4 2002/10/04 22:35:17 rbcollins Exp $
+ * $Id: enums.h,v 1.40.2.5 2002/10/08 04:06:35 rbcollins Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -251,7 +251,7 @@
 } http_hdr_type;
 
 typedef enum {
-    CC_PUBLIC,
+    CC_PUBLIC = 0,
     CC_PRIVATE,
     CC_NO_CACHE,
     CC_NO_STORE,
Index: squid/src/structs.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/structs.h,v
retrieving revision 1.70.2.5
retrieving revision 1.70.2.6
diff -u -r1.70.2.5 -r1.70.2.6
--- squid/src/structs.h	8 Oct 2002 02:25:37 -0000	1.70.2.5
+++ squid/src/structs.h	8 Oct 2002 04:06:35 -0000	1.70.2.6
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.70.2.5 2002/10/08 02:25:37 rbcollins Exp $
+ * $Id: structs.h,v 1.70.2.6 2002/10/08 04:06:35 rbcollins Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -806,13 +806,6 @@
     String boundary;		/* boundary for multipart responses */
 };
 
-/* constant attributes of http header fields */
-struct _HttpHeaderFieldAttrs {
-    const char *name;
-    http_hdr_type id;
-    field_type type;
-};
-
 /* per field statistics */
 struct _HttpHeaderFieldStat {
     int aliveCount;		/* created but not destroyed (count) */
