# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: kinkie@squid-cache.org-20140105130744-gqkbrnvpk1feg3bm # target_branch: file:///home/kinkie/squid/workspace/trunk/ # testament_sha1: 8d4dd50d54986910c84248b7242fe15b22dbdb20 # timestamp: 2014-01-05 16:17:42 +0100 # base_revision_id: kinkie@squid-cache.org-20140103175235-\ # fo37ieq0a1td0ata # # Begin patch === modified file 'src/base/CharacterSet.cc' --- src/base/CharacterSet.cc 2013-12-18 15:22:06 +0000 +++ src/base/CharacterSet.cc 2013-12-30 13:22:05 +0000 @@ -1,7 +1,7 @@ #include "squid.h" #include "CharacterSet.h" -const CharacterSet & +CharacterSet & CharacterSet::operator +=(const CharacterSet &src) { Storage::const_iterator s = src.chars_.begin(); @@ -16,6 +16,14 @@ return *this; } +CharacterSet +CharacterSet::operator +(const CharacterSet &src) const +{ + CharacterSet rv(*this); + rv += src; + return rv; +} + CharacterSet & CharacterSet::add(const unsigned char c) { @@ -23,6 +31,16 @@ return *this; } +CharacterSet & +CharacterSet::addRange(unsigned char low, unsigned char high) +{ + while (low <= high) { + chars_[static_cast(low)] = 1; + ++low; + } + return *this; +} + CharacterSet::CharacterSet(const char *label, const char * const c) : name(label == NULL ? "anonymous" : label), chars_(Storage(256,0)) { @@ -30,3 +48,28 @@ for (size_t i = 0; i < clen; ++i) add(c[i]); } + +CharacterSet::CharacterSet(const char *label, unsigned char low, unsigned char high) +: name(label == NULL ? "anonymous" : label), chars_(Storage(256,0)) +{ + addRange(low,high); +} + +const CharacterSet +CharacterSet::ALPHA("ALPHA", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), +CharacterSet::BIT("BIT","01"), +CharacterSet::CR("CR","\r"), +CharacterSet::LF("LF","\n"), +CharacterSet::CRLF("CRLF","\r\n"), +CharacterSet::DIGIT("DIGIT","0123456789"), +CharacterSet::DQUOTE("DQUOTE","\""), +CharacterSet::HTAB("HTAB","\t"), +CharacterSet::HEXDIG("HEXDIG","0123456789aAbBcCdDeEfF"), +CharacterSet::SP("SP"," "), +CharacterSet::VCHAR("VCHAR", 0x21, 0x7e), +CharacterSet::WSP("WSP"," \t"), +CharacterSet::TCHAR("TCHAR","!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), +CharacterSet::SPECIAL("SPECIAL","()<>@,;:\\\"/[]?={}") +//,CharacterSet::QDTEXT("QDTEXT",{{9,9},{0x20,0x21},{0x23,0x5b},{0x5d,0x7e},{0x80,0xff}}) +//,CharacterSet::OBSTEXT("OBSTEXT",0x80,0xff) +; === modified file 'src/base/CharacterSet.h' --- src/base/CharacterSet.h 2013-12-18 15:22:06 +0000 +++ src/base/CharacterSet.h 2013-12-30 13:22:05 +0000 @@ -13,18 +13,64 @@ /// with specified initial contents CharacterSet(const char *label, const char * const initial); + /// define a character set with the given label ("anonymous" if NULL) + /// containing characters defined in the supplied ranges + /// \see addRange + CharacterSet(const char *label, unsigned char low, unsigned char high); + /// whether a given character exists in the set bool operator[](unsigned char c) const {return chars_[static_cast(c)] != 0;} /// add a given character to the character set CharacterSet & add(const unsigned char c); + /// add a list of character ranges, expressed as pairs [low,high], including both ends + CharacterSet & addRange(unsigned char low, unsigned char high); + /// add all characters from the given CharacterSet to this one - const CharacterSet &operator +=(const CharacterSet &src); + CharacterSet &operator +=(const CharacterSet &src); + + /// return a new CharacterSet containing the union of two sets + CharacterSet operator +(const CharacterSet &src) const; /// optional set label for debugging (default: "anonymous") const char * name; + // common character sets, insipired to RFC5234 + // A-Za-z + static const CharacterSet ALPHA; + // 0-1 + static const CharacterSet BIT; + // carriage return + static const CharacterSet CR; + // line feed + static const CharacterSet LF; + // CRLF + static const CharacterSet CRLF; + // double quote + static const CharacterSet DQUOTE; + // 0-9 + static const CharacterSet DIGIT; + // 0-9aAbBcCdDeEfF + static const CharacterSet HEXDIG; + // horizontal tab + static const CharacterSet HTAB; + // white space + static const CharacterSet SP; + // visible (printable) characters + static const CharacterSet VCHAR; + // + static const CharacterSet WSP; + // character sets from draft httpbis + // any VCHAR except for SPECIAL + static const CharacterSet TCHAR; + // special VCHARs + static const CharacterSet SPECIAL; + // qdtext (ready but not enabled for now) + //static const CharacterSet QDTEXT; + // obs-text + //static const CharacterSet OBSTEXT; + private: /** index of characters in this set * === modified file 'src/base/Makefile.am' --- src/base/Makefile.am 2013-12-17 10:19:44 +0000 +++ src/base/Makefile.am 2014-01-01 17:15:10 +0000 @@ -26,3 +26,27 @@ TextException.h \ Vector.cc \ Vector.h + +EXTRA_PROGRAMS = \ + testCharacterSet + +check_PROGRAMS += testCharacterSet +TESTS += testCharacterSet + +testCharacterSet_SOURCES = \ + CharacterSet.h \ + testCharacterSet.h \ + testCharacterSet.cc +nodist_testCharacterSet_SOURCES = \ + $(top_srcdir)/src/tests/testMain.cc \ + $(top_srcdir)/src/tests/stub_debug.cc \ + $(top_srcdir)/src/tests/stub_MemBuf.cc \ + $(top_srcdir)/src/tests/stub_cbdata.cc +testCharacterSet_LDFLAGS = $(LIBADD_DL) +testCharacterSet_LDADD=\ + $(SQUID_CPPUNIT_LIBS) \ + $(SQUID_CPPUNIT_LA) \ + libbase.la \ + $(COMPAT_LIB) \ + $(XTRA_LIBS) +testCharacterSet_DEPENDENCIES= $(SQUID_CPPUNIT_LA) === added file 'src/base/testCharacterSet.cc' --- src/base/testCharacterSet.cc 1970-01-01 00:00:00 +0000 +++ src/base/testCharacterSet.cc 2013-12-30 13:22:05 +0000 @@ -0,0 +1,82 @@ +#define SQUID_UNIT_TEST 1 + +#include "squid.h" +#include "base/CharacterSet.h" +#include "testCharacterSet.h" + +#include + +CPPUNIT_TEST_SUITE_REGISTRATION( testCharacterSet ); + +void +testCharacterSet::CharacterSetConstruction() +{ + { + CharacterSet t(NULL,""); + CPPUNIT_ASSERT_EQUAL(std::string("anonymous"),std::string(t.name)); + } + { + CharacterSet t("test",""); + CPPUNIT_ASSERT_EQUAL(std::string("test"),std::string(t.name)); + } + { + CharacterSet t("test",""); + for (int j = 0; j < 255; ++j) + CPPUNIT_ASSERT_EQUAL(false,t[j]); + } + { + CharacterSet t("test","0"); + CPPUNIT_ASSERT_EQUAL(true,t['0']); + for (int j = 0; j < 255; ++j) + if (j != '0') + CPPUNIT_ASSERT_EQUAL(false,t[j]); + } +} + +void +testCharacterSet::CharacterSetAdd() +{ + CharacterSet t("test","0"); + t.add(0); + CPPUNIT_ASSERT_EQUAL(true,t['\0']); + CPPUNIT_ASSERT_EQUAL(true,t['0']); +} + +void +testCharacterSet::CharacterSetAddRange() +{ + CharacterSet t("test",""); + t.addRange('0','9'); + CPPUNIT_ASSERT_EQUAL(true,t['0']); + CPPUNIT_ASSERT_EQUAL(true,t['5']); + CPPUNIT_ASSERT_EQUAL(true,t['9']); + CPPUNIT_ASSERT_EQUAL(false,t['a']); +} + +void +testCharacterSet::CharacterSetConstants() +{ + CPPUNIT_ASSERT_EQUAL(true,CharacterSet::ALPHA['a']); + CPPUNIT_ASSERT_EQUAL(true,CharacterSet::ALPHA['z']); + CPPUNIT_ASSERT_EQUAL(true,CharacterSet::ALPHA['A']); + CPPUNIT_ASSERT_EQUAL(true,CharacterSet::ALPHA['Z']); + CPPUNIT_ASSERT_EQUAL(false,CharacterSet::ALPHA['5']); +} + +void +testCharacterSet::CharacterSetUnion() +{ + { + CharacterSet hex("hex",""); + hex += CharacterSet::DIGIT; + hex += CharacterSet(NULL,"aAbBcCdDeEfF"); + for (int j = 0; j < 255; ++j) + CPPUNIT_ASSERT_EQUAL(CharacterSet::HEXDIG[j],hex[j]); + } + { + CharacterSet hex(NULL,""); + hex = CharacterSet::DIGIT + CharacterSet(NULL,"aAbBcCdDeEfF"); + for (int j = 0; j < 255; ++j) + CPPUNIT_ASSERT_EQUAL(CharacterSet::HEXDIG[j],hex[j]); + } +} === added file 'src/base/testCharacterSet.h' --- src/base/testCharacterSet.h 1970-01-01 00:00:00 +0000 +++ src/base/testCharacterSet.h 2013-12-30 09:44:52 +0000 @@ -0,0 +1,26 @@ +#ifndef SQUID_BASE_TESTCHARACTERSET_H +#define SQUID_BASE_TESTCHARACTERSET_H + +#define SQUID_UNIT_TEST 1 + +#include + +class testCharacterSet : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE( testCharacterSet ); + CPPUNIT_TEST( CharacterSetConstruction ); + CPPUNIT_TEST( CharacterSetAdd ); + CPPUNIT_TEST( CharacterSetAddRange ); + CPPUNIT_TEST( CharacterSetConstants ); + CPPUNIT_TEST( CharacterSetUnion ); + CPPUNIT_TEST_SUITE_END(); + +protected: + void CharacterSetConstruction(); + void CharacterSetAdd(); + void CharacterSetAddRange(); + void CharacterSetConstants(); + void CharacterSetUnion(); +}; + +#endif /* SQUID_BASE_TESTCHARACTERSET_H */ # Begin bundle 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