+ synchronization with the zimlib svn trunk

pull/9/head
kelson42 15 years ago
parent 653257cb1f
commit 9a9c9baf94

@ -86,11 +86,15 @@ namespace zim
const_iterator find(const std::string& url);
bool good() const { return impl.getPointer() != 0; }
time_t getMTime() const { return impl->getMTime(); }
const std::string& getMimeType(uint16_t idx) const { return impl->getMimeType(idx); }
std::string getChecksum() { return impl->getChecksum(); }
bool verify() { return impl->verify(); }
};
std::string urldecode(const std::string& url);
}
#endif // ZIM_FILE_H

@ -45,6 +45,7 @@ namespace zim
offset_type blobPtrPos;
size_type mainPage;
size_type layoutPage;
offset_type checksumPos;
public:
Fileheader()
@ -54,7 +55,8 @@ namespace zim
blobCount(0),
blobPtrPos(0),
mainPage(std::numeric_limits<size_type>::max()),
layoutPage(std::numeric_limits<size_type>::max())
layoutPage(std::numeric_limits<size_type>::max()),
checksumPos(std::numeric_limits<offset_type>::max())
{}
const Uuid& getUuid() const { return uuid; }
@ -85,6 +87,10 @@ namespace zim
bool hasLayoutPage() const { return layoutPage != std::numeric_limits<size_type>::max(); }
size_type getLayoutPage() const { return layoutPage; }
void setLayoutPage(size_type s) { layoutPage = s; }
bool hasChecksum() const { return getMimeListPos() >= 80; }
offset_type getChecksumPos() const { return hasChecksum() ? checksumPos : 0; }
void setChecksumPos(offset_type p) { checksumPos = p; }
};
std::ostream& operator<< (std::ostream& out, const Fileheader& fh);

@ -46,7 +46,6 @@ namespace zim
NamespaceCache namespaceEndCache;
std::string namespaces;
time_t mtime;
typedef std::vector<std::string> MimeTypes;
MimeTypes mimeTypes;
@ -56,8 +55,6 @@ namespace zim
public:
explicit FileImpl(const char* fname);
time_t getMTime() const { return mtime; }
const std::string& getFilename() const { return filename; }
const Fileheader& getFileheader() const { return header; }
@ -79,6 +76,9 @@ namespace zim
bool hasNamespace(char ch);
const std::string& getMimeType(uint16_t idx) const;
std::string getChecksum();
bool verify();
};
}

@ -60,7 +60,7 @@ namespace zim
FilesType files;
OpenFilesCacheType openFilesCache;
OpenfileInfoPtr currentFile;
offset_type currentPos;
zim::offset_type currentPos;
std::streambuf::int_type overflow(std::streambuf::int_type ch);
std::streambuf::int_type underflow();

