[pan2] Bug 549655: Suppor 64 bit article numbers



commit 647b8c2cc79468611ef91637cedc3aebb3921119
Author: Charles Kerr <charles rebelbase com>
Date:   Mon Sep 28 18:43:13 2009 -0500

    Bug 549655: Suppor 64 bit article numbers

 pan/data-impl/article-filter.cc |    3 +-
 pan/data-impl/data-impl.h       |   10 +++---
 pan/data-impl/groups.cc         |    9 +++--
 pan/data-impl/headers.cc        |    3 +-
 pan/data-impl/xover.cc          |    2 +-
 pan/data/data.h                 |    8 ++--
 pan/data/xref-test.cc           |    4 +-
 pan/data/xref.cc                |   11 ++++---
 pan/data/xref.h                 |   13 ++++----
 pan/tasks/nntp.cc               |   10 +++---
 pan/tasks/nntp.h                |   11 ++++---
 pan/tasks/nzb-test.cc           |    2 +-
 pan/tasks/task-article.cc       |    2 +-
 pan/tasks/task-xover.cc         |   38 ++++++++++++++++-------
 pan/tasks/task-xover.h          |   12 ++++----
 pan/usenet-utils/numbers.cc     |   63 ++++++++++++++++++--------------------
 pan/usenet-utils/numbers.h      |   25 ++++++++-------
 17 files changed, 123 insertions(+), 103 deletions(-)
---
diff --git a/pan/data-impl/article-filter.cc b/pan/data-impl/article-filter.cc
index e55177c..315131a 100644
--- a/pan/data-impl/article-filter.cc
+++ b/pan/data-impl/article-filter.cc
@@ -22,6 +22,7 @@
 #include <pan/general/debug.h>
 #include <pan/general/macros.h>
 #include <pan/data/data.h>
+#include <glib/gprintf.h>
 #include "article-filter.h"
 
 using namespace pan;
@@ -145,7 +146,7 @@ ArticleFilter :: test_article (const Data        & data,
             s += xit->group;
             s += ':';
             char buf[32];
-            snprintf (buf, sizeof(buf), "%lu", xit->number);
+            g_snprintf (buf, sizeof(buf), "%"G_GUINT64_FORMAT, xit->number);
             s += buf;
             s += ' ';
           }
diff --git a/pan/data-impl/data-impl.h b/pan/data-impl/data-impl.h
index 3e3c6e4..87d660f 100644
--- a/pan/data-impl/data-impl.h
+++ b/pan/data-impl/data-impl.h
@@ -198,7 +198,7 @@ namespace pan
          */
         struct Server {
           Numbers _read;
-          unsigned long _xover_high;
+          uint64_t _xover_high;
           Server(): _xover_high(0) {}
         };
         typedef Loki::AssocVector<Quark,Server> servers_t;
@@ -586,16 +586,16 @@ namespace pan
 
       virtual void xover_unref   (const Quark           & group);
 
-      virtual unsigned long get_xover_high (const Quark & group,
-                                            const Quark & server) const;
+      virtual uint64_t get_xover_high (const Quark & group,
+                                       const Quark & server) const;
 
       virtual void set_xover_high (const Quark          & group,
                                    const Quark          & server,
-                                   const unsigned long    high);
+                                   const uint64_t         high);
 
        virtual void set_xover_low (const Quark          & group,
                                    const Quark          & server,
-                                   const unsigned long    low);
+                                   const uint64_t         low);
 
 
     /**
diff --git a/pan/data-impl/groups.cc b/pan/data-impl/groups.cc
index 0319a73..73941a3 100644
--- a/pan/data-impl/groups.cc
+++ b/pan/data-impl/groups.cc
@@ -28,6 +28,7 @@
 #include <set>
 #include <vector>
 
+#include <glib.h>
 extern "C" {
   #include <unistd.h>
   #include <glib/gi18n.h>
@@ -360,7 +361,7 @@ DataImpl :: load_group_xovers (const DataIO& data_io)
 
         while (line.pop_token (xover))
           if (xover.pop_token(servername,':'))
-            g[servername]._xover_high = strtoul (xover.str, NULL, 10);
+            g[servername]._xover_high = g_ascii_strtoull (xover.str, NULL, 10);
       }
     }
   }
@@ -457,11 +458,11 @@ DataImpl :: save_group_xovers (DataIO& data_io) const
 *****
 ****/
 
