}
CharacterSet &
-CharacterSet::addRange(const unsigned char low, const unsigned char high)
+CharacterSet::addRange(const RangeSpec & v)
{
- assert(low <= high);
- unsigned char c = low;
- while (c <= high) {
- chars_[static_cast<uint8_t>(c)] = 1;
- ++c;
+ for (RangeSpec::const_iterator i = v.begin(); i != v.end(); ++i) {
+ assert(i->first <= i->second);
+ unsigned char c = i->first;
+ unsigned char high = i->second;
+ while (c <= high) {
+ chars_[static_cast<uint8_t>(c)] = 1;
+ ++c;
+ }
}
return *this;
}
add(c[i]);
}
+CharacterSet::CharacterSet(const char *label, const RangeSpec & ranges)
+: CharacterSet(label,"")
+{
+ addRange(ranges);
+}
+
const CharacterSet
-CharacterSet::ALPHA("ALPHA","ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),
+CharacterSet::ALPHA("ALPHA", {{ 'a', 'z' }, { 'A', 'Z'} }),
CharacterSet::BIT("BIT","01"),
+CharacterSet::CHAR("CHAR",{{ 1, 127}}),
CharacterSet::CRLF("CRLF","\r\n"),
CharacterSet::DIGIT("DIGIT","0123456789"),
CharacterSet::HEXDIG("HEXDIG","0123456789aAbBcCdDeEfF"),
{
public:
typedef std::vector<uint8_t> Storage;
+ typedef std::vector<std::pair<unsigned char, unsigned char> > RangeSpec;
/// define a character set with the given label ("anonymous" if NULL)
/// 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, const RangeSpec &);
+
/// whether a given character exists in the set
bool operator[](unsigned char c) const {return chars_[static_cast<uint8_t>(c)] != 0;}
/// add a given character to the character set
CharacterSet & add(const unsigned char c);
- /// add a character range to the set from low to high included
- CharacterSet & addRange(const unsigned char low, const unsigned char high);
+ /** add a list of character ranges, expressed as pairs [low,high]
+ *
+ * Both ends of the specified ranges are included in the added set
+ * e.g. addRange(RangeSpec( { { '0','9'}, { 'a', 'z' } ) )
+ */
+ CharacterSet & addRange(const RangeSpec &);
/// add all characters from the given CharacterSet to this one
CharacterSet &operator +=(const CharacterSet &src);
static const CharacterSet ALPHA;
// 0-1
static const CharacterSet BIT;
+ // any 7-bit US-ASCII character, except for NUL
+ static const CharacterSet CHAR;
// CRLF
static const CharacterSet CRLF;
// 0-9
// <space><tab>
static const CharacterSet WSP;
-
private:
/** index of characters in this set
*
testCharacterSet::CharacterSetAddRange()
{
CharacterSet t("test","");
- t.addRange('0','9');
+ t.addRange(CharacterSet::RangeSpec( { { '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']);
+}
CPPUNIT_TEST( CharacterSetConstruction );
CPPUNIT_TEST( CharacterSetAdd );
CPPUNIT_TEST( CharacterSetAddRange );
+ CPPUNIT_TEST( CharacterSetConstants );
CPPUNIT_TEST_SUITE_END();
protected:
void CharacterSetConstruction();
void CharacterSetAdd();
void CharacterSetAddRange();
+ void CharacterSetConstants();
};
#endif /* SQUID_BASE_TESTCHARACTERSET_H */