X-Git-Url: http://p2p-next.cs.pub.ro/gitweb/?a=blobdiff_plain;f=src%2Flibswift_udp%2Fbin.cpp;fp=src%2Flibswift_udp%2Fbin.cpp;h=1878f3ea558ded9f662b1ad9dcd0684394eddc9c;hb=46f3ca346fe499ba3e8f595fc5c2aa2b3e3c4d5f;hp=0000000000000000000000000000000000000000;hpb=d8da6fc1273a2acee935a15761b77a73424faef5;p=swifty.git diff --git a/src/libswift_udp/bin.cpp b/src/libswift_udp/bin.cpp new file mode 100644 index 0000000..1878f3e --- /dev/null +++ b/src/libswift_udp/bin.cpp @@ -0,0 +1,169 @@ +/* + * bin.cpp + * swift + * + * Created by Victor Grishchenko on 10/10/09. + * Reimplemented by Alexander G. Pronchenkov on 05/05/10 + * + * Copyright 2010 Delft University of Technology. All rights reserved. + * + */ + +#include "bin.h" +#include + + +const bin_t bin_t::NONE(8 * sizeof(bin_t::uint_t), 0); +const bin_t bin_t::ALL(8 * sizeof(bin_t::uint_t) - 1, 0); + + +/* Methods */ + +/** + * Gets the layer value of a bin + */ +int bin_t::layer(void) const +{ + if (is_none()) { + return -1; + } + + int r = 0; + +#ifdef _MSC_VER +# pragma warning (push) +# pragma warning (disable:4146) +#endif + register uint_t tail; + tail = v_ + 1; + tail = tail & (-tail); +#ifdef _MSC_VER +# pragma warning (pop) +#endif + + if (tail > 0x80000000U) { + r = 32; + tail >>= 16; // FIXME: hide warning + tail >>= 16; + } + + // courtesy of Sean Eron Anderson + // http://graphics.stanford.edu/~seander/bithacks.html + static const char DeBRUIJN[32] = { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 }; + + return r + DeBRUIJN[ 0x1f & ((tail * 0x077CB531U) >> 27) ]; +} + +/* String operations */ + +namespace { + +char* append(char* buf, int x) +{ + char* l = buf; + char* r = buf; + + if (x < 0) { + *r++ = '-'; + x = -x; + } + + do { + *r++ = '0' + x % 10; + x /= 10; + } while (x); + + char* e = r--; + + while (l < r) { + const char t = *l; + *l++ = *r; + *r-- = t; + } + + *e = '\0'; + + return e; +} + +char* append(char* buf, bin_t::uint_t x) +{ + char* l = buf; + char* r = buf; + + do { + *r++ = '0' + x % 10; + x /= 10; + } while (x); + + char* e = r--; + + while (l < r) { + const char t = *l; + *l++ = *r; + *r-- = t; + } + + *e = '\0'; + + return e; +} + +char* append(char* buf, const char* s) +{ + char* e = buf; + + while (*s) { + *e++ = *s++; + } + + *e = '\0'; + + return e; +} + +char* append(char* buf, char c) +{ + char* e = buf; + + *e++ = c; + *e = '\0'; + + return e; +} + +} /* namespace */ + + +/** + * Get the standard-form of this bin, e.g. "(2,1)". + * (buffer should have enough of space) + */ +const char* bin_t::str(char* buf) const +{ + char* e = buf; + + if (is_all()) { + e = append(e, "(ALL)"); + } else if (is_none()) { + e = append(e, "(NONE)"); + } else { + e = append(e, '('); + e = append(e, layer()); + e = append(e, ','); + e = append(e, layer_offset()); + e = append(e, ')'); + } + + return buf; +} + + +/** + * Output operator + */ +std::ostream & operator << (std::ostream & ostream, const bin_t & bin) +{ + char bin_name_buf[64]; + return ostream << bin.str(bin_name_buf); +}