Pieter Wuille
13 years ago
3 changed files with 371 additions and 0 deletions
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef _BITCOIN_COMPAT_H |
||||
#define _BITCOIN_COMPAT_H 1 |
||||
|
||||
#ifdef WIN32 |
||||
#define _WIN32_WINNT 0x0501 |
||||
#define WIN32_LEAN_AND_MEAN 1 |
||||
#ifndef NOMINMAX |
||||
#define NOMINMAX |
||||
#endif |
||||
#include <winsock2.h> |
||||
#include <mswsock.h> |
||||
#include <ws2tcpip.h> |
||||
#else |
||||
#include <sys/types.h> |
||||
#include <sys/socket.h> |
||||
#include <sys/fcntl.h> |
||||
#include <arpa/inet.h> |
||||
#include <netdb.h> |
||||
#include <net/if.h> |
||||
#include <netinet/in.h> |
||||
#include <ifaddrs.h> |
||||
#endif |
||||
|
||||
typedef u_int SOCKET; |
||||
#ifdef WIN32 |
||||
#define MSG_NOSIGNAL 0 |
||||
#define MSG_DONTWAIT 0 |
||||
typedef int socklen_t; |
||||
#else |
||||
#include "errno.h" |
||||
#define WSAGetLastError() errno |
||||
#define WSAEINVAL EINVAL |
||||
#define WSAEALREADY EALREADY |
||||
#define WSAEWOULDBLOCK EWOULDBLOCK |
||||
#define WSAEMSGSIZE EMSGSIZE |
||||
#define WSAEINTR EINTR |
||||
#define WSAEINPROGRESS EINPROGRESS |
||||
#define WSAEADDRINUSE EADDRINUSE |
||||
#define WSAENOTSOCK EBADF |
||||
#define INVALID_SOCKET (SOCKET)(~0) |
||||
#define SOCKET_ERROR -1 |
||||
#endif |
||||
|
||||
inline int myclosesocket(SOCKET& hSocket) |
||||
{ |
||||
if (hSocket == INVALID_SOCKET) |
||||
return WSAENOTSOCK; |
||||
#ifdef WIN32 |
||||
int ret = closesocket(hSocket); |
||||
#else |
||||
int ret = close(hSocket); |
||||
#endif |
||||
hSocket = INVALID_SOCKET; |
||||
return ret; |
||||
} |
||||
#define closesocket(s) myclosesocket(s) |
||||
|
||||
|
||||
#endif |
@ -0,0 +1,90 @@
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> |
||||
* |
||||
* Permission to use, copy, modify, and distribute this software for any |
||||
* purpose with or without fee is hereby granted, provided that the above |
||||
* copyright notice and this permission notice appear in all copies. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
*/ |
||||
#ifndef BITCOIN_STRLCPY_H |
||||
#define BITCOIN_STRLCPY_H |
||||
|
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters |
||||
* will be copied. Always NUL terminates (unless siz == 0). |
||||
* Returns strlen(src); if retval >= siz, truncation occurred. |
||||
*/ |
||||
inline size_t strlcpy(char *dst, const char *src, size_t siz) |
||||
{ |
||||
char *d = dst; |
||||
const char *s = src; |
||||
size_t n = siz; |
||||
|
||||
/* Copy as many bytes as will fit */ |
||||
if (n != 0) |
||||
{ |
||||
while (--n != 0) |
||||
{ |
||||
if ((*d++ = *s++) == '\0') |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */ |
||||
if (n == 0) |
||||
{ |
||||
if (siz != 0) |
||||
*d = '\0'; /* NUL-terminate dst */ |
||||
while (*s++) |
||||
; |
||||
} |
||||
|
||||
return(s - src - 1); /* count does not include NUL */ |
||||
} |
||||
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the |
||||
* full size of dst, not space left). At most siz-1 characters |
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)). |
||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)). |
||||
* If retval >= siz, truncation occurred. |
||||
*/ |
||||
inline size_t strlcat(char *dst, const char *src, size_t siz) |
||||
{ |
||||
char *d = dst; |
||||
const char *s = src; |
||||
size_t n = siz; |
||||
size_t dlen; |
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */ |
||||
while (n-- != 0 && *d != '\0') |
||||
d++; |
||||
dlen = d - dst; |
||||
n = siz - dlen; |
||||
|
||||
if (n == 0) |
||||
return(dlen + strlen(s)); |
||||
while (*s != '\0') |
||||
{ |
||||
if (n != 1) |
||||
{ |
||||
*d++ = *s; |
||||
n--; |
||||
} |
||||
s++; |
||||
} |
||||
*d = '\0'; |
||||
|
||||
return(dlen + (s - src)); /* count does not include NUL */ |
||||
} |
||||
#endif |
@ -0,0 +1,218 @@
@@ -0,0 +1,218 @@
|
||||
#include <stdio.h> |
||||
#include "util.h" |
||||
|
||||
using namespace std; |
||||
|
||||
string vstrprintf(const std::string &format, va_list ap) |
||||
{ |
||||
char buffer[50000]; |
||||
char* p = buffer; |
||||
int limit = sizeof(buffer); |
||||
int ret; |
||||
loop |
||||
{ |
||||
va_list arg_ptr; |
||||
va_copy(arg_ptr, ap); |
||||
ret = vsnprintf(p, limit, format.c_str(), arg_ptr); |
||||
va_end(arg_ptr); |
||||
if (ret >= 0 && ret < limit) |
||||
break; |
||||
if (p != buffer) |
||||
delete[] p; |
||||
limit *= 2; |
||||
p = new char[limit]; |
||||
if (p == NULL) |
||||
throw std::bad_alloc(); |
||||
} |
||||
string str(p, p+ret); |
||||
if (p != buffer) |
||||
delete[] p; |
||||
return str; |
||||
} |
||||
|
||||
string EncodeBase32(const unsigned char* pch, size_t len) |
||||
{ |
||||
static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567"; |
||||
|
||||
string strRet=""; |
||||
strRet.reserve((len+4)/5*8); |
||||
|
||||
int mode=0, left=0; |
||||
const unsigned char *pchEnd = pch+len; |
||||
|
||||
while (pch<pchEnd) |
||||
{ |
||||
int enc = *(pch++); |
||||
switch (mode) |
||||
{ |
||||
case 0: // we have no bits
|
||||
strRet += pbase32[enc >> 3]; |
||||
left = (enc & 7) << 2; |
||||
mode = 1; |
||||
break; |
||||
|
||||
case 1: // we have three bits
|
||||
strRet += pbase32[left | (enc >> 6)]; |
||||
strRet += pbase32[(enc >> 1) & 31]; |
||||
left = (enc & 1) << 4; |
||||
mode = 2; |
||||
break; |
||||
|
||||
case 2: // we have one bit
|
||||
strRet += pbase32[left | (enc >> 4)]; |
||||
left = (enc & 15) << 1; |
||||
mode = 3; |
||||
break; |
||||
|
||||
case 3: // we have four bits
|
||||
strRet += pbase32[left | (enc >> 7)]; |
||||
strRet += pbase32[(enc >> 2) & 31]; |
||||
left = (enc & 3) << 3; |
||||
mode = 4; |
||||
break; |
||||
|
||||
case 4: // we have two bits
|
||||
strRet += pbase32[left | (enc >> 5)]; |
||||
strRet += pbase32[enc & 31]; |
||||
mode = 0; |
||||
} |
||||
} |
||||
|
||||
static const int nPadding[5] = {0, 6, 4, 3, 1}; |
||||
if (mode) |
||||
{ |
||||
strRet += pbase32[left]; |
||||
for (int n=0; n<nPadding[mode]; n++) |
||||
strRet += '='; |
||||
} |
||||
|
||||
return strRet; |
||||
} |
||||
|
||||
string EncodeBase32(const string& str) |
||||
{ |
||||
return EncodeBase32((const unsigned char*)str.c_str(), str.size()); |
||||
} |
||||
|
||||
vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid) |
||||
{ |
||||
static const int decode32_table[256] = |
||||
{ |
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, |
||||
-1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2, |
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, |
||||
23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 |
||||
}; |
||||
|
||||
if (pfInvalid) |
||||
*pfInvalid = false; |
||||
|
||||
vector<unsigned char> vchRet; |
||||
vchRet.reserve((strlen(p))*5/8); |
||||
|
||||
int mode = 0; |
||||
int left = 0; |
||||
|
||||
while (1) |
||||
{ |
||||
int dec = decode32_table[(unsigned char)*p]; |
||||
if (dec == -1) break; |
||||
p++; |
||||
switch (mode) |
||||
{ |
||||
case 0: // we have no bits and get 5
|
||||
left = dec; |
||||
mode = 1; |
||||
break; |
||||
|
||||
case 1: // we have 5 bits and keep 2
|
||||
vchRet.push_back((left<<3) | (dec>>2)); |
||||
left = dec & 3; |
||||
mode = 2; |
||||
break; |
||||
|
||||
case 2: // we have 2 bits and keep 7
|
||||
left = left << 5 | dec; |
||||
mode = 3; |
||||
break; |
||||
|
||||
case 3: // we have 7 bits and keep 4
|
||||
vchRet.push_back((left<<1) | (dec>>4)); |
||||
left = dec & 15; |
||||
mode = 4; |
||||
break; |
||||
|
||||
case 4: // we have 4 bits, and keep 1
|
||||
vchRet.push_back((left<<4) | (dec>>1)); |
||||
left = dec & 1; |
||||
mode = 5; |
||||
break; |
||||
|
||||
case 5: // we have 1 bit, and keep 6
|
||||
left = left << 5 | dec; |
||||
mode = 6; |
||||
break; |
||||
|
||||
case 6: // we have 6 bits, and keep 3
|
||||
vchRet.push_back((left<<2) | (dec>>3)); |
||||
left = dec & 7; |
||||
mode = 7; |
||||
break; |
||||
|
||||
case 7: // we have 3 bits, and keep 0
|
||||
vchRet.push_back((left<<5) | dec); |
||||
mode = 0; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (pfInvalid) |
||||
switch (mode) |
||||
{ |
||||
case 0: // 8n base32 characters processed: ok
|
||||
break; |
||||
|
||||
case 1: // 8n+1 base32 characters processed: impossible
|
||||
case 3: // +3
|
||||
case 6: // +6
|
||||
*pfInvalid = true; |
||||
break; |
||||
|
||||
case 2: // 8n+2 base32 characters processed: require '======'
|
||||
if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1) |
||||
*pfInvalid = true; |
||||
break; |
||||
|
||||
case 4: // 8n+4 base32 characters processed: require '===='
|
||||
if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1) |
||||
*pfInvalid = true; |
||||
break; |
||||
|
||||
case 5: // 8n+5 base32 characters processed: require '==='
|
||||
if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1) |
||||
*pfInvalid = true; |
||||
break; |
||||
|
||||
case 7: // 8n+7 base32 characters processed: require '='
|
||||
if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1) |
||||
*pfInvalid = true; |
||||
break; |
||||
} |
||||
|
||||
return vchRet; |
||||
} |
||||
|
||||
string DecodeBase32(const string& str) |
||||
{ |
||||
vector<unsigned char> vchRet = DecodeBase32(str.c_str()); |
||||
return string((const char*)&vchRet[0], vchRet.size()); |
||||
} |
Loading…
Reference in new issue