This commit is contained in:
2024-12-03 17:12:18 +08:00
parent 95925cc855
commit f2a470c59d
62 changed files with 1332 additions and 477 deletions

246
.clang-format Normal file
View File

@@ -0,0 +1,246 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: true
AcrossComments: true
AlignCompound: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseColons: false
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowBreakBeforeNoexceptSpecifier: Never
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: false
BinPackParameters: false
BitFieldColonSpacing: Both
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAdjacentStringLiterals: true
BreakAfterAttributes: Leave
BreakAfterJavaFieldAnnotations: false
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Attach
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: false
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
KeepEmptyLinesAtEOF: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PackConstructorInitializers: BinPack
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakScopeResolution: 500
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
PPIndentWidth: -1
QualifierAlignment: Leave
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SkipMacroDefinitionBody: false
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
AfterPlacementOperator: true
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInSquareBrackets: false
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
...

4
.gitignore vendored
View File

@@ -1,2 +1,4 @@
.cache
build
build
.VSCodeCounter
.vscode

View File

@@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.28...3.30)
project(latch)
set(CMAKE_EXPORT_COMPILE_COMMANDS yes)
set(CMAKE_C_STANDARD 99)
include(FetchContent)
include(GoogleTest)
if(MSVC)
add_compile_options("/source-charset:utf-8")
@@ -10,6 +14,7 @@ endif()
option(TEST "是否启动单元测试" ON)
option(SHARED "是否编译为动态库" OFF)
option(with-debug "同时编译附加debug功能的版本" ON)
include_directories(include)
@@ -18,6 +23,7 @@ add_subdirectory(src)
message(是否开启编译测试单元?${TEST})
if (TEST)
enable_testing()
find_package(GTest)
add_subdirectory(tests)
endif()

9
CMakeUserPresets.json Normal file
View File

@@ -0,0 +1,9 @@
{
"version": 4,
"vendor": {
"conan": {}
},
"include": [
"build/Release/generators/CMakePresets.json"
]
}

View File

@@ -1,6 +1,5 @@
# Latch 一个c语言stl库
其创建的目的是为了对标准库最少的侵入,最少的修改,最少的对标准库的包装且套,来达到其标准库还未支持的跨平台功能。并对部分功能进行增强。
# 构建
## conan2构建

View File

@@ -11,22 +11,30 @@ class LatchRecipe(ConanFile):
author = "321640253@qq.com"
url = "https://github.com/WangZhongDian/latch.git"
description = "一个c开发增强库,简单易用,提供常用的开发工具与容器"
topics = ("latch", "C", "simple", "easy-to-use", "glib2","tbox")
topics = ("latch", "C", "simple", "easy-to-use", "glib2", "tbox")
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False], "fPIC": [True, False], "test": [True, False]}
default_options = {"shared": False, "fPIC": True, "test": True}
options = {
"shared": [True, False],
"fPIC": [True, False],
"test": [True, False],
"with-debug": [True, False],
}
default_options = {"shared": False, "fPIC": True, "test": True, "with-debug": True}
exports_sources = "include/*", "CMakeLists.txt", "src/*", "tests/*"
def requirements(self):
self.requires("gtest/1.15.0")
def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
def configure(self):
if self.options.shared:
self.options.rm_safe("fPIC")
def layout(self):
cmake_layout(self)
@@ -36,6 +44,7 @@ class LatchRecipe(ConanFile):
tc = CMakeToolchain(self)
tc.variables["SHARED"] = True if self.options.shared else False
tc.variables["TEST"] = True if self.options.test else False
tc.variables["with-debug"] = True if self.options.test else False
tc.generate()
def build(self):
@@ -46,13 +55,53 @@ class LatchRecipe(ConanFile):
cmake.test()
def package(self):
copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))
copy(self, pattern="*.h", src=os.path.join(self.source_folder, "include"), dst=os.path.join(self.package_folder, "include"))
copy(self, pattern="*.a", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False)
copy(self, pattern="*.so", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False)
copy(self, pattern="*.lib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False)
copy(self, pattern="*.dll", src=self.build_folder, dst=os.path.join(self.package_folder, "bin"), keep_path=False)
copy(self, pattern="*.dylib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False)
copy(
self,
"LICENSE",
src=self.source_folder,
dst=os.path.join(self.package_folder, "licenses"),
)
copy(
self,
pattern="*.h",
src=os.path.join(self.source_folder, "include"),
dst=os.path.join(self.package_folder, "include"),
)
copy(
self,
pattern="*.a",
src=self.build_folder,
dst=os.path.join(self.package_folder, "lib"),
keep_path=False,
)
copy(
self,
pattern="*.so",
src=self.build_folder,
dst=os.path.join(self.package_folder, "lib"),
keep_path=False,
)
copy(
self,
pattern="*.lib",
src=self.build_folder,
dst=os.path.join(self.package_folder, "lib"),
keep_path=False,
)
copy(
self,
pattern="*.dll",
src=self.build_folder,
dst=os.path.join(self.package_folder, "bin"),
keep_path=False,
)
copy(
self,
pattern="*.dylib",
src=self.build_folder,
dst=os.path.join(self.package_folder, "lib"),
keep_path=False,
)
def package_info(self):
self.cpp_info.libs = ["latch"]
self.cpp_info.libs = ["latch"]

View File

@@ -1,9 +0,0 @@
#ifndef __LATCH_ENCODING_H__
#define __LATCH_ENCODING_H__
typedef enum _latch_encoding_type {
LT_ENCODING_UTF8 = 0,
LT_ENCODING_UTF16LE = 1,
} lt_encoding_type_t;
#endif //__LATCH_ENCODING_H__

View File

@@ -1,10 +0,0 @@
#ifndef __LATCH_STATS_H__
#define __LATCH_STATS_H__
typedef enum _latch_error {
LT_ERROR_OK = 0,
LT_ERROR_MEMORY,
LT_ERROR_IO,
} lt_error_t;
#endif // __LATCH_STATS_H__

View File

@@ -1,36 +0,0 @@
#ifndef __LATCH_TYPES_H__
#define __LATCH_TYPES_H__
typedef unsigned char lt_u8;
typedef unsigned short lt_u16;
typedef unsigned int lt_u32;
typedef unsigned long lt_u64;
typedef signed char lt_int8;
typedef signed short lt_int16;
typedef signed int lt_int32;
typedef signed long lt_int64;
typedef unsigned char lt_byte;
typedef lt_u64 lt_size_t;
typedef lt_u64 lt_time_t;
typedef lt_u8 lt_bool;
#define true 1
#define false 0
#define LT_NULL 0
#define LT_NULL_PTR ((void *)0)
typedef union {
lt_u8 u8;
lt_u16 u16;
lt_u32 u32;
lt_u64 u64;
lt_int8 i8;
lt_int16 i16;
lt_int32 i32;
lt_int64 i64;
lt_byte byte;
lt_bool bool;
lt_size_t size_t;
} lt_any_type_t;
#endif // __LATCH_TYPES_H__

View File

@@ -0,0 +1,16 @@
#ifndef __LT_ARRAY_H__
#define __LT_ARRAY_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif // __LT_ARRAY_H__

View File

@@ -1,12 +1,20 @@
#ifndef __LATCH_CONTAINER_BYTES_H__
#define __LATCH_CONTAINER_BYTES_H__
#include "latch/base/lt-types.h"
#include <stddef.h>
typedef struct __lt_bytes {
lt_size_t length;
#ifdef __cplusplus
extern "C" {
#endif
typedef struct lt_bytes_s {
size_t length;
lt_byte *data;
void (*close)(struct __lt_bytes *self);
} LT_Bytes;
void (*close)(struct lt_bytes_s *self);
} lt_bytes_t;
#endif // __LATCH_CONTAINER_BYTES_H__
#ifdef __cplusplus
}
#endif
#endif // __LATCH_CONTAINER_BYTES_H__

View File

@@ -0,0 +1,12 @@
#ifndef __LT_DLIST_H__
#define __LT_DLIST_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif // __LT_DLIST_H__

View File

@@ -0,0 +1,10 @@
#ifndef __LT_MAP_H__
#define __LT_MAP_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif // __LT_MAP_H__

View File

@@ -0,0 +1,46 @@
#ifndef __LATCH_CONTAINER_SLIST_H__
#define __LATCH_CONTAINER_SLIST_H__
#include <stdbool.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
struct lt_slist_node_s {
void *data;
struct lt_slist_node_s *next;
};
typedef struct lt_slist_s {
struct lt_slist_node_s *head;
struct lt_slist_node_s *tail;
size_t size;
size_t type_size;
} lt_slist_t;
/**
*!...
* @brief 新建一个单链表
* @param type_size 单链表存储的数据类型大小
* @return lt_slist_t*
*/
lt_slist_t *lt_slist_new(size_t type_size);
/**
* @brief 单链表添加数据
* @param
* @return
*/
bool lt_slist_append(lt_slist_t *self, void *data);
void *lt_slist_pop(lt_slist_t *self);
void *lt_slist_get(lt_slist_t *self, size_t index);
#ifdef __cplusplus
}
#endif
#endif // __LATCH_CONTAINER_SLIST_H__

View File

@@ -1,18 +1,61 @@
#ifndef __LATCH_CONTAINER_STRING_H__
#define __LATCH_CONTAINER_STRING_H__
#include "latch/base/lt-types.h"
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct __lt_string {
lt_size_t length;
typedef struct lt_string_s {
/// 字符串长度
size_t length;
/// 字符串数据
char *data;
void (*close)(struct __lt_string *self);
} LT_String;
} lt_string_t;
/**
* @brief 创建字符串
* @param data 字符串数据
* @return lt_string_t*
*/
lt_string_t *lt_string_new(const char *data);
LT_String *lt_string_new(const char *data);
void lt_string_reNew(LT_String* str, const char *data);
LT_String *lt_string_reverse(LT_String *self);
LT_String *lt_string_cut(LT_String *self, lt_int64 start, lt_int64 end, lt_int64 step);
/**
* @brief 销毁字符串
* @param str 字符串指针
* @return void
*/
void lt_string_close(lt_string_t *str);
#endif // __LATCH_CONTAINER_STRING_H__
/**
* @brief 重新设置字符串的值
* @param str 字符串指针
* @param data 字符串数据
* @return
*/
void lt_string_reNew(lt_string_t *str, const char *data);
/**
* @brief 字符串反转
* @param str 字符串指针
* @return
*/
lt_string_t *lt_string_reverse(lt_string_t *str);
/**
* @brief 字符串切片
* @param str 字符串指针
* @param start 开始位置
* @param end 结束位置
* @param step 步长
* @return
*/
lt_string_t *
lt_string_cut(lt_string_t *self, int32_t start, int32_t end, int32_t step);
#ifdef __cplusplus
}
#endif
#endif // __LATCH_CONTAINER_STRING_H__

