This commit is contained in:
2022-01-07 21:14:56 +08:00
parent 037eaf60b1
commit a8705ecb0f
7 changed files with 371 additions and 0 deletions

View File

@@ -52,6 +52,7 @@ set(SOURCE_FILE
encoding.cpp
str_util.cpp
c_linked_list.cpp
file_reader.c
)
set(SOURCE_FILE_HEADERS
cfileop.h
@@ -68,6 +69,7 @@ set(SOURCE_FILE_HEADERS
str_util.h
linked_list.h
c_linked_list.h
file_reader.h
)
add_library(utils STATIC ${SOURCE_FILE} ${SOURCE_FILE_HEADERS})

View File

@@ -79,3 +79,29 @@ int fileop_set_file_time(const char* path, time_t ctime, time_t actime, time_t m
if (!path) return 0;
return fileop::set_file_time(path, ctime, actime, modtime) ? 1 : 0;
}
int fileop_mkdirs(const char* path, int mode, int allow_exists) {
if (!path) return 0;
return fileop::mkdirs(path, mode, allow_exists) ? 1 : 0;
}
int fileop_get_file_size(const char* path, size_t* size) {
if (!path || !size) return 0;
size_t s;
auto re = fileop::get_file_size(path, s);
if (re) *size = s;
return re ? 1 : 0;
}
int fileop_fseek(FILE* f, int64_t offset, int origin) {
return fileop::fseek(f, offset, origin);
}
int fileop_mkdir_for_file(const char* path, int mode) {
if (!path) return 0;
return fileop::mkdir_for_file(path, mode) ? 1 : 0;
}
int64_t fileop_ftell(FILE* f) {
return fileop::ftell(f);
}

View File

@@ -5,6 +5,7 @@ extern "C" {
#endif
#include <stddef.h>
#include <time.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
@@ -104,6 +105,42 @@ int fileop_set_file_time(const char* path, time_t ctime, time_t actime, time_t m
#define fileop_close(fd) (!close(fd))
#endif
#define fileop_fclose(stream) (!fclose(stream))
/**
* @brief Creates a new directory recursively.
* @param path Path for a new directory.
* @param mode Directory permission. (Linux only)
* @param allow_exists If directory is already exists return 1 rather than 0.
* @return 1 if create successfully otherwise 0
*/
int fileop_mkdirs(const char* path, int mode, int allow_exists);
/**
* @brief Retrieves the size of the specified file, in bytes.
* @param path The path of file.
* @param size Result.
* @return 1 if successed otherwise 0
*/
int fileop_get_file_size(const char* path, size_t* size);
/**
* @brief Moves the file pointer to a specified location.
* @param f File
* @param offset Number of bytes from origin.
* @param origin Initial position.
* @return 0 if successed otherwise a nonzero value
*/
int fileop_fseek(FILE* f, int64_t offset, int origin);
/**
* @brief Make sure file's directory is already exists, if not exists, try create it.
* @param path File's path
* @param mode Directory permission. (Linux only)
* @return 1 if file's directory is exists now otherwise 0.
*/
int fileop_mkdir_for_file(const char* path, int mode);
/**
* @brief Gets the current position of a file pointer.
* @param f Target FILE structure.
* @return The current position
*/
int64_t fileop_ftell(FILE* f);
#ifdef __cplusplus
}
#endif

View File

@@ -1,9 +1,15 @@
#include "cstr_util.h"
#include "utils_config.h"
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#if HAVE_PRINTF_S
#define printf printf_s
#endif
int cstr_util_copy_str(char** dest, const char* str) {
if (!dest || !str) return 1;
size_t le = strlen(str);
@@ -52,3 +58,66 @@ int32_t cstr_read_int32(const uint8_t* bytes, int big) {
if (!bytes) return 0;
return cstr_read_uint32(bytes, big);
}
void cstr_tolowercase2(char* str, size_t len) {
if (!str) return;
if (!len) len = strlen(str);
for (size_t i = 0; i < len; i++) {
str[i] = tolower(str[i]);
}
}
uint64_t cstr_read_uint64(const uint8_t* bytes, int big) {
if (!bytes) return 0;
return big ? ((uint64_t)bytes[0] << 56) + ((uint64_t)bytes[1] << 48) + ((uint64_t)bytes[2] << 40) + ((uint64_t)bytes[3] << 32) + ((uint64_t)bytes[4] << 24) + ((uint64_t)bytes[5] << 16) + ((uint64_t)bytes[6] << 8) + (uint64_t)bytes[7] : (uint64_t)bytes[0] + ((uint64_t)bytes[1] << 8) + ((uint64_t)bytes[2] << 16) + ((uint64_t)bytes[3] << 24) + ((uint64_t)bytes[4] << 32) + ((uint64_t)bytes[5] << 40) + ((uint64_t)bytes[6] << 48) + ((uint64_t)bytes[7] << 56);
}
int64_t cstr_read_int64(const uint8_t* bytes, int big) {
if (!bytes) return 0;
return cstr_read_uint64(bytes, big);
}
uint16_t cstr_read_uint16(const uint8_t* bytes, int big) {
if (!bytes) return 0;
return big ? (bytes[0] << 8) + bytes[1] : bytes[0] + (bytes[1] << 8);
}
int16_t cstr_read_int16(const uint8_t* bytes, int big) {
if (!bytes) return 0;
return cstr_read_uint16(bytes, big);
}
int cstr_read_str(char* buf, char** dest, size_t* pos, size_t buf_len) {
if (!buf || !dest || !pos) return 1;
if (*pos >= buf_len) return 1;
char* tmp = NULL;
size_t p = *pos, tmp_len = 128, n = 0;
tmp = malloc(tmp_len);
if (!tmp) {
printf("Out of memory.\n");
return 1;
}
while (p < buf_len) {
tmp[n] = buf[p];
if (!buf[p]) break;
p++;
n++;
if (n >= tmp_len) {
tmp_len += 128;
char* ntmp = realloc(tmp, tmp_len);
if (!ntmp) {
printf("Out of memory.\n");
free(tmp);
return 1;
}
tmp = ntmp;
}
}
if (p == buf_len && tmp[n - 1]) {
tmp[n] = 0;
}
*pos = p >= buf_len ? p : p + 1;
char* ntmp = realloc(tmp, n);
*dest = ntmp ? ntmp : tmp;
return 0;
}

View File

@@ -41,6 +41,49 @@ uint32_t cstr_read_uint32(const uint8_t* bytes, int big);
* @return result
*/
int32_t cstr_read_int32(const uint8_t* bytes, int big);
/**
* @brief Convert string to lowercase
* @param str String needed to convert
* @param len The length of the string. If is 0, strlen will be called to calculate length.
*/
void cstr_tolowercase2(char* str, size_t len);
/**
* @brief Convert bytes to uint64
* @param bytes Bytes (at least 8 bytes)
* @param big 0 if little endian otherwise big endian
* @return result
*/
uint64_t cstr_read_uint64(const uint8_t* bytes, int big);
/**
* @brief Convert bytes to int64
* @param bytes Bytes (at least 8 bytes)
* @param big 0 if little endian otherwise big endian
* @return result
*/
int64_t cstr_read_int64(const uint8_t* bytes, int big);
/**
* @brief Convert bytes to uint16
* @param bytes Bytes (at least 2 bytes)
* @param big 0 if little endian otherwise big endian
* @return result
*/
uint16_t cstr_read_uint16(const uint8_t* bytes, int big);
/**
* @brief Convert bytes to int16
* @param bytes Bytes (at least 2 bytes)
* @param big 0 if little endian otherwise big endian
* @return result
*/
int16_t cstr_read_int16(const uint8_t* bytes, int big);
/**
* @brief Read string from buffer
* @param buf Buffer
* @param dest Result string
* @param pos The start position in buffer. After a successed called, the position will be updated.
* @param buf_len The length of buffer
* @return 0 if successed otherwise 1
*/
int cstr_read_str(char* buf, char** dest, size_t* pos, size_t buf_len);
#ifdef __cplusplus
}
#endif

136
file_reader.c Normal file
View File

@@ -0,0 +1,136 @@
#include "file_reader.h"
#include <malloc.h>
#include <stdio.h>
#include "cfileop.h"
#include "cstr_util.h"
typedef struct file_reader_file {
FILE* f;
/// 0 if little endian otherwise big endian
unsigned char endian;
} file_reader_file;
file_reader_file* create_file_reader(FILE* f, unsigned char endian) {
if (!f) return NULL;
file_reader_file* r = malloc(sizeof(file_reader_file));
if (!r) return NULL;
r->f = f;
r->endian = endian;
return r;
}
void free_file_reader(file_reader_file* f) {
if (!f) return;
free(f);
}
void set_file_reader_endian(file_reader_file* f, unsigned char endian) {
if (!f) return;
f->endian = endian;
}
int file_reader_read_int32(file_reader_file* f, int32_t* re) {
if (!f) return 1;
int64_t offset = fileop_ftell(f->f);
int32_t r = 0;
int origin = SEEK_SET;
if (offset == -1) {
origin = SEEK_CUR;
}
size_t c;
uint8_t buf[4];
if ((c = fread(buf, 1, 4, f->f)) < 4) {
if (origin == SEEK_CUR) offset = -c;
fileop_fseek(f->f, offset, origin);
return 1;
}
r = cstr_read_int32(buf, f->endian);
if (re) *re = r;
return 0;
}
int file_reader_read_uint32(file_reader_file* f, uint32_t* re) {
return file_reader_read_int32(f, (int32_t*)re);
}
int file_reader_read_int64(file_reader_file* f, int64_t* re) {
if (!f) return 1;
int64_t offset = fileop_ftell(f->f), r = 0;
int origin = SEEK_SET;
if (offset == -1) {
origin = SEEK_CUR;
}
size_t c;
uint8_t buf[8];
if ((c = fread(buf, 1, 8, f->f)) < 8) {
if (origin == SEEK_CUR) offset = -c;
fileop_fseek(f->f, offset, origin);
return 1;
}
r = cstr_read_int64(buf, f->endian);
if (re) *re = r;
return 0;
}
int file_reader_read_str(file_reader_file* f, char** buf) {
if (!f) return 1;
char* b = NULL;
char bu[128];
size_t blen = 128, n = 0, c = 0, tc = 0, pos = 0;
if (buf) {
b = malloc(blen);
if (!b) return 1;
}
int64_t offset = fileop_ftell(f->f);
int origin = SEEK_SET;
if (offset == -1) {
origin = SEEK_CUR;
}
while (1) {
if (n >= c) {
if (!(tc = fread(bu, 1, 128, f->f))) {
if (b) free(b);
if (origin == SEEK_CUR) {
offset = -c;
}
fileop_fseek(f->f, offset, origin);
return 1;
}
c += tc;
}
if (buf && n >= blen) {
size_t nlen = blen + 128;
char* nb = realloc(b, nlen);
if (!nb) {
if (b) free(b);
if (origin == SEEK_CUR) {
offset = -c;
}
fileop_fseek(f->f, offset, origin);
return 1;
}
b = nb;
blen = nlen;
}
pos = n - (c - tc);
if (buf && b) {
b[n] = bu[pos];
}
if (bu[pos] == 0) {
break;
}
n++;
}
if (buf) {
char* nb = realloc(b, n + 1);
*buf = nb ? nb : b;
}
if (origin == SEEK_SET) {
offset += n + 1;
} else {
offset = -(c - n - 1);
}
fileop_fseek(f->f, offset, origin);
return 0;
}

58
file_reader.h Normal file
View File

@@ -0,0 +1,58 @@
#ifndef _UTILS_FILE_READER_H
#define _UTILS_FILE_READER_H
#include <stdint.h>
#include <stdio.h>
#if __cplusplus
extern "C" {
#endif
typedef struct file_reader_file file_reader_file;
/**
* @brief Create a reader from a stream
* @param f File stream
* @param endian 0 if little endian otherwise big endian
* @return the reader, NULL if OOM or stream is NULL.
*/
file_reader_file* create_file_reader(FILE* f, unsigned char endian);
/**
* @brief Free a reader. This will not close stream.
* @param f the pointer to reader struct
*/
void free_file_reader(file_reader_file* f);
/**
* @brief Set endian for reader
* @param f reader
* @param endian 0 if little endian otherwise big endian
*/
void set_file_reader_endian(file_reader_file* f, unsigned char endian);
/**
* @brief Read int32 from reader
* @param f reader
* @param re result
* @return 0 if successed otherwise 1
*/
int file_reader_read_int32(file_reader_file* f, int32_t* re);
/**
* @brief Read uint32 from reader
* @param f reader
* @param re result
* @return 0 if successed otherwise 1
*/
int file_reader_read_uint32(file_reader_file* f, uint32_t* re);
/**
* @brief Read int64 from reader
* @param f reader
* @param re result
* @return 0 if successed otherwise 1
*/
int file_reader_read_int64(file_reader_file* f, int64_t* re);
/**
* @brief Read 0 terminal string from reader
* @param f reader
* @param buf Result. Need free memory by using free.
* @return 0 if successed otherwise 1
*/
int file_reader_read_str(file_reader_file* f, char** buf);
#if __cplusplus
}
#endif
#endif