This commit is contained in:
2021-12-30 22:05:42 +08:00
parent 4618b97a2e
commit ac4fee1977
7 changed files with 162 additions and 5 deletions

View File

@@ -23,6 +23,9 @@ if (WIN32)
check_symbol_exists(_wcserror_s "string.h" HAVE__WCSERROR_S)
check_symbol_exists(printf_s "stdio.h" HAVE_PRINTF_S)
check_symbol_exists(sscanf_s "stdio.h" HAVE_SSCANF_S)
else()
check_symbol_exists(fseeko "stdio.h" HAVE_FSEEKO)
check_symbol_exists(fseeko64 "stdio.h" HAVE_FSEEKO64)
endif()
check_symbol_exists(strerror_r "string.h" HAVE_STRERROR_R)
if (HAVE_STRERROR_R)
@@ -60,6 +63,7 @@ set(SOURCE_FILE_HEADERS
time_util.h
encoding.h
str_util.h
linked_list.h
)
add_library(utils STATIC ${SOURCE_FILE} ${SOURCE_FILE_HEADERS})

View File

@@ -42,3 +42,13 @@ int cstr_tolowercase(const char* str, size_t input_len, char** output) {
*output = tmp;
return 1;
}
uint32_t cstr_read_uint32(const uint8_t* bytes, int big) {
if (!bytes) return 0;
return big ? (bytes[0] << 24) + (bytes[1] << 16) + (bytes[2] << 8) + bytes[3] : bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24);
}
int32_t cstr_read_int32(const uint8_t* bytes, int big) {
if (!bytes) return 0;
return cstr_read_uint32(bytes, big);
}

View File

@@ -4,6 +4,7 @@
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
/**
* @brief Copy string to another string
* @param dest The pointer of output string
@@ -26,6 +27,20 @@ int cstr_is_integer(const char* str, int allow_sign);
* @return 1 if successed otherwise 0.
*/
int cstr_tolowercase(const char* str, size_t input_len, char** output);
/**
* @brief Convert bytes to uint32
* @param bytes Bytes (at least 4 bytes)
* @param big 0 if little endian otherwise big endian
* @return result
*/
uint32_t cstr_read_uint32(const uint8_t* bytes, int big);
/**
* @brief Convert bytes to int32
* @param bytes Bytes (at least 4 bytes)
* @param big 0 if little endian otherwise big endian
* @return result
*/
int32_t cstr_read_int32(const uint8_t* bytes, int big);
#ifdef __cplusplus
}
#endif

View File