View File

@@ -0,0 +1,10 @@
#ifndef __LT_SHA_H__
#define __LT_SHA_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif // __LT_SHA_H__

View File

@@ -0,0 +1,98 @@
#ifndef __LT_HTTP_BASE_H__
#define __LT_HTTP_BASE_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief HTTP status code
* is_informational | 100 <= status <= 199 | HTTP Semantics RFC 9110, Section 15
* is_success | 200 <= status <= 299 | HTTP Semantics RFC 9110, Section 15
* is_redirection | 300 <= status <= 399 | HTTP Semantics RFC 9110, Section 15
* is_client_error | 400 <= status <= 499 | HTTP Semantics RFC 9110, Section 15
* is_server_error | 500 <= status <= 599 | HTTP Semantics RFC 9110, Section 15
*/
typedef enum lt_http_status_code_e {
LT_HTTP_CONTINUE = 100,
LT_HTTP_SWITCHING_PROTOCOLS = 101,
LT_HTTP_PROCESSING = 102,
LT_HTTP_EARLY_HINTS = 103,
LT_HTTP_OK = 200,
LT_HTTP_CREATED = 201,
LT_HTTP_ACCEPTED = 202,
LT_HTTP_NON_AUTHORITATIVE = 203,
LT_HTTP_NO_CONTENT = 204,
LT_HTTP_RESET_CONTENT = 205,
LT_HTTP_PARTIAL_CONTENT = 206,
LT_HTTP_MULTI_STATUS = 207,
LT_HTTP_ALREADY_REPORTED = 208,
LT_HTTP_IM_USED = 226,
LT_HTTP_MULTIPLE_CHOICES = 300,
LT_HTTP_MOVED_PERMANENTLY = 301,
LT_HTTP_FOUND = 302,
LT_HTTP_SEE_OTHER = 303,
LT_HTTP_NOT_MODIFIED = 304,
LT_HTTP_USE_PROXY = 305,
LT_HTTP_SWITCH_PROXY = 306,
LT_HTTP_TEMPORARY_REDIRECT = 307,
LT_HTTP_PERMANENT_REDIRECT = 308,
LT_HTTP_BAD_REQUEST = 400,
LT_HTTP_UNAUTHORIZED = 401,
LT_HTTP_PAYMENT_REQUIRED = 402,
LT_HTTP_FORBIDDEN = 403,
LT_HTTP_NOT_FOUND = 404,
LT_HTTP_METHOD_NOT_ALLOWED = 405,
LT_HTTP_NOT_ACCEPTABLE = 406,
LT_HTTP_PROXY_AUTHENTICATION_REQUIRED = 407,
LT_HTTP_REQUEST_TIMEOUT = 408,
LT_HTTP_CONFLICT = 409,
LT_HTTP_GONE = 410,
LT_HTTP_LENGTH_REQUIRED = 411,
LT_HTTP_PRECONDITION_FAILED = 412,
LT_HTTP_PAYLOAD_TOO_LARGE = 413,
LT_HTTP_URI_TOO_LONG = 414,
LT_HTTP_UNSUPPORTED_MEDIA_TYPE = 415,
LT_HTTP_RANGE_NOT_SATISFIABLE = 416,
LT_HTTP_EXPECTATION_FAILED = 417,
LT_HTTP_I_AM_A_TEAPOT = 418,
LT_HTTP_MISDIRECTED_REQUEST = 421,
LT_HTTP_UNPROCESSABLE_ENTITY = 422,
LT_HTTP_LOCKED = 423,
LT_HTTP_FAILED_DEPENDENCY = 424,
LT_HTTP_TOO_EARLY = 425,
LT_HTTP_UPGRADE_REQUIRED = 426,
LT_HTTP_PRECONDITION_REQUIRED = 428,
LT_HTTP_TOO_MANY_REQUESTS = 429,
LT_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
LT_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451,
LT_HTTP_INTERNAL_SERVER_ERROR = 500,
LT_HTTP_NOT_IMPLEMENTED = 501,
LT_HTTP_BAD_GATEWAY = 502,
LT_HTTP_SERVICE_UNAVAILABLE = 503,
LT_HTTP_GATEWAY_TIMEOUT = 504,
LT_HTTP_VERSION_NOT_SUPPORTED = 505,
LT_HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506,
LT_HTTP_INSUFFICIENT_STORAGE = 507,
LT_HTTP_LOOP_DETECTED = 508,
LT_HTTP_NOT_EXTENDED = 510,
LT_HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511,
} lt_http_status_code_e;
typedef enum lt_http_method_e {
LT_HTTP_GET = 0,
LT_HTTP_HEAD,
LT_HTTP_POST,
LT_HTTP_PUT,
LT_HTTP_DELETE,
LT_HTTP_CONNECT,
LT_HTTP_OPTIONS,
LT_HTTP_TRACE,
LT_HTTP_PATCH,
} lt_http_method_e;
#ifdef __cplusplus
}
#endif
#endif // __LT_HTTP_BASE_H__

