mirror of
https://github.com/lifegpc/c-utils.git
synced 2026-06-06 13:18:57 +08:00
Update
This commit is contained in:
@@ -80,3 +80,6 @@ if (Iconv_FOUND)
|
||||
target_link_libraries(utils Iconv::Iconv)
|
||||
endif()
|
||||
endif()
|
||||
if (NOT MSVC)
|
||||
target_link_libraries(utils m)
|
||||
endif()
|
||||
|
||||
156
cstr_util.c
156
cstr_util.c
@@ -2,6 +2,7 @@
|
||||
#include "utils_config.h"
|
||||
|
||||
#include <malloc.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
@@ -10,6 +11,44 @@
|
||||
#define printf printf_s
|
||||
#endif
|
||||
|
||||
typedef enum float_format {
|
||||
undetected_endian,
|
||||
ieee_big_endian,
|
||||
ieee_little_endian,
|
||||
unknown_endian,
|
||||
} float_format_type;
|
||||
|
||||
static float_format_type double_format = undetected_endian;
|
||||
static float_format_type float_format = undetected_endian;
|
||||
|
||||
void detect_double_format() {
|
||||
if (sizeof(double) != 8) double_format = unknown_endian;
|
||||
else {
|
||||
double x = 9006104071833999.0;
|
||||
if (!memcmp(&x, "C?\xff\x01\x02\x03\t\x8f", 8)) {
|
||||
double_format = ieee_big_endian;
|
||||
} else if (!memcmp(&x, "\x8f\t\x03\x02\x01\xff?C", 8)) {
|
||||
double_format = ieee_little_endian;
|
||||
} else {
|
||||
double_format = unknown_endian;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void detect_float_format() {
|
||||
if (sizeof(float) != 4) float_format = unknown_endian;
|
||||
else {
|
||||
float x = 213213216.0;
|
||||
if (!memcmp(&x, "MKV\x02", 4)) {
|
||||
float_format = ieee_big_endian;
|
||||
} else if (!memcmp(&x, "\x02VKM", 4)) {
|
||||
float_format = ieee_little_endian;
|
||||
} else {
|
||||
float_format = unknown_endian;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cstr_util_copy_str(char** dest, const char* str) {
|
||||
if (!dest || !str) return 1;
|
||||
size_t le = strlen(str);
|
||||
@@ -121,3 +160,120 @@ int cstr_read_str(char* buf, char** dest, size_t* pos, size_t buf_len) {
|
||||
*dest = ntmp ? ntmp : tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
float cstr_read_float(const uint8_t* p, int big) {
|
||||
if (float_format == undetected_endian) detect_float_format();
|
||||
if (float_format == unknown_endian) {
|
||||
unsigned char sign;
|
||||
int e;
|
||||
unsigned int f;
|
||||
float x;
|
||||
int incr = 1;
|
||||
if (!big) {
|
||||
p += 3;
|
||||
incr = -1;
|
||||
}
|
||||
sign = (*p >> 7) & 1;
|
||||
e = (*p & 0x7F) << 1;
|
||||
p += incr;
|
||||
e |= (*p >> 7) & 1;
|
||||
f = (*p & 0x7F) << 16;
|
||||
p += incr;
|
||||
f |= *p << 8;
|
||||
p += incr;
|
||||
f |= *p;
|
||||
if (e == 255) {
|
||||
if (f == 0) return sign ? -INFINITY : INFINITY;
|
||||
else return NAN;
|
||||
}
|
||||
x = (float)f / 8388608.0;
|
||||
if (e == 0) {
|
||||
e = -126;
|
||||
} else {
|
||||
x += 1.0;
|
||||
e -= 127;
|
||||
}
|
||||
x = ldexpf(x, e);
|
||||
if (sign) x = -x;
|
||||
return x;
|
||||
} else {
|
||||
float x;
|
||||
if ((float_format == ieee_little_endian && big) || (float_format == ieee_big_endian && !big)) {
|
||||
char buf[4];
|
||||
char* d = &(buf[3]);
|
||||
int i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
*d-- = *p++;
|
||||
}
|
||||
memcpy(&x, buf, 4);
|
||||
} else {
|
||||
memcpy(&x, p, 4);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
double cstr_read_double(const uint8_t* p, int big) {
|
||||
if (double_format == undetected_endian) detect_double_format();
|
||||
if (double_format == unknown_endian) {
|
||||
unsigned char sign;
|
||||
int e;
|
||||
unsigned int fhi, flo;
|
||||
double x;
|
||||
int incr = 1;
|
||||
if (!big) {
|
||||
p += 7;
|
||||
incr = -1;
|
||||
}
|
||||
sign = (*p >> 7) & 1;
|
||||
e = (*p & 0x7F) << 4;
|
||||
p += incr;
|
||||
e |= (*p >> 4) & 0xF;
|
||||
fhi = (*p & 0xF) << 24;
|
||||
p += incr;
|
||||
fhi |= *p << 16;
|
||||
p += incr;
|
||||
fhi |= *p << 8;
|
||||
p += incr;
|
||||
fhi |= *p;
|
||||
p += incr;
|
||||
flo = *p << 16;
|
||||
p += incr;
|
||||
flo |= *p << 8;
|
||||
p += incr;
|
||||
flo |= *p;
|
||||
if (e == 2047) {
|
||||
if (flo == 0 && fhi == 0) {
|
||||
return sign ? -INFINITY : INFINITY;
|
||||
} else {
|
||||
float a = NAN;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
x = (double)fhi + (double)flo / 16777216.0;
|
||||
x /= 268435456.0;
|
||||
if (e == 0)
|
||||
e = -1022;
|
||||
else {
|
||||
x += 1.0;
|
||||
e -= 1023;
|
||||
}
|
||||
x = ldexp(x, e);
|
||||
if (sign) x = -x;
|
||||
return x;
|
||||
} else {
|
||||
double x;
|
||||
if ((double_format == ieee_little_endian && big) || (double_format == ieee_big_endian && !big)) {
|
||||
char buf[8];
|
||||
char* d = &(buf[7]);
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
*d-- = *p++;
|
||||
}
|
||||
memcpy(&x, buf, 8);
|
||||
} else {
|
||||
memcpy(&x, p, 8);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
14
cstr_util.h
14
cstr_util.h
@@ -84,6 +84,20 @@ int16_t cstr_read_int16(const uint8_t* bytes, int big);
|
||||
* @return 0 if successed otherwise 1
|
||||
*/
|
||||
int cstr_read_str(char* buf, char** dest, size_t* pos, size_t buf_len);
|
||||
/**
|
||||
* @brief Convert bytes to float
|
||||
* @param bytes Bytes (at least 4 bytes)
|
||||
* @param big 0 if little endian otherwise big endian
|
||||
* @return result
|
||||
*/
|
||||
float cstr_read_float(const uint8_t* bytes, int big);
|
||||
/**
|
||||
* @brief Convert bytes to double
|
||||
* @param bytes Bytes (at least 8 bytes)
|
||||
* @param big 0 if little endian otherwise big endian
|
||||
* @return result
|
||||
*/
|
||||
double cstr_read_double(const uint8_t* bytes, int big);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
6
dict.h
6
dict.h
@@ -31,6 +31,12 @@ struct dict_entry<K, V>* dict_get(struct Dict<K, V>* d, K key) {
|
||||
return &re->d;
|
||||
}
|
||||
template <typename K, typename V>
|
||||
V dict_get_value(struct Dict<K, V>* d, K key) {
|
||||
struct dict_entry<K, V>* re = dict_get(d, key);
|
||||
if (!re) return nullptr;
|
||||
return re->value;
|
||||
}
|
||||
template <typename K, typename V>
|
||||
bool dict_heve_key_internal(struct dict_entry<K, V> origin, K key) {
|
||||
return key == origin.key;
|
||||
}
|
||||
|
||||
@@ -94,6 +94,46 @@ int file_reader_read_char(file_reader_file* f, char* re) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int file_reader_read_double(file_reader_file* f, double* re) {
|
||||
if (!f) return 1;
|
||||
int64_t offset = f->tell(f->f);
|
||||
double r = 0;
|
||||
int origin = SEEK_SET;
|
||||
if (offset == -1) {
|
||||
origin = SEEK_CUR;
|
||||
}
|
||||
size_t c;
|
||||
uint8_t buf[8];
|
||||
if ((c = f->read(f->f, 8, buf)) < 8) {
|
||||
if (origin == SEEK_CUR) offset = -c;
|
||||
f->seek(f->f, offset, origin);
|
||||
return 1;
|
||||
}
|
||||
r = cstr_read_double(buf, f->endian);
|
||||
if (re) *re = r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int file_reader_read_float(file_reader_file* f, float* re) {
|
||||
if (!f) return 1;
|
||||
int64_t offset = f->tell(f->f);
|
||||
float r = 0;
|
||||
int origin = SEEK_SET;
|
||||
if (offset == -1) {
|
||||
origin = SEEK_CUR;
|
||||
}
|
||||
size_t c;
|
||||
uint8_t buf[4];
|
||||
if ((c = f->read(f->f, 4, buf)) < 4) {
|
||||
if (origin == SEEK_CUR) offset = -c;
|
||||
f->seek(f->f, offset, origin);
|
||||
return 1;
|
||||
}
|
||||
r = cstr_read_float(buf, f->endian);
|
||||
if (re) *re = r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int file_reader_read_uint8(file_reader_file* f, uint8_t* re) {
|
||||
return file_reader_read_char(f, (char*)re);
|
||||
}
|
||||
@@ -118,6 +158,10 @@ int file_reader_read_int16(file_reader_file* f, int16_t* re) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int file_reader_read_uint16(file_reader_file* f, uint16_t* re) {
|
||||
return file_reader_read_int16(f, (int16_t*)re);
|
||||
}
|
||||
|
||||
int file_reader_read_int32(file_reader_file* f, int32_t* re) {
|
||||
if (!f) return 1;
|
||||
int64_t offset = f->tell(f->f);
|
||||
|
||||
@@ -54,6 +54,20 @@ int64_t file_reader_tell(file_reader_file* f);
|
||||
* @return 0 if successed otherwise 1
|
||||
*/
|
||||
int file_reader_read_char(file_reader_file* f, char* re);
|
||||
/**
|
||||
* @brief Read double from reader
|
||||
* @param f reader
|
||||
* @param re result
|
||||
* @return 0 if successed otherwise 1
|
||||
*/
|
||||
int file_reader_read_double(file_reader_file* f, double* re);
|
||||
/**
|
||||
* @brief Read float from reader
|
||||
* @param f reader
|
||||
* @param re result
|
||||
* @return 0 if successed otherwise 1
|
||||
*/
|
||||
int file_reader_read_float(file_reader_file* f, float* re);
|
||||
/**
|
||||
* @brief Read uint8 from reader
|
||||
* @param f reader
|
||||
@@ -68,6 +82,13 @@ int file_reader_read_uint8(file_reader_file* f, uint8_t* re);
|
||||
* @return 0 if successed otherwise 1
|
||||
*/
|
||||
int file_reader_read_int16(file_reader_file* f, int16_t* re);
|
||||
/**
|
||||
* @brief Read uint16 from reader
|
||||
* @param f reader
|
||||
* @param re result
|
||||
* @return 0 if successed otherwise 1
|
||||
*/
|
||||
int file_reader_read_uint16(file_reader_file* f, uint16_t* re);
|
||||
/**
|
||||
* @brief Read int32 from reader
|
||||
* @param f reader
|
||||
|
||||
Reference in New Issue
Block a user