mirror of
https://github.com/lifegpc/c-utils.git
synced 2026-06-06 21:28:50 +08:00
Update
This commit is contained in:
@@ -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})
|
||||
|
||||
10
cstr_util.c
10
cstr_util.c
@@ -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);
|
||||
}
|
||||
|
||||
15
cstr_util.h
15
cstr_util.h
@@ -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
|
||||
|
||||
62
fileop.cpp
62
fileop.cpp
@@ -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);
|
||||
}
|
||||
|
||||
23
fileop.h
23
fileop.h
@@ -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
51
linked_list.h
Normal 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
|
||||
@@ -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@
|
||||
|
||||
Reference in New Issue
Block a user