View File

@@ -1,11 +1,32 @@
#ifndef __LT_HTTP_H__
#define __LT_HTTP_H__
typedef enum __lt_http_code{
LT_HTTP_OK = 200,
LT_HTTP_BAD_REQUEST = 400,
LT_HTTP_NOT_FOUND = 404,
} lt_http_status_code;
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#endif //__LT_HTTP_H__
typedef struct lt_http_s {
// TODO
} lt_http_t;
lt_http_t *lt_http_init(void);
void lt_http_close(lt_http_t *h);
int lt_http_listen(lt_http_t *h,
char *host,
int port,
uint32_t blocksize); // TODO
int lt_http_connect(lt_http_t *h,
char *host,
uint32_t port,
uint32_t timeout,
uint32_t blocksize); // TODO
#ifdef __cplusplus
}
#endif
#endif //__LT_HTTP_H__

View File

@@ -0,0 +1,10 @@
#ifndef __LT_HTTPS_H__
#define __LT_HTTPS_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif // __LT_HTTPS_H__

View File

@@ -1,37 +1,20 @@
#ifndef __LATCH_FILE_H__
#define __LATCH_FILE_H__
#include "latch/base/lt-stats.h"
#include "latch/base/lt-types.h"
#include "latch/container/lt-bytes.h"
#include "latch/container/lt-string.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
LT_FILE_SENK_BEG = 0,
LT_FILE_SENK_CUR,
LT_FILE_SENK_END,
} lt_file_senk_flag_t;
int64_t lt_get_file_size(FILE *f);
time_t lt_get_file_mtime(FILE *f);
time_t lt_get_file_ctime(FILE *f);
typedef struct __LT_File {
LT_String *name;
LT_String *path;
lt_size_t size;
lt_time_t create_time;
lt_time_t modify_time;
FILE *fp;
lt_error_t *(*read_bytes)(struct __LT_File *self, lt_size_t size,
LT_Bytes *read_buffer);
lt_error_t (*write_bytes)(struct __LT_File *self, LT_Bytes *write_buffer);
void (*seek)(struct __LT_File *self, lt_int64 offset,
lt_file_senk_flag_t flag);
void (*close)(struct __LT_File *self);
} LT_File;
LT_File *lt_file_open(const char *path, const char *mode);
lt_bool lt_file_copy(const char *src, const char *dst); //TODO 文件复制
lt_bool lt_file_remove(const char *path); //TODO 文件删除
lt_bool lt_file_create(const char *path, const char *mode); //TODO 文件创建
lt_bool lt_file_chmod(const char *path, lt_u32 mode); //TODO 文件权限修改
#ifdef __cplusplus
}
#endif
#endif // __LATCH_FILE_H__

View File

@@ -1,23 +0,0 @@
#ifndef __LATCH_H__
#define __LATCH_H__
#include "latch/lt-version.h"
//基础
#include "latch/base/lt-types.h"
#include "latch/base/lt-stats.h"
//容器
#include "latch/container/lt-string.h"
#include "latch/container/lt-bytes.h"
#include "latch/container/lt-dlist.h"
#include "latch/container/lt-map.h"
#include "latch/container/lt-slist.h"
#include "latch/memory/lt-memory.h"
#include "latch/io/lt-file.h"
#endif

View File

@@ -7,4 +7,12 @@
#define LATCH_VERSION "0.1.0"
#endif // __LATCH_VERSION_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif // __LATCH_VERSION_H__

View File

@@ -0,0 +1,35 @@
#ifndef __LATCH_MEMORY_DEBUG_H__
#define __LATCH_MEMORY_DEBUG_H__
#include <stdbool.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct lt_memory_debug_info_s {
char *file;
int line;
void *ptr;
size_t size;
struct lt_memory_debug_info_s *next;
} lt_memory_debug_info_t;
typedef struct lt_memory_debug_info_list_s {
lt_memory_debug_info_t *head;
lt_memory_debug_info_t *tail;
size_t size;
} lt_memory_debug_info_list_t;
void lt_memory_debug_info_add(const char *file,
int line,
void *ptr,
size_t size);
void lt_memory_debug_print_info();
bool lt_memory_debug_info_remove_prt(void *ptr);
#ifdef __cplusplus
}
#endif
#endif // __LATCH_MEMORY_DEBUG_H__

View File

@@ -1,18 +1,39 @@
#ifndef __LATCH_MEMORY_H__
#define __LATCH_MEMORY_H__
#include "latch/base/lt-types.h"
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum lt_memory_type {
LT_MEMORY_TYPE_LIBC = 1,
LT_MEMORY_TYPE_POOL,
LT_MEMORY_TYPE_LIBC = 1,
LT_MEMORY_TYPE_POOL,
} lt_memory_type_e;
void *lt_malloc(lt_size_t size);
void *lt_calloc(lt_size_t nmemb, lt_size_t size);
void *lt_realloc(void *ptr, lt_size_t size);
void lt_free(void *ptr);
#define lt_malloc(size) lt_malloc_direct((size), __FILE__, __LINE__)
#define lt_calloc(nmemb, size) \
lt_calloc_direct((nmemb), (size), __FILE__, __LINE__)
#define lt_realloc(ptr, size) \
lt_realloc_direct((ptr), (size), __FILE__, __LINE__)
#define lt_free(ptr) lt_free_direct((ptr), __FILE__, __LINE__)
void lt_set_default_memory_type(lt_memory_type_e type);
void *lt_malloc_direct(size_t size, char *file, int line);
void *lt_calloc_direct(size_t nmemb, size_t size, char *file, int line);
void *lt_realloc_direct(void *ptr, size_t size, char *file, int line);
void lt_free_direct(void *ptr, char *file, int line);
void lt_memory_set_default_type(lt_memory_type_e type);
void lt_memory_set_functions(void *(*malloc_func)(size_t size),
void *(*calloc_func)(size_t nmemb,
size_t size),
void *(*realloc_func)(void *ptr, size_t size),
void (*free_func)(void *ptr));
#ifdef __cplusplus
}
#endif
#endif // __LATCH_MEMORY_H__

