//
// File: hzCodec.h
//
// Legal Notice: This file is part of the HadronZoo C++ Class Library.
//
// Copyright 2025 HadronZoo Project (http://www.hadronzoo.com)
//
// The HadronZoo C++ Class 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 3 of the License, or any later version.
//
// The HadronZoo C++ Class 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 the HadronZoo C++ Class Library. If not, see http://www.gnu.org/licenses.
//
#ifndef hzCodec_h
#define hzCodec_h
#include <openssl/sha.h>
#include "hzChain.h"
#include "hzXbuf.h"
enum hzCoding
{
// Category: Codec
//
// List of supported encodings
ENCODING_UNDEFINED, // No coding specified
ENCODING_UTF8, // Standard unicode
ENCODING_BASE64, // The windows-1252 char set (char/byte ratio of 1, assigned meanings to high end ASCII)
ENCODING_QP, // Quoted-printable encoding
ENCODING_INVALID // Invalid encoding
} ;
class hzMD5
{
// Category: Codec
//
// An MD5 digest is a 128-bit hash value, commonly used as a checksum in such applications as messaging and file transmission. The hzMD5 class is simply a
// wrapper to limit the operations that may be performed.
uint32_t m_Parts[4] ; // Total 128 bits
public:
hzMD5 (void) ;
// Set functions
hzEcode CalcMD5File (const char* filepath) ;
hzEcode CalcMD5 (const hzChain& Z) ;
hzEcode CalcMD5 (const char* cstr) ;
void Clear (void) ;
// Get functions
const uchar* Value (void) const { return (const uchar*) m_Parts ; }
bool IsNull (void) const ;
const char* Txt (void) const ;
operator const char* (void) const { return Txt() ; }
// Assignement Operators
hzMD5& operator= (const char* pMd5) ;
hzMD5& operator= (const hzString& md5) ;
// Test operators
bool operator== (const hzMD5& op) const ;
bool operator!= (const hzMD5& op) const ;
// Stream operators
//friend std::istream& operator>> (std::istream& is, hzMD5& md5) ;
//friend std::ostream& operator<< (std::ostream& os, const hzMD5& md5) ;
} ;
/*
** Endian conversion
**
** The common assertion that there is no difference between little endian machines and big endian machines, is not completely true. With big endian architecture, string comparison
** can be sped up by casting char* pointers to int and comparing integers - on the very strict proviso that the string addresses are an exact multiple of the int size. With little
** endian architecture, the same technique can only be used to test for equality. The _endian_import functions convert strings in chunks of 2, 4 or 8 bytes to integers that can be
** compared, independent of architecture. The _endian_export functions convert integers back to string chunks.
*/
// Import an internal uint16_t from char array of 2 bytes
void _endian_import2 (uint16_t& v, const uchar* i) ;
// Import an internal uint32_t from char array of 2 to 4 bytes
void _endian_import2 (uint32_t& v, const uchar* i) ;
void _endian_import3 (uint32_t& v, const uchar* i) ;
void _endian_import4 (uint32_t& v, const uchar* i) ;
// Import an internal uint32_t from char array of 2 to 8 bytes
void _endian_import2 (uint64_t& v, const uchar* i) ;
void _endian_import3 (uint64_t& v, const uchar* i) ;
void _endian_import4 (uint64_t& v, const uchar* i) ;
void _endian_import5 (uint64_t& v, const uchar* i) ;
void _endian_import6 (uint64_t& v, const uchar* i) ;
void _endian_import7 (uint64_t& v, const uchar* i) ;
void _endian_import8 (uint64_t& v, const uchar* i) ;
// Export an internal uint16_t to char array of 2 bytes
void _endian_export2 (uchar* s, uint16_t n) ;
// Export an internal uint32_t to char array of 2 to 4 bytes
void _endian_export2 (uchar* s, uint32_t n) ;
void _endian_export3 (uchar* s, uint32_t n) ;
void _endian_export4 (uchar* s, uint32_t n) ;
// Export an internal uint64_t to char array of 2 to 8 bytes
void _endian_export2 (uchar* s, uint64_t n) ;
void _endian_export3 (uchar* s, uint64_t n) ;
void _endian_export4 (uchar* s, uint64_t n) ;
void _endian_export5 (uchar* s, uint64_t n) ;
void _endian_export6 (uchar* s, uint64_t n) ;
void _endian_export7 (uchar* s, uint64_t n) ;
void _endian_export8 (uchar* s, uint64_t n) ;
/*
** Serial Integer Read and Write functions
*/
// State size of serial integer based on the integer
#define SizeSerialUINT32(val) (val<0x80?1:val<0x2000?2:val<0x20000?3:val<0x20000000?4:5)
// Read integer from uchar buffer
hzEcode ReadSerialUINT64 (uint64_t& nValue, uint32_t& nLen, const uchar* ptr) ;
hzEcode ReadSerialUINT32 (uint32_t& nValue, uint32_t& nLen, const uchar* ptr) ;
hzEcode ReadSerialSINT64 (int64_t& nValue, uint32_t& nLen, const uchar* ptr) ;
hzEcode ReadSerialSINT32 (int32_t& nValue, uint32_t& nLen, const uchar* ptr) ;
// Read integer from hzChain
hzEcode ReadSerialUINT64 (uint64_t& nValue, hzChain::Iter& zi) ;
hzEcode ReadSerialUINT32 (uint32_t& nValue, hzChain::Iter& zi) ;
hzEcode ReadSerialSINT64 (int64_t& nValue, hzChain::Iter& zi) ;
hzEcode ReadSerialSINT32 (int32_t& nValue, hzChain::Iter& zi) ;
// Read integer from hzXbuf
hzEcode ReadSerialUINT64 (uint64_t& nValue, xbufIter& zi) ;
hzEcode ReadSerialUINT32 (uint32_t& nValue, xbufIter& zi) ;
// Serialize integer to uchar buffer
void WriteSerialUINT64 (uchar* pBuf, uint32_t& nLen, uint64_t nValue) ;
void WriteSerialUINT32 (uchar* pBuf, uint32_t& nLen, uint32_t nValue) ;
void WriteSerialSINT64 (uchar* pBuf, uint32_t& nLen, int64_t nValue) ;
void WriteSerialSINT32 (uchar* pBuf, uint32_t& nLen, int32_t nValue) ;
// Serialize integer to hzChain
void WriteSerialUINT64 (hzChain& Z, uint32_t& nLen, uint64_t nValue) ;
void WriteSerialUINT32 (hzChain& Z, uint32_t& nLen, uint32_t nValue) ;
void WriteSerialSINT64 (hzChain& Z, uint32_t& nLen, int64_t nValue) ;
void WriteSerialSINT32 (hzChain& Z, uint32_t& nLen, int32_t nValue) ;
/*
** Base-64 encoding/decoding
*/
void Base64Encode (hzChain& Encoded, const char* pRaw) ;
void Base64Encode (hzChain& Encoded, const hzString& raw) ;
void Base64Encode (hzChain& Encoded, const hzChain& raw) ;
hzEcode Base64Encode (hzChain& Encoded, const char* cpDir, const char* cpFilename) ;
hzEcode Base64Decode (hzChain& Decoded, const char* pRaw) ;
hzEcode Base64Decode (hzChain& Decoded, const hzString& raw) ;
hzEcode Base64Decode (hzChain& Decoded, const hzChain& raw) ;
hzEcode Base64Decode (hzChain& Decoded, hzChain::Iter& raw) ;
hzEcode Base64Decode (hzString& Decoded, const char* pRaw) ;
hzEcode Base64Decode (hzString& Decoded, const hzString& raw) ;
hzEcode Base64Decode (hzString& Decoded, const hzChain& raw) ;
hzEcode Base64Decode (hzString& Decoded, hzChain::Iter& raw) ;
/*
** Quoted-printable decoding (HadronZoo does not use QP encoding)
*/
hzEcode QPDecode (hzString& Decoded, const char* pRaw) ;
hzEcode QPDecode (hzChain& Decoded, const hzChain& Raw) ;
// Decoding for short, charset encoded strings
hzEcode CharsetStringDecode (hzString& Decoded, const hzString& raw) ;
/*
** Zipping & un-zipping
*/
hzEcode Gzip (hzChain& compressed, const hzChain& orig) ;
hzEcode Gunzip (hzChain& orig, const hzChain& compressed) ;
// Globals
extern const hzMD5 _hz_null_hzMD5 ;
#endif // hzCodec_h