-unsigned long
+uint64_t
 DataImpl :: get_xover_high (const Quark  & groupname,
                             const Quark  & servername) const
 {
-  unsigned long high (0ul);
+  uint64_t high (0ul);
   const ReadGroup::Server * rgs (find_read_group_server (groupname, servername));
   if (rgs)
     high = rgs->_xover_high;
@@ -471,7 +472,7 @@ DataImpl :: get_xover_high (const Quark  & groupname,
 void
 DataImpl :: set_xover_high (const Quark & group,
                             const Quark & server,
-                            const unsigned long high)
+                            const uint64_t high)
 {
   //std::cerr << LINE_ID << "setting " << get_server_address(server) << ':' << group << " xover high to " << high << std::endl;
   ReadGroup::Server& rgs (_read_groups[group][server]);
diff --git a/pan/data-impl/headers.cc b/pan/data-impl/headers.cc
index 16b81dd..a3083db 100644
--- a/pan/data-impl/headers.cc
+++ b/pan/data-impl/headers.cc
@@ -24,6 +24,7 @@
 #include <vector>
 #include <string>
 #include <cmath>
+#include <glib.h>
 extern "C" {
   #include <sys/types.h> // for chmod
   #include <sys/stat.h> // for chmod
@@ -510,7 +511,7 @@ DataImpl :: load_headers (const DataIO   & data_io,
           if (tok.pop_token(server_tok,':') && tok.pop_token(group_tok,':')) {
             target_it->server = server_tok;
             target_it->group = group_tok.len==1 ? xref_lookup[(int)*group_tok.str] : Quark(group_tok);
-            target_it->number = atoi (tok.str);
+            target_it->number = g_ascii_strtoull (tok.str, NULL, 10);
             const Server * server (find_server (target_it->server));
             if (server && ((!server->article_expiration_age) || (days_old <= server->article_expiration_age)))
               ++target_it;
diff --git a/pan/data-impl/xover.cc b/pan/data-impl/xover.cc
index 21e3ef4..36a20f6 100644
--- a/pan/data-impl/xover.cc
+++ b/pan/data-impl/xover.cc
@@ -215,7 +215,7 @@ DataImpl :: xover_unref (const Quark& group)
 void
 DataImpl :: set_xover_low (const Quark   & group,
                            const Quark   & server,
-                           const unsigned long   low)
+                           const uint64_t   low)
 {
   ReadGroup::Server * rgs (find_read_group_server (group, server));
   if (rgs != 0)
diff --git a/pan/data/data.h b/pan/data/data.h
index de1af5b..7ca95f0 100644
--- a/pan/data/data.h
+++ b/pan/data/data.h
@@ -556,8 +556,8 @@ namespace pan
        * run on the specified {server,group}, or 0 if it's never 
        * been run there.
        */
-      virtual unsigned long get_xover_high (const Quark  & group,
-                                    const Quark  & server) const = 0;
+      virtual uint64_t get_xover_high (const Quark  & group,
+                                       const Quark  & server) const = 0;
 
        /**
         * After an XOVER command has been run, its range should be set
@@ -567,7 +567,7 @@ namespace pan
         */
        virtual void set_xover_high (const Quark         & group,
                                     const Quark         & server,
-                                    const unsigned long    high) = 0;
+                                    const uint64_t    high) = 0;
 
        /**
         * Used to fold the Newsrc ranges together:
@@ -576,7 +576,7 @@ namespace pan
         */
        virtual void set_xover_low (const Quark         & group,
                                    const Quark         & server,
-                                   const unsigned long   low) = 0;
+                                   const uint64_t   low) = 0;
 
   };
 }
diff --git a/pan/data/xref-test.cc b/pan/data/xref-test.cc
index 936f561..928176d 100644
--- a/pan/data/xref-test.cc
+++ b/pan/data/xref-test.cc
@@ -42,7 +42,7 @@ main (void)
    **/
 
 #if 0
-   unsigned long number;
+   uint64_t number;
    check (s.find (s1, g1, number))
    check (number == 100)
    check (s.find (s2, g1, number))
@@ -105,7 +105,7 @@ main (void)
   check (s.size() == 2);
 
   Quark group;
-  unsigned long number (0ul);
+  uint64_t number (0ul);
   check (s.find ("netfront", group, number))
   check (number!=175094)
   check (number==10033 || number==107169)
diff --git a/pan/data/xref.cc b/pan/data/xref.cc
index 12523c4..8f0869b 100644
--- a/pan/data/xref.cc
+++ b/pan/data/xref.cc
@@ -18,6 +18,7 @@
  */
 
 #include <config.h>
+#include <glib.h>
 #include <pan/general/debug.h>
 #include <pan/general/macros.h>
 #include <pan/general/messages.h>
@@ -42,7 +43,7 @@ Xref :: insert (const Quark             & server,
 
   // walk through the xrefs, of format "group1:number group2:number" 
   targets.reserve (targets.size() + std::count(xref.begin(), xref.end(), ':'));
-  StringView s, group;
+  StringView s;
   while (xref.pop_token (s)) {
     if (s.strchr (':') != 0) {
       StringView group_name;
@@ -50,7 +51,7 @@ Xref :: insert (const Quark             & server,
         Target t;
         t.server = server;
         t.group = group_name;
-        t.number = strtoul (s.str, NULL, 10);
+        t.number = g_ascii_strtoull (s.str, NULL, 10);
         targets.get_container().push_back (t);
       }
     }
@@ -73,7 +74,7 @@ Xref :: remove_server (const Quark& server)
 void
 Xref :: remove_targets_less_than (const Quark    & server,
                                   const Quark    & group,
-                                  unsigned long    n)
+                                  uint64_t         n)
 {
   std::vector<Target> t;
   t.reserve (targets.size());
@@ -105,7 +106,7 @@ Xref :: has_server (const Quark  & server) const
 bool
 Xref :: find (const Quark    & server,
               Quark          & setme_group,
-              unsigned long  & setme_number) const
+              uint64_t       & setme_number) const
 {
   Target tmp;
   tmp.server = server;
@@ -118,7 +119,7 @@ Xref :: find (const Quark    & server,
   return found;
 }
 
-unsigned long
+uint64_t
 Xref :: find_number (const Quark    & server,
                      const Quark    & group) const
 {
diff --git a/pan/data/xref.h b/pan/data/xref.h
index 577d2ad..7236c35 100644
--- a/pan/data/xref.h
+++ b/pan/data/xref.h
@@ -20,6 +20,7 @@
 #ifndef __Xref_h__
 #define __Xref_h__
 
+#include <stdint.h>
 #include <algorithm>
 #include <pan/general/quark.h>
 #include <pan/general/sorted-vector.h>
@@ -47,7 +48,7 @@ namespace pan
       {
         Quark server;
         Quark group;
-        unsigned long number;
+        uint64_t number;
 
         Target (): number(0ul) { }
         bool operator== (const Target& t) const
@@ -57,7 +58,7 @@ namespace pan
           if (group != t.group) return group < t.group;
           return false;
         }
-        Target (const Quark& sq, const Quark& gq, unsigned long n):
+        Target (const Quark& sq, const Quark& gq, uint64_t n):
           server (sq), group (gq), number (n) { }
       };
 
@@ -70,15 +71,15 @@ namespace pan
     public:
       unsigned long size () const { return targets.size(); }
       bool empty () const { return targets.empty(); }
-      unsigned long find_number (const Quark& server, const Quark& group) const;
-      bool find (const Quark& server, Quark& setme_group, unsigned long& setme_number) const;
+      uint64_t find_number (const Quark& server, const Quark& group) const;
+      bool find (const Quark& server, Quark& setme_group, uint64_t& setme_number) const;
       bool has_server (const Quark& server) const;
       void get_servers (quarks_t& addme) const;
 
     public:
       void clear () { targets.clear(); }
       void remove_server (const Quark& server);
-      void remove_targets_less_than (const Quark& s, const Quark& g, unsigned long less_than_this);
+      void remove_targets_less_than (const Quark& s, const Quark& g, uint64_t less_than_this);
 
     public:
 
@@ -86,7 +87,7 @@ namespace pan
         targets.insert (a, b);
       }
       void insert (const Target& target) { targets.insert (target); }
-      void insert (const Quark& s, const Quark& g, unsigned long n) {targets.insert (Target(s,g,n));} 
+      void insert (const Quark& s, const Quark& g, uint64_t n) {targets.insert (Target(s,g,n));} 
       void insert (const Xref& xref) { insert (xref.begin(), xref.end()); }
 
       template<typename ForwardIterator> void assign (ForwardIterator a, ForwardIterator b) {
diff --git a/pan/tasks/nntp.cc b/pan/tasks/nntp.cc
index 4f87a80..d097667 100644
--- a/pan/tasks/nntp.cc
+++ b/pan/tasks/nntp.cc
@@ -334,8 +334,8 @@ NNTP :: write_next_command ()
 
 void
 NNTP :: xover (const Quark   & group,
-               unsigned long   low,
-               unsigned long   high,
+               uint64_t        low,
+               uint64_t        high,
                Listener      * l)
 {
    _listener = l;
@@ -343,7 +343,7 @@ NNTP :: xover (const Quark   & group,
    if (group != _group)
       _commands.push_back (build_command ("GROUP %s\r\n", group.c_str()));
 
-   _commands.push_back (build_command ("XOVER %lu-%lu\r\n", low, high));
+   _commands.push_back (build_command ("XOVER %"G_GUINT64_FORMAT"-%"G_GUINT64_FORMAT"\r\n", low, high));
 
    write_next_command ();
 }
@@ -366,7 +366,7 @@ NNTP :: list (Listener * l)
 
 void
 NNTP :: article (const Quark     & group,
-                 unsigned long     article_number,
+                 uint64_t          article_number,
                  Listener        * l)
 {
    _listener = l;
@@ -374,7 +374,7 @@ NNTP :: article (const Quark     & group,
    if (group != _group)
       _commands.push_back (build_command ("GROUP %s\r\n", group.c_str()));
 
-   _commands.push_back (build_command ("ARTICLE %lu\r\n", article_number));
+   _commands.push_back (build_command ("ARTICLE %"G_GUINT64_FORMAT"\r\n", article_number));
 
    write_next_command ();
 }
diff --git a/pan/tasks/nntp.h b/pan/tasks/nntp.h
index 3c59a11..20e3adf 100644
--- a/pan/tasks/nntp.h
+++ b/pan/tasks/nntp.h
@@ -20,6 +20,7 @@
 #ifndef __NNTP_h__
 #define __NNTP_h__
 
+#include <stdint.h>
 #include <deque>
 #include <pan/general/macros.h> // for UNUSED
 #include <pan/general/quark.h>
@@ -85,8 +86,8 @@ namespace pan
         virtual void on_nntp_group (NNTP               * nntp          UNUSED,
                                     const Quark        & group         UNUSED,
                                     unsigned long        estimated_qty UNUSED,
-                                    unsigned long        low           UNUSED,
-                                    unsigned long        high          UNUSED) {}
+                                    uint64_t             low           UNUSED,
+                                    uint64_t             high          UNUSED) {}
        };
 
       public:
@@ -129,8 +130,8 @@ namespace pan
        * command is successful or not.
        */
       void xover            (const Quark        & group,
-                             unsigned long        low,
-                             unsigned long        high,
+                             uint64_t             low,
+                             uint64_t             high,
                              Listener           * l);
 
       /**
@@ -170,7 +171,7 @@ namespace pan
        * to change groups.
        */
       void article          (const Quark        & group,
-                             unsigned long        article_number,
+                             uint64_t             article_number,
                              Listener           * l);
 
       /**
diff --git a/pan/tasks/nzb-test.cc b/pan/tasks/nzb-test.cc
index c21eb8e..f066c54 100644
--- a/pan/tasks/nzb-test.cc
+++ b/pan/tasks/nzb-test.cc
@@ -81,7 +81,7 @@ int main ()
   check (part_bytes == 102394)
   check (part_mid == "<123456789abcdef news newzbin com>")
   Quark group;
-  unsigned long number;
+  uint64_t number;
   check (a.xref.find ("cox", group, number))
   check (group == "alt.binaries.newzbin")
   check (number == 0)
diff --git a/pan/tasks/task-article.cc b/pan/tasks/task-article.cc
index fdac4c7..3c77f7b 100644
--- a/pan/tasks/task-article.cc
+++ b/pan/tasks/task-article.cc
@@ -207,7 +207,7 @@ TaskArticle :: use_nntp (NNTP * nntp)
     needed->buf.clear ();
 
     Quark group;
-    unsigned long number (0ul);
+    uint64_t number (0ul);
     needed->xref.find (nntp->_server, group, number);
     if (number)
       nntp->article (group, number, this);
diff --git a/pan/tasks/task-xover.cc b/pan/tasks/task-xover.cc
index 27ef109..3affae1 100644
--- a/pan/tasks/task-xover.cc
+++ b/pan/tasks/task-xover.cc
@@ -172,8 +172,8 @@ void
 TaskXOver :: on_nntp_group (NNTP          * nntp,
                             const Quark   & group,
                             unsigned long   qty,
-                            unsigned long   low,
-                            unsigned long   high)
+                            uint64_t        low,
+                            uint64_t        high)
 {
   const Quark& servername (nntp->_server);
 
@@ -188,7 +188,7 @@ TaskXOver :: on_nntp_group (NNTP          * nntp,
          << " low " << low
          << " high " << high);
 
-  unsigned long l(low), h(high);
+  uint64_t l(low), h(high);
   _data.set_xover_low (group, nntp->_server, low);
   //std::cerr << LINE_ID << " This group's range is [" << low << "..." << high << ']' << std::endl;
 
@@ -200,7 +200,7 @@ TaskXOver :: on_nntp_group (NNTP          * nntp,
     l = std::max (low, high+1-_sample_size);
   }
   else { // NEW
-    unsigned long xh (_data.get_xover_high (group, nntp->_server));
+    uint64_t xh (_data.get_xover_high (group, nntp->_server));
     //std::cerr << LINE_ID << " current xover high is " << xh << std::endl;
     l = std::max (xh+1, low);
   }
@@ -211,7 +211,7 @@ TaskXOver :: on_nntp_group (NNTP          * nntp,
     add_steps (h-l);
     const int INCREMENT (1000);
     MiniTasks_t& minitasks (_server_to_minitasks[servername]);
-    for (unsigned long m=l; m<=h; m+=INCREMENT) {
+    for (uint64_t m=l; m<=h; m+=INCREMENT) {
       MiniTask mt (MiniTask::XOVER, m, m+INCREMENT);
       debug ("adding MiniTask for " << servername << ": xover [" << mt._low << '-' << mt._high << ']');
       minitasks.push_front (mt);
@@ -240,6 +240,19 @@ namespace
 
     return ul;
   }
+  uint64_t view_to_ull (const StringView& view)
+  {
+    uint64_t ul = 0ul;
+
+    if (!view.empty()) {
+      errno = 0;
+      ul = g_ascii_strtoull (view.str, 0, 10);
+      if (errno)
+        ul = 0ul;
+    }
+
+    return ul;
+  }
 
   bool header_is_nonencoded_utf8 (const StringView& in)
   {
@@ -260,10 +273,11 @@ TaskXOver :: on_nntp_line (NNTP               * nntp,
   _bytes_so_far += line.len;
 
   unsigned int lines=0u;
-  unsigned long number=0ul, bytes=0ul;
+  unsigned long bytes=0ul;
+  uint64_t number=0;
   StringView subj, author, date, mid, ref, tmp, xref, l(line);
   bool ok = !l.empty();
-  ok = ok && l.pop_token (tmp, '\t');    if (ok) number = view_to_ul (tmp);
+  ok = ok && l.pop_token (tmp, '\t');    if (ok) number = view_to_ull (tmp);
   ok = ok && l.pop_token (subj, '\t');   if (ok) subj.trim ();
   ok = ok && l.pop_token (author, '\t'); if (ok) author.trim ();
   ok = ok && l.pop_token (date, '\t');   if (ok) date.trim ();
@@ -291,10 +305,12 @@ TaskXOver :: on_nntp_line (NNTP               * nntp,
   // if news server doesn't provide an xref, fake one
   char * buf (0);
   if (xref.empty())
-    xref = buf = g_strdup_printf ("%s %s:%lu",
-                       nntp->_server.c_str(), nntp->_group.c_str(), number);
+    xref = buf = g_strdup_printf ("%s %s:%"G_GUINT64_FORMAT,
+                                  nntp->_server.c_str(),
+                                  nntp->_group.c_str(),
+                                  number);
 
-  unsigned long& h (_high[nntp->_server]);
+  uint64_t& h (_high[nntp->_server]);
   h = std::max (h, number);
 
   const char * fallback_charset = NULL; // FIXME
@@ -318,7 +334,7 @@ TaskXOver :: on_nntp_line (NNTP               * nntp,
     ++_articles_so_far;
 
   // emit a status update
-  int& prev = _last_xover_number[nntp];
+  uint64_t& prev = _last_xover_number[nntp];
   increment_step (number - prev);
   prev = number;
   if (!(_parts_so_far % 500))
diff --git a/pan/tasks/task-xover.h b/pan/tasks/task-xover.h
index f551572..8701808 100644
--- a/pan/tasks/task-xover.h
+++ b/pan/tasks/task-xover.h
@@ -49,14 +49,14 @@ namespace pan
     private: // NNTP::Listener
       virtual void on_nntp_line (NNTP*, const StringView&);
       virtual void on_nntp_done (NNTP*, Health, const StringView&);
-      virtual void on_nntp_group (NNTP*, const Quark&, unsigned long, unsigned long, unsigned long);
+      virtual void on_nntp_group (NNTP*, const Quark&, unsigned long, uint64_t, uint64_t);
 
     private: // implementation - minitasks
       struct MiniTask {
         enum Type { GROUP, XOVER };
         Type _type;
-        unsigned long _low, _high;
-        MiniTask (Type type, unsigned long low=0ul, unsigned long high=0ul):
+        uint64_t _low, _high;
+        MiniTask (Type type, uint64_t low=0ul, uint64_t high=0ul):
           _type(type), _low(low), _high(high) {}
       };
       typedef std::deque<MiniTask> MiniTasks_t;
@@ -68,14 +68,14 @@ namespace pan
       const Quark _group;
       std::string _short_group_name;
       Mode _mode;
-      unsigned long _sample_size;
+      uint64_t _sample_size;
       time_t _days_cutoff;
       bool _group_xover_is_reffed;
-      typedef std::map<Quark,unsigned long> server_to_high_t;
+      typedef std::map<Quark,uint64_t> server_to_high_t;
       server_to_high_t _high;
       void update_work (bool subtract_one_from_nntp_count=false);
       std::set<Quark> _servers_that_got_xover_minitasks;
-      std::map<NNTP*,int> _last_xover_number;
+      std::map<NNTP*,uint64_t> _last_xover_number;
       unsigned long _bytes_so_far;
       unsigned long _parts_so_far;
       unsigned long _articles_so_far;
diff --git a/pan/usenet-utils/numbers.cc b/pan/usenet-utils/numbers.cc
index 35d6b71..6e6d0b3 100644
--- a/pan/usenet-utils/numbers.cc
+++ b/pan/usenet-utils/numbers.cc
@@ -21,6 +21,7 @@
 #include <cctype>
 #include <cstdio> // snprintf
 #include <algorithm>
+#include <glib.h>
 #include <pan/general/string-view.h>
 #include "numbers.h"
 
@@ -37,11 +38,11 @@ namespace
    typedef Numbers::ranges_t::const_iterator r_cit;
 
    bool
-   maybe_merge_ranges (Numbers::ranges_t & ranges, int low)
+   maybe_merge_ranges (Numbers::ranges_t & ranges, Numbers::ranges_t::size_type low)
    {
       bool merged = false;
 
-      if (0<=low && low<=(int)ranges.size()-2)
+      if (low+2<=ranges.size())
       {
          Numbers::Range & r1 = ranges[low];
          Numbers::Range & r2 = ranges[low+1];
@@ -60,20 +61,20 @@ namespace
 /**
  * @return the number of articles newly-marked as read 
  */
-unsigned long
+uint64_t
 Numbers :: mark_range (const Range& rr)
 {
-   int i;
-   unsigned long retval = 0;
+   ranges_t::size_type i;
+   uint64_t retval = 0;
    bool range_found = false;
-   int low_index (std::lower_bound (_marked.begin(), _marked.end(), rr.low)
+   ranges_t::size_type low_index (std::lower_bound (_marked.begin(), _marked.end(), rr.low)
                   - _marked.begin());
-   int high_index (std::lower_bound (_marked.begin(), _marked.end(), rr.high)
+   ranges_t::size_type high_index (std::lower_bound (_marked.begin(), _marked.end(), rr.high)
                    - _marked.begin());
 
    retval = rr.high + 1 - rr.low;
 
-   for (i=low_index; i<=high_index && i<(int)_marked.size(); ++i)
+   for (i=low_index; i<=high_index && i<_marked.size(); ++i)
    {
       Range& r = _marked[i];
 
@@ -98,7 +99,7 @@ Numbers :: mark_range (const Range& rr)
       }
       else if (r.contains (rr.low)) /* change high */
       {
-         Range * next = i==(int)_marked.size()-1 ? NULL : &_marked[i+1];
+         Range * next = i==_marked.size()-1 ? NULL : &_marked[i+1];
          range_found = true;
          retval -= r.high+1 - rr.low; /* remove intersection from retval */
          r.high = next ? std::min(rr.high, next->low-1) : rr.high;
@@ -108,11 +109,11 @@ Numbers :: mark_range (const Range& rr)
    if (!range_found)
    {
       _marked.insert (_marked.begin()+low_index, rr);
-      --low_index;
+      if (low_index!=0) --low_index;
       ++high_index;
    }
 
-   for (i=low_index; i<=high_index && i<(int)_marked.size(); )
+   for (i=low_index; i<=high_index && i<_marked.size(); )
    {
       if (maybe_merge_ranges (_marked, i))
          --high_index;
@@ -123,17 +124,17 @@ Numbers :: mark_range (const Range& rr)
    return retval;
 }
 
-unsigned long
+uint64_t
 Numbers :: unmark_range (const Range& ur)
 {
-   unsigned long retval = 0;
-   int i;
-   int low_index (std::lower_bound (_marked.begin(), _marked.end(), ur.low)
+   uint64_t retval = 0;
+   ranges_t::size_type i;
+   ranges_t::size_type low_index (std::lower_bound (_marked.begin(), _marked.end(), ur.low)
                   - _marked.begin());
-   int high_index (std::lower_bound (_marked.begin(), _marked.end(), ur.high)
+   ranges_t::size_type high_index (std::lower_bound (_marked.begin(), _marked.end(), ur.high)
                    - _marked.begin ());
 
-   for (i=low_index; i<=high_index && i<(int)_marked.size(); )
+   for (i=low_index; i<=high_index && i<_marked.size(); )
    {
       Range& r (_marked[i]);
       if (ur.contains (r)) // remove
@@ -173,17 +174,17 @@ Numbers :: unmark_range (const Range& ur)
 ******  MARK (PUBLIC)
 *****/
 
-unsigned long
-Numbers :: mark_range (unsigned long low, unsigned long high, bool add)
+uint64_t
+Numbers :: mark_range (uint64_t low, uint64_t high, bool add)
 {
    const Range r (low, high);
    return add ? mark_range(r) : unmark_range(r);
 }
 
 bool
-Numbers :: mark_one (unsigned long number, bool add)
+Numbers :: mark_one (uint64_t number, bool add)
 {
-   const unsigned long changed_qty (mark_range (number, number, add));
+   const uint64_t changed_qty (mark_range (number, number, add));
 
    if (add)
       return changed_qty==0;
@@ -202,8 +203,8 @@ Numbers :: mark_str (const StringView& str, bool add)
       phigh.pop_token (plow, '-');
       plow.trim ();
       phigh.trim ();
-      const unsigned long low (plow.empty() ? 0 : strtoul (plow.str, NULL, 10));
-      const unsigned long high (phigh.empty() ? low : strtoul (phigh.str, NULL, 10));
+      const uint64_t low (plow.empty() ? 0 : g_ascii_strtoull (plow.str, NULL, 10));
+      const uint64_t high (phigh.empty() ? low : g_ascii_strtoull (phigh.str, NULL, 10));
       mark_range (low, high, add);
    }
 }
@@ -219,7 +220,7 @@ Numbers :: clear ()
 *****/
 
 void
-Numbers :: clip (unsigned long low, unsigned long high)
+Numbers :: clip (uint64_t low, uint64_t high)
 {
    r_it it = std::lower_bound (_marked.begin(), _marked.end(), low);
    _marked.erase (_marked.begin(), it);
@@ -238,7 +239,7 @@ Numbers :: clip (unsigned long low, unsigned long high)
 *****/
 
 bool
-Numbers :: is_marked (unsigned long number) const
+Numbers :: is_marked (uint64_t number) const
 {
    r_cit it = std::lower_bound (_marked.begin(), _marked.end(), number);
 
@@ -263,15 +264,11 @@ Numbers :: to_string (std::string & str) const
    {
       Range r (*it);
 
-      snprintf (buf, sizeof(buf), "%lu", r.low);
+      if (r.low == r.high)
+        g_snprintf (buf, sizeof(buf), "%"G_GUINT64_FORMAT, r.low);
+      else
+         g_snprintf (buf, sizeof(buf), "%"G_GUINT64_FORMAT"-%"G_GUINT64_FORMAT, r.low, r.high);
       str += buf;
-
-      if (r.low != r.high) {
-         snprintf (buf, sizeof(buf), "-%lu", r.high);
-         str += buf;
-      }
-
-      str += ',';
    }
 
    if (!str.empty())
diff --git a/pan/usenet-utils/numbers.h b/pan/usenet-utils/numbers.h
index da6a77b..d2b0588 100644
--- a/pan/usenet-utils/numbers.h
+++ b/pan/usenet-utils/numbers.h
@@ -20,6 +20,7 @@
 #ifndef __Numbers_h__
 #define __Numbers_h__
 
+#include <stdint.h>
 #include <vector>
 #include <pan/general/string-view.h>
 
@@ -38,25 +39,25 @@ namespace pan
 
       /** Simple two-field struct defining a range. */
       struct Range {
-        unsigned long low;
-        unsigned long high;
+        uint64_t low;
+        uint64_t high;
         bool operator ==(const Range& that) const {
           return low==that.low && high==that.high;
         }
         Range (): low(0), high(0) {}
-        Range (unsigned long l, unsigned long h): low(l<h?l:h), high(h>l?h:l) {}
-        bool contains (unsigned long point) const {
+        Range (uint64_t l, uint64_t h): low(l<h?l:h), high(h>l?h:l) {}
+        bool contains (uint64_t point) const {
           return low<=point && point<=high;
         }
         bool contains (const Range& r) const {
           return low<=r.low && r.high<=high;
         }
-        int compare (unsigned long point) const {
+        int compare (uint64_t point) const {
           if (point < low) return -1;
           if (point > high) return 1;
           return 0;
         }
-        bool operator< (unsigned long point) const {
+        bool operator< (uint64_t point) const {
           return high < point;
         }
       };
@@ -65,8 +66,8 @@ namespace pan
       
     private:
       ranges_t _marked;
-      unsigned long mark_range (const Range&);
-      unsigned long unmark_range (const Range&);
+      uint64_t mark_range (const Range&);
+      uint64_t unmark_range (const Range&);
 
     public:
       bool operator== (const Numbers& that) const {
@@ -85,7 +86,7 @@ namespace pan
        * @param add true if we're adding the number, false if removing
        * @return the number's previous state in the set.
        */
-      bool mark_one (unsigned long number, bool add=true);
+      bool mark_one (uint64_t number, bool add=true);
 
       /**
        * Add or remove the specified range of numbers from the set.
@@ -96,7 +97,7 @@ namespace pan
        * @param add true if we're adding the numbers, false if removing
        * @return the quantity of numbers whose presence in the set changed.
        */
-      unsigned long mark_range (unsigned long low, unsigned long high, bool add=true);
+      uint64_t mark_range (uint64_t low, uint64_t high, bool add=true);
 
       /**
        * Mark numbers from a text string in to_str() and from_str() fromat.
@@ -108,7 +109,7 @@ namespace pan
       /**
        * @return true if the number is in this set, false otherwise
        */
-      bool is_marked (const unsigned long) const;
+      bool is_marked (const uint64_t) const;
 
       void clear ();
 
@@ -122,7 +123,7 @@ namespace pan
 
     public:
 
-      void clip (const unsigned long low, const unsigned long high);
+      void clip (const uint64_t low, const uint64_t high);
   };
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]