Drop sprintf dependency
[novacoin.git] / src / uint256.h
index 95e3749..526aa71 100644 (file)
@@ -5,15 +5,13 @@
 #ifndef BITCOIN_UINT256_H
 #define BITCOIN_UINT256_H
 
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
+#include <limits>
 #include <string>
 #include <vector>
-#include <stdint.h>
-
-inline int Testuint256AdHoc(std::vector<std::string> vArg);
+#include <iomanip>
+#include <sstream>
 
+using namespace std;
 
 
 /** Base class without constructors for uint256 and uint160.
@@ -24,9 +22,17 @@ class base_uint
 {
 protected:
     enum { WIDTH=BITS/32 };
-    unsigned int pn[WIDTH];
+    uint32_t pn[WIDTH];
 public:
 
+    const base_uint max()
+    {
+        base_uint ret;
+        for (int i = 0; i < WIDTH; i++)
+            ret.pn[i] = std::numeric_limits<uint32_t>::max();
+        return ret;
+    }
+
     bool operator!() const
     {
         for (int i = 0; i < WIDTH; i++)
@@ -65,8 +71,8 @@ public:
 
     base_uint& operator=(uint64_t b)
     {
-        pn[0] = (unsigned int)b;
-        pn[1] = (unsigned int)(b >> 32);
+        pn[0] = (uint32_t)b;
+        pn[1] = (uint32_t)(b >> 32);
         for (int i = 2; i < WIDTH; i++)
             pn[i] = 0;
         return *this;
@@ -95,15 +101,15 @@ public:
 
     base_uint& operator^=(uint64_t b)
     {
-        pn[0] ^= (unsigned int)b;
-        pn[1] ^= (unsigned int)(b >> 32);
+        pn[0] ^= (uint32_t)b;
+        pn[1] ^= (uint32_t)(b >> 32);
         return *this;
     }
 
     base_uint& operator|=(uint64_t b)
     {
-        pn[0] |= (unsigned int)b;
-        pn[1] |= (unsigned int)(b >> 32);
+        pn[0] |= (uint32_t)b;
+        pn[1] |= (uint32_t)(b >> 32);
         return *this;
     }
 
@@ -269,9 +275,9 @@ public:
 
     friend inline bool operator==(const base_uint& a, uint64_t b)
     {
-        if (a.pn[0] != (unsigned int)b)
+        if (a.pn[0] != (uint32_t)b)
             return false;
-        if (a.pn[1] != (unsigned int)(b >> 32))
+        if (a.pn[1] != (uint32_t)(b >> 32))
             return false;
         for (int i = 2; i < base_uint::WIDTH; i++)
             if (a.pn[i] != 0)
@@ -289,14 +295,13 @@ public:
         return (!(a == b));
     }
 
-
-
     std::string GetHex() const
     {
-        char psz[sizeof(pn)*2 + 1];
-        for (unsigned int i = 0; i < sizeof(pn); i++)
-            sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
-        return std::string(psz, psz + sizeof(pn)*2);
+        std::stringstream ss;
+        size_t pn_size = sizeof(pn) / sizeof(pn[0]);
+        for (size_t i = 1; i <= pn_size; i++)
+             ss << std::setfill('0') << std::setw(8) << std::setbase(16) << pn[pn_size-i];
+        return ss.str();
     }
 
     void SetHex(const char* psz)
@@ -341,12 +346,12 @@ public:
         return (GetHex());
     }
 
-    unsigned char* begin()
+    unsigned char* begin() const
     {
         return (unsigned char*)&pn[0];
     }
 
-    unsigned char* end()
+    unsigned char* end() const
     {
         return (unsigned char*)&pn[WIDTH];
     }
@@ -356,7 +361,7 @@ public:
         return std::vector<unsigned char>(begin(), end());
     }
 
-    unsigned int size()
+    size_t size() const
     {
         return sizeof(pn);
     }
@@ -366,11 +371,30 @@ public:
         return pn[2*n] | (uint64_t)pn[2*n+1] << 32;
     }
 
+    uint32_t Get32(int n=0) const
+    {
+        return pn[n];
+    }
+
     unsigned int GetSerializeSize(int nType, int nVersion) const
     {
         return sizeof(pn);
     }
 
+    unsigned int bits() const
+    {
+        for (int pos = WIDTH - 1; pos >= 0; pos--) {
+            if (pn[pos]) {
+                for (int bits = 31; bits > 0; bits--) {
+                    if (pn[pos] & 1 << bits)
+                        return 32 * pos + bits + 1;
+                }
+                return 32 * pos + 1;
+            }
+        }
+        return 0;
+    }
+
     template<typename Stream>
     void Serialize(Stream& s, int nType, int nVersion) const
     {
@@ -385,7 +409,6 @@ public:
 
     friend class uint160;
     friend class uint256;
-    friend inline int Testuint256AdHoc(std::vector<std::string> vArg);
 };
 
 typedef base_uint<160> base_uint160;
@@ -409,54 +432,13 @@ class uint160 : public base_uint160
 public:
     typedef base_uint160 basetype;
 
-    uint160()
-    {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = 0;
-    }
-
-    uint160(const basetype& b)
-    {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = b.pn[i];
-    }
-
-    uint160& operator=(const basetype& b)
-    {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = b.pn[i];
-        return *this;
-    }
-
-    uint160(uint64_t b)
-    {
-        pn[0] = (unsigned int)b;
-        pn[1] = (unsigned int)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-    }
-
-    uint160& operator=(uint64_t b)
-    {
-        pn[0] = (unsigned int)b;
-        pn[1] = (unsigned int)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-        return *this;
-    }
-
-    explicit uint160(const std::string& str)
-    {
-        SetHex(str);
-    }
-
-    explicit uint160(const std::vector<unsigned char>& vch)
-    {
-        if (vch.size() == sizeof(pn))
-            memcpy(pn, &vch[0], sizeof(pn));
-        else
-            *this = 0;
-    }
+    uint160();
+    uint160(const basetype& b);
+    uint160& operator=(const basetype& b);
+    uint160(uint64_t b);
+    uint160& operator=(uint64_t b);
+    explicit uint160(const std::string& str);
+    explicit uint160(const std::vector<unsigned char>& vch);
 };
 
 inline bool operator==(const uint160& a, uint64_t b)                           { return (base_uint160)a == b; }
@@ -518,60 +500,37 @@ inline const uint160 operator-(const uint160& a, const uint160& b)      { return
 // uint256
 //
 
+
+/** Errors thrown by the uint256 class */
+class uint256_error : public std::exception
+{
+public:
+        explicit uint256_error(const std::string& error_message)  : what_(error_message) {}
+
+        virtual const char* what() const throw () { return what_.c_str(); }
+        virtual ~uint256_error() throw () {}
+private:
+        std::string what_; 
+};
+
 /** 256-bit unsigned integer */
 class uint256 : public base_uint256
 {
 public:
     typedef base_uint256 basetype;
 
-    uint256()
-    {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = 0;
-    }
-
-    uint256(const basetype& b)
-    {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = b.pn[i];
-    }
-
-    uint256& operator=(const basetype& b)
-    {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = b.pn[i];
-        return *this;
-    }
-
-    uint256(uint64_t b)
-    {
-        pn[0] = (unsigned int)b;
-        pn[1] = (unsigned int)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-    }
-
-    uint256& operator=(uint64_t b)
-    {
-        pn[0] = (unsigned int)b;
-        pn[1] = (unsigned int)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-        return *this;
-    }
-
-    explicit uint256(const std::string& str)
-    {
-        SetHex(str);
-    }
-
-    explicit uint256(const std::vector<unsigned char>& vch)
-    {
-        if (vch.size() == sizeof(pn))
-            memcpy(pn, &vch[0], sizeof(pn));
-        else
-            *this = 0;
-    }
+    uint256();
+    uint256(const basetype& b);
+    uint256& operator=(const basetype& b);
+    uint256(uint64_t b);
+    uint256& operator=(uint64_t b);
+    uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL);
+    uint32_t GetCompact(bool fNegative = false) const;
+    uint256& operator*=(uint32_t b32);
+    uint256& operator*=(const uint256& b);
+    uint256& operator/=(const uint256& b);
+    explicit uint256(const std::string& str);
+    explicit uint256(const std::vector<unsigned char>& vch);
 };
 
 inline bool operator==(const uint256& a, uint64_t b)                           { return (base_uint256)a == b; }
@@ -585,6 +544,8 @@ inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { r
 inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; }
 inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; }
 inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; }
+inline const uint256 operator*(const base_uint256& a, const base_uint256& b) { return uint256(a) *= b; }
+inline const uint256 operator/(const base_uint256& a, const base_uint256& b) { return uint256(a) /= b; }
 inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; }
 
 inline bool operator<(const base_uint256& a, const uint256& b)          { return (base_uint256)a <  (base_uint256)b; }
@@ -597,6 +558,8 @@ inline const uint256 operator^(const base_uint256& a, const uint256& b) { return
 inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a &  (base_uint256)b; }
 inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a |  (base_uint256)b; }
 inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a +  (base_uint256)b; }
+inline const uint256 operator*(const base_uint256& a, const uint256& b) { return (base_uint256)a *  (base_uint256)b; }
+inline const uint256 operator/(const base_uint256& a, const uint256& b) { return (base_uint256)a /  (base_uint256)b; }
 inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a -  (base_uint256)b; }
 
 inline bool operator<(const uint256& a, const base_uint256& b)          { return (base_uint256)a <  (base_uint256)b; }