View File

@@ -1,5 +1,23 @@
#ifndef __LATCH_OS_H__
#define __LATCH_OS_H__
#ifndef __LT_OS_H__
#define __LT_OS_H__
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#endif // __LATCH_OS_H__
uint32_t lt_os_get_cpu_count(void);
uint64_t lt_os_get_memory_size(void);
char *lt_os_get_username(void);
char *lt_os_get_hostname(void);
char *lt_os_get_cwd(void);
bool lt_os_mkdir(const char *path, uint32_t mode);
#ifdef __cplusplus
}
#endif
#endif // __LT_OS_H__

View File

@@ -1,10 +1,24 @@
#ifndef __LATCH_PATH_H__
#define __LATCH_PATH_H__
#include "latch/base/lt-types.h"
#include <stdbool.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
lt_bool lt_path_is_file(const char *path);
lt_bool lt_path_is_dir(const char *path);
lt_bool lt_path_exists(const char *path);
bool lt_path_is_file(const char *path);
bool lt_path_is_dir(const char *path);
bool lt_path_is_link(const char *path);
bool lt_path_exists(const char *path);
void lt_path_join(char *dest,
size_t dest_size,
const char *left,
const char *right);
bool lt_path_split(const char *path, char *dir, char *file);
#endif // __LATCH_PATH_H__
#ifdef __cplusplus
}
#endif
#endif // __LATCH_PATH_H__

View File

@@ -0,0 +1,23 @@
#ifndef __LT_SOCKET_BASE_H__
#define __LT_SOCKET_BASE_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef enum lt_socket_type_e {
LT_SOCKET_TYPE_TCP,
LT_SOCKET_TYPE_UDP,
LT_SOCKET_TYPE_RAW,
} lt_socket_type_e;
typedef enum lt_socket_ip_type_e {
LT_SOCKET_IP_TYPE_IPV4,
LT_SOCKET_IP_TYPE_IPV6,
} lt_socket_ip_type_e;
#ifdef __cplusplus
}
#endif
#endif // __LT_SOCKET_BASE_H__

View File

@@ -0,0 +1,25 @@
#ifndef __LATCH_SOCKET_H__
#define __LATCH_SOCKET_H__
#include "lt-socket-base.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct lt_socket_s {
lt_socket_type_e type;
} lt_socket_t;
lt_socket_t *lt_socket_new(lt_socket_type_e type);
void lt_socket_close(lt_socket_t *socket);
void lt_socket_bind(lt_socket_t *socket, const char *ip, int port);
void lt_socket_listen(lt_socket_t *socket, int max_backlog);
lt_socket_t *lt_socket_accept(lt_socket_t *socket);
#ifdef __cplusplus
}
#endif
#endif // __LATCH_SOCKET_H__

15
makefile Normal file
View File

@@ -0,0 +1,15 @@
PHONY: test build conan_install
test:build
cd build/Release && cmake --build . && ctest
build:conan_install
cmake --preset conan-release .
conan_install:
conan install . -b missing

View File

@@ -1,3 +0,0 @@
#!/bin/bash
#使用该脚本编译并测试项目或者使用ide的插件进行编译和测试
cmake build -B build . && cd build && cmake --build . && ctest

View File

@@ -2,35 +2,45 @@ project(latch)
if(SHARED)
add_library(${PROJECT_NAME} SHARED)
add_library(${PROJECT_NAME}_debug SHARED)
else()
add_library(${PROJECT_NAME} STATIC)
add_library(${PROJECT_NAME}_debug STATIC)
endif()
aux_source_directory("memory" MEMORY_SRC)
target_sources(
${PROJECT_NAME} PRIVATE
${MEMORY_SRC}
)
aux_source_directory("memory" LATCH_SRC)
#编译容器模块
aux_source_directory("container/string" CONTAINER_SRC)
aux_source_directory("container/map" CONTAINER_SRC)
target_sources(
${PROJECT_NAME} PRIVATE
${CONTAINER_SRC}
)
aux_source_directory("container/string" LATCH_SRC)
aux_source_directory("container/map" LATCH_SRC)
aux_source_directory("container/list" LATCH_SRC)
#编译IO模块
aux_source_directory("io" IO_SRC)
aux_source_directory("io" LATCH_SRC)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
aux_source_directory("io/cross/unix" IO_SRC)
aux_source_directory("io/cross/unix" LATCH_SRC)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
aux_source_directory("io/cross/windows" IO_SRC)
aux_source_directory("io/cross/windows" LATCH_SRC)
endif()
#编译os模块
aux_source_directory("os" LATCH_SRC)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
aux_source_directory("os/cross/unix" LATCH_SRC)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
aux_source_directory("os/cross/windows" LATCH_SRC)
endif()
#构建发行版本
target_sources(
${PROJECT_NAME} PRIVATE
${IO_SRC}
${LATCH_SRC}
)
#构建具有debug的发行版本
target_sources(
${PROJECT_NAME}_debug PRIVATE
${LATCH_SRC}
)
target_compile_definitions(
${PROJECT_NAME}_debug PRIVATE
-DLATCH_DEBUG)

44
src/cmake_install.cmake Normal file
View File

@@ -0,0 +1,44 @@
# Install script for directory: /home/wangko/project/C/latch/src
# Set the install prefix
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "/usr/local")
endif()
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
# Set the install configuration name.
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
if(BUILD_TYPE)
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
else()
set(CMAKE_INSTALL_CONFIG_NAME "")
endif()
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
endif()
# Set the component getting installed.
if(NOT CMAKE_INSTALL_COMPONENT)
if(COMPONENT)
message(STATUS "Install component: \"${COMPONENT}\"")
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
else()
set(CMAKE_INSTALL_COMPONENT)
endif()
endif()
# Install shared libraries without execute permission?
if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
set(CMAKE_INSTALL_SO_NO_EXE "1")
endif()
# Is this installation the result of a crosscompile?
if(NOT DEFINED CMAKE_CROSSCOMPILING)
set(CMAKE_CROSSCOMPILING "FALSE")
endif()
# Set path to fallback-tool for dependency-resolution.
if(NOT DEFINED CMAKE_OBJDUMP)
set(CMAKE_OBJDUMP "/bin/objdump")
endif()

