* This avoids a copy to use hash<const char*>
*/
register size_t t = 0;
- for (std::string::const_iterator x = s.begin(); x != s.end(); x++) /* ++x not x++, so we don't hash the \0 */
+ for (std::string::const_iterator x = s.begin(); x != s.end(); ++x) /* ++x not x++, as its faster */
t = 5 * t + lowermap[(unsigned char)*x];
- return size_t(t);
+ return t;
}
bool irc::StrHashComp::operator()(const std::string& s1, const std::string& s2) const
while (n != tokens.end())
{
+ /** Skip multi space, converting " " into " "
+ */
+ while ((n+1 != tokens.end()) && (*n == ' ') && (*(n+1) == ' '))
+ n++;
+
if ((last_pushed) && (*n == ':'))
{
/* If we find a token thats not the first and starts with :,
return n;
}
+
+irc::stringjoiner::stringjoiner(const std::string &seperator, const std::vector<std::string> &sequence, int begin, int end)
+{
+ for (int v = begin; v < end; v++)
+ joined.append(sequence[v]).append(seperator);
+ joined.append(sequence[end]);
+}
+
+irc::stringjoiner::stringjoiner(const std::string &seperator, const std::deque<std::string> &sequence, int begin, int end)
+{
+ for (int v = begin; v < end; v++)
+ joined.append(sequence[v]).append(seperator);
+ joined.append(sequence[end]);
+}
+
+irc::stringjoiner::stringjoiner(const std::string &seperator, const char** sequence, int begin, int end)
+{
+ for (int v = begin; v < end; v++)
+ joined.append(sequence[v]).append(seperator);
+ joined.append(sequence[end]);
+}
+
+std::string& irc::stringjoiner::GetJoined()
+{
+ return joined;
+}
+
+irc::portparser::portparser(const std::string &source, bool allow_overlapped) : in_range(0), range_begin(0), range_end(0), overlapped(allow_overlapped)
+{
+ sep = new irc::commasepstream(source);
+ overlap_set.clear();
+}
+
+irc::portparser::~portparser()
+{
+ delete sep;
+}
+
+bool irc::portparser::Overlaps(long val)
+{
+ if (!overlapped)
+ return false;
+
+ if (overlap_set.find(val) == overlap_set.end())
+ {
+ overlap_set[val] = true;
+ return false;
+ }
+ else
+ return true;
+}
+
+long irc::portparser::GetToken()
+{
+ if (in_range > 0)
+ {
+ in_range++;
+ if (in_range <= range_end)
+ {
+ if (!Overlaps(in_range))
+ {
+ return in_range;
+ }
+ else
+ {
+ while (((Overlaps(in_range)) && (in_range <= range_end)))
+ in_range++;
+
+ if (in_range <= range_end)
+ return in_range;
+ }
+ }
+ else
+ in_range = 0;
+ }
+
+ std::string x = sep->GetToken();
+
+ if (x == "")
+ return 0;
+
+ while (Overlaps(atoi(x.c_str())))
+ {
+ x = sep->GetToken();
+
+ if (x == "")
+ return 0;
+ }
+
+ std::string::size_type dash = x.rfind('-');
+ if (dash != std::string::npos)
+ {
+ std::string sbegin = x.substr(0, dash);
+ std::string send = x.substr(dash+1, x.length());
+ range_begin = atoi(sbegin.c_str());
+ range_end = atoi(send.c_str());
+
+ if ((range_begin > 0) && (range_end > 0) && (range_begin < 65536) && (range_end < 65536) && (range_begin < range_end))
+ {
+ in_range = range_begin;
+ return in_range;
+ }
+ else
+ {
+ /* Assume its just the one port */
+ return atoi(sbegin.c_str());
+ }
+ }
+ else
+ {
+ return atoi(x.c_str());
+ }
+}
+
+irc::dynamicbitmask::dynamicbitmask() : bits_size(4)
+{
+ /* We start with 4 bytes allocated which is room
+ * for 4 items. Something makes me doubt its worth
+ * allocating less than 4 bytes.
+ */
+ bits = new unsigned char[bits_size];
+ freebits = new unsigned char[bits_size];
+ memset(bits, 0, bits_size);
+ memset(freebits, 0, bits_size);
+}
+
+irc::dynamicbitmask::~dynamicbitmask()
+{
+ /* Tidy up the entire used memory on delete */
+ delete[] bits;
+ delete[] freebits;
+}
+
+irc::bitfield irc::dynamicbitmask::Allocate()
+{
+ for (size_t i = 0; i < bits_size; i++)
+ {
+ for (unsigned char current_pos = 1; current_pos; current_pos = current_pos << 1)
+ {
+ if (!(freebits[i] & current_pos))
+ {
+ freebits[i] |= current_pos;
+ return std::make_pair(i, current_pos);
+ }
+ }
+ }
+ /* We dont have any free space left, increase by one */
+ int old_bits_size = bits_size;
+ bits_size++;
+ /* Allocate new bitfield space */
+ unsigned char* temp_bits = new unsigned char[bits_size];
+ unsigned char* temp_freebits = new unsigned char[bits_size];
+ /* Copy the old data in */
+ memcpy(temp_bits, bits, old_bits_size);
+ memcpy(temp_freebits, freebits, old_bits_size);
+ /* Delete the old data pointers */
+ delete[] bits;
+ delete[] freebits;
+ /* Swap the pointers over so now the new
+ * pointers point to our member values
+ */
+ bits = temp_bits;
+ freebits = temp_freebits;
+ /* Initialize the new byte on the end of
+ * the bitfields, pre-allocate the one bit
+ * for this allocation
+ */
+ bits[old_bits_size] = 0;
+ bits[old_bits_size] = 1;
+ /* We already know where we just allocated
+ * the bitfield, so no loop needed
+ */
+ return std::make_pair(old_bits_size, 1);
+}
+
+bool irc::dynamicbitmask::Deallocate(irc::bitfield &pos)
+{
+ /* We dont bother to shrink the bitfield
+ * on deallocation, the most we could do
+ * is save one byte (!) and this would cost
+ * us a loop (ugly O(n) stuff) so we just
+ * clear the bit and leave the memory
+ * claimed -- nobody will care about one
+ * byte.
+ */
+ if (pos.first < bits_size)
+ {
+ freebits[pos.first] &= ~pos.second;
+ return true;
+ }
+ /* They gave a bitfield outside of the
+ * length of our array. BAD programmer.
+ */
+ return false;
+}
+
+void irc::dynamicbitmask::Toggle(irc::bitfield &pos, bool state)
+{
+ if (pos.first < bits_size)
+ {
+ if (state)
+ /* Set state, OR the state in */
+ bits[pos.first] |= pos.second;
+ else
+ /* Clear state, AND the !state out */
+ bits[pos.first] &= ~pos.second;
+ }
+}
+