@ -112,7 +112,7 @@ namespace zim
{
// initialize input-stream for
stream.next_in = reinterpret_cast<Bytef*>(&obuffer[0]);
stream.avail_in = pptr() - pbase();
stream.avail_in = pptr() - &obuffer[0];
char zbuffer[8192];
while (stream.avail_in > 0)
{
@ -142,7 +142,7 @@ namespace zim
char zbuffer[8192];
// initialize input-stream for
stream.next_in = reinterpret_cast<Bytef*>(&obuffer[0]);
stream.avail_in = pptr() - pbase();
stream.avail_in = pptr() - &obuffer[0];
while (true)
{
// initialize zbuffer
@ -157,7 +157,7 @@ namespace zim
{
std::streamsize n = sink->sputn(zbuffer, count);
if (n < count)
return -1;
throw DeflateError(0, "failed to send compressed data to sink in deflatestream");
}
if (ret == Z_STREAM_END)
break;

@ -26,6 +26,20 @@ log_define("zim.file")
namespace zim
{
namespace
{
int hexval(char ch)
{
if (ch >= '0' && ch <= '9')
return ch - '0';
if (ch >= 'a' && ch <= 'f')
return ch - 'a' + 10;
if (ch >= 'A' && ch <= 'F')
return ch - 'A' + 10;
return -1;
}
}
Article File::getArticle(size_type idx) const
{
return Article(*this, idx);
@ -184,4 +198,75 @@ namespace zim
File::const_iterator File::findByTitle(char ns, const std::string& title)
{ return findxByTitle(ns, title).second; }
std::string urldecode(const std::string& url)
{
std::string ret;
enum {
state_0,
state_h1,
state_h2,
} state = state_0;
char ch;
for (std::string::const_iterator it = url.begin(); it != url.end(); ++it)
{
switch (state)
{
case state_0:
if (*it == '+')
ret += ' ';
else if (*it == '%')
state = state_h1;
else
ret += *it;
break;
case state_h1:
if (*it >= '0' && *it <= '9'
||*it >= 'A' && *it <= 'F'
||*it >= 'a' && *it <= 'f')
{
ch = *it;
state = state_h2;
}
else
{
ret += '%';
ret += *it;
state = state_0;
}
break;
case state_h2:
if (*it >= '0' && *it <= '9'
||*it >= 'A' && *it <= 'F'
||*it >= 'a' && *it <= 'f')
{
ret += static_cast<char>(hexval(ch) * 16 + hexval(*it));
}
else
{
ret += static_cast<char>(hexval(ch));
ret += *it;
}
state = state_0;
break;
}
}
switch (state)
{
case state_h1:
ret += '%';
break;
case state_h2:
ret += '%';
ret += ch;
break;
}
return ret;
}
}

@ -28,7 +28,7 @@ namespace zim
{
const size_type Fileheader::zimMagic = 0x044d495a; // ="ZIM^d"
const size_type Fileheader::zimVersion = 5;
const size_type Fileheader::size = 72;
const size_type Fileheader::size = 80;
std::ostream& operator<< (std::ostream& out, const Fileheader& fh)
{
@ -44,6 +44,7 @@ namespace zim
toLittleEndian(fh.getMimeListPos(), header + 56);
toLittleEndian(fh.getMainPage(), header + 64);
toLittleEndian(fh.getLayoutPage(), header + 68);
toLittleEndian(fh.getChecksumPos(), header + 72);
out.write(header, Fileheader::size);
@ -90,6 +91,7 @@ namespace zim
offset_type mimeListPos = fromLittleEndian(reinterpret_cast<const offset_type*>(header + 56));
size_type mainPage = fromLittleEndian(reinterpret_cast<const size_type*>(header + 64));
size_type layoutPage = fromLittleEndian(reinterpret_cast<const size_type*>(header + 68));
offset_type checksumPos = fromLittleEndian(reinterpret_cast<const offset_type*>(header + 72));
fh.setUuid(uuid);
fh.setArticleCount(articleCount);
@ -100,6 +102,7 @@ namespace zim
fh.setMimeListPos(mimeListPos);
fh.setMainPage(mainPage);
fh.setLayoutPage(layoutPage);
fh.setChecksumPos(checksumPos);
return in;
}

@ -25,12 +25,16 @@
#include <sys/stat.h>
#include <sstream>
#include <errno.h>
#include <cstring>
#include "config.h"
#include "log.h"
#include "envvalue.h"
#ifdef WITH_CXXTOOLS
# include <cxxtools/systemerror.h>
# include <cxxtools/md5stream.h>
#else
# include "md5stream.h"
#endif
log_define("zim.file.impl")
@ -295,4 +299,62 @@ namespace zim
return mimeTypes[idx];
}
std::string FileImpl::getChecksum()
{
if (!header.hasChecksum())
return std::string();
zimFile.seekg(header.getChecksumPos());
unsigned char chksum[16];
zimFile.read(reinterpret_cast<char*>(chksum), 16);
if (!zimFile)
{
log_warn("error reading checksum");
return std::string();
}
char hexdigest[33];
hexdigest[32] = '\0';
static const char hex[] = "0123456789abcdef";
char* p = hexdigest;
for (int i = 0; i < 16; ++i)
{
*p++ = hex[chksum[i] >> 4];
*p++ = hex[chksum[i] & 0xf];
}
log_debug("chksum=" << hexdigest);
return hexdigest;
}
bool FileImpl::verify()
{
if (!header.hasChecksum())
return false;
#ifdef WITH_CXXTOOLS
cxxtools::Md5stream md5;
#else
Md5stream md5;
#endif
zimFile.seekg(0);
char ch;
for (offset_type n = 0; n < header.getChecksumPos() && zimFile.get(ch); ++n)
md5 << ch;
unsigned char chksumFile[16];
unsigned char chksumCalc[16];
zimFile.read(reinterpret_cast<char*>(chksumFile), 16);
if (!zimFile)
throw ZimFileFormatError("failed to read checksum from zim file");
md5.getDigest(chksumCalc);
if (std::memcmp(chksumFile, chksumCalc, 16) != 0)
throw ZimFileFormatError("invalid checksum in zim file");
return true;
}
}

@ -28,6 +28,12 @@
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
@ -36,10 +42,6 @@
#define O_BINARY 0
#endif
#ifdef _WIN32
#include <io.h>
#endif
log_define("zim.fstream")
namespace zim
@ -78,10 +80,10 @@ streambuf::OpenfileInfo::~OpenfileInfo()
streambuf::FileInfo::FileInfo(const std::string& fname_, int fd)
: fname(fname_)
{
#ifdef HAVE_LSEEK64
#if defined(_WIN32)
__int64 ret = ::_lseeki64(fd, 0, SEEK_END);
#elif defined(HAVE_LSEEK64)
off64_t ret = ::lseek64(fd, 0, SEEK_END);
#elif _WIN32
offset_type ret = ::_lseeki64(fd, 0, SEEK_END);
#else
off_t ret = ::lseek(fd, 0, SEEK_END);
#endif
@ -92,7 +94,7 @@ streambuf::FileInfo::FileInfo(const std::string& fname_, int fd)
throw std::runtime_error(msg.str());
}
fsize = static_cast<offset_type>(ret);
fsize = static_cast<zim::offset_type>(ret);
}
std::streambuf::int_type streambuf::overflow(std::streambuf::int_type ch)
@ -241,11 +243,10 @@ void streambuf::setCurrentFile(const std::string& fname, zim::offset_type off)
if (f.first || off != 0) // found in cache or seek requested
{
#ifdef HAVE_LSEEK64
off64_t ret = ::lseek64(currentFile->fd, off, SEEK_SET);
#elif _WIN32
#if defined(_WIN32)
offset_type ret = ::_lseeki64(currentFile->fd, off, SEEK_SET);
#elif defined(HAVE_LSEEK64)
off64_t ret = ::lseek64(currentFile->fd, off, SEEK_SET);
#else
off_t ret = ::lseek(currentFile->fd, off, SEEK_SET);
#endif

@ -118,7 +118,7 @@ namespace zim
{
// initialize input-stream for
stream.next_in = reinterpret_cast<const uint8_t*>(&obuffer[0]);
stream.avail_in = pptr() - pbase();
stream.avail_in = pptr() - &obuffer[0];
char zbuffer[8192];
while (stream.avail_in > 0)
{
@ -148,7 +148,7 @@ namespace zim
char zbuffer[8192];
// initialize input-stream for
stream.next_in = reinterpret_cast<const uint8_t*>(&obuffer[0]);
stream.avail_in = pptr() - pbase();
stream.avail_in = pptr() - &obuffer[0];
lzma_ret ret;
do
{
@ -164,7 +164,7 @@ namespace zim
{
std::streamsize n = sink->sputn(zbuffer, count);
if (n < count)
return -1;
throw LzmaError(static_cast<lzma_ret>(0), "failed to send compressed data to sink in lzmastream");
}
} while (ret != LZMA_STREAM_END);

@ -0,0 +1,340 @@
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "md5.h"
#include <string.h>
#define MD5_CTX zim_MD5_CTX
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform PROTO_LIST ((UINT4 [4], const unsigned char [64]));
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST
((UINT4 *, const unsigned char *, unsigned int));
/*
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
*/
#define MD5_memcpy memcpy
#define MD5_memset memset
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void zim_MD5Init (MD5_CTX* context)
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void zim_MD5Update (
MD5_CTX *context,
const unsigned char *input, /* input block */
unsigned int inputLen) /* length of input block */
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void zim_MD5Final (
unsigned char digest[16], /* message digest */
MD5_CTX *context) /* context */
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
zim_MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
zim_MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (
UINT4 state[4],
const unsigned char block[64])
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (
unsigned char *output,
UINT4 *input,
unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (
UINT4 *output,
const unsigned char *input,
unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
#if 0
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (
POINTER output,
POINTER input,
unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (
POINTER output,
int value,
unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}
#endif

@ -0,0 +1,107 @@
/*
* Copyright (C) 2003 Tommi Maekitalo
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* As a special exception, you may use this file as part of a free
* software library without restriction. Specifically, if other files
* instantiate templates or use macros or inline functions from this
* file, or you compile this file and link it with other files to
* produce an executable, this file does not by itself cause the
* resulting executable to be covered by the GNU General Public
* License. This exception does not however invalidate any other
* reasons why the executable file might be covered by the GNU Library
* General Public License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* RSAREF types and constants
*/
/* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping.
The following makes PROTOTYPES default to 0 if it has not already
been defined with C compiler flags.
*/
#ifndef ZIM_MD5_H
#define ZIM_MD5_H
#ifndef PROTOTYPES
#define PROTOTYPES 1
#endif
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
typedef unsigned int UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list.
*/
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif
/* MD5 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} zim_MD5_CTX;
#ifdef __cplusplus
extern "C" {
#endif
void zim_MD5Init PROTO_LIST ((zim_MD5_CTX *));
void zim_MD5Update PROTO_LIST
((zim_MD5_CTX *, const unsigned char *, unsigned int));
void zim_MD5Final PROTO_LIST ((unsigned char [16], zim_MD5_CTX *));
#ifdef __cplusplus
}
#endif
#endif /* ZIM_MD5_H */

@ -0,0 +1,134 @@
/*
* Copyright (C) 2003 Tommi Maekitalo
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* As a special exception, you may use this file as part of a free
* software library without restriction. Specifically, if other files
* instantiate templates or use macros or inline functions from this
* file, or you compile this file and link it with other files to
* produce an executable, this file does not by itself cause the
* resulting executable to be covered by the GNU General Public
* License. This exception does not however invalidate any other
* reasons why the executable file might be covered by the GNU Library
* General Public License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*
* copied from cxxtools
*/
#include "md5stream.h"
#include <cstring>
namespace zim
{
////////////////////////////////////////////////////////////////////////
// Md5streambuf
//
Md5streambuf::Md5streambuf()
{
std::memset(digest, 0, 16);
}
std::streambuf::int_type Md5streambuf::overflow(
std::streambuf::int_type ch)
{
if (pptr() == 0)
{
// Ausgabepuffer ist leer - initialisieren
zim_MD5Init(&context);
}
else
{
// konsumiere Zeichen aus dem Puffer
zim_MD5Update(&context,
(const unsigned char*)pbase(),
pptr() - pbase());
}
// setze Ausgabepuffer
setp(buffer, buffer + bufsize);
if (ch != traits_type::eof())
{
// das Zeichen, welches den overflow ausgelöst hat, stecken
// wir in den Puffer.
*pptr() = traits_type::to_char_type(ch);
pbump(1);
}
return 0;
}
std::streambuf::int_type Md5streambuf::underflow()
{
// nur Ausgabestrom
return traits_type::eof();
}
int Md5streambuf::sync()
{
if (pptr() != pbase())
{
// konsumiere Zeichen aus dem Puffer
zim_MD5Update(&context, (const unsigned char*)pbase(), pptr() - pbase());
// leere Ausgabepuffer
setp(buffer, buffer + bufsize);
}
return 0;
}
void Md5streambuf::getDigest(unsigned char digest_[16])
{
if (pptr())
{
if (pptr() != pbase())
{
// konsumiere Zeichen aus dem Puffer
zim_MD5Update(&context, (const unsigned char*)pbase(), pptr() - pbase());
}
// deinitialisiere Ausgabepuffer
setp(0, 0);
zim_MD5Final(digest, &context);
}
std::memcpy(digest_, digest, 16);
}
////////////////////////////////////////////////////////////////////////
// Md5stream
//
const char* Md5stream::getHexDigest()
{
static const char hex[] = "0123456789abcdef";
unsigned char md5[16];
getDigest(md5);
int i;
char* p = hexdigest;
for (i = 0; i < 16; ++i)
{
*p++ = hex[md5[i] >> 4];
*p++ = hex[md5[i] & 0xf];
}
*p = '\0';
return hexdigest;
}
}

@ -0,0 +1,134 @@
/*
* Copyright (C) 2003 Tommi Maekitalo
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* As a special exception, you may use this file as part of a free
* software library without restriction. Specifically, if other files
* instantiate templates or use macros or inline functions from this
* file, or you compile this file and link it with other files to
* produce an executable, this file does not by itself cause the
* resulting executable to be covered by the GNU General Public
* License. This exception does not however invalidate any other
* reasons why the executable file might be covered by the GNU Library
* General Public License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*
* copied from cxxtools
*/
#ifndef ZIM_MD5STREAM_H
#define ZIM_MD5STREAM_H
#include "md5.h"
#include <iostream>
#include <iterator>
#include <algorithm>
namespace zim
{
class Md5streambuf : public std::streambuf
{
public:
Md5streambuf();
void getDigest(unsigned char digest[16]);
private:
static const unsigned int bufsize = 64;
char buffer[bufsize];
zim_MD5_CTX context;
unsigned char digest[16];
std::streambuf::int_type overflow(std::streambuf::int_type ch);
std::streambuf::int_type underflow();
int sync();
};
/**
This is a easy and safe interface to MD5-calculation.
To get a MD5-sum of data, instantiate a md5stream, copy your data
into it and read the digest.
After calling getDigest or getHexDigest, the class can be reused
for another md5-calculation. The algorithm is automatically
reinitialized when the first character is received.
example:
\code
int main(int argc, char* argv[])
{
Md5stream s;
for (int i = 1; i < argc; ++i)
{
std::ifstream in(argv[i]);
if (in)
{
s << in.rdbuf();
std::cout << s.getHexDigest() << " " << argv[i] << std::endl;
}
}
}
\endcode
*/
class Md5stream : public std::ostream
{
public:
typedef std::ostreambuf_iterator<char> iterator;
private:
Md5streambuf streambuf;
char hexdigest[33];
public:
/// initializes md5-calculation
Md5stream()
: std::ostream(0)
{
init(&streambuf);
}
/// ends md5-calculation and returns 16 bytes digest
void getDigest(unsigned char digest[16])
{ streambuf.getDigest(digest); }
/// ends md5-calculation and digest as 32 bytes hex
const char* getHexDigest();
/// returns output-iterator to Md5stream
iterator begin()
{ return iterator(&streambuf); }
};
template <typename iterator_type>
std::string md5(iterator_type from, iterator_type to)
{
Md5stream s;
std::copy(from, to, std::ostream_iterator<char>(s));
return s.getHexDigest();
}
template <typename data_type>
std::string md5(const data_type& data)
{
Md5stream s;
s << data;
return s.getHexDigest();
}
}
#endif // ZIM_MD5STREAM_H
Loading…
Cancel
Save