//
//  QMD5.hpp
//  qlibc++
//
//  Created by 胡涛 on 2017/11/17.
//  Copyright © 2017年 胡涛. All rights reserved.
//

#ifndef QMD5_hpp
#define QMD5_hpp

#include <string>
#include <fstream>
#include <cross/platform.h>
#include <cross/ctypes.h>

#include <jebase/config.h>

/* Type define */
typedef unsigned char byte;

//#ifndef __USE_GNU
//typedef unsigned int ulong;
//#endif

using std::string;
using std::ifstream;

/* MD5 declaration. */
class JE_API QMD5 {
public:
     QMD5();
     QMD5(const void *input, size_t length);
     QMD5(const string &str);
     QMD5(ifstream &in);
     void update(const void *input, size_t length);
     void update(const string &str);
     void update(ifstream &in);
     const byte* digest();
     string toString();
     void reset();
private:
     void update(const byte *input, size_t length);
     void final();
     void transform(const byte block[64]);
     void encode(const ulong *input, byte *output, size_t length);
     void decode(const byte *input, ulong *output, size_t length);
     string bytesToHexString(const byte *input, size_t length);
    
    /* class uncopyable */
     QMD5(const QMD5&);
     QMD5& operator=(const QMD5&);
private:
    ulong _state[4];    /* state (ABCD) */
    ulong _count[2];    /* number of bits, modulo 2^64 (low-order word first) */
    byte _buffer[64];   /* input buffer */
    byte _digest[16];   /* message digest */
    bool _finished;     /* calculate finished ? */
    
    static const byte PADDING[64];  /* padding for calculate */
    static const char HEX[16];
    static const size_t BUFFER_SIZE = 1024;
};

#endif /* QMD5_hpp */