View File

@@ -0,0 +1,43 @@
#include "latch/container/lt-slist.h"
#include "latch/memory/lt-memory.h"
#include <stdbool.h>
#include <stddef.h>
/**
* @brief 单量表创建
* @param type_size 数据类型大小 (单位:byte)
* @return lt_slist_t*
*/
lt_slist_t *lt_slist_new(size_t type_size) {
lt_slist_t *list = (lt_slist_t *)lt_malloc(sizeof(lt_slist_t));
if (list == NULL)
return NULL;
list->type_size = type_size;
list->size = 0;
list->head = list->tail = NULL;
return list;
}
/**
* @brief 单量表表添加数据
* @param self 单量表
* @param data 数据
* @return lt_error_t
*/
bool lt_slist_append(lt_slist_t *self, void *data) {
struct lt_slist_node_s *node =
(struct lt_slist_node_s *)lt_malloc(sizeof(struct lt_slist_node_s));
if (node == NULL)
return false;
node->data = data;
node->next = NULL;
if (self->tail == NULL) {
self->tail = node;
self->size++;
return true;
}
self->tail->next = node;
self->size++;
return true;
}

View File

@@ -1,96 +1,111 @@
#include "latch/container/lt-string.h"
#include "latch/base/lt-types.h"
#include "latch/memory/lt-memory.h"
#include <stdlib.h>
#include <string.h>
static void __LT_String_free(LT_String *self){
if(self)free(self->data);
free(self);
return;
void lt_string_close(lt_string_t *str) {
lt_free(str->data);
lt_free(str);
}
/**
* @brief 创建字符串
*/
LT_String *lt_string_new(const char *data){
LT_String *str = (LT_String*)lt_malloc(sizeof(LT_String));
if(!str) return LT_NULL_PTR;
* @brief 创建字符串
*/
lt_string_t *lt_string_new(const char *data) {
lt_string_t *str = (lt_string_t *)lt_malloc(sizeof(lt_string_t));
if (!str)
return NULL;
str->length = strlen(data);
str->data = (char*)malloc(str->length + 1);
str->data = (char *)lt_malloc(str->length + 1);
strcpy(str->data, data);
str->close = __LT_String_free;
return str;
}
void lt_string_reNew(LT_String* str, const char *data){
lt_size_t newLength = strlen(data);
char* newData = (char*)malloc(newLength + 1);
void lt_string_reNew(lt_string_t *str, const char *data) {
size_t newLength = strlen(data);
char *newData = (char *)lt_malloc(newLength + 1);
strcpy(newData, data);
free(str->data);
str->data = newData;
str->data = newData;
str->length = newLength;
}
/**
* @brief 字符串反转
*/
LT_String *lt_string_reverse(LT_String *self){
LT_String *str = (LT_String*)malloc(sizeof(LT_String));
if(!str) return LT_NULL_PTR;
* @brief 字符串反转
*/
lt_string_t *lt_string_reverse(lt_string_t *str) {
lt_string_t *new_str = (lt_string_t *)lt_malloc(sizeof(lt_string_t));
if (!new_str)
return NULL;
str->data = (char*)malloc(self->length + 1);
for(lt_int64 i = self->length - 1, j = 0; i >= 0; --i, ++j){
str->data[j] = self->data[i];
new_str->data = (char *)lt_malloc(str->length + 1);
for (int32_t i = str->length - 1, j = 0; i >= 0; --i, ++j) {
new_str->data[j] = str->data[i];
}
str->length = self->length;
str->data[self->length] = '\0';
str->close = __LT_String_free;
return str;
new_str->length = str->length;
new_str->data[str->length] = '\0';
return new_str;
}
/**
* @brief 字符串内容切割step为正
*/
static LT_String* __lt_string_cut_step_P(LT_String *self, lt_int64 start, lt_int64 end, lt_int64 step){
if(end > self->length || start > end || start > self->length)
return LT_NULL_PTR;
* @brief 字符串内容切割step为正
*/
static lt_string_t *lt_string_s_cut_step_P(lt_string_t *self,
int32_t start,
int32_t end,
int32_t step) {
if (end > self->length || start > end || start > self->length || step <= 0)
return NULL;
LT_String *str = (LT_String*)malloc(sizeof(LT_String));
if(!str) return LT_NULL_PTR;
// 计算实际长度
int32_t actualLength = 0;
for (int32_t i = start; i < end; i += step) {
if (i >= self->length)
break;
actualLength++;
}
str->close = __LT_String_free;
str->length = (end - start) / step;
str->data = (char*)malloc(str->length + 1);
for(lt_int64 i = 0; i < str->length; ++i){
if((start + i * step)>= self->length) break;
str->data[i] = self->data[(start + i * step)];
lt_string_t *str = (lt_string_t *)lt_malloc(sizeof(lt_string_t));
if (!str)
return NULL;
str->length = actualLength;
str->data = (char *)lt_malloc(str->length + 1);
int32_t index = 0;
for (int32_t i = start; i < end && index < str->length; i += step) {
str->data[index++] = self->data[i];
}
str->data[str->length] = '\0';
return str;
}
/**
* @brief 字符串内容切割step为负
*/
static LT_String* __lt_string_cut_step_N(LT_String *self, lt_int64 start, lt_int64 end, lt_int64 step){
LT_String *self_res =lt_string_reverse(self);//字符串反转
LT_String *new_str = __lt_string_cut_step_P(self_res, start, end, -step);
__LT_String_free(self_res);
* @brief 字符串内容切割step为负
*/
static lt_string_t *lt_string_s_cut_step_N(lt_string_t *self,
int32_t start,
int32_t end,
int32_t step) {
lt_string_t *self_res = lt_string_reverse(self); // 字符串反转
lt_string_t *new_str = lt_string_s_cut_step_P(self_res, start, end, -step);
lt_string_close(self_res);
return new_str;
}
/**
* @brief 字符串内容切割
* @param self 切割的字符串
* @param start 切割的起始位置
* @param end 切割的结束位置
* @param step 切割的步长,为负表示反转
*/
LT_String *lt_string_cut(LT_String *self, lt_int64 start, lt_int64 end, lt_int64 step){
if (step > 0)return __lt_string_cut_step_P(self, start, end, step);
if (step < 0)return __lt_string_cut_step_N(self, start, end, step);
return LT_NULL_PTR;
* @brief 字符串内容切割
* @param self 切割的字符串
* @param start 切割的起始位置
* @param end 切割的结束位置
* @param step 切割的步长,为负表示反转
*/
lt_string_t *
lt_string_cut(lt_string_t *self, int32_t start, int32_t end, int32_t step) {
if (step > 0)
return lt_string_s_cut_step_P(self, start, end, step);
if (step < 0)
return lt_string_s_cut_step_N(self, start, end, step);
return NULL;
}

0
src/hash/lt-sha.c Normal file
View File

View File

@@ -1,22 +1,22 @@
#include "lt-file-linux.h"
#include "latch/base/lt-types.h"
#include <sys/stat.h>
#include <time.h>
lt_time_t lt_cross_file_get_create_time(LT_String* path){
time_t lt_cross_file_get_create_time(lt_string_t* path){
struct stat fileStat;
if (stat(path->data, &fileStat) == -1){
return 0;
}
lt_time_t createTime = fileStat.st_ctime;
time_t createTime = fileStat.st_ctime;
return createTime;
}
lt_time_t lt_cross_file_get_modify_time(LT_String* path){
time_t lt_cross_file_get_modify_time(lt_string_t* path){
struct stat fileStat;
if (stat(path->data, &fileStat) == -1){
return 0;
}
lt_time_t modifyTime = fileStat.st_mtime;
time_t modifyTime = fileStat.st_mtime;
return modifyTime;
}

View File

@@ -1,23 +1,24 @@
#ifndef __LATCH_FILE_UNIX_H__
#define __LATCH_FILE_UNIX_H__
#include "latch/base/lt-types.h"
#include "latch/container/lt-string.h"
#include <stdbool.h>
#include <time.h>
/**
* @brief 获取文件创建时间戳
* @brief 标准接口:禁止以任何形式改动。每个平台实现对应的接口实现
* @param path 文件路径
* @return lt_time_t 文件创建时间戳
*/
lt_time_t lt_cross_file_get_create_time(LT_String* path);
* @brief 获取文件创建时间戳
* @brief 标准接口:禁止以任何形式改动。每个平台实现对应的接口实现
* @param path 文件路径
* @return time_t 文件创建时间戳
*/
time_t lt_cross_file_get_create_time(lt_string_t *path);
/**
* @brief 获取文件修改时间戳
* @brief 标准接口:禁止以任何形式改动。每个平台实现对应的接口实现
* @param path 文件路径
* @return lt_time_t 文件创建时间戳
*/
lt_time_t lt_cross_file_get_modify_time(LT_String* path);
* @brief 获取文件修改时间戳
* @brief 标准接口:禁止以任何形式改动。每个平台实现对应的接口实现
* @param path 文件路径
* @return time_t 文件创建时间戳
*/
time_t lt_cross_file_get_modify_time(lt_string_t *path);
#endif //__LATCH_FILE_UNIX_H__
#endif //__LATCH_FILE_UNIX_H__

View File

@@ -3,11 +3,11 @@
#include <windows.h>
lt_time_t lt_cross_file_get_create_time(LT_String* path){
time_t lt_cross_file_get_create_time(lt_string_t* path){
return 0;//TODO 实现windows的创建时间
}
lt_time_t lt_cross_file_get_modify_time(LT_String* path){
time_t lt_cross_file_get_modify_time(lt_string_t* path){
return 0;//TODO 实现windows的修改时间
}

View File

@@ -1,23 +1,23 @@
#ifndef __LATCH_FILE_WINDOWS_H__
#define __LATCH_FILE_WINDOWS_H__
#include "latch/base/lt-types.h"
#include "latch/container/lt-string.h"
/**
* @brief 获取文件创建时间戳
* @brief 标准接口:禁止以任何形式改动。每个平台实现对应的接口实现
* @param path 文件路径
* @return lt_time_t 文件创建时间戳
* @return time_t 文件创建时间戳
*/
lt_time_t lt_cross_file_get_create_time(LT_String* path);
time_t lt_cross_file_get_create_time(lt_string_t* path);
/**
* @brief 获取文件修改时间戳
* @brief 标准接口:禁止以任何形式改动。每个平台实现对应的接口实现
* @param path 文件路径
* @return lt_time_t 文件创建时间戳
* @return time_t 文件创建时间戳
*/
lt_time_t lt_cross_file_get_modify_time(LT_String* path);
time_t lt_cross_file_get_modify_time(lt_string_t* path);
#endif //__LATCH_FILE_WINDOWS_H__

View File

@@ -1,60 +1,2 @@
#include "latch/io/lt-file.h"
#include "latch/base/lt-types.h"
#include "latch/container/lt-string.h"
#include "latch/memory/lt-memory.h"
#include <stdio.h>
#ifdef __linux__
#include "cross/unix/lt-file-linux.h"
#elif defined(__WIN32__) || defined(_WIN32)
#include "cross/windows/lt-file-windows.h"
#endif
/**
* @brief 获取文件大小
*/
static lt_size_t __lt_file_get_size(FILE *fp){
fseek(fp, 0L, SEEK_END);
lt_size_t size = ftell(fp);
rewind(fp);
return size;
}
/**
* @brief 关闭文件
*/
static void __lt_file_close(LT_File *file){
fclose(file->fp);
file->name->close(file->name);
file->path->close(file->path);
lt_free(file);
}
/**
* @brief 打开文件
* @param path 文件路径
* @param mode 文件打开模式,"w","r","rb"
*/
LT_File *lt_file_open(const char *path, const char *mode){
LT_File *file = (LT_File*)lt_malloc(sizeof(LT_File));
if (file==LT_NULL_PTR)return LT_NULL_PTR;
FILE *fp = fopen(path, mode);
if (fp==LT_NULL_PTR){
lt_free(file);
return LT_NULL_PTR;
}
file->fp = fp;
file->path = lt_string_new(path);
file->size = __lt_file_get_size(fp);
file->create_time = lt_cross_file_get_create_time(file->path);
file->modify_time = lt_cross_file_get_modify_time(file->path);
file->name = lt_string_new(path);
file->close = __lt_file_close;
file->read_bytes = LT_NULL_PTR; //TODO 未实现
file->write_bytes = LT_NULL_PTR; //TODO 未实现
return file;
}

View File

@@ -0,0 +1,86 @@
#include "latch/memory/lt-memory-debug.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static lt_memory_debug_info_list_t LT_MEMORY_DEBUG_INFO_LIST = {
NULL, NULL, 0};
/**
* @brief 内存调试信息添加
* @param file 文件名
* @param line 行号
* @param ptr 内存地址
* @param size 内存大小
*/
void lt_memory_debug_info_add(const char *file,
int line,
void *ptr,
size_t size) {
lt_memory_debug_info_t *info =
(lt_memory_debug_info_t *)malloc(sizeof(lt_memory_debug_info_t));
info->file = (char *)malloc(strlen(file) + 1);
strcpy(info->file, file);
info->line = line;
info->ptr = ptr;
info->size = size;
info->next = NULL;
if (LT_MEMORY_DEBUG_INFO_LIST.head == NULL) {
LT_MEMORY_DEBUG_INFO_LIST.head = info;
LT_MEMORY_DEBUG_INFO_LIST.tail = info;
} else {
LT_MEMORY_DEBUG_INFO_LIST.tail->next = info;
LT_MEMORY_DEBUG_INFO_LIST.tail = info;
}
LT_MEMORY_DEBUG_INFO_LIST.size++;
}
/**
* @brief 打印内存调试信息
*/
void lt_memory_debug_print_info() {
printf("LT_MEMORY_DEBUG_INFO_LIST size:%lu\n",
LT_MEMORY_DEBUG_INFO_LIST.size);
lt_memory_debug_info_t *i = LT_MEMORY_DEBUG_INFO_LIST.head;
while (i != NULL) {
printf("file: %s:%d:0 ptr:0x%p size:%lu\n",
i->file,
i->line,
i->ptr,
i->size);
i = i->next;
}
}
/**
* @brief 内存调试信息移除指定内存记录
*/
bool lt_memory_debug_info_remove_prt(void *ptr) {
lt_memory_debug_info_t *i = LT_MEMORY_DEBUG_INFO_LIST.head;
lt_memory_debug_info_t *pre = NULL;
while (i != NULL) {
if (i->ptr == ptr) {
if (pre != NULL)
pre->next = i->next;
else
LT_MEMORY_DEBUG_INFO_LIST.head = i->next;
free(i->file);
free(i);
break;
}
pre = i;
i = i->next;
}
LT_MEMORY_DEBUG_INFO_LIST.size--;
if (LT_MEMORY_DEBUG_INFO_LIST.size == 0) {
LT_MEMORY_DEBUG_INFO_LIST.head = NULL;
LT_MEMORY_DEBUG_INFO_LIST.tail = NULL;
} else if (i == NULL) {
return false;
} else {
LT_MEMORY_DEBUG_INFO_LIST.tail = pre;
}
return true;
}

View File

@@ -1,18 +0,0 @@
#include "lt-memory-libc.h"
#include <stdlib.h>
void *lt_malloc_libc(lt_size_t size){
return malloc(size);
}
void *lt_calloc_libc(lt_size_t nmemb, lt_size_t size){
return calloc(nmemb, size);
}
void *lt_realloc_libc(void *ptr, lt_size_t size){
return realloc(ptr, size);
}
void lt_free_libc(void *ptr){
free(ptr);
}

View File

@@ -1,11 +0,0 @@
#ifndef __LATCH_MEMORY_LIBC_H__
#define __LATCH_MEMORY_LIBC_H__
#include "latch/base/lt-types.h"
void *lt_malloc_libc(lt_size_t size);
void *lt_calloc_libc(lt_size_t nmemb, lt_size_t size);
void *lt_realloc_libc(void *ptr, lt_size_t size);
void lt_free_libc(void *ptr);
#endif //__LATCH_MEMORY_LIBC_H__

View File

@@ -1,11 +1,11 @@
#ifndef __LATCH_MEMORY_POOL_H__
#define __LATCH_MEMORY_POOL_H__
#include "latch/base/lt-types.h"
#include <stddef.h>
void *lt_malloc_pool(lt_size_t size);
void *lt_calloc_pool(lt_size_t nmemb, lt_size_t size);
void *lt_realloc_pool(void *ptr, lt_size_t size);
void lt_free_pool(void *ptr);
void *lt_malloc_pool(size_t size);
void *lt_calloc_pool(size_t nmemb, size_t size);
void *lt_realloc_pool(void *ptr, size_t size);
void lt_free_pool(void *ptr);
#endif //__LATCH_MEMORY_POOL_H__

View File

@@ -1,58 +1,66 @@
#include "latch/memory/lt-memory.h"
#include "latch/base/lt-types.h"
#include "lt-memory-libc.h"
lt_memory_type_e lt_default_memory_manager_G = LT_MEMORY_TYPE_LIBC;
#include <stdlib.h>
static void *(*__lt_malloc)(size_t size) = malloc;
static void *(*__lt_calloc)(size_t nmemb, size_t size) = calloc;
static void *(*__lt_realloc)(void *ptr, size_t size) = realloc;
static void (*__lt_free)(void *ptr) = free;
void *lt_malloc(lt_size_t size){
switch (lt_default_memory_manager_G) {
case LT_MEMORY_TYPE_LIBC:
return lt_malloc_libc(size);
break;
case LT_MEMORY_TYPE_POOL:
return LT_NULL_PTR;
break;
default:
return LT_NULL_PTR;
}
#ifndef LATCH_DEBUG
void *lt_malloc_direct(size_t size, char *file, int line) {
return __lt_malloc(size);
}
void *lt_calloc_direct(size_t nmemb, size_t size, char *file, int line) {
return __lt_calloc(nmemb, size);
}
void *lt_realloc_direct(void *ptr, size_t size, char *file, int line) {
return __lt_realloc(ptr, size);
}
void lt_free_direct(void *ptr, char *file, int line) { __lt_free(ptr); }
#else
#include "latch/memory/lt-memory-debug.h"
#include <stdio.h>
void *lt_malloc_direct(size_t size, char *file, int line) {
void *new_mem = __lt_malloc(size);
lt_memory_debug_info_add(file, line, new_mem, size);
return new_mem;
}
void *lt_calloc(lt_size_t nmemb, lt_size_t size){
switch (lt_default_memory_manager_G) {
case LT_MEMORY_TYPE_LIBC:
return lt_calloc_libc(nmemb, size);
break;
case LT_MEMORY_TYPE_POOL:
return LT_NULL_PTR;
break;
default:
return LT_NULL_PTR;
}
void *lt_calloc_direct(size_t nmemb, size_t size, char *file, int line) {
return __lt_calloc(nmemb, size);
}
void *lt_realloc(void *ptr, lt_size_t size){
switch (lt_default_memory_manager_G) {
case LT_MEMORY_TYPE_LIBC:
return lt_realloc_libc(ptr, size);
break;
case LT_MEMORY_TYPE_POOL:
return LT_NULL_PTR;
break;
default:
return LT_NULL_PTR;
}
void *lt_realloc_direct(void *ptr, size_t size, char *file, int line) {
return __lt_realloc(ptr, size);
}
void lt_free(void *ptr){
switch (lt_default_memory_manager_G) {
case LT_MEMORY_TYPE_LIBC:
return lt_free_libc(ptr);
break;
case LT_MEMORY_TYPE_POOL:
return ;
break;
default:
return ;
void lt_free_direct(void *ptr, char *file, int line) {
if (lt_memory_debug_info_remove_prt(ptr))
__lt_free(ptr);
else
printf("重复释放 file:%s %d\n", file, line);
}
#endif
void lt_memory_set_functions(void *(*malloc_func)(size_t size),
void *(*calloc_func)(size_t nmemb,
size_t size),
void *(*realloc_func)(void *ptr, size_t size),
void (*free_func)(void *ptr)) {
__lt_malloc = malloc_func;
__lt_calloc = calloc_func;
__lt_realloc = realloc_func;
__lt_free = free_func;
}
void lt_memory_set_default_type(lt_memory_type_e type) {
switch (type) {
case LT_MEMORY_TYPE_LIBC:
lt_memory_set_functions(malloc, calloc, realloc, free);
break;
default:
lt_memory_set_functions(malloc, calloc, realloc, free);
break;
}
}

View File

@@ -0,0 +1,12 @@
#include "lt-os-unix.h"
#include <sys/stat.h>
#include <stdbool.h>
#include <stdint.h>
bool lt_cross_os_mkdir(const char *path, uint32_t mode) {
if (mkdir(path, (mode_t)mode) == 0) {
return true;
} else {
return false;
}
}

View File

@@ -0,0 +1,15 @@
#ifndef __LT_OS_UNIX_H__
#define __LT_OS_UNIX_H__
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
bool lt_cross_os_mkdir(const char *path, uint32_t mode);
#ifdef __cplusplus
}
#endif
#endif // __LT_OS_UNIX_H__

View File

@@ -0,0 +1,15 @@
#if defined(__WIN32__) || defined(_WIN32)
#include "lt-os-windows.h"
#include <windows.h>
bool lt_cross_os_mkdir(const char *path, uint32_t mode){
}
#endif

View File

@@ -0,0 +1,13 @@
#ifndef __LT_OS_WINDOWS_H__
#define __LT_OS_WINDOWS_H__
#ifdef __cplusplus
extern "C" {
#endif
bool lt_cross_os_mkdir(const char *path, uint32_t mode);
#ifdef __cplusplus
}
#endif
#endif // __LT_OS_WINDOWS_H__

11
src/os/lt-os.c Normal file
View File

@@ -0,0 +1,11 @@
#include "latch/os/lt-os.h"
#include <stdint.h>
#if defined (__linux__)
#include "cross/unix/lt-os-unix.h"
#endif
bool lt_os_mkdir(const char *path, uint32_t mode){
return lt_cross_os_mkdir(path, mode);
}

View File

@@ -1 +1,20 @@
#include "latch/latch.h"
#include "latch/os/lt-path.h"
#include <stdio.h>
bool lt_path_is_file(const char *path) {
FILE *fp = fopen(path, "r");
if (fp == NULL)
return false;
fclose(fp);
return true;
}
bool lt_path_is_dir(const char *path) {
if (lt_path_is_file(path))
return false;
return true;
}
//TODO
bool lt_path_exists(const char *path) { return true; }

View File

@@ -0,0 +1,4 @@
#ifndef __LT_SOCKET_UNIX_H__
#define __LT_SOCKET_UNIX_H__
#endif // __LT_SOCKET_UNIX_H__

View File

@@ -0,0 +1,4 @@
#ifndef __LT_SOCKET_WINDOWS_H__
#define __LT_SOCKET_WINDOWS_H__
#endif // __LT_SOCKET_WINDOWS_H__

5
src/socket/lt-socket.c Normal file
View File

@@ -0,0 +1,5 @@
#include "latch/socket/lt-socket.h"

View File

@@ -1,7 +1,5 @@
project(test)
add_subdirectory(container)
add_subdirectory(io)
# add_subdirectory(io)

View File

@@ -1,10 +1,14 @@
project(test-container)
add_executable(${PROJECT_NAME}-string test-lt-string.c)
target_link_libraries(${PROJECT_NAME}-string latch)
if(UNIX)
add_test(${PROJECT_NAME}-string ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-string)
elseif(WIN32)
add_test(${PROJECT_NAME}-string ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-string.exe)
endif()
add_executable(
${PROJECT_NAME}_string
test_sring.cpp
)
target_link_libraries(
${PROJECT_NAME}_string
latch
gtest::gtest
)
gtest_discover_tests(${PROJECT_NAME}_string)

View File

@@ -1,31 +0,0 @@
#include "latch/container/lt-string.h"
#include <stdio.h>
int main(int argc, char *argv[]){
printf("LT_String 创建测试\n");
LT_String *str = lt_string_new("Hello, world!");
printf("字符串内容: %s\n", str->data);
printf("字符串长度: %ld\n", str->length);
printf("LT_String cut测试 start=0,end=11,step=1\n");
LT_String *str2 = lt_string_cut(str, 0, 11, 1);
printf("字符串内容: %s\n", str2->data);
printf("字符串长度: %ld\n", str2->length);
str2->close(str2);
printf("LT_String cut测试-反转cut start=0,end=11,step=-1\n");
LT_String *str3 = lt_string_cut(str, 0, 11, -1);
printf("字符串内容: %s\n", str3->data);
printf("字符串长度: %ld\n", str3->length);
str3->close(str3);
printf("LT_String 测试反转\n");
LT_String *str4 = lt_string_reverse(str);
printf("字符串内容: %s\n", str4->data);
printf("字符串长度: %ld\n", str4->length);
str4->close(str4);
str->close(str);
return 0;
}

View File

@@ -0,0 +1,47 @@
#include "latch/container/lt-string.h"
#include "gtest/gtest.h"
TEST(TestString, StringNew) {
lt_string_t *str = lt_string_new("Hello World");
EXPECT_STREQ(str->data, "Hello World");
lt_string_close(str);
}
TEST(TestString, StringReverse) {
lt_string_t *str = lt_string_new("Hello World");
EXPECT_STREQ(str->data, "Hello World");
lt_string_t *str_r = lt_string_reverse(str);
EXPECT_STREQ(str_r->data, "dlroW olleH");
lt_string_close(str);
lt_string_close(str_r);
}
TEST(TestString, StringCut) {
lt_string_t *str = lt_string_new("Hello World");
EXPECT_STREQ(str->data, "Hello World");
EXPECT_EQ(str->length, 11);
lt_string_t *str_c = lt_string_cut(str, 0, 5, 1);
EXPECT_STREQ(str_c->data, "Hello");
EXPECT_EQ(str_c->length, 5);
lt_string_t *str_c1 = lt_string_cut(str, 0, 5, -1);
EXPECT_STREQ(str_c1->data, "dlroW");
EXPECT_EQ(str_c1->length, 5);
lt_string_t *str_c2 = lt_string_cut(str, 0, 5, 2);
EXPECT_STREQ(str_c2->data, "Hlo");
EXPECT_EQ(str_c2->length, 3);
lt_string_t *str_c3 = lt_string_cut(str, 0, 5, -2);
EXPECT_STREQ(str_c3->data, "drW");
EXPECT_EQ(str_c3->length, 3);
lt_string_close(str);
lt_string_close(str_c);
lt_string_close(str_c1);
lt_string_close(str_c2);
lt_string_close(str_c3);
}

View File

@@ -1,11 +0,0 @@
project(test-io)
add_executable(${PROJECT_NAME}-file test-lt-file.c)
target_link_libraries(${PROJECT_NAME}-file latch)
if(UNIX)
add_test(${PROJECT_NAME}-file ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-file)
elseif(WIN32)
add_test(${PROJECT_NAME}-file ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-file.exe)
endif()

View File

@@ -1,16 +0,0 @@
#include "latch/io/lt-file.h"
#include <stdio.h>
int main(int argc, char *argv[]){
LT_File* f = lt_file_open("test.txt", "w");
printf("LT_File size: %ld\n", sizeof(LT_File));
printf("File: %p\n", f);
printf("File name: %s\n", f->name->data);
printf("File path: %s\n", f->path->data);
printf("File size: %ld\n", f->size);
printf("file create time %ld\n", f->create_time);
printf("file modify time %ld\n", f->modify_time);
f->close(f);
return 0;
}