@@ -81,6 +81,10 @@ HANDLE set_file_time_internal(wchar_t* fn) {
return CreateFileW(fn, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
}
HANDLE get_file_size_internal(wchar_t* fn) {
return CreateFileW(fn, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
}
template <typename T, typename ... Args>
T fileop_internal(const char* fname, UINT codePage, T(*callback)(wchar_t* fn, Args... args), T failed, Args... args) {
int wlen;
@@ -371,16 +375,16 @@ bool fileop::mkdirs(std::string path, int mode, bool allow_exists) {
std::list<std::string> li;
li.push_back(dn);
do {
dn = dirname(dn) + sp;
if (dn.length() == 1) {
dn = dirname(dn);
if (dn.length() == 0) {
if (li.size() > 0) {
auto en = *(li.rbegin());
if (en == ("." + sp)) return false;
}
dn = "." + sp;
dn = ".";
}
if (!isdir(dn, exists)) return false;
if (!exists) li.push_back(dn);
if (!isdir(dn + sp, exists)) return false;
if (!exists) li.push_back(dn + sp);
} while (!exists);
auto it = li.rbegin();
for (; it != li.rend(); it++) {
@@ -388,3 +392,51 @@ bool fileop::mkdirs(std::string path, int mode, bool allow_exists) {
}
return true;
}
bool fileop::get_file_size(std::string path, size_t& size) {
if (!exists(path)) return false;
#if _WIN32
UINT cp[] = { CP_UTF8, CP_OEMCP, CP_ACP };
int i;
HANDLE file;
for (i = 0; i < 3; i++) {
if ((file = fileop_internal(path.c_str(), cp[i], &get_file_size_internal, INVALID_HANDLE_VALUE)) != INVALID_HANDLE_VALUE) {
break;
}
}
if (file == INVALID_HANDLE_VALUE) {
file = CreateFileA(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (file == INVALID_HANDLE_VALUE) return false;
}
LARGE_INTEGER si;
auto re = GetFileSizeEx(file, &si);
if (re) size = si.QuadPart;
CloseHandle(file);
return re ? true : false;
#else
struct stat stats;
if (stat(path.c_str(), &stats)) {
return false;
}
size = stats.st_size;
return true;
#endif
}
int fileop::fseek(FILE* f, int64_t offset, int origin) {
#if _WIN32
return ::_fseeki64(f, offset, origin);
#else
#if HAVE_FSEEKO64
return ::fseek64(f, offset, origin);
#elif HAVE_FSEEKO
return ::fseeko(f, offset, origin);
#else
return ::fseek(f, offset, origin);
#endif
#endif
}
bool fileop::mkdir_for_file(std::string path, int mode) {
return mkdirs(dirname(path), mode, true);
}

View File

@@ -2,6 +2,7 @@
#define _UTIL_FILEOP_H
#include <string>
#include <time.h>
#include <stdint.h>
#include <stdio.h>
namespace fileop {
@@ -125,5 +126,27 @@ namespace fileop {
* @return true if create successfully otherwise false
*/
bool mkdirs(std::string path, int mode, bool allow_exists = false);
/**
* @brief Retrieves the size of the specified file, in bytes.
* @param path The path of file.
* @param size Result.
* @return true if successed otherwise false
*/
bool get_file_size(std::string 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 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 true if file's directory is exists now.
*/
bool mkdir_for_file(std::string path, int mode);
}
#endif

51
linked_list.h Normal file
View File

@@ -0,0 +1,51 @@
#ifndef _UTIL_LINKED_LIST_H
#define _UTIL_LINKED_LIST_H
#include <list>
#include <malloc.h>
template <typename T>
struct LinkedList {
T d;
struct LinkedList* prev;
struct LinkedList* next;
};
template <typename T>
bool linked_list_append(struct LinkedList<T>*& list, T* data = nullptr, struct LinkedList<T>** tail = nullptr) {
bool have_list = list;
struct LinkedList<T>* tmp = (struct LinkedList<T>*)malloc(sizeof(LinkedList<T>));
if (!tmp) return false;
memset(tmp, 0, sizeof(LinkedList<T>));
if (data) tmp->d = T(*data); else tmp->d = T();
if (!have_list) {
list = tmp;
} else {
struct LinkedList<T>* t = list;
while (t->next) t = t->next;
t->next = tmp;
tmp->prev = t;
}
if (tail) *tail = tmp;
return true;
}
template <typename T>
bool linked_list_append(struct LinkedList<T>*& list, struct LinkedList<T>** tail) {
return linked_list_append(list, (T*)nullptr, tail);
}
template <typename T>
void linked_list_clear(struct LinkedList<T>*& list, void(*free_func)(T) = nullptr) {
if (!list) return;
struct LinkedList<T>* t = list;
struct LinkedList<T>* tmp = nullptr;
if (free_func) free_func(t->d);
while (t->next) {
tmp = t;
t = t->next;
free(tmp);
if (free_func) free_func(t->d);
}
free(t);
list = nullptr;
}
#endif

View File

@@ -8,3 +8,5 @@
#cmakedefine HAVE_STRERROR_R @HAVE_STRERROR_R@
#cmakedefine HAVE_GNU_STRERROR_R @HAVE_GNU_STRERROR_R@
#cmakedefine HAVE_SSCANF_S @HAVE_SSCANF_S@
#cmakedefine HAVE_FSEEKO @HAVE_FSEEKO@
#cmakedefine HAVE_FSEEKO64 @HAVE_FSEEKO64@