diff --git a/applications/ems_datahubs/kutilities.cpp b/applications/ems_datahubs/kutilities.cpp new file mode 100644 index 0000000..0be5e50 --- /dev/null +++ b/applications/ems_datahubs/kutilities.cpp @@ -0,0 +1,269 @@ +#include "kutilities.h" + +#include +#include +#include +#include +#include + +#define CHUNK 16384 + +/* Compress from file source to file dest until EOF on source. +def() returns Z_OK on success, Z_MEM_ERROR if memory could not be +allocated for processing, Z_STREAM_ERROR if an invalid compression +level is supplied, Z_VERSION_ERROR if the version of zlib.h and the +version of the library linked do not match, or Z_ERRNO if there is +an error reading or writing the files. */ +int CompressString(const char* in_str, size_t in_len, std::string& out_str, int level) +{ + if( !in_str ) + return Z_DATA_ERROR; + + int ret, flush; + unsigned have; + z_stream strm; + + unsigned char out[CHUNK]; + + /* allocate deflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit(&strm, level); + if( ret != Z_OK ) + return ret; + + std::shared_ptr sp_strm(&strm, [](z_stream* strm) + { + (void)deflateEnd(strm); + }); + + const char* end = in_str + in_len; + + //size_t pos_index = 0; + size_t distance = 0; + /* compress until end of file */ + do + { + distance = end - in_str; + strm.avail_in = (distance >= CHUNK) ? CHUNK : distance; + strm.next_in = (Bytef*)in_str; + + // next pos + in_str += strm.avail_in; + flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH; + + /* run deflate() on input until output buffer not full, finish + compression if all of source has been read in */ + do + { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = deflate(&strm, flush); /* no bad return value */ + if( ret == Z_STREAM_ERROR ) + break; + have = CHUNK - strm.avail_out; + out_str.append((const char*)out, have); + } + while( strm.avail_out == 0 ); + + if( strm.avail_in != 0 ); /* all input will be used */ + break; + + /* done when last data in file processed */ + } + while( flush != Z_FINISH ); + + if( ret != Z_STREAM_END ) /* stream will be complete */ + return Z_STREAM_ERROR; + + /* clean up and return */ + return Z_OK; +} + +/* Decompress from file source to file dest until stream ends or EOF. +inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be +allocated for processing, Z_DATA_ERROR if the deflate data is +invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and +the version of the library linked do not match, or Z_ERRNO if there +is an error reading or writing the files. */ +int DecompressString(const char* in_str, size_t in_len, std::string& out_str) +{ + if( !in_str ) + return Z_DATA_ERROR; + + int ret; + unsigned have; + z_stream strm; + unsigned char out[CHUNK]; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); + if( ret != Z_OK ) + return ret; + + std::shared_ptr sp_strm(&strm, [](z_stream* strm) + { + (void)inflateEnd(strm); + }); + + const char* end = in_str + in_len; + + //size_t pos_index = 0; + size_t distance = 0; + + int flush = 0; + /* decompress until deflate stream ends or end of file */ + do + { + distance = end - in_str; + strm.avail_in = (distance >= CHUNK) ? CHUNK : distance; + strm.next_in = (Bytef*)in_str; + + // next pos + in_str += strm.avail_in; + flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH; + + /* run inflate() on input until output buffer not full */ + do + { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = inflate(&strm, Z_NO_FLUSH); + + if( ret == Z_STREAM_ERROR ) /* state not clobbered */ + break; + + switch( ret ) + { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + return ret; + } + have = CHUNK - strm.avail_out; + out_str.append((const char*)out, have); + } + while( strm.avail_out == 0 ); + + /* done when inflate() says it's done */ + } + while( flush != Z_FINISH ); + + /* clean up and return */ + return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; +} + +// 函数用于将内存块转换为十六进制字符串 +std::string printHex(const void* data, size_t size) +{ + std::ostringstream oss; + std::ostringstream oss2; + std::ostringstream ossrow; + + const size_t lineSize = 16; // 每行输出的字节数 + const unsigned char* p = static_cast(data); + + int ic = 0; + int row = 0; + + ossrow << std::setw(8) << std::setfill('0') << std::hex << row++ << "h : "; + oss << ossrow.str().c_str(); + + for( size_t i = 0; i < size; ++i ) + { + ic++; + + // 每个字节之间用空格分隔 + oss << std::setw(2) << std::setfill('0') << std::hex << std::uppercase << static_cast(p[i]); + + char ch = (isprint(p[i]) != 0) ? p[i] : '.'; + + oss2 << ch; + + // 每lineSize个字节换行 + if( (i + 1) % lineSize == 0 ) + { + ossrow.clear(); + ossrow.str(""); + + oss << " [" << oss2.str().c_str() << "]" << std::endl; + oss2.clear(); + oss2.str(""); + + ossrow << std::setw(8) << std::setfill('0') << std::hex << row++ << "h : "; + oss << ossrow.str().c_str(); + + ic = 0; + } + else if( i == size - 1 ) + { + if( (i + 1) % lineSize != 0 ) + { + if( i % 2 != 0 ) + { + for( size_t j = 0; j < (lineSize - ic); j++ ) + { + oss << " --"; + } + } + else + { + for( size_t j = 0; j < (lineSize - ic); j++ ) + { + oss << " --"; + } + } + } + oss << " [" << oss2.str().c_str(); + + if( (i + 1) % lineSize != 0 ) + { + for( size_t j = 0; j < (lineSize - ic); j++ ) + { + oss << " "; + } + } + + oss << "]" << std::endl; + oss2.clear(); + oss2.str(""); + + ic = 0; + } +#if 0 + else if( (i + 1) % 8 == 0 ) + { + oss << " "; + oss2 << " "; + } +#endif + else + { + oss << " "; + } + } + return oss.str(); +} + + +std::string get_current_timestamp() +{ + auto now = std::chrono::system_clock::now(); + //通过不同精度获取相差的毫秒数 + uint64_t dis_millseconds = std::chrono::duration_cast(now.time_since_epoch()).count() + - std::chrono::duration_cast(now.time_since_epoch()).count() * 1000; + time_t tt = std::chrono::system_clock::to_time_t(now); + auto time_tm = localtime(&tt); + char strTime[25] = { 0 }; + sprintf(strTime, "%d-%02d-%02d %02d:%02d:%02d.%03d", time_tm->tm_year + 1900, + time_tm->tm_mon + 1, time_tm->tm_mday, time_tm->tm_hour, + time_tm->tm_min, time_tm->tm_sec, (int)dis_millseconds); + return std::string(strTime); +} \ No newline at end of file diff --git a/applications/ems_datahubs/kutilities.h b/applications/ems_datahubs/kutilities.h new file mode 100644 index 0000000..a3e74e9 --- /dev/null +++ b/applications/ems_datahubs/kutilities.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +int CompressString(const char* in_str, size_t in_len, std::string& out_str, int level); +int DecompressString(const char* in_str, size_t in_len, std::string& out_str); +std::string printHex(const void* data, size_t size); +std::string get_current_timestamp(); \ No newline at end of file