Compare commits

6 Commits

Author SHA1 Message Date
wash 346193aad9 meta: add c++ wrapper for ds module 2026-03-15 14:42:47 +00:00
wash d599eb539a mm: core: add iterator class 2026-03-15 14:42:31 +00:00
wash 146db5f6ef test: add core-mm tests 2026-02-03 17:41:34 +00:00
wash 13136ecbd6 meta: add c++ wrapper of core module 2026-02-03 17:41:25 +00:00
wash e0efbd1ec4 build: add template for c++-based modules 2026-02-03 17:41:01 +00:00
wash e0aea0be19 core: slight changes to allow compilation under c++ 2026-02-03 17:40:45 +00:00
327 changed files with 25087 additions and 28156 deletions
+66 -124
View File
@@ -1,122 +1,6 @@
BasedOnStyle: WebKit
IndentWidth: 8
---
Language: C
DerivePointerAlignment: false
PointerAlignment: Right
ColumnLimit: 80
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: Right
AlignOperands: AlignAfterOperator
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: OnePerLine
ExperimentalAutoDetectBinPacking: false
BitFieldColonSpacing: Both
BreakBeforeBraces: Linux
BreakBeforeBinaryOperators: All
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
BreakStringLiterals: true
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
IncludeBlocks: Regroup
SortIncludes: true
IndentRequires: true
NamespaceIndentation: Inner
ReflowComments: true
SpacesBeforeTrailingComments: 3
TabWidth: 8
UseTab: AlignWithSpaces
PenaltyReturnTypeOnItsOwnLine: 1000000
PenaltyExcessCharacter: 999999999
PenaltyBreakOpenParenthesis: 5
PenaltyBreakBeforeFirstCallParameter: 5
PenaltyIndentedWhitespace: 0
AttributeMacros:
- FX_API
ForEachMacros:
- fx_btree_foreach
- fx_queue_foreach
MacroBlockBegin: "FX_(TYPE|ASSEMBLY)_.*_BEGIN"
MacroBlockEnd: "FX_(TYPE|ASSEMBLY)_.*_END"
---
Language: ObjC
DerivePointerAlignment: false
PointerAlignment: Right
ColumnLimit: 80
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: Right
AlignOperands: AlignAfterOperator
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: true
ExperimentalAutoDetectBinPacking: false
BitFieldColonSpacing: Both
BreakBeforeBraces: Linux
BreakBeforeBinaryOperators: All
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
BreakStringLiterals: true
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
IncludeBlocks: Regroup
SortIncludes: true
IndentRequires: true
NamespaceIndentation: Inner
ReflowComments: true
SpacesBeforeTrailingComments: 3
TabWidth: 8
UseTab: AlignWithSpaces
PenaltyReturnTypeOnItsOwnLine: 1000000
PenaltyExcessCharacter: 5
PenaltyBreakOpenParenthesis: 5
PenaltyBreakBeforeFirstCallParameter: 5
PenaltyIndentedWhitespace: 0
AttributeMacros:
- FX_API
ForEachMacros:
- fx_btree_foreach
- fx_queue_foreach
MacroBlockBegin: "FX_(TYPE|ASSEMBLY)_.*_BEGIN"
MacroBlockEnd: "FX_(TYPE|ASSEMBLY)_.*_END"
---
Language: Cpp
DerivePointerAlignment: false
PointerAlignment: Right
@@ -142,8 +26,8 @@ AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: OnePerLine
BinPackArguments: true
BinPackParameters: true
ExperimentalAutoDetectBinPacking: false
BitFieldColonSpacing: Both
BreakBeforeBraces: Linux
@@ -163,14 +47,72 @@ SpacesBeforeTrailingComments: 3
TabWidth: 8
UseTab: AlignWithSpaces
PenaltyReturnTypeOnItsOwnLine: 1000000
PenaltyExcessCharacter: 9999999
PenaltyExcessCharacter: 5
PenaltyBreakOpenParenthesis: 5
PenaltyBreakBeforeFirstCallParameter: 5
PenaltyIndentedWhitespace: 0
AttributeMacros:
- FX_API
- BLUELIB_API
ForEachMacros:
- fx_btree_foreach
- fx_queue_foreach
MacroBlockBegin: "FX_(TYPE|ASSEMBLY)_.*_BEGIN"
MacroBlockEnd: "FX_(TYPE|ASSEMBLY)_.*_END"
- b_btree_foreach
- b_queue_foreach
MacroBlockBegin: "B_TYPE_.*_BEGIN"
MacroBlockEnd: "B_TYPE_.*_END"
---
Language: ObjC
DerivePointerAlignment: false
PointerAlignment: Right
ColumnLimit: 80
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: Right
AlignOperands: AlignAfterOperator
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
ExperimentalAutoDetectBinPacking: false
BitFieldColonSpacing: Both
BreakBeforeBraces: Linux
BreakBeforeBinaryOperators: All
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
BreakStringLiterals: true
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
IncludeBlocks: Regroup
SortIncludes: true
IndentRequires: true
NamespaceIndentation: Inner
ReflowComments: true
SpacesBeforeTrailingComments: 3
TabWidth: 8
UseTab: AlignWithSpaces
PenaltyReturnTypeOnItsOwnLine: 1000000
PenaltyExcessCharacter: 5
PenaltyBreakOpenParenthesis: 5
PenaltyBreakBeforeFirstCallParameter: 5
PenaltyIndentedWhitespace: 0
AttributeMacros:
- BLUELIB_API
ForEachMacros:
- b_btree_foreach
- b_queue_foreach
MacroBlockBegin: "B_TYPE_.*_BEGIN"
MacroBlockEnd: "B_TYPE_.*_END"
+50 -34
View File
@@ -1,54 +1,70 @@
cmake_minimum_required(VERSION 3.25)
project(fx C)
project(bluelib C CXX)
include (TestBigEndian)
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(fx_all_assemblies
fx.runtime
fx.collections)
set(b_modules
core ds serial term cmd io compress
core-mm ds-mm)
if (NOT DEFINED fx_assemblies)
set(fx_assemblies ${fx_all_assemblies})
endif ()
set(b_system_name ${CMAKE_SYSTEM_NAME})
string(TOLOWER ${b_system_name} b_system_name)
if (NOT DEFINED fx_enable_floating_point)
set(fx_enable_floating_point 1)
endif ()
if (NOT DEFINED fx_enable_tests)
set(fx_enable_tests 1)
endif ()
message(STATUS "Floating point support: ${fx_enable_floating_point}")
set(fx_system_name ${CMAKE_SYSTEM_NAME})
string(TOLOWER ${fx_system_name} fx_system_name)
message(STATUS "System name: ${fx_system_name}")
message(STATUS "System name: ${b_system_name}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Templates.cmake)
foreach (module ${b_modules})
add_subdirectory(${module})
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/${module})
message(STATUS "Building unit tests for module ${module}")
if ("fx.runtime" IN_LIST fx_assemblies)
add_fx_assembly(
NAME fx.runtime
NAMESPACES fx fx.reflection)
endif ()
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/${module}/${module}-units.c)
add_executable(blue-${module}-units
test/${module}/${module}-units.c
misc/AllTests.c
misc/CuTest.c
misc/CuTest.h)
target_link_libraries(blue-${module}-units blue-${module})
target_include_directories(blue-${module}-units PRIVATE misc/)
set_target_properties(blue-${module}-units PROPERTIES FOLDER "Tests/${module}")
if ("fx.collections" IN_LIST fx_assemblies)
add_fx_assembly(
NAME fx.collections
NAMESPACES fx.collections
DEPENDENCIES fx.runtime)
endif ()
endif ()
add_executable(dynamic-test test/dynamic-test.c)
file(GLOB test_sources test/${module}/*.c test/${module}/*.cpp)
list(REMOVE_ITEM test_sources "${CMAKE_CURRENT_SOURCE_DIR}/test/${module}/${module}-units.c")
foreach (test_file ${test_sources})
get_filename_component(test_name ${test_file} NAME_WE)
add_executable(blue-${module}-${test_name} ${test_file})
set_target_properties(blue-${module}-${test_name} PROPERTIES FOLDER "Tests/${module}")
target_link_libraries(blue-${module}-${test_name} blue-${module})
endforeach (test_file)
endif ()
endforeach (module)
file(GLOB test_sources test/*.c)
list(REMOVE_ITEM test_sources "${CMAKE_CURRENT_SOURCE_DIR}/test/units.c")
foreach (test_file ${test_sources})
get_filename_component(test_name ${test_file} NAME_WE)
add_executable(blue-${test_name} ${test_file})
set_target_properties(blue-${test_name} PROPERTIES FOLDER "Tests")
foreach (module ${b_modules})
target_link_libraries(blue-${test_name} blue-${module})
endforeach (module)
endforeach (test_file)
-14
View File
@@ -1,14 +0,0 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_NAME("fx.collections");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "array", fx_array);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "bitbuffer", fx_bitbuffer);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "bitmap", fx_bitmap);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "dict", fx_dict);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "hashmap", fx_hashmap);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "list", fx_list);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "tree", fx_tree);
FX_ASSEMBLY_END()
-12
View File
@@ -1,12 +0,0 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_NAME("fx.runtime");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_EXPORT_TYPE("fx", "stream", fx_stream);
FX_ASSEMBLY_EXPORT_TYPE("fx", "string", fx_string);
FX_ASSEMBLY_EXPORT_TYPE("fx", "stringstream", fx_stringstream);
FX_ASSEMBLY_EXPORT_TYPE("fx", "iterator", fx_iterator);
FX_ASSEMBLY_EXPORT_TYPE("fx.reflection", "assembly", fx_assembly);
FX_ASSEMBLY_END()
+189
View File
@@ -0,0 +1,189 @@
#[=======================================================================[.rst:
FindBluelib
------------
Find the Bluelib library and header directories
Imported Targets
^^^^^^^^^^^^^^^^
This module defines the following :prop_tgt:`IMPORTED` target:
``Bluelib::Bluelib``
The Bluelib library, if found
Result Variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
``Bluelib_FOUND``
true if the Bluelib C headers and libraries were found
``Bluelib_INCLUDE_DIR``
directories containing the Bluelib C headers.
``Bluelib_LIBRARY``
the C library to link against
Hints
^^^^^
The user may set the environment variable ``Bluelib_PREFIX`` to the root
directory of a Bluelib library installation.
#]=======================================================================]
set (Bluelib_SEARCH_PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr/local/share
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
${Bluelib_PREFIX}
$ENV{Bluelib_PREFIX})
if (Bluelib_STATIC)
set(_lib_suffix "-s")
endif ()
set(supported_components Core Ds Term Cmd Io Serial Compress)
set(components ${Bluelib_FIND_COMPONENTS})
string(REPLACE ";" ", " supported_components_string_list "${supported_components}")
if (NOT components)
set(components ${supported_components})
endif ()
set(required_vars)
foreach (component ${components})
if (NOT "${component}" IN_LIST supported_components)
message(FATAL_ERROR "'${component}' is not a valid Bluelib module.\nSupported modules: ${supported_components_string_list}")
endif ()
string(TOLOWER ${component} header_name)
set(lib_name ${header_name}${_lib_suffix})
if (NOT Bluelib_${component}_INCLUDE_DIR)
find_path(Bluelib_${component}_INCLUDE_DIR
NAMES blue/${header_name}.h ${Bluelib_FIND_ARGS}
PATH_SUFFIXES include
PATHS ${Bluelib_SEARCH_PATHS})
endif ()
if (NOT Bluelib_${component}_LIBRARY)
find_library(Bluelib_${component}_LIBRARY
NAMES blue-${lib_name} ${Bluelib_FIND_ARGS}
PATH_SUFFIXES lib
PATHS ${Bluelib_SEARCH_PATHS})
else ()
# on Windows, ensure paths are in canonical format (forward slahes):
file(TO_CMAKE_PATH "${Bluelib_${component}_LIBRARY}" Bluelib_${component}_LIBRARY)
endif()
list(APPEND required_vars Bluelib_${component}_INCLUDE_DIR Bluelib_${component}_LIBRARY)
endforeach (component)
unset(Bluelib_FIND_ARGS)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Bluelib
REQUIRED_VARS ${required_vars})
if (Bluelib_FOUND)
set(created_targets)
foreach (component ${components})
string(TOLOWER ${component} header_name)
set(lib_name ${header_name}${_lib_suffix})
if(NOT TARGET Bluelib::${component})
add_library(Bluelib::${component} UNKNOWN IMPORTED)
set_target_properties(Bluelib::${component} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Bluelib_${component}_INCLUDE_DIR}")
target_compile_definitions(Bluelib::${component} INTERFACE _CRT_SECURE_NO_WARNINGS=1)
if (Bluelib_STATIC)
target_compile_definitions(Bluelib::${component} INTERFACE BLUELIB_STATIC=1)
endif ()
set_target_properties(Bluelib::${component} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${Bluelib_${component}_LIBRARY}")
set(created_targets ${created_targets} ${component})
endif ()
endforeach (component)
foreach (component ${created_targets})
if ("${component}" STREQUAL "Ds")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Ds' depends on 'Core', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Ds INTERFACE Bluelib::Core)
endif ()
if ("${component}" STREQUAL "Term")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Term' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Ds)
message(FATAL_ERROR "Bluelib: Module 'Term' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Term INTERFACE Bluelib::Core Bluelib::Ds)
endif ()
if ("${component}" STREQUAL "Serial")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Serial' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Ds)
message(FATAL_ERROR "Bluelib: Module 'Serial' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Serial INTERFACE Bluelib::Core Bluelib::Ds)
endif ()
if ("${component}" STREQUAL "Cmd")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Cmd' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Ds)
message(FATAL_ERROR "Bluelib: Module 'Cmd' depends on 'Ds', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Term)
message(FATAL_ERROR "Bluelib: Module 'Cmd' depends on 'Term', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Cmd INTERFACE Bluelib::Core Bluelib::Ds Bluelib::Term)
endif ()
if ("${component}" STREQUAL "Io")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Io' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Ds)
message(FATAL_ERROR "Bluelib: Module 'Io' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Io INTERFACE Bluelib::Core Bluelib::Ds)
endif ()
if ("${component}" STREQUAL "Compress")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Compress' depends on 'Core', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Compress INTERFACE Bluelib::Core Bluelib::Ds)
endif ()
endforeach (component)
endif()
-189
View File
@@ -1,189 +0,0 @@
#[=======================================================================[.rst:
FindFX
------------
Find the FX library and header directories
Imported Targets
^^^^^^^^^^^^^^^^
This module defines the following :prop_tgt:`IMPORTED` target:
``FX::FX``
The FX library, if found
Result Variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
``FX_FOUND``
true if the FX C headers and libraries were found
``FX_INCLUDE_DIR``
directories containing the FX C headers.
``FX_LIBRARY``
the C library to link against
Hints
^^^^^
The user may set the environment variable ``FX_PREFIX`` to the root
directory of a FX library installation.
#]=======================================================================]
set (FX_SEARCH_PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr/local/share
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
${FX_PREFIX}
$ENV{FX_PREFIX})
if (FX_STATIC)
set(_lib_suffix "-s")
endif ()
set(supported_components Core Ds Term Cmd Io Serial Compress)
set(components ${FX_FIND_COMPONENTS})
string(REPLACE ";" ", " supported_components_string_list "${supported_components}")
if (NOT components)
set(components ${supported_components})
endif ()
set(required_vars)
foreach (component ${components})
if (NOT "${component}" IN_LIST supported_components)
message(FATAL_ERROR "'${component}' is not a valid FX module.\nSupported modules: ${supported_components_string_list}")
endif ()
string(TOLOWER ${component} header_name)
set(lib_name ${header_name}${_lib_suffix})
if (NOT FX_${component}_INCLUDE_DIR)
find_path(FX_${component}_INCLUDE_DIR
NAMES fx/${header_name}.h ${FX_FIND_ARGS}
PATH_SUFFIXES include
PATHS ${FX_SEARCH_PATHS})
endif ()
if (NOT FX_${component}_LIBRARY)
find_library(FX_${component}_LIBRARY
NAMES fx-${lib_name} ${FX_FIND_ARGS}
PATH_SUFFIXES lib
PATHS ${FX_SEARCH_PATHS})
else ()
# on Windows, ensure paths are in canonical format (forward slahes):
file(TO_CMAKE_PATH "${FX_${component}_LIBRARY}" FX_${component}_LIBRARY)
endif()
list(APPEND required_vars FX_${component}_INCLUDE_DIR FX_${component}_LIBRARY)
endforeach (component)
unset(FX_FIND_ARGS)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FX
REQUIRED_VARS ${required_vars})
if (FX_FOUND)
set(created_targets)
foreach (component ${components})
string(TOLOWER ${component} header_name)
set(lib_name ${header_name}${_lib_suffix})
if(NOT TARGET FX::${component})
add_library(FX::${component} UNKNOWN IMPORTED)
set_target_properties(FX::${component} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${FX_${component}_INCLUDE_DIR}")
target_compile_definitions(FX::${component} INTERFACE _CRT_SECURE_NO_WARNINGS=1)
if (FX_STATIC)
target_compile_definitions(FX::${component} INTERFACE FX_STATIC=1)
endif ()
set_target_properties(FX::${component} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${FX_${component}_LIBRARY}")
set(created_targets ${created_targets} ${component})
endif ()
endforeach (component)
foreach (component ${created_targets})
if ("${component}" STREQUAL "Ds")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Ds' depends on 'Core', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Ds INTERFACE FX::Core)
endif ()
if ("${component}" STREQUAL "Term")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Term' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Ds)
message(FATAL_ERROR "FX: Module 'Term' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Term INTERFACE FX::Core FX::Ds)
endif ()
if ("${component}" STREQUAL "Serial")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Serial' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Ds)
message(FATAL_ERROR "FX: Module 'Serial' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Serial INTERFACE FX::Core FX::Ds)
endif ()
if ("${component}" STREQUAL "Cmd")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Cmd' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Ds)
message(FATAL_ERROR "FX: Module 'Cmd' depends on 'Ds', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Term)
message(FATAL_ERROR "FX: Module 'Cmd' depends on 'Term', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Cmd INTERFACE FX::Core FX::Ds FX::Term)
endif ()
if ("${component}" STREQUAL "Io")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Io' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Ds)
message(FATAL_ERROR "FX: Module 'Io' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Io INTERFACE FX::Core FX::Ds)
endif ()
if ("${component}" STREQUAL "Compress")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Compress' depends on 'Core', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Compress INTERFACE FX::Core FX::Ds)
endif ()
endforeach (component)
endif()
+173 -51
View File
@@ -1,100 +1,222 @@
function(add_fx_assembly)
function(add_bluelib_module)
set(options)
set(one_value_args NAME)
set(multi_value_args
NAMESPACES
DEPENDENCIES
LIBS)
SUBDIRS
EXTRA_SOURCES
LIBS
INCLUDE_DIRS
DEFINES)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${options}"
"${one_value_args}"
"${multi_value_args}")
set(assembly_name ${arg_NAME})
string(REPLACE "." "/" assembly_path ${assembly_name})
set(assembly_target_name ${assembly_name})
string(REPLACE "." "_" assembly_token ${assembly_name})
string(TOUPPER ${assembly_token} assembly_token)
set(module_name ${arg_NAME})
set(assembly_include_paths "")
set(assembly_sources
${CMAKE_CURRENT_SOURCE_DIR}/assemblies/${assembly_name}.c)
file(GLOB sources *.c *.h)
foreach (dir ${arg_NAMESPACES})
add_subdirectory(${dir})
set(assembly_sources ${assembly_sources} ${namespace_sources})
set(assembly_include_paths ${assembly_include_paths} ${namespace_include_paths})
foreach (dir ${arg_SUBDIRS})
file(GLOB dir_sources ${dir}/*.c ${dir}/*.h)
set(sources ${sources} ${dir_sources})
endforeach (dir)
message(STATUS "Building assembly ${assembly_name}")
add_library(${assembly_target_name} SHARED
${assembly_sources})
file(GLOB sys_sources sys/${b_system_name}/*.c sys/${b_system_name}/*.h)
set(root_header include/blue/${module_name}.h)
file(GLOB headers include/blue/${module_name}/*.h)
target_include_directories(${assembly_target_name} PUBLIC ${assembly_include_paths})
string(REPLACE "-" "_" module_preproc_token ${module_name})
string(TOUPPER ${module_preproc_token} module_preproc_token)
set(module_preproc_token BLUELIB_${module_preproc_token})
target_compile_definitions(${assembly_target_name} PUBLIC
FX_EXPORT=1
FX_ENABLE_FLOATING_POINT=${fx_enable_floating_point})
message(STATUS "Building module ${module_name} (shared)")
add_library(blue-${module_name} SHARED
${sources}
${sys_sources}
${root_header}
${headers}
${arg_EXTRA_SOURCES})
message(STATUS "Building module ${module_name} (static)")
add_library(blue-${module_name}-s STATIC
${sources}
${sys_sources}
${root_header}
${headers}
${arg_EXTRA_SOURCES})
set_target_properties(${assembly_target_name}
target_include_directories(blue-${module_name} PUBLIC include/)
target_include_directories(blue-${module_name}-s PUBLIC include/)
target_compile_definitions(blue-${module_name} PUBLIC
${module_preproc_token}
BLUELIB_EXPORT=1)
target_compile_definitions(blue-${module_name}-s PUBLIC
${module_preproc_token}
BLUELIB_EXPORT=1
BLUELIB_STATIC=1)
set_target_properties(blue-${module_name}
PROPERTIES POSITION_INDEPENDENT_CODE ON)
foreach (dep ${arg_DEPENDENCIES})
target_link_libraries(${assembly_target_name} ${dep})
target_link_libraries(blue-${module_name} blue-${dep})
target_link_libraries(blue-${module_name}-s blue-${dep}-s)
endforeach (dep)
foreach (lib ${arg_LIBS})
target_link_libraries(${assembly_target_name} ${lib})
target_link_libraries(blue-${module_name} ${lib})
target_link_libraries(blue-${module_name}-s ${lib})
endforeach (lib)
foreach (dir ${arg_INCLUDE_DIRS})
target_include_directories(${assembly_target_name} PRIVATE ${dir})
target_include_directories(blue-${module_name} PRIVATE
${dir})
target_include_directories(blue-${module_name}-s PRIVATE
${dir})
endforeach (dir)
foreach (def ${arg_DEFINES})
target_compile_definitions(${assembly_target_name} PRIVATE ${def})
target_compile_definitions(blue-${module_name} PRIVATE
${def})
target_compile_definitions(blue-${module_name}-s PRIVATE
${def})
endforeach (def)
set_target_properties(${assembly_target_name} PROPERTIES
FOLDER "${assembly_name}")
set_target_properties(blue-${module_name} PROPERTIES
FOLDER "Shared/${module_name}")
set_target_properties(blue-${module_name}-s PROPERTIES
FOLDER "Static/${module_name}")
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
if(IS_BIG_ENDIAN)
target_compile_definitions(${assembly_target_name} PRIVATE
target_compile_definitions(blue-${module_name} PRIVATE
BIG_ENDIAN)
target_compile_definitions(blue-${module_name}-s PRIVATE
BIG_ENDIAN)
else()
target_compile_definitions(${assembly_target_name} PRIVATE
target_compile_definitions(blue-${module_name} PRIVATE
LITTLE_ENDIAN)
target_compile_definitions(blue-${module_name}-s PRIVATE
LITTLE_ENDIAN)
endif()
install(TARGETS ${assembly_target_name})
install(FILES ${headers} DESTINATION include/${assembly_path})
endfunction(add_fx_assembly)
install(TARGETS blue-${module_name} blue-${module_name}-s)
install(FILES ${root_header} DESTINATION include/blue)
install(FILES ${headers} DESTINATION include/blue/${module_name})
endfunction(add_bluelib_module)
macro(export_fx_namespace_details)
function(add_bluelib_mm_module)
set(options)
set(one_value_args NAME)
set(multi_value_args)
set(multi_value_args
DEPENDENCIES
SUBDIRS
EXTRA_SOURCES
LIBS
INCLUDE_DIRS
DEFINES)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${options}"
"${one_value_args}"
"${multi_value_args}")
set(namespace_name ${arg_NAME})
string(REPLACE "." "/" namespace_path ${namespace_name})
set(namespace_target_name ${namespace_name})
set(short_module_name ${arg_NAME})
set(module_name ${arg_NAME}-mm)
set(namespace_include_paths ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE)
file(GLOB namespace_sources
file(GLOB sources
*.c *.h
${CMAKE_CURRENT_SOURCE_DIR}/include/${namespace_path}/*.h)
file(GLOB sys_sources sys/${fx_system_name}/*.c sys/${fx_system_name}/*.h)
file(GLOB headers include/${namespace_path}/*.h)
set(namespace_sources
${namespace_sources}
${sys_sources}
${headers}
PARENT_SCOPE)
endmacro(export_fx_namespace_details)
*.cpp *.hpp)
foreach (dir ${arg_SUBDIRS})
file(GLOB dir_sources
${dir}/*.c ${dir}/*.h
${dir}/*.cpp ${dir}/*.hpp)
set(sources ${sources} ${dir_sources})
endforeach (dir)
file(GLOB sys_sources
sys/${b_system_name}/*.c sys/${b_system_name}/*.h
sys/${b_system_name}/*.cpp sys/${b_system_name}/*.hpp)
set(root_header include/blue/${short_module_name}.hpp)
file(GLOB headers include/blue/${short_module_name}/*.hpp)
string(REPLACE "-" "_" module_preproc_token ${short_module_name})
string(TOUPPER ${module_preproc_token} module_preproc_token)
set(module_preproc_token BLUELIB_${module_preproc_token})
message(STATUS "Building mm module ${short_module_name} (shared)")
add_library(blue-${module_name} SHARED
${sources}
${sys_sources}
${root_header}
${headers}
${arg_EXTRA_SOURCES})
message(STATUS "Building mm module ${short_module_name} (static)")
add_library(blue-${module_name}-s STATIC
${sources}
${sys_sources}
${root_header}
${headers}
${arg_EXTRA_SOURCES})
target_include_directories(blue-${module_name} PUBLIC include/)
target_include_directories(blue-${module_name}-s PUBLIC include/)
target_compile_definitions(blue-${module_name} PUBLIC
${module_preproc_token}
BLUELIB_EXPORT=1)
target_compile_definitions(blue-${module_name}-s PUBLIC
${module_preproc_token}
BLUELIB_EXPORT=1
BLUELIB_STATIC=1)
set_target_properties(blue-${module_name}
PROPERTIES POSITION_INDEPENDENT_CODE ON)
foreach (dep ${arg_DEPENDENCIES})
target_link_libraries(blue-${module_name} blue-${dep})
target_link_libraries(blue-${module_name}-s blue-${dep}-s)
endforeach (dep)
foreach (lib ${arg_LIBS})
target_link_libraries(blue-${module_name} ${lib})
target_link_libraries(blue-${module_name}-s ${lib})
endforeach (lib)
foreach (dir ${arg_INCLUDE_DIRS})
target_include_directories(blue-${module_name} PRIVATE
${dir})
target_include_directories(blue-${module_name}-s PRIVATE
${dir})
endforeach (dir)
foreach (def ${arg_DEFINES})
target_compile_definitions(blue-${module_name} PRIVATE
${def})
target_compile_definitions(blue-${module_name}-s PRIVATE
${def})
endforeach (def)
set_target_properties(blue-${module_name} PROPERTIES
FOLDER "mm/Shared/${short_module_name}")
set_target_properties(blue-${module_name}-s PROPERTIES
FOLDER "mm/Static/${short_module_name}")
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
if(IS_BIG_ENDIAN)
target_compile_definitions(blue-${module_name} PRIVATE
BIG_ENDIAN)
target_compile_definitions(blue-${module_name}-s PRIVATE
BIG_ENDIAN)
else()
target_compile_definitions(blue-${module_name} PRIVATE
LITTLE_ENDIAN)
target_compile_definitions(blue-${module_name}-s PRIVATE
LITTLE_ENDIAN)
endif()
install(TARGETS blue-${module_name} blue-${module_name}-s)
install(FILES ${root_header} DESTINATION include/blue)
install(FILES ${headers} DESTINATION include/blue/${short_module_name})
endfunction(add_bluelib_mm_module)
+3
View File
@@ -0,0 +1,3 @@
include(../cmake/Templates.cmake)
add_bluelib_module(NAME cmd DEPENDENCIES core ds term)
+39 -39
View File
@@ -1,13 +1,13 @@
#include "command.h"
#include <fx/cmd.h>
#include <fx/ds/string.h>
#include <blue/cmd.h>
#include <blue/ds/string.h>
#include <stdlib.h>
#include <string.h>
struct fx_command_arg *fx_command_arg_create(void)
struct b_command_arg *b_command_arg_create(void)
{
struct fx_command_arg *out = malloc(sizeof *out);
struct b_command_arg *out = malloc(sizeof *out);
if (!out) {
return out;
}
@@ -16,7 +16,7 @@ struct fx_command_arg *fx_command_arg_create(void)
return out;
}
void fx_command_arg_destroy(struct fx_command_arg *arg)
void b_command_arg_destroy(struct b_command_arg *arg)
{
if (arg->arg_name) {
free(arg->arg_name);
@@ -37,11 +37,11 @@ void fx_command_arg_destroy(struct fx_command_arg *arg)
free(arg);
}
fx_status fx_command_arg_set_name(struct fx_command_arg *arg, const char *name)
b_status b_command_arg_set_name(struct b_command_arg *arg, const char *name)
{
char *n = fx_strdup(name);
char *n = b_strdup(name);
if (!n) {
return FX_ERR_NO_MEMORY;
return B_ERR_NO_MEMORY;
}
if (arg->arg_name) {
@@ -50,15 +50,15 @@ fx_status fx_command_arg_set_name(struct fx_command_arg *arg, const char *name)
}
arg->arg_name = n;
return FX_SUCCESS;
return B_SUCCESS;
}
fx_status fx_command_arg_set_description(
struct fx_command_arg *arg, const char *description)
b_status b_command_arg_set_description(
struct b_command_arg *arg, const char *description)
{
char *desc = fx_strdup(description);
char *desc = b_strdup(description);
if (!desc) {
return FX_ERR_NO_MEMORY;
return B_ERR_NO_MEMORY;
}
if (arg->arg_description) {
@@ -67,18 +67,18 @@ fx_status fx_command_arg_set_description(
}
arg->arg_description = desc;
return FX_SUCCESS;
return B_SUCCESS;
}
fx_status fx_command_arg_set_nr_values(
struct fx_command_arg *arg, enum fx_command_arg_value_count nr_values)
b_status b_command_arg_set_nr_values(
struct b_command_arg *arg, enum b_command_arg_value_count nr_values)
{
arg->arg_nr_values = nr_values;
return FX_SUCCESS;
return B_SUCCESS;
}
fx_status fx_command_arg_set_allowed_values(
struct fx_command_arg *arg, const char **allowed_values)
b_status b_command_arg_set_allowed_values(
struct b_command_arg *arg, const char **allowed_values)
{
size_t count;
for (count = 0; allowed_values[count]; count++)
@@ -86,35 +86,35 @@ fx_status fx_command_arg_set_allowed_values(
char **values = calloc(count + 1, sizeof *values);
if (!values) {
return FX_ERR_NO_MEMORY;
return B_ERR_NO_MEMORY;
}
for (size_t i = 0; i < count; i++) {
values[i] = fx_strdup(allowed_values[i]);
values[i] = b_strdup(allowed_values[i]);
if (!values[i]) {
/* TODO also free strings in `values` */
free(values);
return FX_ERR_NO_MEMORY;
return B_ERR_NO_MEMORY;
}
}
arg->arg_allowed_values = values;
return FX_SUCCESS;
return B_SUCCESS;
}
void z__fx_get_arg_usage_string(struct fx_command_arg *arg, bool colour, fx_string *out)
void z__b_get_arg_usage_string(struct b_command_arg *arg, bool colour, b_string *out)
{
bool optional = false, multi = false;
switch (arg->arg_nr_values) {
case FX_ARG_0_OR_1_VALUES:
case B_ARG_0_OR_1_VALUES:
optional = true;
multi = false;
break;
case FX_ARG_0_OR_MORE_VALUES:
case B_ARG_0_OR_MORE_VALUES:
optional = true;
multi = true;
break;
case FX_ARG_1_OR_MORE_VALUES:
case B_ARG_1_OR_MORE_VALUES:
optional = false;
multi = true;
break;
@@ -125,30 +125,30 @@ void z__fx_get_arg_usage_string(struct fx_command_arg *arg, bool colour, fx_stri
}
if (optional) {
fx_string_append_cstrf(
b_string_append_cstrf(
out, colour ? F_GREEN "[[%s]" : "[[%s]", arg->arg_name);
} else {
fx_string_append_cstrf(
b_string_append_cstrf(
out, colour ? F_GREEN "<%s>" : "<%s>", arg->arg_name);
}
for (int i = 1; i < arg->arg_nr_values; i++) {
fx_string_append_cstrf(out, " <%s>", arg->arg_name);
b_string_append_cstrf(out, " <%s>", arg->arg_name);
}
if (multi) {
fx_string_append_cstr(out, "...");
b_string_append_cstr(out, "...");
}
if (colour) {
fx_string_append_cstr(out, F_RESET);
b_string_append_cstr(out, F_RESET);
}
}
void z__fx_get_arg_description(struct fx_command_arg *arg, fx_string *out)
void z__b_get_arg_description(struct b_command_arg *arg, b_string *out)
{
if (arg->arg_description) {
fx_string_append_cstr(out, arg->arg_description);
b_string_append_cstr(out, arg->arg_description);
}
if (!arg->arg_allowed_values) {
@@ -156,19 +156,19 @@ void z__fx_get_arg_description(struct fx_command_arg *arg, fx_string *out)
}
if (arg->arg_description) {
fx_string_append_cstr(out, " ");
b_string_append_cstr(out, " ");
}
fx_string_append_cstr(out, "[[values:");
b_string_append_cstr(out, "[[values:");
for (size_t i = 0; arg->arg_allowed_values[i]; i++) {
if (i > 0) {
fx_string_append_cstr(out, ",");
b_string_append_cstr(out, ",");
}
fx_string_append_cstrf(
b_string_append_cstrf(
out, " " F_GREEN "%s" F_RESET, arg->arg_allowed_values[i]);
}
fx_string_append_cstr(out, "]");
b_string_append_cstr(out, "]");
}
+1050
View File
File diff suppressed because it is too large Load Diff
+1076
View File
File diff suppressed because it is too large Load Diff
+151
View File
@@ -0,0 +1,151 @@
#ifndef _B_COMMAND_H_
#define _B_COMMAND_H_
#include <blue/cmd.h>
#include <blue/core/btree.h>
#include <blue/core/queue.h>
#include <blue/ds/string.h>
#define F_RED "[bright_red]"
#define F_GREEN "[bright_green]"
#define F_YELLOW "[bright_yellow]"
#define F_RED_BOLD "[bright_red,bold]"
#define F_GREEN_BOLD "[bright_green,bold]"
#define F_YELLOW_BOLD "[bright_yellow,bold]"
#define F_RESET "[reset]"
enum cmd_string_flags {
CMD_STR_COLOUR = 0x01u,
CMD_STR_DIRECT_USAGE = 0x02u,
};
enum b_command_usage_entry_type {
CMD_USAGE_NONE = 0,
CMD_USAGE_ARG,
CMD_USAGE_OPT,
CMD_USAGE_COMMAND,
};
struct b_command {
unsigned int b_id;
unsigned int b_parent_id;
struct b_command *b_parent;
enum b_command_flags b_flags;
char *b_name;
char *b_long_name;
char b_short_name;
char *b_description;
struct b_queue b_opt;
struct b_queue b_arg;
struct b_queue b_subcommands;
struct b_queue b_usage;
b_command_callback b_callback;
struct b_queue_entry b_entry;
struct b_btree_node b_node;
};
struct b_command_usage_entry {
struct b_queue_entry e_entry;
enum b_command_usage_entry_type e_type;
union {
struct b_command_option *e_opt;
struct b_command_arg *e_arg;
unsigned int e_cmd_id;
};
};
struct b_command_usage {
b_command_usage_flags u_flags;
struct b_queue_entry u_entry;
struct b_queue u_parts;
};
struct b_command_option {
unsigned int opt_id;
char *opt_long_name;
char opt_short_name;
char *opt_description;
// b_command_arg_value_count arg_nr_values;
// char **arg_allowed_values;
struct b_queue opt_args;
struct b_queue_entry opt_entry;
};
struct b_command_arg {
unsigned int arg_id;
char *arg_name;
char *arg_description;
b_command_arg_value_count arg_nr_values;
char **arg_allowed_values;
struct b_queue_entry arg_entry;
};
struct b_arglist_option {
unsigned int opt_id;
struct b_btree opt_values;
struct b_btree_node opt_node;
};
struct b_arglist {
size_t list_argc;
const char **list_argv;
unsigned int list_argv_last_command;
struct b_command *list_command;
struct b_btree list_options;
};
BLUE_API struct b_command *b_command_get_subcommand_with_name(
struct b_command *cmd, const char *name);
BLUE_API struct b_command *b_command_get_subcommand_with_long_name(
struct b_command *cmd, const char *long_name);
BLUE_API struct b_command *b_command_get_subcommand_with_short_name(
struct b_command *cmd, char short_name);
BLUE_API struct b_command_option *b_command_get_option_with_long_name(
struct b_command *cmd, const char *long_name);
BLUE_API struct b_command_option *b_command_get_option_with_short_name(
struct b_command *cmd, char short_name);
BLUE_API struct b_command_option *b_command_get_option_with_id(
struct b_command *cmd, unsigned int id);
BLUE_API struct b_command_arg *b_command_get_arg_with_id(
struct b_command *cmd, unsigned int id);
BLUE_API struct b_command_arg *b_command_option_get_arg_with_id(
struct b_command_option *opt, unsigned int id);
BLUE_API struct b_command_option *b_command_option_create(void);
BLUE_API void b_command_option_destroy(struct b_command_option *opt);
BLUE_API struct b_command_arg *b_command_arg_create(void);
BLUE_API void b_command_arg_destroy(struct b_command_arg *arg);
BLUE_API struct b_arglist *b_arglist_create(void);
BLUE_API b_status b_arglist_parse(
struct b_arglist *args, struct b_command **cmd, int argc,
const char **argv);
BLUE_API void b_arglist_destroy(struct b_arglist *args);
BLUE_API b_string *z__b_command_default_usage_string(
struct b_command *cmd, struct b_command_option *with_opt,
const struct b_arglist *args);
BLUE_API void z__b_get_arg_usage_string(
struct b_command_arg *arg, bool colour, b_string *out);
BLUE_API void z__b_get_arg_description(struct b_command_arg *arg, b_string *out);
BLUE_API void z__b_get_option_usage_string(
struct b_command_option *opt, enum cmd_string_flags flags, b_string *out);
BLUE_API void z__b_get_option_description(
struct b_command_option *opt, b_string *out);
#endif
+289
View File
@@ -0,0 +1,289 @@
#ifndef BLUE_CMD_H_
#define BLUE_CMD_H_
#include <blue/core/btree.h>
#include <blue/core/init.h>
#include <blue/core/iterator.h>
#include <blue/core/queue.h>
#include <blue/ds/array.h>
#include <stdbool.h>
#include <stdint.h>
#define b_arglist_foreach(it, q) \
for (int z__b_unique_name() = b_arglist_iterator_begin( \
q, B_COMMAND_INVALID_ID, B_COMMAND_INVALID_ID, (it)); \
b_arglist_iterator_is_valid(it); b_arglist_iterator_next(it))
#define b_arglist_foreach_filtered(it, q, opt_id, arg_id) \
for (int z__b_unique_name() \
= b_arglist_iterator_begin(q, opt_id, arg_id, (it)); \
b_arglist_iterator_is_valid(it); b_arglist_iterator_next(it))
#define b_arglist_option_foreach(it, q) \
for (int z__b_unique_name() \
= b_arglist_option_iterator_begin(q, B_COMMAND_INVALID_ID, (it)); \
b_arglist_option_iterator_is_valid(it); \
b_arglist_option_iterator_next(it))
#define b_arglist_option_foreach_filtered(it, q, opt_id) \
for (int z__b_unique_name() \
= b_arglist_option_iterator_begin(q, opt_id, (it)); \
b_arglist_option_iterator_is_valid(it); \
b_arglist_option_iterator_next(it))
#define B_COMMAND(id, parent_id) \
static b_command *command_##id = NULL; \
static void __init_##id( \
b_command *, b_command_option *, b_command_arg *, \
b_command_usage *); \
B_INIT(init_##id) \
{ \
command_##id = b_command_create(id); \
if ((parent_id) != B_COMMAND_INVALID_ID) { \
b_command_set_parent(command_##id, parent_id); \
} \
__init_##id(command_##id, NULL, NULL, NULL); \
b_command_register(command_##id); \
} \
static void __init_##id( \
b_command *this_cmd, b_command_option *this_opt, \
b_command_arg *this_arg, b_command_usage *this_usage)
#define B_COMMAND_NAME(name) b_command_set_name(this_cmd, (name))
#define B_COMMAND_LONG_NAME(name) b_command_set_long_name(this_cmd, (name))
#define B_COMMAND_SHORT_NAME(name) b_command_set_short_name(this_cmd, (name))
#define B_COMMAND_DESC(desc) b_command_set_description(this_cmd, (desc))
#define B_COMMAND_FLAGS(flags) b_command_set_flags(this_cmd, (flags))
#define B_COMMAND_FUNCTION(fn) b_command_set_callback(this_cmd, (fn))
#define B_COMMAND_OPTION(id) \
b_command_option *opt_##id = b_command_add_option(this_cmd, (id)); \
this_opt = opt_##id; \
if (this_opt)
#define B_COMMAND_OPTION_GEN(id) \
b_command_option *z__b_unique_name() \
= b_command_add_option(this_cmd, (id)); \
this_opt = z__b_unique_name(); \
if (this_opt)
#define B_COMMAND_HELP_OPTION() \
do { \
b_command_option *opt \
= b_command_add_option(this_cmd, B_COMMAND_OPTION_HELP); \
b_command_option_set_description(opt, "Show this help message"); \
b_command_option_set_short_name(opt, 'h'); \
b_command_option_set_long_name(opt, "help"); \
} while (0)
#define B_OPTION_LONG_NAME(name) \
b_command_option_set_long_name(this_opt, (name))
#define B_OPTION_SHORT_NAME(name) \
b_command_option_set_short_name(this_opt, (name))
#define B_OPTION_DESC(desc) b_command_option_set_description(this_opt, (desc))
#define B_OPTION_ARG(id) \
b_command_arg *arg_##id = b_command_option_add_arg(this_opt, (id)); \
this_arg = arg_##id; \
if (this_arg)
#define B_COMMAND_ARG(id) \
b_command_arg *arg_##id = b_command_add_arg(this_cmd, (id)); \
this_arg = arg_##id; \
if (this_arg)
#define B_ARG_NAME(name) b_command_arg_set_name(this_arg, (name))
#define B_ARG_DESC(desc) b_command_arg_set_description(this_arg, (desc))
#define B_ARG_NR_VALUES(nr_values) \
b_command_arg_set_nr_values(this_arg, (nr_values))
#define B_ARG_ALLOWED_VALUES(...) \
static const char *allowed_values[] = { \
__VA_ARGS__, \
NULL, \
}; \
b_command_arg_set_allowed_values(this_arg, allowed_values)
#define B_COMMAND_USAGE() \
b_command_usage *z__b_unique_name() = b_command_add_usage(this_cmd); \
this_usage = z__b_unique_name(); \
if (this_usage)
#define B_COMMAND_USAGE_COMMAND(cmd_id) \
b_command_usage_add_command(this_usage, cmd_id)
#define B_COMMAND_USAGE_COMMAND_PLACEHOLDER() \
b_command_usage_add_command(this_usage, B_COMMAND_INVALID_ID)
#define B_COMMAND_USAGE_OPT(opt_id) \
b_command_usage_add_option(this_usage, opt_##opt_id)
#define B_COMMAND_USAGE_OPT_PLACEHOLDER() \
b_command_usage_add_option(this_usage, NULL)
#define B_COMMAND_USAGE_ARG(opt_id) \
b_command_usage_add_arg(this_usage, arg_##opt_id)
#define B_COMMAND_USAGE_ARG_PLACEHOLDER() \
b_command_usage_add_arg(this_usage, NULL)
#define B_COMMAND_OPTION_HELP ((uintptr_t)0xF0000001)
#define B_COMMAND_INVALID_ID ((uintptr_t)0xFFFFFFFF)
typedef enum b_command_arg_value_count {
B_ARG_0_OR_1_VALUES = -1,
B_ARG_0_OR_MORE_VALUES = -2,
B_ARG_1_OR_MORE_VALUES = -3,
} b_command_arg_value_count;
typedef enum b_command_arg_type {
B_COMMAND_ARG_NONE = 0,
B_COMMAND_ARG_STRING,
B_COMMAND_ARG_SIGNED_INT,
B_COMMAND_ARG_UNSIGNED_INT,
B_COMMAND_ARG_INT = B_COMMAND_ARG_SIGNED_INT,
} b_command_arg_type;
typedef enum b_command_flags {
B_COMMAND_SHOW_HELP_BY_DEFAULT = 0x01u,
} b_command_flags;
typedef enum b_command_usage_flags {
B_COMMAND_USAGE_SHOW_OPTIONS = 0x01u,
} b_command_usage_flags;
typedef struct b_arglist_value {
unsigned int val_id;
b_command_arg_type val_type;
struct b_btree_node val_node;
union {
char *val_str;
long long val_int;
unsigned long long val_uint;
};
} b_arglist_value;
typedef struct b_arglist_iterator {
size_t i;
unsigned int opt_id;
struct b_arglist_value *value;
b_btree_node *_opt_it, *_arg_it;
unsigned int _opt_filter, _arg_filter;
} b_arglist_iterator;
typedef struct b_arglist_option_iterator {
size_t i;
unsigned int opt_id;
struct b_arglist_option *opt;
b_btree_node *_opt_it;
unsigned int _opt_filter;
} b_arglist_option_iterator;
typedef struct b_command b_command;
typedef struct b_command_option b_command_option;
typedef struct b_command_arg b_command_arg;
typedef struct b_command_usage b_command_usage;
typedef struct b_arglist b_arglist;
typedef struct b_arglist_option b_arglist_option;
typedef int (*b_command_callback)(
const b_command *, const b_arglist *, const b_array *);
BLUE_API b_command *b_command_create(unsigned int id);
BLUE_API void b_command_destroy(b_command *cmd);
BLUE_API b_status b_command_register(b_command *cmd);
BLUE_API int b_command_dispatch(unsigned int cmd_id, int argc, const char **argv);
BLUE_API b_status b_command_set_name(b_command *cmd, const char *name);
BLUE_API b_status b_command_set_long_name(b_command *cmd, const char *name);
BLUE_API b_status b_command_set_short_name(b_command *cmd, char name);
BLUE_API b_status b_command_set_flags(b_command *cmd, b_command_flags flags);
BLUE_API b_status b_command_set_description(b_command *cmd, const char *description);
BLUE_API b_status b_command_set_callback(
b_command *cmd, b_command_callback callback);
BLUE_API b_status b_command_set_parent(b_command *cmd, unsigned int parent_id);
BLUE_API b_command_option *b_command_add_option(b_command *cmd, int id);
BLUE_API b_command_arg *b_command_add_arg(b_command *cmd, int id);
BLUE_API b_command_usage *b_command_add_usage(b_command *cmd);
BLUE_API const b_command_option *b_command_get_option(const b_command *cmd, int id);
BLUE_API const char *b_command_option_get_long_name(const b_command_option *opt);
BLUE_API char b_command_option_get_short_name(const b_command_option *opt);
BLUE_API const char *b_command_option_get_description(b_command_option *opt);
BLUE_API b_status b_command_option_set_long_name(
b_command_option *opt, const char *name);
BLUE_API b_status b_command_option_set_short_name(b_command_option *opt, char name);
BLUE_API b_status b_command_option_set_description(
b_command_option *opt, const char *description);
BLUE_API b_command_arg *b_command_option_add_arg(b_command_option *opt, int id);
BLUE_API b_status b_command_arg_set_name(b_command_arg *arg, const char *name);
BLUE_API b_status b_command_arg_set_description(
b_command_arg *arg, const char *description);
BLUE_API b_status b_command_arg_set_nr_values(
b_command_arg *arg, b_command_arg_value_count nr_values);
BLUE_API b_status b_command_arg_set_allowed_values(
b_command_arg *arg, const char **allowed_values);
BLUE_API b_status b_command_usage_add_option(
b_command_usage *usage, b_command_option *opt);
BLUE_API b_status b_command_usage_add_arg(
b_command_usage *usage, b_command_arg *opt);
BLUE_API b_status b_command_usage_add_command(
b_command_usage *usage, unsigned int cmd_id);
BLUE_API b_status b_arglist_get_string(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
unsigned int index, const char **out);
BLUE_API b_status b_arglist_get_int(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
unsigned int index, long long *out);
BLUE_API b_status b_arglist_get_uint(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
unsigned int index, unsigned long long *out);
BLUE_API b_status b_arglist_get_option(
const b_arglist *args, unsigned int opt_id, unsigned int index,
b_arglist_option **out);
BLUE_API size_t b_arglist_get_count(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id);
BLUE_API b_status b_arglist_report_missing_option(
const b_arglist *args, unsigned int opt_id);
BLUE_API b_status b_arglist_report_unexpected_arg(
const b_arglist *args, const char *value);
BLUE_API b_status b_arglist_report_invalid_arg_value(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
const char *value);
BLUE_API b_status b_arglist_report_missing_args(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
size_t nr_supplied);
BLUE_API b_status b_arglist_option_get_value(
const b_arglist_option *opt, unsigned int arg_id, unsigned int index,
b_arglist_value **out);
BLUE_API int b_arglist_iterator_begin(
const b_arglist *args, unsigned int opt_filter, unsigned int arg_filter,
b_arglist_iterator *it);
BLUE_API bool b_arglist_iterator_next(b_arglist_iterator *it);
BLUE_API bool b_arglist_iterator_is_valid(const b_arglist_iterator *it);
BLUE_API int b_arglist_option_iterator_begin(
const b_arglist *args, unsigned int opt_filter,
b_arglist_option_iterator *it);
BLUE_API bool b_arglist_option_iterator_next(b_arglist_option_iterator *it);
BLUE_API bool b_arglist_option_iterator_is_valid(
const b_arglist_option_iterator *it);
#endif
+273
View File
@@ -0,0 +1,273 @@
#include "command.h"
#include <blue/cmd.h>
#include <blue/ds/string.h>
#include <stdlib.h>
#include <string.h>
struct b_command_option *b_command_option_create(void)
{
struct b_command_option *out = malloc(sizeof *out);
if (!out) {
return out;
}
memset(out, 0x0, sizeof *out);
return out;
}
void b_command_option_destroy(struct b_command_option *opt)
{
if (opt->opt_long_name) {
free(opt->opt_long_name);
}
if (opt->opt_description) {
free(opt->opt_description);
}
struct b_queue_entry *entry = b_queue_first(&opt->opt_args);
while (entry) {
struct b_command_arg *arg
= b_unbox(struct b_command_arg, entry, arg_entry);
struct b_queue_entry *next = b_queue_next(entry);
b_queue_delete(&opt->opt_args, entry);
b_command_arg_destroy(arg);
entry = next;
}
free(opt);
}
const char *b_command_option_get_long_name(const struct b_command_option *opt)
{
return opt->opt_long_name;
}
char b_command_option_get_short_name(const struct b_command_option *opt)
{
return opt->opt_short_name;
}
const char *b_command_option_get_description(struct b_command_option *opt)
{
return opt->opt_description;
}
b_status b_command_option_set_long_name(
struct b_command_option *opt, const char *name)
{
char *n = b_strdup(name);
if (!n) {
return B_ERR_NO_MEMORY;
}
if (opt->opt_long_name) {
free(opt->opt_long_name);
opt->opt_long_name = NULL;
}
opt->opt_long_name = n;
return B_SUCCESS;
}
b_status b_command_option_set_short_name(struct b_command_option *opt, char name)
{
opt->opt_short_name = name;
return B_SUCCESS;
}
b_status b_command_option_set_description(
struct b_command_option *opt, const char *description)
{
char *desc = b_strdup(description);
if (!desc) {
return B_ERR_NO_MEMORY;
}
if (opt->opt_description) {
free(opt->opt_description);
opt->opt_description = NULL;
}
opt->opt_description = desc;
return B_SUCCESS;
}
struct b_command_arg *b_command_option_add_arg(struct b_command_option *opt, int id)
{
struct b_command_arg *arg = malloc(sizeof *arg);
if (!arg) {
return NULL;
}
memset(arg, 0x0, sizeof *arg);
arg->arg_id = id;
b_queue_push_back(&opt->opt_args, &arg->arg_entry);
return arg;
}
void z__b_get_option_description(struct b_command_option *opt, b_string *out)
{
if (opt->opt_description) {
b_string_append_cstr(out, opt->opt_description);
}
size_t nr_args = b_queue_length(&opt->opt_args);
bool close_bracket = false;
size_t i = 0;
struct b_queue_entry *entry = b_queue_first(&opt->opt_args);
while (entry) {
struct b_command_arg *arg
= b_unbox(struct b_command_arg, entry, arg_entry);
if (!arg || !arg->arg_allowed_values) {
goto skip;
}
if (i > 0) {
b_string_append_cstr(out, "; ");
} else {
b_string_append_cstr(out, " [[");
close_bracket = true;
}
if (nr_args > 1) {
b_string_append_cstrf(
out, "values for `%s`:", arg->arg_name);
} else {
b_string_append_cstr(out, "values:");
}
for (size_t i = 0; arg->arg_allowed_values[i]; i++) {
if (i > 0) {
b_string_append_cstr(out, ",");
}
b_string_append_cstrf(
out, " " F_GREEN "%s" F_RESET,
arg->arg_allowed_values[i]);
}
skip:
i++;
entry = b_queue_next(entry);
}
if (close_bracket) {
b_string_append_cstr(out, "]");
}
}
void z__b_get_option_usage_string(
struct b_command_option *opt, enum cmd_string_flags flags, b_string *out)
{
if (flags & CMD_STR_DIRECT_USAGE) {
b_string_append_cstr(out, "{");
}
if (opt->opt_short_name) {
b_string_append_cstrf(
out,
(flags & CMD_STR_COLOUR) ? F_GREEN "-%c" F_RESET : "-%c",
opt->opt_short_name);
}
if (opt->opt_short_name && opt->opt_long_name) {
b_string_append_cstr(
out, (flags & CMD_STR_DIRECT_USAGE) ? "|" : ", ");
}
if (opt->opt_long_name) {
b_string_append_cstrf(
out,
(flags & CMD_STR_COLOUR) ? F_GREEN "--%s" F_RESET : "--%s",
opt->opt_long_name);
}
if (flags & CMD_STR_DIRECT_USAGE) {
b_string_append_cstr(out, "}");
}
struct b_queue_entry *entry = b_queue_first(&opt->opt_args);
while (entry) {
struct b_command_arg *arg
= b_unbox(struct b_command_arg, entry, arg_entry);
if (!arg) {
goto skip;
}
bool optional = false, multi = false;
switch (arg->arg_nr_values) {
case B_ARG_0_OR_1_VALUES:
optional = true;
multi = false;
break;
case B_ARG_0_OR_MORE_VALUES:
optional = true;
multi = true;
break;
case B_ARG_1_OR_MORE_VALUES:
optional = false;
multi = true;
break;
default:
optional = false;
multi = false;
break;
}
if (optional) {
b_string_append_cstrf(
out,
(flags & CMD_STR_COLOUR) ? " " F_GREEN "[%s]"
: " [%s]",
arg->arg_name);
} else {
b_string_append_cstrf(
out,
(flags & CMD_STR_COLOUR) ? " " F_GREEN "<%s>"
: " <%s>",
arg->arg_name);
}
for (int i = 1; i < arg->arg_nr_values; i++) {
b_string_append_cstrf(out, " <%s>", arg->arg_name);
}
if (multi) {
b_string_append_cstr(out, "...");
}
if (flags & CMD_STR_COLOUR) {
b_string_append_cstr(out, F_RESET);
}
skip:
entry = b_queue_next(entry);
}
}
struct b_command_arg *b_command_option_get_arg_with_id(
struct b_command_option *opt, unsigned int id)
{
struct b_queue_entry *entry = b_queue_first(&opt->opt_args);
while (entry) {
struct b_command_arg *arg
= b_unbox(struct b_command_arg, entry, arg_entry);
if (arg->arg_id == id) {
return arg;
}
entry = b_queue_next(entry);
}
return NULL;
}
+195
View File
@@ -0,0 +1,195 @@
#include "command.h"
#include <assert.h>
#include <blue/core/stringstream.h>
#include <blue/ds/string.h>
#include <blue/term/print.h>
#include <stdio.h>
enum b_status b_arglist_report_missing_option(
const b_arglist *args, unsigned int opt_id)
{
struct b_command_option *opt = NULL;
if (opt_id != B_COMMAND_INVALID_ID) {
opt = b_command_get_option_with_id(args->list_command, opt_id);
}
if (!opt) {
return B_ERR_INVALID_ARGUMENT;
}
b_string *opt_string = b_string_create();
z__b_get_option_usage_string(opt, 0, opt_string);
b_stringstream *opt_name = b_stringstream_create();
int opt_names = 0;
if (opt->opt_short_name) {
opt_names++;
}
if (opt->opt_long_name) {
opt_names++;
}
if (opt_names == 2) {
b_stream_write_fmt(
opt_name, NULL, "-%c / --%s", opt->opt_short_name,
opt->opt_long_name);
} else if (opt->opt_short_name) {
b_stream_write_fmt(opt_name, NULL, "-%c", opt->opt_short_name);
} else if (opt->opt_long_name) {
b_stream_write_fmt(opt_name, NULL, "--%s", opt->opt_long_name);
}
b_err("required option `" F_YELLOW "%s" F_RESET "` was not specified.",
b_stringstream_ptr(opt_name));
b_i("usage: %s", b_string_ptr(opt_string));
b_i("for more information, use `" F_YELLOW "--help" F_RESET "`");
b_string_unref(opt_string);
b_stringstream_unref(opt_name);
return B_SUCCESS;
}
enum b_status b_arglist_report_unexpected_arg(
const b_arglist *args, const char *value)
{
b_string *usage = z__b_command_default_usage_string(
args->list_command, NULL, args);
b_err("unexpected argument '" F_YELLOW "%s" F_RESET "' found.", value);
b_i("usage: %s", b_string_ptr(usage));
b_i("for more information, use '" F_YELLOW "--help" F_RESET "'");
return B_SUCCESS;
}
enum b_status b_arglist_report_invalid_arg_value(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
const char *value)
{
struct b_command_option *opt = NULL;
struct b_command_arg *arg = NULL;
if (opt_id != B_COMMAND_INVALID_ID) {
opt = b_command_get_option_with_id(args->list_command, opt_id);
}
if (arg_id != B_COMMAND_INVALID_ID) {
arg = opt ? b_command_option_get_arg_with_id(opt, arg_id)
: b_command_get_arg_with_id(args->list_command, arg_id);
}
b_string *usage = z__b_command_default_usage_string(
args->list_command, opt, args);
b_string *opt_string = b_string_create();
if (opt) {
z__b_get_option_usage_string(opt, 0, opt_string);
} else {
z__b_get_arg_usage_string(arg, 0, opt_string);
}
b_err("invalid value '" F_YELLOW "%s" F_RESET "' for '" F_YELLOW
"%s" F_RESET "'.",
value, b_string_ptr(opt_string));
if (opt) {
b_i("'" F_YELLOW "%s" F_RESET
"' accepts the following values for '" F_YELLOW "%s" F_RESET
"':",
b_string_ptr(opt_string), arg->arg_name);
} else {
b_i("'" F_YELLOW "%s" F_RESET "' accepts the following values:",
b_string_ptr(opt_string));
}
for (int i = 0; arg->arg_allowed_values[i]; i++) {
b_printf(
" * " F_GREEN "%s" F_RESET "\n",
arg->arg_allowed_values[i]);
}
b_printf("\n");
b_i("usage: %s", b_string_ptr(usage));
b_i("for more information, use '" F_YELLOW "--help" F_RESET);
b_string_unref(usage);
b_string_unref(opt_string);
return B_SUCCESS;
}
enum b_status b_arglist_report_missing_args(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
size_t args_supplied)
{
struct b_command_option *opt = NULL;
struct b_command_arg *arg = NULL;
if (opt_id != B_COMMAND_INVALID_ID) {
opt = b_command_get_option_with_id(args->list_command, opt_id);
assert(opt);
}
if (arg_id != B_COMMAND_INVALID_ID) {
arg = opt ? b_command_option_get_arg_with_id(opt, arg_id)
: b_command_get_arg_with_id(args->list_command, arg_id);
assert(arg);
}
b_string *usage = z__b_command_default_usage_string(
args->list_command, opt, args);
b_string *opt_string = b_string_create();
if (opt) {
z__b_get_option_usage_string(opt, 0, opt_string);
} else {
z__b_get_arg_usage_string(arg, 0, opt_string);
}
char supplied_arg_str[64];
if (args_supplied == 0) {
snprintf(
supplied_arg_str, sizeof supplied_arg_str,
F_RED_BOLD "none" F_RESET " were provided");
} else if (args_supplied == 1) {
snprintf(
supplied_arg_str, sizeof supplied_arg_str,
"only " F_YELLOW_BOLD "%zu" F_RESET " was provided",
args_supplied);
} else {
snprintf(
supplied_arg_str, sizeof supplied_arg_str,
"only " F_YELLOW_BOLD "%zu" F_RESET " were provided",
args_supplied);
}
char required_arg_count[64];
switch (arg->arg_nr_values) {
case B_ARG_1_OR_MORE_VALUES:
snprintf(
required_arg_count, sizeof required_arg_count,
"one or more");
break;
default:
snprintf(
required_arg_count, sizeof required_arg_count, "%d",
arg->arg_nr_values);
}
b_err("argument `" F_YELLOW "%s" F_RESET "` requires " F_GREEN_BOLD
"%s" F_RESET " `" F_YELLOW "%s" F_RESET "` value%s, but %s.",
b_string_ptr(opt_string), required_arg_count, arg->arg_name,
(arg->arg_nr_values == 1) ? "" : "s", supplied_arg_str);
b_i("usage: %s", b_string_ptr(usage));
b_i("for more information, use '" F_YELLOW "--help" F_RESET "'");
b_string_unref(usage);
b_string_unref(opt_string);
return B_SUCCESS;
}
@@ -6,11 +6,11 @@ if (ZSTD_FOUND)
set(libs ${libs} ${ZSTD_LIBRARY})
set(include_dirs ${include_dirs} ${ZSTD_INCLUDE_DIR})
set(function_sources ${function_sources} ${CMAKE_CURRENT_SOURCE_DIR}/function/zstd.c)
set(defines ${defines} FX_COMPRESSOR_SUPPORTED_ZSTD)
message(STATUS "Enabling ZSTD support in fx-compress")
set(defines ${defines} B_COMPRESSOR_SUPPORTED_ZSTD)
message(STATUS "Enabling ZSTD support in blue-compress")
endif ()
add_fx_module(
add_bluelib_module(
NAME compress
DEPENDENCIES core
EXTRA_SOURCES ${function_sources}
+239
View File
@@ -0,0 +1,239 @@
#include <assert.h>
#include <blue/compress/compressor.h>
#include <blue/core/ringbuffer.h>
#include <stdlib.h>
#include <string.h>
#define COMPRESSOR_DISPATCH_STATIC(func, compressor, ...) \
do { \
struct compressor_data _compressor; \
enum b_status status \
= compressor_get_data(compressor, &_compressor); \
if (!B_OK(status)) { \
return status; \
} \
return func(&_compressor, __VA_ARGS__); \
} while (0)
#define COMPRESSOR_DISPATCH_STATIC_0(func, compressor) \
do { \
struct compressor_data _compressor; \
enum b_status status \
= compressor_get_data(compressor, &_compressor); \
if (!B_OK(status)) { \
return status; \
} \
return func(&_compressor); \
} while (0)
/*** PRIVATE DATA *************************************************************/
struct compressor_data {
b_compressor *c_obj;
b_compressor_class *c_ops;
b_compressor_data *c_data;
};
/*** PRIVATE FUNCTIONS ********************************************************/
static enum b_status compressor_get_data(
b_compressor *compressor, struct compressor_data *out)
{
out->c_obj = compressor;
return b_object_get_data(
compressor, B_TYPE_COMPRESSOR, NULL, (void **)&out->c_data,
(void **)&out->c_ops);
}
static enum b_status compressor_get_mode(
struct compressor_data *p, enum b_compressor_mode *out)
{
if (out) {
*out = p->c_data->c_mode;
}
return B_SUCCESS;
}
static enum b_status compressor_set_mode(
struct compressor_data *p, enum b_compressor_mode mode)
{
if (!p->c_ops->c_set_mode) {
return B_ERR_NOT_SUPPORTED;
}
return p->c_ops->c_set_mode(p->c_obj, mode);
}
static enum b_status compressor_set_buffer(
struct compressor_data *p, b_ringbuffer *inbuf, b_ringbuffer *outbuf)
{
p->c_data->c_in = inbuf;
p->c_data->c_out = outbuf;
return B_SUCCESS;
}
static enum b_status compress(struct compressor_data *p)
{
if (p->c_data->c_mode != B_COMPRESSOR_MODE_COMPRESS) {
return B_ERR_BAD_STATE;
}
if (!p->c_ops->c_compress) {
return B_ERR_NOT_SUPPORTED;
}
return p->c_ops->c_compress(p->c_obj);
}
static enum b_status decompress(struct compressor_data *p)
{
if (p->c_data->c_mode != B_COMPRESSOR_MODE_DECOMPRESS) {
return B_ERR_BAD_STATE;
}
if (!p->c_ops->c_decompress) {
return B_ERR_NOT_SUPPORTED;
}
return p->c_ops->c_decompress(p->c_obj);
}
static enum b_status compressor_step(struct compressor_data *p)
{
switch (p->c_data->c_mode) {
case B_COMPRESSOR_MODE_COMPRESS:
return compress(p);
case B_COMPRESSOR_MODE_DECOMPRESS:
return decompress(p);
default:
return B_ERR_BAD_STATE;
}
}
static enum b_status compressor_end(struct compressor_data *p)
{
if (p->c_data->c_mode != B_COMPRESSOR_MODE_COMPRESS) {
return B_SUCCESS;
}
if (!p->c_ops->c_compress_end) {
return B_ERR_NOT_SUPPORTED;
}
while (b_ringbuffer_available_data_remaining(p->c_data->c_in)) {
if (!b_ringbuffer_write_capacity_remaining(p->c_data->c_out)) {
return B_ERR_NO_SPACE;
}
enum b_status status = compressor_step(p);
if (!B_OK(status)) {
return status;
}
}
return p->c_ops->c_compress_end(p->c_obj);
}
static enum b_status compressor_reset(struct compressor_data *p)
{
p->c_data->c_flags &= ~B_COMPRESSOR_EOF;
if (p->c_ops->c_reset) {
return p->c_ops->c_reset(p->c_obj);
}
return B_SUCCESS;
}
static bool compressor_eof(const struct compressor_data *p)
{
return (p->c_data->c_flags & B_COMPRESSOR_EOF) != 0;
}
/*** PUBLIC FUNCTIONS *********************************************************/
enum b_status b_compressor_get_buffer_size(
b_type type, b_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size)
{
b_class *c = b_class_get(type);
if (!c) {
return B_ERR_INVALID_ARGUMENT;
}
b_compressor_class *ops = b_class_get_interface(c, B_TYPE_COMPRESSOR);
if (!ops) {
return B_ERR_INVALID_ARGUMENT;
}
if (!ops->c_buffer_size) {
return B_ERR_NOT_SUPPORTED;
}
return ops->c_buffer_size(mode, inbuf_size, outbuf_size);
}
enum b_status b_compressor_get_mode(
const b_compressor *compressor, enum b_compressor_mode *out)
{
COMPRESSOR_DISPATCH_STATIC(
compressor_get_mode, (b_compressor *)compressor, out);
}
enum b_status b_compressor_set_mode(
b_compressor *compressor, enum b_compressor_mode mode)
{
COMPRESSOR_DISPATCH_STATIC(compressor_set_mode, compressor, mode);
}
enum b_status b_compressor_set_buffer(
b_compressor *compressor, b_ringbuffer *inbuf, b_ringbuffer *outbuf)
{
COMPRESSOR_DISPATCH_STATIC(compressor_set_buffer, compressor, inbuf, outbuf);
}
enum b_status b_compressor_step(b_compressor *compressor)
{
COMPRESSOR_DISPATCH_STATIC_0(compressor_step, compressor);
}
enum b_status b_compressor_end(b_compressor *compressor)
{
COMPRESSOR_DISPATCH_STATIC_0(compressor_end, compressor);
}
enum b_status b_compressor_reset(b_compressor *compressor)
{
COMPRESSOR_DISPATCH_STATIC_0(compressor_reset, compressor);
}
bool b_compressor_eof(const b_compressor *compressor)
{
COMPRESSOR_DISPATCH_STATIC_0(compressor_eof, (b_compressor *)compressor);
}
/*** VIRTUAL FUNCTIONS ********************************************************/
static void compressor_init(b_object *obj, void *priv)
{
}
static void compressor_fini(b_object *obj, void *priv)
{
}
/*** CLASS DEFINITION *********************************************************/
B_TYPE_CLASS_DEFINITION_BEGIN(b_compressor)
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
B_INTERFACE_ENTRY(to_string) = NULL;
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
B_TYPE_CLASS_DEFINITION_END(b_compressor)
B_TYPE_DEFINITION_BEGIN(b_compressor)
B_TYPE_ID(0x452ee0f9, 0xfe12, 0x48a1, 0xb596, 0xad5b7a3940e7);
B_TYPE_CLASS(b_compressor_class);
B_TYPE_INSTANCE_PROTECTED(b_compressor_data);
B_TYPE_INSTANCE_INIT(compressor_init);
B_TYPE_INSTANCE_FINI(compressor_fini);
B_TYPE_DEFINITION_END(b_compressor)
File diff suppressed because it is too large Load Diff
+362
View File
@@ -0,0 +1,362 @@
#include <blue/compress/zstd.h>
#include <blue/core/ringbuffer.h>
#include <zstd.h>
/*** PRIVATE DATA *************************************************************/
struct b_zstd_compressor_p {
union {
ZSTD_CCtx *zstd_c;
ZSTD_DCtx *zstd_d;
};
};
/*** PUBLIC FUNCTIONS *********************************************************/
b_status b_zstd_compressor_get_buffer_size(
b_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size)
{
switch (mode) {
case B_COMPRESSOR_MODE_COMPRESS:
*inbuf_size = ZSTD_CStreamInSize();
*outbuf_size = ZSTD_CStreamOutSize();
break;
case B_COMPRESSOR_MODE_DECOMPRESS:
*inbuf_size = ZSTD_DStreamInSize();
*outbuf_size = ZSTD_DStreamOutSize();
break;
default:
return B_ERR_INVALID_ARGUMENT;
}
return B_SUCCESS;
}
/*** VIRTUAL FUNCTIONS ********************************************************/
static void zstd_compressor_init(b_object *obj, void *priv)
{
}
static void zstd_compressor_fini(b_object *obj, void *priv)
{
b_compressor_data *c = b_object_get_protected(obj, B_TYPE_COMPRESSOR);
struct b_zstd_compressor_p *ctx = priv;
switch (c->c_mode) {
case B_COMPRESSOR_MODE_COMPRESS:
ZSTD_freeCCtx(ctx->zstd_c);
break;
case B_COMPRESSOR_MODE_DECOMPRESS:
ZSTD_freeDCtx(ctx->zstd_d);
break;
default:
break;
}
}
static enum b_status reset(b_compressor *compressor)
{
struct b_zstd_compressor_p *ctx
= b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
b_compressor_data *data
= b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
if (!ctx || !data) {
return B_ERR_INVALID_ARGUMENT;
}
switch (data->c_mode) {
case B_COMPRESSOR_MODE_COMPRESS:
ZSTD_CCtx_reset(ctx->zstd_c, ZSTD_reset_session_only);
break;
case B_COMPRESSOR_MODE_DECOMPRESS:
ZSTD_DCtx_reset(ctx->zstd_d, ZSTD_reset_session_only);
break;
default:
return B_ERR_BAD_STATE;
}
return B_SUCCESS;
}
static enum b_status compress(b_compressor *compressor)
{
enum b_status status = B_SUCCESS;
struct b_zstd_compressor_p *ctx
= b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
b_compressor_data *data
= b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
if (!ctx || !data) {
return B_ERR_INVALID_ARGUMENT;
}
b_ringbuffer *in = data->c_in;
b_ringbuffer *out = data->c_out;
if (b_ringbuffer_available_data_remaining(in) == 0) {
return B_ERR_NO_DATA;
}
if (b_ringbuffer_write_capacity_remaining(out) == 0) {
return B_ERR_NO_SPACE;
}
size_t nr_consumed = 0;
while (1) {
size_t in_available = 0, out_capacity = 0;
const void *in_buf = NULL;
void *out_buf = NULL;
status = b_ringbuffer_open_read_buffer(in, &in_buf, &in_available);
if (!B_OK(status)) {
break;
}
status = b_ringbuffer_open_write_buffer(
out, &out_buf, &out_capacity);
if (!B_OK(status)) {
b_ringbuffer_close_read_buffer(in, &in_buf, 0);
break;
}
ZSTD_inBuffer z_in = {
.src = in_buf,
.pos = 0,
.size = in_available,
};
ZSTD_outBuffer z_out = {
.dst = out_buf,
.pos = 0,
.size = out_capacity,
};
do {
size_t ret = ZSTD_compressStream2(
ctx->zstd_c, &z_out, &z_in, ZSTD_e_continue);
if (ZSTD_isError(ret)) {
status = B_ERR_COMPRESSION_FAILURE;
break;
}
} while (z_in.pos < z_in.size && z_out.pos < z_out.size);
nr_consumed += z_in.pos;
b_ringbuffer_close_read_buffer(in, &in_buf, z_in.pos);
b_ringbuffer_close_write_buffer(out, &out_buf, z_out.pos);
}
if ((status == B_ERR_NO_SPACE || status == B_ERR_NO_DATA)
&& nr_consumed > 0) {
status = B_SUCCESS;
}
return status;
}
static enum b_status compress_end(b_compressor *compressor)
{
enum b_status status = B_SUCCESS;
struct b_zstd_compressor_p *ctx
= b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
b_compressor_data *data
= b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
if (!ctx || !data) {
return B_ERR_INVALID_ARGUMENT;
}
b_ringbuffer *out = data->c_out;
if (b_ringbuffer_write_capacity_remaining(out) == 0) {
return B_ERR_NO_SPACE;
}
bool finished = false;
do {
void *out_buf = NULL;
size_t out_capacity = 0;
status = b_ringbuffer_open_write_buffer(
out, &out_buf, &out_capacity);
if (!B_OK(status)) {
break;
}
ZSTD_inBuffer z_in = {0};
ZSTD_outBuffer z_out = {
.dst = out_buf,
.pos = 0,
.size = out_capacity,
};
do {
size_t ret = ZSTD_compressStream2(
ctx->zstd_c, &z_out, &z_in, ZSTD_e_end);
if (ZSTD_isError(ret)) {
status = B_ERR_COMPRESSION_FAILURE;
finished = true;
}
if (ret == 0) {
data->c_flags |= B_COMPRESSOR_EOF;
finished = true;
}
} while (!finished && z_out.pos < z_out.size);
b_ringbuffer_close_write_buffer(out, &out_buf, z_out.pos);
} while (!finished);
return status;
}
static enum b_status decompress(b_compressor *compressor)
{
enum b_status status = B_SUCCESS;
struct b_zstd_compressor_p *ctx
= b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
b_compressor_data *data
= b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
if (!ctx || !data) {
return B_ERR_INVALID_ARGUMENT;
}
b_ringbuffer *in = data->c_in;
b_ringbuffer *out = data->c_out;
if (b_ringbuffer_available_data_remaining(in) == 0) {
return B_ERR_NO_DATA;
}
if (b_ringbuffer_write_capacity_remaining(out) == 0) {
return B_ERR_NO_SPACE;
}
size_t nr_consumed = 0;
while (!(data->c_flags & B_COMPRESSOR_EOF)) {
size_t in_available = 0, out_capacity = 0;
const void *in_buf = NULL;
void *out_buf = NULL;
status = b_ringbuffer_open_read_buffer(in, &in_buf, &in_available);
if (!B_OK(status)) {
break;
}
status = b_ringbuffer_open_write_buffer(
out, &out_buf, &out_capacity);
if (!B_OK(status)) {
b_ringbuffer_close_read_buffer(in, &in_buf, 0);
break;
}
ZSTD_inBuffer z_in = {
.src = in_buf,
.pos = 0,
.size = in_available,
};
ZSTD_outBuffer z_out = {
.dst = out_buf,
.pos = 0,
.size = out_capacity,
};
do {
size_t ret = ZSTD_decompressStream(
ctx->zstd_d, &z_out, &z_in);
if (ZSTD_isError(ret)) {
status = B_ERR_COMPRESSION_FAILURE;
break;
}
if (ret == 0) {
data->c_flags |= B_COMPRESSOR_EOF;
break;
}
} while (z_in.pos < z_in.size && z_out.pos < z_out.size);
nr_consumed += z_in.pos;
b_ringbuffer_close_read_buffer(in, &in_buf, z_in.pos);
b_ringbuffer_close_write_buffer(out, &out_buf, z_out.pos);
}
if ((status == B_ERR_NO_SPACE || status == B_ERR_NO_DATA)
&& nr_consumed > 0) {
status = B_SUCCESS;
}
return status;
}
static enum b_status set_mode(b_compressor *compressor, b_compressor_mode mode)
{
struct b_zstd_compressor_p *ctx
= b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
b_compressor_data *data
= b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
if (!ctx || !data) {
return B_ERR_INVALID_ARGUMENT;
}
if (mode == data->c_mode) {
return B_SUCCESS;
}
switch (data->c_mode) {
case B_COMPRESSOR_MODE_COMPRESS:
ZSTD_freeCCtx(ctx->zstd_c);
break;
case B_COMPRESSOR_MODE_DECOMPRESS:
ZSTD_freeDCtx(ctx->zstd_d);
break;
default:
break;
}
data->c_mode = mode;
switch (data->c_mode) {
case B_COMPRESSOR_MODE_COMPRESS:
ctx->zstd_c = ZSTD_createCCtx();
break;
case B_COMPRESSOR_MODE_DECOMPRESS:
ctx->zstd_d = ZSTD_createDCtx();
break;
default:
return B_ERR_INVALID_ARGUMENT;
}
return B_SUCCESS;
}
/*** CLASS DEFINITION *********************************************************/
B_TYPE_CLASS_DEFINITION_BEGIN(b_zstd_compressor)
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
B_INTERFACE_ENTRY(to_string) = NULL;
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
B_TYPE_CLASS_INTERFACE_BEGIN(b_compressor, B_TYPE_COMPRESSOR)
B_INTERFACE_ENTRY(c_buffer_size)
= b_zstd_compressor_get_buffer_size;
B_INTERFACE_ENTRY(c_compress) = compress;
B_INTERFACE_ENTRY(c_compress_end) = compress_end;
B_INTERFACE_ENTRY(c_decompress) = decompress;
B_INTERFACE_ENTRY(c_reset) = reset;
B_INTERFACE_ENTRY(c_set_mode) = set_mode;
B_TYPE_CLASS_INTERFACE_END(b_compressor, B_TYPE_COMPRESSOR)
B_TYPE_CLASS_DEFINITION_END(b_zstd_compressor)
B_TYPE_DEFINITION_BEGIN(b_zstd_compressor)
B_TYPE_ID(0x51d437fc, 0xe789, 0x4105, 0xbac7, 0xe6b3f45df198);
B_TYPE_EXTENDS(B_TYPE_COMPRESSOR);
B_TYPE_CLASS(b_zstd_compressor_class);
B_TYPE_INSTANCE_PRIVATE(struct b_zstd_compressor_p);
B_TYPE_INSTANCE_INIT(zstd_compressor_init);
B_TYPE_INSTANCE_FINI(zstd_compressor_fini);
B_TYPE_DEFINITION_END(b_zstd_compressor)
@@ -0,0 +1,67 @@
#ifndef BLUE_COMPRESS_COMPRESSOR_H_
#define BLUE_COMPRESS_COMPRESSOR_H_
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <blue/core/ringbuffer.h>
#include <blue/core/status.h>
#include <stdbool.h>
B_DECLS_BEGIN;
typedef enum b_compressor_mode {
B_COMPRESSOR_MODE_NONE = 0,
B_COMPRESSOR_MODE_COMPRESS,
B_COMPRESSOR_MODE_DECOMPRESS,
} b_compressor_mode;
typedef enum b_compressor_flags {
B_COMPRESSOR_EOF = 0x01u,
} b_compressor_flags;
#define B_TYPE_COMPRESSOR (b_compressor_get_type())
B_DECLARE_TYPE(b_compressor);
B_TYPE_CLASS_DECLARATION_BEGIN(b_compressor)
b_status (*c_buffer_size)(b_compressor_mode, size_t *, size_t *);
b_status (*c_set_mode)(b_compressor *, b_compressor_mode);
b_status (*c_compress)(b_compressor *);
b_status (*c_compress_end)(b_compressor *);
b_status (*c_decompress)(b_compressor *);
b_status (*c_reset)(b_compressor *);
B_TYPE_CLASS_DECLARATION_END(b_compressor)
typedef struct b_compressor_data {
b_compressor_flags c_flags;
b_compressor_mode c_mode;
b_ringbuffer *c_in, *c_out;
} b_compressor_data;
BLUE_API b_type b_compressor_get_type(void);
#if 0
BLUE_API b_status b_compressor_create(
const struct b_compression_function *func, enum b_compression_mode mode,
struct b_ringbuffer *inbuf, struct b_ringbuffer *outbuf,
b_compressor **out);
#endif
BLUE_API b_status b_compressor_get_buffer_size(
b_type type, b_compressor_mode mode, size_t *inbuf_size,
size_t *outbuf_size);
BLUE_API b_status b_compressor_get_mode(
const b_compressor *compressor, b_compressor_mode *out);
BLUE_API b_status b_compressor_set_mode(
b_compressor *compressor, b_compressor_mode mode);
BLUE_API b_status b_compressor_set_buffer(
b_compressor *compressor, b_ringbuffer *inbuf, b_ringbuffer *outbuf);
BLUE_API b_status b_compressor_step(b_compressor *compressor);
BLUE_API b_status b_compressor_end(b_compressor *compressor);
BLUE_API b_status b_compressor_reset(b_compressor *compressor);
BLUE_API bool b_compressor_eof(const b_compressor *compressor);
B_DECLS_END;
#endif
+50
View File
@@ -0,0 +1,50 @@
#ifndef BLUE_COMPRESS_CSTREAM_H_
#define BLUE_COMPRESS_CSTREAM_H_
#include <blue/core/macros.h>
#include <blue/core/stream.h>
#include <stdbool.h>
B_DECLS_BEGIN;
enum b_compressor_mode;
#define B_TYPE_CSTREAM (b_cstream_get_type())
B_DECLARE_TYPE(b_cstream);
B_TYPE_CLASS_DECLARATION_BEGIN(b_cstream)
B_TYPE_CLASS_DECLARATION_END(b_cstream)
BLUE_API b_type b_cstream_get_type(void);
BLUE_API b_status b_cstream_open(
b_stream *endpoint, b_type compressor_type, enum b_compressor_mode mode,
b_cstream **out);
BLUE_API b_status b_cstream_read(
b_cstream *stream, void *buf, size_t count, size_t *nr_read);
BLUE_API b_status b_cstream_write(
b_cstream *stream, const void *buf, size_t count, size_t *nr_written);
BLUE_API b_status b_cstream_skip(
b_cstream *stream, size_t count, size_t *nr_skipped);
BLUE_API b_status b_cstream_reset(b_cstream *stream);
BLUE_API b_status b_cstream_begin_compressed_section(
b_cstream *stream, size_t *tx_uncompressed_bytes);
BLUE_API b_status b_cstream_end_compressed_section(
b_cstream *stream, size_t *tx_compressed_bytes,
size_t *tx_uncompressed_bytes);
BLUE_API bool b_cstream_in_compressed_section(const b_cstream *stream);
BLUE_API b_status b_cstream_tx_bytes(const b_cstream *stream, size_t *out);
BLUE_API b_status b_cstream_tx_bytes_compressed(
const b_cstream *stream, size_t *out);
BLUE_API b_status b_cstream_tx_bytes_uncompressed(
const b_cstream *stream, size_t *out);
BLUE_API b_status b_cstream_set_cursor_position(b_cstream *stream, size_t pos);
BLUE_API b_status b_cstream_restore_cursor_position(b_cstream *stream);
B_DECLS_END;
#endif
+28
View File
@@ -0,0 +1,28 @@
#ifndef BLUE_COMPRESS_ZSTD_H_
#define BLUE_COMPRESS_ZSTD_H_
#include <blue/compress/compressor.h>
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <stdbool.h>
B_DECLS_BEGIN;
#define B_TYPE_ZSTD_COMPRESSOR (b_zstd_compressor_get_type())
B_DECLARE_TYPE(b_zstd_compressor);
B_TYPE_CLASS_DECLARATION_BEGIN(b_zstd_compressor)
B_TYPE_CLASS_DECLARATION_END(b_compressor)
BLUE_API b_type b_zstd_compressor_get_type(void);
BLUE_API b_status b_zstd_compressor_get_buffer_size(
b_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size);
B_TYPE_DEFAULT_CONSTRUCTOR(b_zstd_compressor, B_TYPE_ZSTD_COMPRESSOR);
B_DECLS_END;
#endif
+6
View File
@@ -0,0 +1,6 @@
include(../cmake/Templates.cmake)
add_bluelib_mm_module(
NAME core
DEPENDENCIES core
SUBDIRS hash)
+1
View File
@@ -0,0 +1 @@
#include <blue/core/encoding.hpp>
+106
View File
@@ -0,0 +1,106 @@
#ifndef BLUE_CORE_ENCODING_HPP_
#define BLUE_CORE_ENCODING_HPP_
#include <blue/core/encoding.h>
#include <cstddef>
#include <cstdint>
namespace blue::core
{
class wchar
{
public:
static const int32_t INVALID = B_WCHAR_INVALID;
wchar();
wchar(std::int32_t v)
: val_(v)
{
}
static wchar decode(const char *s);
operator int32_t() const
{
return val_;
}
bool is_alpha(void) const
{
return b_wchar_is_alpha(val_);
}
bool is_number(void) const
{
return b_wchar_is_number(val_);
}
bool is_bin_digit(void) const
{
return b_wchar_is_bin_digit(val_);
}
bool is_oct_digit(void) const
{
return b_wchar_is_oct_digit(val_);
}
bool is_hex_digit(void) const
{
return b_wchar_is_hex_digit(val_);
}
bool is_space(void) const
{
return b_wchar_is_space(val_);
}
bool is_alnum(void) const
{
return b_wchar_is_alnum(val_);
}
bool is_punct(void) const
{
return b_wchar_is_punct(val_);
}
bool is_valid_utf8_scalar(void) const
{
return b_wchar_utf8_is_valid_scalar(val_);
}
unsigned int get_utf8_codepoint_size(void) const
{
return b_wchar_utf8_codepoint_size(val_);
}
unsigned int encode_utf8(char s[4]) const
{
return b_wchar_utf8_codepoint_encode(val_, s);
}
private:
int32_t val_ = B_WCHAR_INVALID;
};
class utf8
{
public:
static unsigned int decode_header(char c)
{
return b_wchar_utf8_header_decode(c);
}
static unsigned int get_codepoint_stride(const char *s)
{
return b_wchar_utf8_codepoint_stride(s);
}
static std::size_t get_codepoint_count(const char *s, std::size_t nr_bytes)
{
return b_wchar_utf8_codepoint_count(s, nr_bytes);
}
static std::size_t get_string_encoded_size(
const wchar *s, std::size_t nr_codepoints)
{
return b_wchar_utf8_string_encoded_size(
reinterpret_cast<const b_wchar *>(s), nr_codepoints);
}
private:
utf8() = delete;
~utf8() = delete;
};
}
#endif
+13
View File
@@ -0,0 +1,13 @@
#ifndef BLUE_CORE_ITERATOR_HPP_
#define BLUE_CORE_ITERATOR_HPP_
#include <blue/core/object.hpp>
namespace blue::core
{
class iterator : public object
{
};
}
#endif
+46
View File
@@ -0,0 +1,46 @@
#ifndef BLUE_CORE_MISC_HPP_
#define BLUE_CORE_MISC_HPP_
#define Z__B_ENUM_CLASS_BITWISE_OPS(enum_name) \
inline constexpr enum_name operator&(enum_name x, enum_name y) \
{ \
return static_cast<enum_name>( \
static_cast<int>(x) & static_cast<int>(y)); \
} \
\
inline constexpr enum_name operator|(enum_name x, enum_name y) \
{ \
return static_cast<enum_name>( \
static_cast<int>(x) | static_cast<int>(y)); \
} \
\
inline constexpr enum_name operator^(enum_name x, enum_name y) \
{ \
return static_cast<enum_name>( \
static_cast<int>(x) ^ static_cast<int>(y)); \
} \
\
inline constexpr enum_name operator~(enum_name x) \
{ \
return static_cast<enum_name>(~static_cast<int>(x)); \
} \
\
inline enum_name &operator&=(enum_name &x, enum_name y) \
{ \
x = x & y; \
return x; \
} \
\
inline enum_name &operator|=(enum_name &x, enum_name y) \
{ \
x = x | y; \
return x; \
} \
\
inline enum_name &operator^=(enum_name &x, enum_name y) \
{ \
x = x ^ y; \
return x; \
}
#endif
+40
View File
@@ -0,0 +1,40 @@
#ifndef BLUE_CORE_OBJECT_HPP_
#define BLUE_CORE_OBJECT_HPP_
#include <blue/core/object.h>
namespace blue::core
{
class type;
class object
{
public:
static const size_t MAGIC = B_OBJECT_MAGIC;
object(object &) = delete;
object(object &&);
~object();
bool operator!()
{
return ptr_ == nullptr;
}
void to_string(void) const;
bool is_type(const type &type) const;
b_object *ptr(void)
{
return ptr_;
}
const b_object *ptr(void) const
{
return ptr_;
}
protected:
object() = default;
b_object *ptr_ = nullptr;
};
}
#endif
+62
View File
@@ -0,0 +1,62 @@
#ifndef BLUE_CORE_STATUS_HPP_
#define BLUE_CORE_STATUS_HPP_
#include <blue/core/status.h>
namespace blue
{
class status
{
public:
#define __MM_STATUS_ENUM(name) name = B_ERR_##name
enum _status : int {
SUCCESS = B_SUCCESS,
__MM_STATUS_ENUM(NO_MEMORY),
__MM_STATUS_ENUM(OUT_OF_BOUNDS),
__MM_STATUS_ENUM(INVALID_ARGUMENT),
__MM_STATUS_ENUM(NAME_EXISTS),
__MM_STATUS_ENUM(NOT_SUPPORTED),
__MM_STATUS_ENUM(BAD_STATE),
__MM_STATUS_ENUM(NO_ENTRY),
__MM_STATUS_ENUM(NO_DATA),
__MM_STATUS_ENUM(NO_SPACE),
__MM_STATUS_ENUM(UNKNOWN_FUNCTION),
__MM_STATUS_ENUM(BAD_FORMAT),
__MM_STATUS_ENUM(IO_FAILURE),
__MM_STATUS_ENUM(IS_DIRECTORY),
__MM_STATUS_ENUM(NOT_DIRECTORY),
__MM_STATUS_ENUM(PERMISSION_DENIED),
__MM_STATUS_ENUM(BUSY),
__MM_STATUS_ENUM(COMPRESSION_FAILURE),
__MM_STATUS_ENUM(TYPE_REGISTRATION_FAILURE),
__MM_STATUS_ENUM(CLASS_INIT_FAILURE),
};
status() = default;
status(_status v)
: v_(static_cast<b_status>(v))
{
}
status(b_status v)
: v_(v)
{
}
bool operator!() const
{
return v_ != B_SUCCESS;
}
operator b_status() const
{
return v_;
}
const char *to_string(void);
const char *description(void);
private:
b_status v_ = B_SUCCESS;
};
}
#endif
+135
View File
@@ -0,0 +1,135 @@
#ifndef BLUE_CORE_STREAM_HPP_
#define BLUE_CORE_STREAM_HPP_
#include <blue/core/encoding.hpp>
#include <blue/core/misc.hpp>
#include <blue/core/object.hpp>
#include <blue/core/status.hpp>
#include <blue/core/stream.h>
#include <blue/core/type.hpp>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <string>
namespace blue::core
{
class stream_buffer : public object
{
};
class stream : public object
{
public:
enum class mode : int {
READ = B_STREAM_READ,
WRITE = B_STREAM_WRITE,
BINARY = B_STREAM_BINARY,
__STATIC = Z__B_STREAM_STATIC,
};
enum class seek_origin : int {
START = B_STREAM_SEEK_START,
CURRENT = B_STREAM_SEEK_CURRENT,
END = B_STREAM_SEEK_END,
};
static type get_type(void);
static stream &in(void);
static stream &out(void);
static stream &err(void);
stream(stream &) = delete;
stream(std::FILE *fp);
status reserve(std::size_t len);
status seek(long long offset, seek_origin origin);
std::size_t cursor(void) const;
status push_indent(int indent);
status pop_indent(void);
status read_char(wchar &c);
status read_bytes(void *buf, std::size_t count, std::size_t &nr_read);
status read_bytes(void *buf, std::size_t count)
{
std::size_t tmp;
return read_bytes(buf, count, tmp);
}
status read_line(char *s, std::size_t max);
status read_line(std::string &out);
status read_line(stream &dest);
status read_all_bytes(void *p, std::size_t max, std::size_t &nr_read);
status read_all_bytes(
stream &dest, stream_buffer &buf, std::size_t &nr_read);
status read_all_bytes(void *p, std::size_t max)
{
std::size_t tmp;
return read_all_bytes(p, max);
}
status read_all_bytes(stream &dest, stream_buffer &buf)
{
std::size_t tmp;
return read_all_bytes(dest, buf);
}
status write_char(wchar c);
status write_string(const char *s, std::size_t &nr_written);
status write_string(const char *s)
{
std::size_t tmp;
return write_string(s, tmp);
}
status write_string(const std::string &s, std::size_t &nr_written)
{
return write_string(s.c_str(), nr_written);
}
status write_string(const std::string &s)
{
std::size_t tmp;
return write_string(s, tmp);
}
status write_bytes(
const void *buf, std::size_t count, std::size_t &nr_written);
status write_bytes(const void *buf, std::size_t count)
{
std::size_t tmp;
return write_bytes(buf, count, tmp);
}
status write_fmt(std::size_t &nr_written, const char *format, ...);
status write_vfmt(
std::size_t &nr_written, const char *format, std::va_list arg);
status write_fmt(const char *format, ...)
{
std::size_t tmp;
std::va_list arg;
va_start(arg, format);
status s = write_vfmt(tmp, format, arg);
va_end(arg);
return s;
}
status write_vfmt(const char *format, std::va_list arg)
{
std::size_t tmp;
return write_vfmt(tmp, format, arg);
}
protected:
stream() = default;
};
}
Z__B_ENUM_CLASS_BITWISE_OPS(blue::core::stream::mode)
#endif
@@ -0,0 +1,23 @@
#ifndef BLUE_CORE_STRINGSTREAM_HPP_
#define BLUE_CORE_STRINGSTREAM_HPP_
#include <blue/core/stream.hpp>
namespace blue::core
{
class stringstream : public stream
{
public:
stringstream();
stringstream(char *buf, std::size_t max);
status reset();
status reset(char *buf, std::size_t max);
const char *get_ptr() const;
char *steal_ptr();
std::size_t get_length() const;
};
}
#endif
+24
View File
@@ -0,0 +1,24 @@
#ifndef BLUE_CORE_TYPE_HPP_
#define BLUE_CORE_TYPE_HPP_
#include <blue/core/type.h>
namespace blue::core
{
class type
{
public:
type(b_type p)
{
ptr_ = p;
}
~type() = default;
type(type &) = default;
private:
const union b_type_id *ptr_;
};
}
#endif
+1
View File
@@ -0,0 +1 @@
#include <blue/core/iterator.hpp>
+20
View File
@@ -0,0 +1,20 @@
#include <blue/core/object.hpp>
namespace blue::core
{
object::object(object &&other)
{
ptr_ = other.ptr_;
other.ptr_ = nullptr;
}
object::~object()
{
if (ptr_) {
b_object_unref(ptr_);
ptr_ = nullptr;
}
}
}
+169
View File
@@ -0,0 +1,169 @@
#include <blue/core/stream.h>
#include <blue/core/stream.hpp>
namespace blue::core
{
type stream::get_type(void)
{
return b_stream_get_type();
}
stream &stream::in(void)
{
static stream s;
s.ptr_ = b_stdin;
return s;
}
stream &stream::out(void)
{
static stream s;
s.ptr_ = b_stdout;
return s;
}
stream &stream::err(void)
{
static stream s;
s.ptr_ = b_stderr;
return s;
}
stream::stream(std::FILE *fp)
{
ptr_ = b_stream_open_fp(fp);
}
status stream::reserve(std::size_t len)
{
return b_stream_reserve(ptr_, len);
}
status stream::seek(long long offset, seek_origin origin)
{
return b_stream_seek(
ptr_, offset, static_cast<b_stream_seek_origin>(origin));
}
std::size_t stream::cursor(void) const
{
return b_stream_cursor(ptr_);
}
status stream::push_indent(int indent)
{
return b_stream_push_indent(ptr_, indent);
}
status stream::pop_indent(void)
{
return b_stream_pop_indent(ptr_);
}
status stream::read_char(wchar &c)
{
b_wchar tmp;
status s = b_stream_read_char(ptr_, &tmp);
c = tmp;
return s;
}
status stream::read_bytes(void *buf, std::size_t count, std::size_t &nr_read)
{
std::size_t r;
status s = b_stream_read_bytes(ptr_, buf, count, &r);
nr_read = r;
return s;
}
status stream::read_line(char *s, std::size_t max)
{
return b_stream_read_line(ptr_, s, max);
}
status stream::read_line(std::string &out)
{
while (1) {
wchar c = wchar::INVALID;
status s = read_char(c);
if (!s) {
return s;
}
if (c == '\n') {
break;
}
char str[5] = {0};
c.encode_utf8(str);
out.append(str);
}
return status::SUCCESS;
}
status stream::read_line(stream &dest)
{
return b_stream_read_line_s(ptr_, dest.ptr_);
}
status stream::read_all_bytes(void *p, std::size_t max, std::size_t &nr_read)
{
std::size_t tmp;
status s = b_stream_read_all_bytes(ptr_, p, max, &tmp);
nr_read = tmp;
return s;
}
status stream::read_all_bytes(stream &dest, stream_buffer &buf, std::size_t &nr_read)
{
std::size_t tmp;
status s = b_stream_read_all_bytes_s(ptr_, dest.ptr_, buf.ptr(), &tmp);
nr_read = tmp;
return s;
}
status stream::write_char(wchar c)
{
return b_stream_write_char(ptr_, c);
}
status stream::write_string(const char *str, std::size_t &nr_written)
{
std::size_t tmp;
status s = b_stream_write_string(ptr_, str, &tmp);
nr_written = tmp;
return s;
}
status stream::write_bytes(
const void *buf, std::size_t count, std::size_t &nr_written)
{
std::size_t tmp;
status s = b_stream_write_bytes(ptr_, buf, count, &tmp);
nr_written = tmp;
return s;
}
status stream::write_fmt(std::size_t &nr_written, const char *format, ...)
{
size_t tmp;
std::va_list arg;
va_start(arg, format);
status s = b_stream_write_vfmt(ptr_, &tmp, format, arg);
va_end(arg);
nr_written = tmp;
return s;
}
status stream::write_vfmt(std::size_t &nr_written, const char *format, va_list arg)
{
size_t tmp;
status s = b_stream_write_vfmt(ptr_, &tmp, format, arg);
nr_written = tmp;
return s;
}
}
+42
View File
@@ -0,0 +1,42 @@
#include <blue/core/stringstream.h>
#include <blue/core/stringstream.hpp>
namespace blue::core
{
stringstream::stringstream()
{
ptr_ = b_stringstream_create();
}
stringstream::stringstream(char *buf, std::size_t max)
{
ptr_ = b_stringstream_create_with_buffer(buf, max);
}
status stringstream::reset()
{
return b_stringstream_reset(ptr_);
}
status stringstream::reset(char *buf, std::size_t max)
{
return b_stringstream_reset_with_buffer(ptr_, buf, max);
}
const char *stringstream::get_ptr() const
{
return b_stringstream_ptr(ptr_);
}
char *stringstream::steal_ptr()
{
return b_stringstream_steal(ptr_);
}
std::size_t stringstream::get_length() const
{
return b_stringstream_get_length(ptr_);
}
}
+1
View File
@@ -0,0 +1 @@
#include <blue/core/type.hpp>
+5
View File
@@ -0,0 +1,5 @@
include(../cmake/Templates.cmake)
add_bluelib_module(
NAME core
SUBDIRS hash)
+69 -95
View File
@@ -1,37 +1,37 @@
#include "printf.h"
#include <fx/bstr.h>
#include <fx/rope.h>
#include <blue/core/bstr.h>
#include <blue/core/rope.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CHECK_FLAG(str, f) ((((str)->bstr_flags) & (f)) == (f))
#define IS_DYNAMIC(p) (CHECK_FLAG(p, FX_BSTR_F_ALLOC))
#define IS_DYNAMIC(p) (CHECK_FLAG(p, B_BSTR_F_ALLOC))
/* number of bytes that bstr_buf is extended by when required */
#define CAPACITY_STEP 32
void fx_bstr_begin(struct fx_bstr *str, char *buf, size_t max)
void b_bstr_begin(struct b_bstr *str, char *buf, size_t max)
{
memset(str, 0x0, sizeof *str);
str->bstr_magic = FX_BSTR_MAGIC;
str->bstr_magic = B_BSTR_MAGIC;
str->bstr_buf = buf;
str->bstr_capacity = max;
str->bstr_len = 0;
str->bstr_flags = FX_BSTR_F_NONE;
str->bstr_flags = B_BSTR_F_NONE;
}
void fx_bstr_begin_dynamic(struct fx_bstr *str)
void b_bstr_begin_dynamic(struct b_bstr *str)
{
memset(str, 0x0, sizeof *str);
str->bstr_magic = FX_BSTR_MAGIC;
str->bstr_magic = B_BSTR_MAGIC;
str->bstr_buf = NULL;
str->bstr_capacity = 0;
str->bstr_len = 0;
str->bstr_flags = FX_BSTR_F_ALLOC;
str->bstr_flags = B_BSTR_F_ALLOC;
}
static char *truncate_buffer(char *s, size_t len)
@@ -50,7 +50,7 @@ static char *truncate_buffer(char *s, size_t len)
return final;
}
char *fx_bstr_end(struct fx_bstr *str)
char *b_bstr_end(struct b_bstr *str)
{
char *out = str->bstr_buf;
size_t len = str->bstr_len;
@@ -70,29 +70,29 @@ char *fx_bstr_end(struct fx_bstr *str)
return out;
}
enum fx_status fx_bstr_reserve(struct fx_bstr *strv, size_t len)
enum b_status b_bstr_reserve(struct b_bstr *strv, size_t len)
{
if (!IS_DYNAMIC(strv)) {
return FX_SUCCESS;
return B_SUCCESS;
}
if (strv->bstr_capacity > 0 && strv->bstr_capacity - 1 >= len) {
return FX_SUCCESS;
return B_SUCCESS;
}
char *new_buf = realloc(strv->bstr_buf, len + 1);
if (!new_buf) {
return FX_ERR_NO_MEMORY;
return B_ERR_NO_MEMORY;
}
strv->bstr_buf = new_buf;
strv->bstr_capacity = len + 1;
strv->bstr_buf[strv->bstr_len] = '\0';
return FX_SUCCESS;
return B_SUCCESS;
}
static int current_indent(struct fx_bstr *str)
static int current_indent(struct b_bstr *str)
{
if (!str->bstr_istack || !str->bstr_istack_size) {
return 0;
@@ -101,7 +101,7 @@ static int current_indent(struct fx_bstr *str)
return str->bstr_istack[str->bstr_istack_ptr];
}
static void __formatter_putchar(struct fx_bstr *str, char c)
static void __formatter_putchar(struct b_bstr *str, char c)
{
if (str->bstr_capacity > 0 && str->bstr_len < str->bstr_capacity - 1) {
str->bstr_buf[str->bstr_len++] = c;
@@ -109,7 +109,7 @@ static void __formatter_putchar(struct fx_bstr *str, char c)
return;
}
if (!CHECK_FLAG(str, FX_BSTR_F_ALLOC)) {
if (!CHECK_FLAG(str, B_BSTR_F_ALLOC)) {
return;
}
@@ -127,7 +127,7 @@ static void __formatter_putchar(struct fx_bstr *str, char c)
str->bstr_buf[str->bstr_len] = '\0';
}
static void formatter_putchar(struct fx_bstr *f, char c)
static void formatter_putchar(struct b_bstr *f, char c)
{
if (f->bstr_add_indent && c != '\n') {
int indent = current_indent(f);
@@ -148,15 +148,12 @@ static void formatter_putchar(struct fx_bstr *f, char c)
static void bstr_fctprintf(char c, void *arg)
{
struct fx_bstr *str = arg;
struct b_bstr *str = arg;
formatter_putchar(str, c);
}
static enum fx_status bstr_putcs(
struct fx_bstr *str,
const char *s,
size_t len,
size_t *nr_written)
static enum b_status bstr_putcs(
struct b_bstr *str, const char *s, size_t len, size_t *nr_written)
{
for (size_t i = 0; i < len; i++) {
formatter_putchar(str, s[i]);
@@ -166,13 +163,10 @@ static enum fx_status bstr_putcs(
*nr_written = len;
}
return FX_SUCCESS;
return B_SUCCESS;
}
static enum fx_status bstr_puts(
struct fx_bstr *str,
const char *s,
size_t *nr_written)
static enum b_status bstr_puts(struct b_bstr *str, const char *s, size_t *nr_written)
{
size_t i;
for (i = 0; s[i]; i++) {
@@ -183,10 +177,10 @@ static enum fx_status bstr_puts(
*nr_written = i;
}
return FX_SUCCESS;
return B_SUCCESS;
}
enum fx_status fx_bstr_push_indent(struct fx_bstr *str, int indent)
enum b_status b_bstr_push_indent(struct b_bstr *str, int indent)
{
if (!str->bstr_istack) {
str->bstr_istack = calloc(4, sizeof(int));
@@ -199,7 +193,7 @@ enum fx_status fx_bstr_push_indent(struct fx_bstr *str, int indent)
str->bstr_istack,
(str->bstr_istack_size + 4) * sizeof(int));
if (!buf) {
return FX_ERR_NO_MEMORY;
return B_ERR_NO_MEMORY;
}
str->bstr_istack = buf;
@@ -209,55 +203,47 @@ enum fx_status fx_bstr_push_indent(struct fx_bstr *str, int indent)
int cur_indent = str->bstr_istack[str->bstr_istack_ptr];
str->bstr_istack[++str->bstr_istack_ptr] = cur_indent + indent;
return FX_SUCCESS;
return B_SUCCESS;
}
enum fx_status fx_bstr_pop_indent(struct fx_bstr *strv)
enum b_status b_bstr_pop_indent(struct b_bstr *strv)
{
if (strv->bstr_istack_ptr > 0) {
strv->bstr_istack_ptr--;
}
return FX_SUCCESS;
return B_SUCCESS;
}
enum fx_status fx_bstr_write_char(struct fx_bstr *str, char c)
enum b_status b_bstr_write_char(struct b_bstr *str, char c)
{
formatter_putchar(str, c);
return FX_SUCCESS;
return B_SUCCESS;
}
enum fx_status fx_bstr_write_chars(
struct fx_bstr *str,
const char *s,
size_t len,
size_t *nr_written)
enum b_status b_bstr_write_chars(
struct b_bstr *str, const char *s, size_t len, size_t *nr_written)
{
return bstr_putcs(str, s, len, nr_written);
}
enum fx_status fx_bstr_write_cstr(
struct fx_bstr *str,
const char *s,
size_t *nr_written)
enum b_status b_bstr_write_cstr(struct b_bstr *str, const char *s, size_t *nr_written)
{
return bstr_puts(str, s, nr_written);
}
enum fx_status fx_bstr_write_cstr_list(
struct fx_bstr *str,
const char **strs,
size_t *nr_written)
enum b_status b_bstr_write_cstr_list(
struct b_bstr *str, const char **strs, size_t *nr_written)
{
size_t w = 0;
enum fx_status status = FX_SUCCESS;
enum b_status status = B_SUCCESS;
for (size_t i = 0; strs[i]; i++) {
size_t tmp = 0;
status = bstr_puts(str, strs[i], &tmp);
w += tmp;
if (FX_ERR(status)) {
if (B_ERR(status)) {
break;
}
}
@@ -269,13 +255,10 @@ enum fx_status fx_bstr_write_cstr_list(
return status;
}
enum fx_status fx_bstr_write_cstr_array(
struct fx_bstr *str,
const char **strs,
size_t count,
size_t *nr_written)
enum b_status b_bstr_write_cstr_array(
struct b_bstr *str, const char **strs, size_t count, size_t *nr_written)
{
enum fx_status status = FX_SUCCESS;
enum b_status status = B_SUCCESS;
size_t w = 0;
for (size_t i = 0; i < count; i++) {
@@ -287,7 +270,7 @@ enum fx_status fx_bstr_write_cstr_array(
status = bstr_puts(str, strs[i], &tmp);
w += tmp;
if (FX_ERR(status)) {
if (B_ERR(status)) {
break;
}
}
@@ -299,20 +282,20 @@ enum fx_status fx_bstr_write_cstr_array(
return status;
}
enum fx_status fx_bstr_add_many(struct fx_bstr *str, size_t *nr_written, ...)
enum b_status b_bstr_add_many(struct b_bstr *str, size_t *nr_written, ...)
{
va_list arg;
va_start(arg, nr_written);
const char *s = NULL;
size_t w = 0;
enum fx_status status = FX_SUCCESS;
enum b_status status = B_SUCCESS;
while ((s = va_arg(arg, const char *))) {
size_t tmp = 0;
status = bstr_puts(str, s, &tmp);
w += tmp;
if (FX_ERR(status)) {
if (B_ERR(status)) {
break;
}
}
@@ -324,13 +307,11 @@ enum fx_status fx_bstr_add_many(struct fx_bstr *str, size_t *nr_written, ...)
return status;
}
enum fx_status fx_bstr_write_rope(
fx_bstr *strv,
const struct fx_rope *rope,
size_t *nr_written)
enum b_status b_bstr_write_rope(
b_bstr *strv, const struct b_rope *rope, size_t *nr_written)
{
size_t start = strv->bstr_len;
enum fx_status status = fx_rope_to_bstr(rope, strv);
enum b_status status = b_rope_to_bstr(rope, strv);
size_t end = strv->bstr_len;
if (nr_written) {
@@ -340,62 +321,55 @@ enum fx_status fx_bstr_write_rope(
return status;
}
enum fx_status fx_bstr_write_fmt(
struct fx_bstr *str,
size_t *nr_written,
const char *format,
...)
enum b_status b_bstr_write_fmt(
struct b_bstr *str, size_t *nr_written, const char *format, ...)
{
va_list arg;
va_start(arg, format);
enum fx_status result
= fx_bstr_write_vfmt(str, nr_written, format, arg);
enum b_status result = b_bstr_write_vfmt(str, nr_written, format, arg);
va_end(arg);
return result;
}
enum fx_status fx_bstr_write_vfmt(
struct fx_bstr *str,
size_t *nr_written,
const char *format,
va_list arg)
enum b_status b_bstr_write_vfmt(
struct b_bstr *str, size_t *nr_written, const char *format, va_list arg)
{
size_t start = str->bstr_len;
z__fx_fctprintf(bstr_fctprintf, str, format, arg);
z__b_fctprintf(bstr_fctprintf, str, format, arg);
size_t end = str->bstr_len;
if (nr_written) {
*nr_written = end - start;
}
/* TODO update z__fx_fctprintf to support propagating error codes */
return FX_SUCCESS;
/* TODO update z__b_fctprintf to support propagating error codes */
return B_SUCCESS;
}
char *fx_bstr_rope(const struct fx_rope *rope, size_t *nr_written)
char *b_bstr_rope(const struct b_rope *rope, size_t *nr_written)
{
struct fx_bstr str;
fx_bstr_begin_dynamic(&str);
fx_bstr_write_rope(&str, rope, nr_written);
struct b_bstr str;
b_bstr_begin_dynamic(&str);
b_bstr_write_rope(&str, rope, nr_written);
return fx_bstr_end(&str);
return b_bstr_end(&str);
}
char *fx_bstr_fmt(size_t *nr_written, const char *format, ...)
char *b_bstr_fmt(size_t *nr_written, const char *format, ...)
{
va_list arg;
va_start(arg, format);
char *s = fx_bstr_vfmt(nr_written, format, arg);
char *s = b_bstr_vfmt(nr_written, format, arg);
va_end(arg);
return s;
}
char *fx_bstr_vfmt(size_t *nr_written, const char *format, va_list arg)
char *b_bstr_vfmt(size_t *nr_written, const char *format, va_list arg)
{
struct fx_bstr str;
fx_bstr_begin_dynamic(&str);
fx_bstr_write_vfmt(&str, nr_written, format, arg);
struct b_bstr str;
b_bstr_begin_dynamic(&str);
b_bstr_write_vfmt(&str, nr_written, format, arg);
return fx_bstr_end(&str);
return b_bstr_end(&str);
}
+234 -239
View File
@@ -25,10 +25,10 @@
this file implements an extensible AVL binary tree data structure.
the primary rule of an AVL binary tree is that for a given node N,
the heights of N's left and right substs can differ by at most 1.
the heights of N's left and right subtrees can differ by at most 1.
the height of a subst is the length of the longest path between
the root of the subst and a leaf node, including the root node itself.
the height of a subtree is the length of the longest path between
the root of the subtree and a leaf node, including the root node itself.
the height of a leaf node is 1.
@@ -50,45 +50,45 @@
this file intentionally excludes any kind of search function implementation.
it is up to the programmer to implement their own tree node type
using fx_bst_node, and their own search function using fx_bst.
using b_btree_node, and their own search function using b_btree.
this allows the programmer to define their own node types with complex
non-integer key types. bst.h contains a number of macros to help
non-integer key types. btree.h contains a number of macros to help
define these functions. the macros do all the work, you just have to
provide a comparator function.
*/
#include <fx/bst.h>
#include <blue/core/btree.h>
#include <stddef.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define IS_LEFT_CHILD(p, c) ((p) && (c) && ((p)->n_left == (c)))
#define IS_RIGHT_CHILD(p, c) ((p) && (c) && ((p)->n_right == (c)))
#define IS_LEFT_CHILD(p, c) ((p) && (c) && ((p)->b_left == (c)))
#define IS_RIGHT_CHILD(p, c) ((p) && (c) && ((p)->b_right == (c)))
#define HAS_LEFT_CHILD(x) ((x) && ((x)->n_left))
#define HAS_RIGHT_CHILD(x) ((x) && ((x)->n_right))
#define HAS_LEFT_CHILD(x) ((x) && ((x)->b_left))
#define HAS_RIGHT_CHILD(x) ((x) && ((x)->b_right))
#define HAS_NO_CHILDREN(x) ((x) && (!(x)->n_left) && (!(x)->n_right))
#define HAS_NO_CHILDREN(x) ((x) && (!(x)->b_left) && (!(x)->b_right))
#define HAS_ONE_CHILD(x) \
((HAS_LEFT_CHILD(x) && !HAS_RIGHT_CHILD(x)) \
|| (!HAS_LEFT_CHILD(x) && HAS_RIGHT_CHILD(x)))
#define HAS_TWO_CHILDREN(x) (HAS_LEFT_CHILD(x) && HAS_RIGHT_CHILD(x))
#define HEIGHT(x) ((x) ? (x)->n_height : 0)
#define HEIGHT(x) ((x) ? (x)->b_height : 0)
struct fx_bst_iterator_p {
struct b_btree_iterator_p {
size_t i, depth;
fx_bst_node *node;
fx_bst *_b;
b_btree_node *node;
b_btree *_b;
};
static inline void update_height(struct fx_bst_node *x)
static inline void update_height(struct b_btree_node *x)
{
x->n_height = MAX(HEIGHT(x->n_left), HEIGHT((x->n_right))) + 1;
x->b_height = MAX(HEIGHT(x->b_left), HEIGHT((x->b_right))) + 1;
}
static inline int bf(struct fx_bst_node *x)
static inline int bf(struct b_btree_node *x)
{
int bf = 0;
@@ -96,18 +96,18 @@ static inline int bf(struct fx_bst_node *x)
return bf;
}
if (x->n_right) {
bf += x->n_right->n_height;
if (x->b_right) {
bf += x->b_right->b_height;
}
if (x->n_left) {
bf -= x->n_left->n_height;
if (x->b_left) {
bf -= x->b_left->b_height;
}
return bf;
}
/* perform a left rotation on a subst
/* perform a left rotation on a subtree
if you have a tree like this:
@@ -130,42 +130,42 @@ static inline int bf(struct fx_bst_node *x)
/ \
. .
note that this function does NOT update fx_height for the rotated
note that this function does NOT update b_height for the rotated
nodes. it is up to you to call update_height_to_root().
*/
static void rotate_left(struct fx_bst *tree, struct fx_bst_node *x)
static void rotate_left(struct b_btree *tree, struct b_btree_node *x)
{
struct fx_bst_node *y = x->n_right;
struct fx_bst_node *p = x->n_parent;
struct b_btree_node *y = x->b_right;
struct b_btree_node *p = x->b_parent;
if (y->n_left) {
y->n_left->n_parent = x;
if (y->b_left) {
y->b_left->b_parent = x;
}
x->n_right = y->n_left;
x->b_right = y->b_left;
if (!p) {
tree->bst_root = y;
} else if (x == p->n_left) {
p->n_left = y;
tree->b_root = y;
} else if (x == p->b_left) {
p->b_left = y;
} else {
p->n_right = y;
p->b_right = y;
}
x->n_parent = y;
y->n_left = x;
y->n_parent = p;
x->b_parent = y;
y->b_left = x;
y->b_parent = p;
}
static void update_height_to_root(struct fx_bst_node *x)
static void update_height_to_root(struct b_btree_node *x)
{
while (x) {
update_height(x);
x = x->n_parent;
x = x->b_parent;
}
}
/* perform a right rotation on a subst
/* perform a right rotation on a subtree
if you have a tree like this:
@@ -188,31 +188,31 @@ static void update_height_to_root(struct fx_bst_node *x)
/ \
. .
note that this function does NOT update fx_height for the rotated
note that this function does NOT update b_height for the rotated
nodes. it is up to you to call update_height_to_root().
*/
static void rotate_right(struct fx_bst *tree, struct fx_bst_node *y)
static void rotate_right(struct b_btree *tree, struct b_btree_node *y)
{
struct fx_bst_node *x = y->n_left;
struct fx_bst_node *p = y->n_parent;
struct b_btree_node *x = y->b_left;
struct b_btree_node *p = y->b_parent;
if (x->n_right) {
x->n_right->n_parent = y;
if (x->b_right) {
x->b_right->b_parent = y;
}
y->n_left = x->n_right;
y->b_left = x->b_right;
if (!p) {
tree->bst_root = x;
} else if (y == p->n_left) {
p->n_left = x;
tree->b_root = x;
} else if (y == p->b_left) {
p->b_left = x;
} else {
p->n_right = x;
p->b_right = x;
}
y->n_parent = x;
x->n_right = y;
x->n_parent = p;
y->b_parent = x;
x->b_right = y;
x->b_parent = p;
}
/* for a given node Z, perform a right rotation on Z's right child,
@@ -239,13 +239,13 @@ static void rotate_right(struct fx_bst *tree, struct fx_bst_node *y)
. . . .
note that, unlike rotate_left and rotate_right, this function
DOES update fx_height for the rotated nodes (since it needs to be
DOES update b_height for the rotated nodes (since it needs to be
done in a certain order).
*/
static void rotate_double_left(struct fx_bst *tree, struct fx_bst_node *z)
static void rotate_double_left(struct b_btree *tree, struct b_btree_node *z)
{
struct fx_bst_node *x = z->n_right;
struct fx_bst_node *y = x->n_left;
struct b_btree_node *x = z->b_right;
struct b_btree_node *y = x->b_left;
rotate_right(tree, x);
rotate_left(tree, z);
@@ -255,7 +255,7 @@ static void rotate_double_left(struct fx_bst *tree, struct fx_bst_node *z)
while (y) {
update_height(y);
y = y->n_parent;
y = y->b_parent;
}
}
@@ -283,13 +283,13 @@ static void rotate_double_left(struct fx_bst *tree, struct fx_bst_node *z)
. . . .
note that, unlike rotate_left and rotate_right, this function
DOES update fx_height for the rotated nodes (since it needs to be
DOES update b_height for the rotated nodes (since it needs to be
done in a certain order).
*/
static void rotate_double_right(struct fx_bst *tree, struct fx_bst_node *z)
static void rotate_double_right(struct b_btree *tree, struct b_btree_node *z)
{
struct fx_bst_node *x = z->n_left;
struct fx_bst_node *y = x->n_right;
struct b_btree_node *x = z->b_left;
struct b_btree_node *y = x->b_right;
rotate_left(tree, x);
rotate_right(tree, z);
@@ -299,25 +299,25 @@ static void rotate_double_right(struct fx_bst *tree, struct fx_bst_node *z)
while (y) {
update_height(y);
y = y->n_parent;
y = y->b_parent;
}
}
/* run after an insert operation. checks that the balance factor
of the local subst is within the range -1 <= BF <= 1. if it
is not, rotate the subst to restore balance.
of the local subtree is within the range -1 <= BF <= 1. if it
is not, rotate the subtree to restore balance.
note that at most one rotation should be required after a node
is inserted into the tree.
this function depends on all nodes in the tree having
correct fx_height values.
correct b_height values.
@param w the node that was just inserted into the tree
*/
static void insert_fixup(struct fx_bst *tree, struct fx_bst_node *w)
static void insert_fixup(struct b_btree *tree, struct b_btree_node *w)
{
struct fx_bst_node *z = NULL, *y = NULL, *x = NULL;
struct b_btree_node *z = NULL, *y = NULL, *x = NULL;
z = w;
while (z) {
@@ -344,19 +344,19 @@ static void insert_fixup(struct fx_bst *tree, struct fx_bst_node *w)
next_ancestor:
x = y;
y = z;
z = z->n_parent;
z = z->b_parent;
}
}
/* run after a delete operation. checks that the balance factor
of the local subst is within the range -1 <= BF <= 1. if it
is not, rotate the subst to restore balance.
of the local subtree is within the range -1 <= BF <= 1. if it
is not, rotate the subtree to restore balance.
note that, unlike insert_fixup, multiple rotations may be required
to restore balance after a node is deleted.
this function depends on all nodes in the tree having
correct fx_height values.
correct b_height values.
@param w one of the following:
- the parent of the node that was deleted if the node
@@ -366,20 +366,20 @@ static void insert_fixup(struct fx_bst *tree, struct fx_bst_node *w)
- the node that replaced the node that was deleted, if
the node that was deleted had one child.
*/
static void delete_fixup(struct fx_bst *tree, struct fx_bst_node *w)
static void delete_fixup(struct b_btree *tree, struct b_btree_node *w)
{
struct fx_bst_node *z = w;
struct b_btree_node *z = w;
while (z) {
if (bf(z) > 1) {
if (bf(z->n_right) >= 0) {
if (bf(z->b_right) >= 0) {
rotate_left(tree, z);
update_height_to_root(z);
} else {
rotate_double_left(tree, z);
}
} else if (bf(z) < -1) {
if (bf(z->n_left) <= 0) {
if (bf(z->b_left) <= 0) {
rotate_right(tree, z);
update_height_to_root(z);
} else {
@@ -387,23 +387,23 @@ static void delete_fixup(struct fx_bst *tree, struct fx_bst_node *w)
}
}
z = z->n_parent;
z = z->b_parent;
}
}
/* updates fx_height for all nodes between the inserted node and the root
/* updates b_height for all nodes between the inserted node and the root
of the tree, and calls insert_fixup.
@param node the node that was just inserted into the tree.
*/
void fx_bst_insert_fixup(struct fx_bst *tree, struct fx_bst_node *node)
void b_btree_insert_fixup(struct b_btree *tree, struct b_btree_node *node)
{
node->n_height = 0;
node->b_height = 0;
struct fx_bst_node *cur = node;
struct b_btree_node *cur = node;
while (cur) {
update_height(cur);
cur = cur->n_parent;
cur = cur->b_parent;
}
insert_fixup(tree, node);
@@ -414,29 +414,28 @@ void fx_bst_insert_fixup(struct fx_bst *tree, struct fx_bst_node *node)
this function assumes that `node` has no children, and therefore
doesn't need to be replaced.
updates fx_height for all nodes between `node` and the tree root.
updates b_height for all nodes between `node` and the tree root.
@param node the node to delete.
*/
static struct fx_bst_node *remove_node_with_no_children(
struct fx_bst *tree,
struct fx_bst_node *node)
static struct b_btree_node *remove_node_with_no_children(
struct b_btree *tree, struct b_btree_node *node)
{
struct fx_bst_node *w = node->n_parent;
struct fx_bst_node *p = node->n_parent;
node->n_parent = NULL;
struct b_btree_node *w = node->b_parent;
struct b_btree_node *p = node->b_parent;
node->b_parent = NULL;
if (!p) {
tree->bst_root = NULL;
tree->b_root = NULL;
} else if (IS_LEFT_CHILD(p, node)) {
p->n_left = NULL;
p->b_left = NULL;
} else {
p->n_right = NULL;
p->b_right = NULL;
}
while (p) {
update_height(p);
p = p->n_parent;
p = p->b_parent;
}
return w;
@@ -447,41 +446,40 @@ static struct fx_bst_node *remove_node_with_no_children(
this function assumes that `node` has one child.
the child of `node` is inherited by `node`'s parent, and `node` is removed.
updates fx_height for all nodes between the node that replaced
updates b_height for all nodes between the node that replaced
`node` and the tree root.
@param node the node to delete.
*/
static struct fx_bst_node *replace_node_with_one_subst(
struct fx_bst *tree,
struct fx_bst_node *node)
static struct b_btree_node *replace_node_with_one_subtree(
struct b_btree *tree, struct b_btree_node *node)
{
struct fx_bst_node *p = node->n_parent;
struct fx_bst_node *z = NULL;
struct b_btree_node *p = node->b_parent;
struct b_btree_node *z = NULL;
if (HAS_LEFT_CHILD(node)) {
z = node->n_left;
z = node->b_left;
} else {
z = node->n_right;
z = node->b_right;
}
struct fx_bst_node *w = z;
struct b_btree_node *w = z;
if (!p) {
tree->bst_root = z;
tree->b_root = z;
} else if (IS_LEFT_CHILD(p, node)) {
p->n_left = z;
p->b_left = z;
} else if (IS_RIGHT_CHILD(p, node)) {
p->n_right = z;
p->b_right = z;
}
z->n_parent = p;
z->b_parent = p;
node->n_parent = NULL;
node->n_left = node->n_right = NULL;
node->b_parent = NULL;
node->b_left = node->b_right = NULL;
while (z) {
update_height(z);
z = z->n_parent;
z = z->b_parent;
}
return w;
@@ -497,101 +495,100 @@ static struct fx_bst_node *replace_node_with_one_subst(
if Y has a child (it will never have more than one), have Y's parent inherit
Y's child.
updates fx_height for all nodes between the deepest node that was modified
updates b_height for all nodes between the deepest node that was modified
and the tree root.
@param z the node to delete.
*/
static struct fx_bst_node *replace_node_with_two_substs(
struct fx_bst *tree,
struct fx_bst_node *z)
static struct b_btree_node *replace_node_with_two_subtrees(
struct b_btree *tree, struct b_btree_node *z)
{
/* x will replace z */
struct fx_bst_node *x = z->n_left;
struct b_btree_node *x = z->b_left;
while (x->n_right) {
x = x->n_right;
while (x->b_right) {
x = x->b_right;
}
/* y is the node that will replace x (if x has a left child) */
struct fx_bst_node *y = x->n_left;
struct b_btree_node *y = x->b_left;
/* w is the starting point for the height update and fixup */
struct fx_bst_node *w = x;
if (w->n_parent != z) {
w = w->n_parent;
struct b_btree_node *w = x;
if (w->b_parent != z) {
w = w->b_parent;
}
if (y) {
w = y;
}
if (IS_LEFT_CHILD(x->n_parent, x)) {
x->n_parent->n_left = y;
} else if (IS_RIGHT_CHILD(x->n_parent, x)) {
x->n_parent->n_right = y;
if (IS_LEFT_CHILD(x->b_parent, x)) {
x->b_parent->b_left = y;
} else if (IS_RIGHT_CHILD(x->b_parent, x)) {
x->b_parent->b_right = y;
}
if (y) {
y->n_parent = x->n_parent;
y->b_parent = x->b_parent;
}
if (IS_LEFT_CHILD(z->n_parent, z)) {
z->n_parent->n_left = x;
} else if (IS_RIGHT_CHILD(z->n_parent, z)) {
z->n_parent->n_right = x;
if (IS_LEFT_CHILD(z->b_parent, z)) {
z->b_parent->b_left = x;
} else if (IS_RIGHT_CHILD(z->b_parent, z)) {
z->b_parent->b_right = x;
}
x->n_parent = z->n_parent;
x->n_left = z->n_left;
x->n_right = z->n_right;
x->b_parent = z->b_parent;
x->b_left = z->b_left;
x->b_right = z->b_right;
if (x->n_left) {
x->n_left->n_parent = x;
if (x->b_left) {
x->b_left->b_parent = x;
}
if (x->n_right) {
x->n_right->n_parent = x;
if (x->b_right) {
x->b_right->b_parent = x;
}
if (!x->n_parent) {
tree->bst_root = x;
if (!x->b_parent) {
tree->b_root = x;
}
struct fx_bst_node *cur = w;
struct b_btree_node *cur = w;
while (cur) {
update_height(cur);
cur = cur->n_parent;
cur = cur->b_parent;
}
return w;
}
/* delete a node from the tree and re-balance it afterwards */
void fx_bst_delete(struct fx_bst *tree, struct fx_bst_node *node)
void b_btree_delete(struct b_btree *tree, struct b_btree_node *node)
{
struct fx_bst_node *w = NULL;
struct b_btree_node *w = NULL;
if (HAS_NO_CHILDREN(node)) {
w = remove_node_with_no_children(tree, node);
} else if (HAS_ONE_CHILD(node)) {
w = replace_node_with_one_subst(tree, node);
w = replace_node_with_one_subtree(tree, node);
} else if (HAS_TWO_CHILDREN(node)) {
w = replace_node_with_two_substs(tree, node);
w = replace_node_with_two_subtrees(tree, node);
}
if (w) {
delete_fixup(tree, w);
}
node->n_left = node->n_right = node->n_parent = NULL;
node->b_left = node->b_right = node->b_parent = NULL;
}
static struct fx_bst_node *first_node(const struct fx_bst *tree, int *depth)
static struct b_btree_node *first_node(const struct b_btree *tree, int *depth)
{
/* the first node in the tree is the node with the smallest key.
we keep moving left until we can't go any further */
struct fx_bst_node *cur = tree->bst_root;
struct b_btree_node *cur = tree->b_root;
int d = 0;
if (!cur) {
@@ -599,47 +596,47 @@ static struct fx_bst_node *first_node(const struct fx_bst *tree, int *depth)
return NULL;
}
while (cur->n_left) {
while (cur->b_left) {
d++;
cur = cur->n_left;
cur = cur->b_left;
}
*depth = d;
return cur;
}
struct fx_bst_node *fx_bst_first(const struct fx_bst *tree)
struct b_btree_node *b_btree_first(const struct b_btree *tree)
{
int d;
return first_node(tree, &d);
}
static struct fx_bst_node *last_node(const struct fx_bst *tree, int *depth)
static struct b_btree_node *last_node(const struct b_btree *tree, int *depth)
{
/* the first node in the tree is the node with the largest key.
we keep moving right until we can't go any further */
struct fx_bst_node *cur = tree->bst_root;
struct b_btree_node *cur = tree->b_root;
int d = 0;
if (!cur) {
return NULL;
}
while (cur->n_right) {
while (cur->b_right) {
d++;
cur = cur->n_right;
cur = cur->b_right;
}
*depth = d;
return cur;
}
fx_bst_node *fx_bst_last(const struct fx_bst *tree)
b_btree_node *b_btree_last(const struct b_btree *tree)
{
int d;
return last_node(tree, &d);
}
static fx_bst_node *next_node(const struct fx_bst_node *node, int *depth_diff)
static b_btree_node *next_node(const struct b_btree_node *node, int *depth_diff)
{
if (!node) {
return NULL;
@@ -651,18 +648,18 @@ static fx_bst_node *next_node(const struct fx_bst_node *node, int *depth_diff)
1. if `node` has a right sub-tree, every node in this sub-tree is
bigger than node. the in-order successor of `node` is the smallest
node in this subst.
node in this subtree.
2. if `node` has no right sub-tree, we've reached the largest node in
the sub-tree rooted at `node`. we need to go back to our parent
and continue the search elsewhere.
*/
if (node->n_right) {
if (node->b_right) {
/* case 1: step into `node`'s right sub-tree and keep going
left to find the smallest node */
struct fx_bst_node *cur = node->n_right;
struct b_btree_node *cur = node->b_right;
depth++;
while (cur->n_left) {
cur = cur->n_left;
while (cur->b_left) {
cur = cur->b_left;
depth++;
}
@@ -674,16 +671,16 @@ static fx_bst_node *next_node(const struct fx_bst_node *node, int *depth_diff)
if we encounter a step where we are our parent's left child,
we've found a parent with a value larger than us. this parent
is the in-order successor of `node` */
while (node->n_parent && node->n_parent->n_left != node) {
node = node->n_parent;
while (node->b_parent && node->b_parent->b_left != node) {
node = node->b_parent;
depth--;
}
*depth_diff = depth - 1;
return node->n_parent;
return node->b_parent;
}
static fx_bst_node *prev_node(const struct fx_bst_node *node, int *depth_diff)
static b_btree_node *prev_node(const struct b_btree_node *node, int *depth_diff)
{
if (!node) {
return NULL;
@@ -695,18 +692,18 @@ static fx_bst_node *prev_node(const struct fx_bst_node *node, int *depth_diff)
1. if `node` has a left sub-tree, every node in this sub-tree is
smaller than `node`. the in-order predecessor of `node` is the
largest node in this subst.
largest node in this subtree.
2. if `node` has no left sub-tree, we've reached the smallest node in
the sub-tree rooted at `node`. we need to go back to our parent
and continue the search elsewhere.
*/
if (node->n_left) {
if (node->b_left) {
/* case 1: step into `node`'s left sub-tree and keep going
right to find the largest node */
fx_bst_node *cur = node->n_left;
b_btree_node *cur = node->b_left;
depth++;
while (cur->n_right) {
cur = cur->n_right;
while (cur->b_right) {
cur = cur->b_right;
depth++;
}
@@ -718,67 +715,65 @@ static fx_bst_node *prev_node(const struct fx_bst_node *node, int *depth_diff)
if we encounter a step where we are our parent's right child,
we've found a parent with a value smaller than us. this parent
is the in-order predecessor of `node`. */
while (node->n_parent && node->n_parent->n_right != node) {
node = node->n_parent;
while (node->b_parent && node->b_parent->b_right != node) {
node = node->b_parent;
depth--;
}
*depth_diff = depth - 1;
return node->n_parent;
return node->b_parent;
}
fx_bst_node *fx_bst_next(const struct fx_bst_node *node)
b_btree_node *b_btree_next(const struct b_btree_node *node)
{
int d;
return next_node(node, &d);
}
fx_bst_node *fx_bst_prev(const struct fx_bst_node *node)
b_btree_node *b_btree_prev(const struct b_btree_node *node)
{
int d;
return prev_node(node, &d);
}
void fx_bst_move(
struct fx_bst *tree,
struct fx_bst_node *dest,
struct fx_bst_node *src)
void b_btree_move(
struct b_btree *tree, struct b_btree_node *dest, struct b_btree_node *src)
{
if (src->n_parent) {
if (src->n_parent->n_left == src) {
src->n_parent->n_left = dest;
if (src->b_parent) {
if (src->b_parent->b_left == src) {
src->b_parent->b_left = dest;
} else {
src->n_parent->n_right = dest;
src->b_parent->b_right = dest;
}
}
if (src->n_left) {
src->n_left->n_parent = dest;
if (src->b_left) {
src->b_left->b_parent = dest;
}
if (src->n_right) {
src->n_right->n_parent = dest;
if (src->b_right) {
src->b_right->b_parent = dest;
}
if (tree->bst_root == src) {
tree->bst_root = dest;
if (tree->b_root == src) {
tree->b_root = dest;
}
memmove(dest, src, sizeof *src);
}
fx_iterator *fx_bst_begin(struct fx_bst *tree)
b_iterator *b_btree_begin(struct b_btree *tree)
{
fx_iterator *it_obj = fx_object_create(FX_TYPE_BST_ITERATOR);
b_iterator *it_obj = b_object_create(B_TYPE_BTREE_ITERATOR);
if (!it_obj) {
return NULL;
}
struct fx_bst_iterator_p *it
= fx_object_get_private(it_obj, FX_TYPE_BST_ITERATOR);
struct b_btree_iterator_p *it
= b_object_get_private(it_obj, B_TYPE_BTREE_ITERATOR);
int depth = 0;
it->_b = (struct fx_bst *)tree;
it->_b = (struct b_btree *)tree;
it->i = 0;
it->node = first_node(tree, &depth);
it->depth = depth;
@@ -786,18 +781,18 @@ fx_iterator *fx_bst_begin(struct fx_bst *tree)
return it_obj;
}
const fx_iterator *fx_bst_cbegin(const struct fx_bst *tree)
const b_iterator *b_btree_cbegin(const struct b_btree *tree)
{
fx_iterator *it_obj = fx_object_create(FX_TYPE_BST_ITERATOR);
b_iterator *it_obj = b_object_create(B_TYPE_BTREE_ITERATOR);
if (!it_obj) {
return NULL;
}
struct fx_bst_iterator_p *it
= fx_object_get_private(it_obj, FX_TYPE_BST_ITERATOR);
struct b_btree_iterator_p *it
= b_object_get_private(it_obj, B_TYPE_BTREE_ITERATOR);
int depth = 0;
it->_b = (struct fx_bst *)tree;
it->_b = (struct b_btree *)tree;
it->i = 0;
it->node = first_node(tree, &depth);
it->depth = depth;
@@ -805,13 +800,13 @@ const fx_iterator *fx_bst_cbegin(const struct fx_bst *tree)
return it_obj;
}
static enum fx_status iterator_move_next(const fx_iterator *obj)
static enum b_status iterator_move_next(const b_iterator *obj)
{
struct fx_bst_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_BST_ITERATOR);
struct b_btree_iterator_p *it
= b_object_get_private(obj, B_TYPE_BTREE_ITERATOR);
int depth_diff = 0;
struct fx_bst_node *next = next_node(it->node, &depth_diff);
struct b_btree_node *next = next_node(it->node, &depth_diff);
if (!next) {
it->node = NULL;
@@ -826,19 +821,19 @@ static enum fx_status iterator_move_next(const fx_iterator *obj)
return true;
}
static enum fx_status iterator_erase(fx_iterator *obj)
static enum b_status iterator_erase(b_iterator *obj)
{
struct fx_bst_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_BST_ITERATOR);
struct b_btree_iterator_p *it
= b_object_get_private(obj, B_TYPE_BTREE_ITERATOR);
if (!it->node) {
return FX_ERR_OUT_OF_BOUNDS;
return B_ERR_OUT_OF_BOUNDS;
}
int depth_diff = 0;
struct fx_bst_node *next = next_node(it->node, &depth_diff);
struct b_btree_node *next = next_node(it->node, &depth_diff);
fx_bst_delete(it->_b, it->node);
b_btree_delete(it->_b, it->node);
if (!next) {
it->node = NULL;
it->depth = 0;
@@ -846,51 +841,51 @@ static enum fx_status iterator_erase(fx_iterator *obj)
it->node = next;
it->depth = 0;
struct fx_bst_node *cur = next->n_parent;
struct b_btree_node *cur = next->b_parent;
while (cur) {
it->depth++;
cur = cur->n_parent;
cur = cur->b_parent;
}
}
return FX_SUCCESS;
return B_SUCCESS;
}
static fx_iterator_value iterator_get_value(fx_iterator *obj)
static b_iterator_value iterator_get_value(b_iterator *obj)
{
struct fx_bst_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_BST_ITERATOR);
struct b_btree_iterator_p *it
= b_object_get_private(obj, B_TYPE_BTREE_ITERATOR);
return FX_ITERATOR_VALUE_PTR(it->node);
return B_ITERATOR_VALUE_PTR(it->node);
}
static const fx_iterator_value iterator_get_cvalue(const fx_iterator *obj)
static const b_iterator_value iterator_get_cvalue(const b_iterator *obj)
{
struct fx_bst_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_BST_ITERATOR);
struct b_btree_iterator_p *it
= b_object_get_private(obj, B_TYPE_BTREE_ITERATOR);
return FX_ITERATOR_VALUE_CPTR(it->node);
return B_ITERATOR_VALUE_CPTR(it->node);
}
/*** CLASS DEFINITION *********************************************************/
// ---- fx_bst_iterator DEFINITION
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_bst_iterator)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = NULL;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
// ---- b_btree_iterator DEFINITION
B_TYPE_CLASS_DEFINITION_BEGIN(b_btree_iterator)
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
B_INTERFACE_ENTRY(to_string) = NULL;
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_iterator, FX_TYPE_ITERATOR)
FX_INTERFACE_ENTRY(it_move_next) = iterator_move_next;
FX_INTERFACE_ENTRY(it_erase) = iterator_erase;
FX_INTERFACE_ENTRY(it_get_value) = iterator_get_value;
FX_INTERFACE_ENTRY(it_get_cvalue) = iterator_get_cvalue;
FX_TYPE_CLASS_INTERFACE_END(fx_iterator, FX_TYPE_ITERATOR)
FX_TYPE_CLASS_DEFINITION_END(fx_bst_iterator)
B_TYPE_CLASS_INTERFACE_BEGIN(b_iterator, B_TYPE_ITERATOR)
B_INTERFACE_ENTRY(it_move_next) = iterator_move_next;
B_INTERFACE_ENTRY(it_erase) = iterator_erase;
B_INTERFACE_ENTRY(it_get_value) = iterator_get_value;
B_INTERFACE_ENTRY(it_get_cvalue) = iterator_get_cvalue;
B_TYPE_CLASS_INTERFACE_END(b_iterator, B_TYPE_ITERATOR)
B_TYPE_CLASS_DEFINITION_END(b_btree_iterator)
FX_TYPE_DEFINITION_BEGIN(fx_bst_iterator)
FX_TYPE_ID(0x432779d7, 0xc03a, 0x48ea, 0xae8f, 0x12c666c767ae);
FX_TYPE_EXTENDS(FX_TYPE_ITERATOR);
FX_TYPE_CLASS(fx_bst_iterator_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_bst_iterator_p);
FX_TYPE_DEFINITION_END(fx_bst_iterator)
B_TYPE_DEFINITION_BEGIN(b_btree_iterator)
B_TYPE_ID(0x432779d7, 0xc03a, 0x48ea, 0xae8f, 0x12c666c767ae);
B_TYPE_EXTENDS(B_TYPE_ITERATOR);
B_TYPE_CLASS(b_btree_iterator_class);
B_TYPE_INSTANCE_PRIVATE(struct b_btree_iterator_p);
B_TYPE_DEFINITION_END(b_btree_iterator)
+79
View File
@@ -0,0 +1,79 @@
#include "class.h"
#include "type.h"
#include <assert.h>
#include <blue/core/class.h>
#include <stdlib.h>
#include <string.h>
void *b_class_get(b_type id)
{
struct b_type_registration *r = b_type_get_registration(id);
if (!r) {
return NULL;
}
return r->r_class;
}
const char *b_class_get_name(const struct _b_class *c)
{
if (!c) {
return NULL;
}
assert(c->c_magic == B_CLASS_MAGIC);
return c->c_type->r_info->t_name;
}
void *b_class_get_interface(const struct _b_class *c, const union b_type_id *id)
{
if (!c) {
return NULL;
}
assert(c->c_magic == B_CLASS_MAGIC);
const struct b_type_registration *type_reg = c->c_type;
struct b_type_component *comp
= b_type_get_component(&type_reg->r_components, id);
if (!comp) {
return NULL;
}
return (char *)c + comp->c_class_data_offset;
}
b_result b_class_instantiate(
struct b_type_registration *type, struct _b_class **out_class)
{
struct _b_class *out = malloc(type->r_class_size);
if (!out) {
return B_RESULT_ERR(NO_MEMORY);
}
memset(out, 0x0, type->r_class_size);
out->c_magic = B_CLASS_MAGIC;
out->c_type = type;
struct b_queue_entry *entry = b_queue_first(&type->r_class_hierarchy);
while (entry) {
struct b_type_component *comp
= b_unbox(struct b_type_component, entry, c_entry);
const struct b_type_info *class_info = comp->c_type->r_info;
void *class_data = (char *)out + comp->c_class_data_offset;
if (class_info->t_class_init) {
class_info->t_class_init(out, class_data);
}
entry = b_queue_next(entry);
}
*out_class = out;
return B_RESULT_SUCCESS;
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef _CLASS_H_
#define _CLASS_H_
#include <blue/core/error.h>
#include <blue/core/misc.h>
#include <stdint.h>
struct b_type_registration;
struct _b_class {
uint64_t c_magic;
const struct b_type_registration *c_type;
};
extern b_result b_class_instantiate(
struct b_type_registration *type, struct _b_class **out);
#endif
+25 -27
View File
@@ -1,12 +1,12 @@
#include <fx/encoding.h>
#include <blue/core/encoding.h>
#include <wctype.h>
bool fx_wchar_is_number(fx_wchar c)
bool b_wchar_is_number(b_wchar c)
{
return iswdigit((wchar_t)c);
return iswnumber((wchar_t)c);
}
bool fx_wchar_is_alpha(fx_wchar c)
bool b_wchar_is_alpha(b_wchar c)
{
if (c == 0) {
return false;
@@ -1177,28 +1177,28 @@ bool fx_wchar_is_alpha(fx_wchar c)
}
}
bool fx_wchar_is_hex_digit(fx_wchar c)
bool b_wchar_is_hex_digit(b_wchar c)
{
return iswxdigit(c);
return isxdigit(c);
}
bool fx_wchar_is_space(fx_wchar c)
bool b_wchar_is_space(b_wchar c)
{
return iswspace((wchar_t)c);
}
bool fx_wchar_is_punct(fx_wchar c)
bool b_wchar_is_punct(b_wchar c)
{
return iswpunct((wchar_t)c);
}
bool fx_wchar_utf8_is_valid_scalar(fx_wchar c)
bool b_wchar_utf8_is_valid_scalar(b_wchar c)
{
return (((c) >= 0x0000 && (c) <= 0xD7FF)
|| ((c) >= 0xE000 && (c) <= 0x10FFFF));
}
unsigned int fx_wchar_utf8_header_decode(char c)
unsigned int b_wchar_utf8_header_decode(char c)
{
unsigned int len = 0;
@@ -1217,9 +1217,9 @@ unsigned int fx_wchar_utf8_header_decode(char c)
return len;
}
unsigned int fx_wchar_utf8_codepoint_size(fx_wchar c)
unsigned int b_wchar_utf8_codepoint_size(b_wchar c)
{
if (!fx_wchar_utf8_is_valid_scalar(c)) {
if (!b_wchar_utf8_is_valid_scalar(c)) {
return 0;
}
@@ -1251,9 +1251,9 @@ static int32_t decode_utf8_trailer_byte(char c)
return c & 0x3F;
}
fx_wchar fx_wchar_utf8_codepoint_decode(const char *s)
b_wchar b_wchar_utf8_codepoint_decode(const char *s)
{
fx_wchar result = 0;
b_wchar result = 0;
int len = 0;
if (!(s[0] & 0x80)) {
@@ -1272,29 +1272,29 @@ fx_wchar fx_wchar_utf8_codepoint_decode(const char *s)
result = s[0] & 0x07;
result <<= 18;
} else {
return FX_WCHAR_INVALID;
return B_WCHAR_INVALID;
}
for (int i = 1; i < len; i++) {
int32_t c = decode_utf8_trailer_byte(s[i]);
if (c == -1) {
return FX_WCHAR_INVALID;
return B_WCHAR_INVALID;
}
c <<= 6 * (len - i - 1);
result |= c;
}
if (!fx_wchar_utf8_is_valid_scalar(result)) {
return FX_WCHAR_INVALID;
if (!b_wchar_utf8_is_valid_scalar(result)) {
return B_WCHAR_INVALID;
}
return result;
}
unsigned int fx_wchar_utf8_codepoint_encode(fx_wchar c, char s[4])
unsigned int b_wchar_utf8_codepoint_encode(b_wchar c, char s[4])
{
unsigned int len = fx_wchar_utf8_codepoint_size(c);
unsigned int len = b_wchar_utf8_codepoint_size(c);
switch (len) {
case 1:
@@ -1322,7 +1322,7 @@ unsigned int fx_wchar_utf8_codepoint_encode(fx_wchar c, char s[4])
return len;
}
unsigned int fx_wchar_utf8_codepoint_stride(const char *s)
unsigned int b_wchar_utf8_codepoint_stride(const char *s)
{
char c = *s;
@@ -1345,13 +1345,13 @@ unsigned int fx_wchar_utf8_codepoint_stride(const char *s)
return 0;
}
size_t fx_wchar_utf8_codepoint_count(const char *s, size_t nr_bytes)
size_t b_wchar_utf8_codepoint_count(const char *s, size_t nr_bytes)
{
size_t nr_codepoints = 0;
const char *end = s + nr_bytes;
while (*s && s < end) {
size_t stride = fx_wchar_utf8_codepoint_stride(s);
size_t stride = b_wchar_utf8_codepoint_stride(s);
if (stride == 0) {
/* invalid codepoint */
return 0;
@@ -1364,13 +1364,11 @@ size_t fx_wchar_utf8_codepoint_count(const char *s, size_t nr_bytes)
return nr_codepoints;
}
size_t fx_wchar_utf8_string_encoded_size(
const fx_wchar *s,
size_t nr_codepoints)
size_t b_wchar_utf8_string_encoded_size(const b_wchar *s, size_t nr_codepoints)
{
size_t len = 0;
for (size_t i = 0; i < nr_codepoints; i++) {
size_t l = fx_wchar_utf8_codepoint_size(s[i]);
size_t l = b_wchar_utf8_codepoint_size(s[i]);
if (l == 0) {
/* invalid codepoint */
return 0;
+19 -19
View File
@@ -1,8 +1,8 @@
#include <fx/endian.h>
#include <blue/core/endian.h>
fx_i16 fx_i16_htob(uint16_t v)
b_i16 b_i16_htob(uint16_t v)
{
fx_i16 x;
b_i16 x;
#ifdef BIG_ENDIAN
x.i_uval = v;
@@ -15,9 +15,9 @@ fx_i16 fx_i16_htob(uint16_t v)
return x;
}
fx_i16 fx_i16_htos(uint16_t v)
b_i16 b_i16_htos(uint16_t v)
{
fx_i16 x;
b_i16 x;
#ifdef LITTLE_ENDIAN
x.i_uval = v;
@@ -30,7 +30,7 @@ fx_i16 fx_i16_htos(uint16_t v)
return x;
}
uint16_t fx_i16_btoh(fx_i16 v)
uint16_t b_i16_btoh(b_i16 v)
{
uint16_t x;
@@ -45,7 +45,7 @@ uint16_t fx_i16_btoh(fx_i16 v)
return x;
}
uint16_t fx_i16_stoh(fx_i16 v)
uint16_t b_i16_stoh(b_i16 v)
{
uint16_t x;
@@ -60,9 +60,9 @@ uint16_t fx_i16_stoh(fx_i16 v)
return x;
}
fx_i32 fx_i32_htob(uint32_t v)
b_i32 b_i32_htob(uint32_t v)
{
fx_i32 x;
b_i32 x;
#ifdef BIG_ENDIAN
x.i_uval = v;
@@ -77,9 +77,9 @@ fx_i32 fx_i32_htob(uint32_t v)
return x;
}
fx_i32 fx_i32_htos(uint32_t v)
b_i32 b_i32_htos(uint32_t v)
{
fx_i32 x;
b_i32 x;
#ifdef LITTLE_ENDIAN
x.i_uval = v;
@@ -94,7 +94,7 @@ fx_i32 fx_i32_htos(uint32_t v)
return x;
}
uint32_t fx_i32_btoh(fx_i32 v)
uint32_t b_i32_btoh(b_i32 v)
{
uint32_t x;
@@ -111,7 +111,7 @@ uint32_t fx_i32_btoh(fx_i32 v)
return x;
}
uint32_t fx_i32_stoh(fx_i32 v)
uint32_t b_i32_stoh(b_i32 v)
{
uint32_t x;
@@ -128,9 +128,9 @@ uint32_t fx_i32_stoh(fx_i32 v)
return x;
}
fx_i64 fx_i64_htob(uint64_t v)
b_i64 b_i64_htob(uint64_t v)
{
fx_i64 x;
b_i64 x;
#ifdef BIG_ENDIAN
x.i_uval = v;
@@ -149,9 +149,9 @@ fx_i64 fx_i64_htob(uint64_t v)
return x;
}
fx_i64 fx_i64_htos(uint64_t v)
b_i64 b_i64_htos(uint64_t v)
{
fx_i64 x;
b_i64 x;
#ifdef LITTLE_ENDIAN
x.i_uval = v;
@@ -170,7 +170,7 @@ fx_i64 fx_i64_htos(uint64_t v)
return x;
}
uint64_t fx_i64_btoh(fx_i64 v)
uint64_t b_i64_btoh(b_i64 v)
{
uint64_t x;
@@ -191,7 +191,7 @@ uint64_t fx_i64_btoh(fx_i64 v)
return x;
}
uint64_t fx_i64_stoh(fx_i64 v)
uint64_t b_i64_stoh(b_i64 v)
{
uint64_t x;
+1059
View File
File diff suppressed because it is too large Load Diff
+37
View File
@@ -0,0 +1,37 @@
#ifndef _BLUELIB_ERROR_H_
#define _BLUELIB_ERROR_H_
#include <blue/core/error.h>
#include <blue/core/queue.h>
struct b_error_stack_frame {
b_queue_entry f_entry;
const char *f_file;
unsigned int f_line_number;
const char *f_function;
};
struct b_error_submsg {
b_queue_entry msg_entry;
b_error_submsg_type msg_type;
char *msg_content;
const struct b_error_msg *msg_msg;
struct b_error_template_parameter msg_params[B_ERROR_TEMPLATE_PARAMETER_MAX];
};
struct b_error {
const struct b_error_vendor *err_vendor;
b_error_status_code err_code;
const struct b_error_definition *err_def;
const struct b_error_msg *err_msg;
char *err_description;
struct b_error_template_parameter err_params[B_ERROR_TEMPLATE_PARAMETER_MAX];
struct b_queue err_submsg;
struct b_queue err_stack;
b_queue_entry err_entry;
struct b_error *err_caused_by;
};
#endif
+178
View File
@@ -0,0 +1,178 @@
#include "hash.h"
#include <blue/core/hash.h>
#include <blue/core/rope.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#define FNV1_OFFSET_BASIS 0xcbf29ce484222325
#define FNV1_PRIME 0x100000001b3
extern struct b_hash_function_ops z__b_md4_ops;
extern struct b_hash_function_ops z__b_md5_ops;
extern struct b_hash_function_ops z__b_sha1_ops;
extern struct b_hash_function_ops z__b_sha2_224_ops;
extern struct b_hash_function_ops z__b_sha2_256_ops;
extern struct b_hash_function_ops z__b_sha2_384_ops;
extern struct b_hash_function_ops z__b_sha2_512_ops;
extern struct b_hash_function_ops z__b_sha3_224_ops;
extern struct b_hash_function_ops z__b_sha3_256_ops;
extern struct b_hash_function_ops z__b_sha3_384_ops;
extern struct b_hash_function_ops z__b_sha3_512_ops;
extern struct b_hash_function_ops z__b_shake128_ops;
extern struct b_hash_function_ops z__b_shake256_ops;
static const struct b_hash_function_ops *hash_functions[] = {
[B_HASH_NONE] = NULL,
[B_HASH_MD4] = &z__b_md4_ops,
[B_HASH_MD5] = &z__b_md5_ops,
[B_HASH_SHA1] = &z__b_sha1_ops,
[B_HASH_SHA2_224] = &z__b_sha2_224_ops,
[B_HASH_SHA2_256] = &z__b_sha2_256_ops,
[B_HASH_SHA2_384] = &z__b_sha2_384_ops,
[B_HASH_SHA2_512] = &z__b_sha2_512_ops,
[B_HASH_SHA3_224] = &z__b_sha3_224_ops,
[B_HASH_SHA3_256] = &z__b_sha3_256_ops,
[B_HASH_SHA3_384] = &z__b_sha3_384_ops,
[B_HASH_SHA3_512] = &z__b_sha3_512_ops,
[B_HASH_SHAKE128] = &z__b_shake128_ops,
[B_HASH_SHAKE256] = &z__b_shake256_ops,
};
static const size_t nr_hash_functions
= sizeof hash_functions / sizeof hash_functions[0];
uint64_t b_hash_cstr(const char *s)
{
size_t x = 0;
return b_hash_cstr_ex(s, &x);
}
uint64_t b_hash_cstr_ex(const char *s, size_t *len)
{
uint64_t hash = FNV1_OFFSET_BASIS;
size_t i = 0;
for (i = 0; s[i]; i++) {
hash ^= s[i];
hash *= FNV1_PRIME;
}
if (len) {
*len = i;
}
return hash;
}
enum b_status b_hash_ctx_init(struct b_hash_ctx *ctx, enum b_hash_function func)
{
if (func < 0 || func >= nr_hash_functions) {
return B_ERR_NOT_SUPPORTED;
}
const struct b_hash_function_ops *hash_function = hash_functions[func];
if (!hash_function) {
return B_ERR_NOT_SUPPORTED;
}
memset(ctx, 0x0, sizeof *ctx);
ctx->ctx_func = func;
ctx->ctx_ops = hash_function;
if (hash_function->hash_init) {
hash_function->hash_init(ctx);
}
return B_SUCCESS;
}
enum b_status b_hash_ctx_reset(struct b_hash_ctx *ctx)
{
if (ctx->ctx_func == B_HASH_NONE || !ctx->ctx_ops) {
return B_ERR_BAD_STATE;
}
memset(&ctx->ctx_state, 0x0, sizeof ctx->ctx_state);
if (ctx->ctx_ops->hash_init) {
ctx->ctx_ops->hash_init(ctx);
}
return B_SUCCESS;
}
enum b_status b_hash_ctx_update(struct b_hash_ctx *ctx, const void *p, size_t len)
{
if (!ctx->ctx_ops) {
return B_ERR_BAD_STATE;
}
if (!ctx->ctx_ops->hash_update) {
return B_ERR_NOT_SUPPORTED;
}
ctx->ctx_ops->hash_update(ctx, p, len);
return B_SUCCESS;
}
static void update_rope(const b_rope *rope, void *arg)
{
struct b_hash_ctx *ctx = arg;
unsigned int type = B_ROPE_TYPE(rope->r_flags);
char tmp[64];
size_t len = 0;
switch (type) {
case B_ROPE_F_CHAR:
b_hash_ctx_update(ctx, &rope->r_v.v_char, sizeof rope->r_v.v_char);
break;
case B_ROPE_F_CSTR:
case B_ROPE_F_CSTR_BORROWED:
case B_ROPE_F_CSTR_STATIC:
b_hash_ctx_update(
ctx, rope->r_v.v_cstr.s, strlen(rope->r_v.v_cstr.s));
break;
case B_ROPE_F_INT:
len = snprintf(tmp, sizeof tmp, "%" PRIdPTR, rope->r_v.v_int);
b_hash_ctx_update(ctx, tmp, len);
break;
case B_ROPE_F_UINT:
len = snprintf(tmp, sizeof tmp, "%" PRIuPTR, rope->r_v.v_uint);
b_hash_ctx_update(ctx, tmp, len);
break;
default:
break;
}
}
enum b_status b_hash_ctx_update_rope(
struct b_hash_ctx *ctx, const struct b_rope *rope)
{
b_rope_iterate(rope, update_rope, ctx);
return B_SUCCESS;
}
enum b_status b_hash_ctx_finish(
struct b_hash_ctx *ctx, void *out_digest, size_t out_max)
{
if (!ctx->ctx_ops) {
return B_ERR_BAD_STATE;
}
if (!ctx->ctx_ops->hash_finish) {
return B_ERR_NOT_SUPPORTED;
}
ctx->ctx_ops->hash_finish(ctx, out_digest, out_max);
memset(&ctx->ctx_state, 0x0, sizeof ctx->ctx_state);
if (ctx->ctx_ops->hash_init) {
ctx->ctx_ops->hash_init(ctx);
}
return B_SUCCESS;
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef _HASH_H_
#define _HASH_H_
#include <stddef.h>
struct b_hash_ctx;
struct b_hash_function_ops {
void (*hash_init)(struct b_hash_ctx *);
void (*hash_update)(struct b_hash_ctx *, const void *, size_t);
void (*hash_finish)(struct b_hash_ctx *, void *, size_t);
};
#endif
+6 -9
View File
@@ -36,7 +36,7 @@
*/
#include "hash.h"
#include <fx/hash.h>
#include <blue/core/hash.h>
#include <stdint.h>
#include <string.h>
@@ -88,10 +88,7 @@
* This processes one or more 64-byte data blocks, but does NOT update the bit
* counters. There are no alignment requirements.
*/
static const void *body(
struct fx_hash_ctx *ctx,
const void *data,
unsigned long size)
static const void *body(struct b_hash_ctx *ctx, const void *data, unsigned long size)
{
const unsigned char *ptr;
uint32_t a, b, c, d;
@@ -181,7 +178,7 @@ static const void *body(
return ptr;
}
void md4_init(struct fx_hash_ctx *ctx)
void md4_init(struct b_hash_ctx *ctx)
{
ctx->ctx_state.md4.a = 0x67452301;
ctx->ctx_state.md4.b = 0xefcdab89;
@@ -192,7 +189,7 @@ void md4_init(struct fx_hash_ctx *ctx)
ctx->ctx_state.md4.hi = 0;
}
void md4_update(struct fx_hash_ctx *ctx, const void *data, unsigned long size)
void md4_update(struct b_hash_ctx *ctx, const void *data, unsigned long size)
{
uint32_t saved_lo;
unsigned long used, available;
@@ -232,7 +229,7 @@ void md4_update(struct fx_hash_ctx *ctx, const void *data, unsigned long size)
(dst)[2] = (unsigned char)((src) >> 16); \
(dst)[3] = (unsigned char)((src) >> 24);
void md4_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
void md4_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{
unsigned char *result = out;
unsigned long used, available;
@@ -264,7 +261,7 @@ void md4_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
OUT(&result[12], ctx->ctx_state.md4.d)
}
struct fx_hash_function_ops z__fx_md4_ops = {
struct b_hash_function_ops z__b_md4_ops = {
.hash_init = md4_init,
.hash_update = md4_update,
.hash_finish = md4_finish,
+14 -23
View File
@@ -3,11 +3,11 @@
* and is in the public domain. */
#include "hash.h"
#include <fx/hash.h>
#include <blue/core/hash.h>
#include <memory.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define F(x, y, z) (z ^ (x & (y ^ z)))
#define G(x, y, z) (y ^ (z & (x ^ y)))
@@ -19,7 +19,7 @@
#define STEP(f, a, b, c, d, x, t, s) \
(a += f(b, c, d) + x + t, a = ROTATE_LEFT(a, s), a += b)
void md5_init(struct fx_hash_ctx *ctx)
void md5_init(struct b_hash_ctx *ctx)
{
ctx->ctx_state.md5.a = 0x67452301;
ctx->ctx_state.md5.b = 0xefcdab89;
@@ -30,10 +30,7 @@ void md5_init(struct fx_hash_ctx *ctx)
ctx->ctx_state.md5.count[1] = 0;
}
uint8_t *md5_transform(
struct fx_hash_ctx *ctx,
const void *data,
uintmax_t size)
uint8_t *md5_transform(struct b_hash_ctx *ctx, const void *data, uintmax_t size)
{
uint8_t *ptr = (uint8_t *)data;
uint32_t a, b, c, d, aa, bb, cc, dd;
@@ -143,14 +140,13 @@ uint8_t *md5_transform(
return ptr;
}
void md5_update(struct fx_hash_ctx *ctx, const void *buffer, size_t buffer_size)
void md5_update(struct b_hash_ctx *ctx, const void *buffer, size_t buffer_size)
{
uint32_t saved_low = ctx->ctx_state.md5.count[0];
uint32_t used;
uint32_t free;
if ((ctx->ctx_state.md5.count[0]
= ((saved_low + buffer_size) & 0x1fffffff))
if ((ctx->ctx_state.md5.count[0] = ((saved_low + buffer_size) & 0x1fffffff))
< saved_low) {
ctx->ctx_state.md5.count[1]++;
}
@@ -162,8 +158,7 @@ void md5_update(struct fx_hash_ctx *ctx, const void *buffer, size_t buffer_size)
free = 64 - used;
if (buffer_size < free) {
memcpy(&ctx->ctx_state.md5.input[used],
buffer,
memcpy(&ctx->ctx_state.md5.input[used], buffer,
buffer_size);
return;
}
@@ -176,16 +171,14 @@ void md5_update(struct fx_hash_ctx *ctx, const void *buffer, size_t buffer_size)
if (buffer_size >= 64) {
buffer = md5_transform(
ctx,
buffer,
buffer_size & ~(unsigned long)0x3f);
ctx, buffer, buffer_size & ~(unsigned long)0x3f);
buffer_size = buffer_size % 64;
}
memcpy(ctx->ctx_state.md5.input, buffer, buffer_size);
}
void md5_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
void md5_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{
uint32_t used = ctx->ctx_state.md5.count[0] & 0x3f;
ctx->ctx_state.md5.input[used++] = 0x80;
@@ -200,19 +193,17 @@ void md5_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
memset(&ctx->ctx_state.md5.input[used], 0, free - 8);
unsigned char digest[FX_DIGEST_LENGTH_MD5];
unsigned char digest[B_DIGEST_LENGTH_MD5];
ctx->ctx_state.md5.count[0] <<= 3;
ctx->ctx_state.md5.input[56] = (uint8_t)(ctx->ctx_state.md5.count[0]);
ctx->ctx_state.md5.input[57]
= (uint8_t)(ctx->ctx_state.md5.count[0] >> 8);
ctx->ctx_state.md5.input[57] = (uint8_t)(ctx->ctx_state.md5.count[0] >> 8);
ctx->ctx_state.md5.input[58]
= (uint8_t)(ctx->ctx_state.md5.count[0] >> 16);
ctx->ctx_state.md5.input[59]
= (uint8_t)(ctx->ctx_state.md5.count[0] >> 24);
ctx->ctx_state.md5.input[60] = (uint8_t)(ctx->ctx_state.md5.count[1]);
ctx->ctx_state.md5.input[61]
= (uint8_t)(ctx->ctx_state.md5.count[1] >> 8);
ctx->ctx_state.md5.input[61] = (uint8_t)(ctx->ctx_state.md5.count[1] >> 8);
ctx->ctx_state.md5.input[62]
= (uint8_t)(ctx->ctx_state.md5.count[1] >> 16);
ctx->ctx_state.md5.input[63]
@@ -237,10 +228,10 @@ void md5_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
digest[14] = (uint8_t)(ctx->ctx_state.md5.d >> 16);
digest[15] = (uint8_t)(ctx->ctx_state.md5.d >> 24);
memcpy(out, digest, fx_min(size_t, sizeof digest, max));
memcpy(out, digest, b_min(size_t, sizeof digest, max));
}
struct fx_hash_function_ops z__fx_md5_ops = {
struct b_hash_function_ops z__b_md5_ops = {
.hash_init = md5_init,
.hash_update = md5_update,
.hash_finish = md5_finish,
+14 -16
View File
@@ -19,7 +19,7 @@ A million repetitions of "a"
#include "hash.h"
#include <fx/hash.h>
#include <blue/core/hash.h>
#include <stdio.h>
#include <string.h>
@@ -187,7 +187,7 @@ void SHA1Transform(uint32_t state[5], const unsigned char buffer[64])
/* sha_init - Initialize new context */
static void sha_init(struct fx_hash_ctx *context)
static void sha_init(struct b_hash_ctx *context)
{
/* SHA1 initialization constants */
context->ctx_state.sha1.state[0] = 0x67452301;
@@ -200,7 +200,7 @@ static void sha_init(struct fx_hash_ctx *context)
/* Run your data through this. */
static void sha_update(struct fx_hash_ctx *context, const void *p, size_t len)
static void sha_update(struct b_hash_ctx *context, const void *p, size_t len)
{
const unsigned char *data = p;
uint32_t i, j;
@@ -226,7 +226,7 @@ static void sha_update(struct fx_hash_ctx *context, const void *p, size_t len)
/* Add padding and return the message digest. */
static void sha_finish(struct fx_hash_ctx *context, void *out, size_t max)
static void sha_finish(struct b_hash_ctx *context, void *out, size_t max)
{
unsigned i;
@@ -235,14 +235,13 @@ static void sha_finish(struct fx_hash_ctx *context, void *out, size_t max)
unsigned char c;
for (i = 0; i < 8; i++) {
finalcount[i]
= (unsigned char)((context->ctx_state.sha1
.count[(i >= 4 ? 0 : 1)]
>> ((3 - (i & 3)) * 8))
& 255); /* Endian independent */
finalcount[i] = (unsigned char)((context->ctx_state.sha1
.count[(i >= 4 ? 0 : 1)]
>> ((3 - (i & 3)) * 8))
& 255); /* Endian independent */
}
char digest[FX_DIGEST_LENGTH_SHA1];
char digest[B_DIGEST_LENGTH_SHA1];
c = 0200;
sha_update(context, &c, 1);
while ((context->ctx_state.sha1.count[0] & 504) != 448) {
@@ -251,18 +250,17 @@ static void sha_finish(struct fx_hash_ctx *context, void *out, size_t max)
}
sha_update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++) {
digest[i]
= (unsigned char)((context->ctx_state.sha1.state[i >> 2]
>> ((3 - (i & 3)) * 8))
& 255);
digest[i] = (unsigned char)((context->ctx_state.sha1.state[i >> 2]
>> ((3 - (i & 3)) * 8))
& 255);
}
memcpy(out, digest, fx_min(size_t, sizeof digest, max));
memcpy(out, digest, b_min(size_t, sizeof digest, max));
/* Wipe variables */
memset(&finalcount, '\0', sizeof(finalcount));
}
struct fx_hash_function_ops z__fx_sha1_ops = {
struct b_hash_function_ops z__b_sha1_ops = {
.hash_init = sha_init,
.hash_update = sha_update,
.hash_finish = sha_finish,
+12 -17
View File
@@ -1,19 +1,14 @@
// SHA-224. Adapted from LibTomCrypt. This code is Public Domain
#include "hash.h"
#include <fx/hash.h>
#include <blue/core/hash.h>
#include <string.h>
extern void z__fx_sha2_256_update(
struct fx_hash_ctx *md,
const void *src,
size_t inlen);
extern void z__fx_sha2_256_finish(
struct fx_hash_ctx *md,
void *out,
size_t max);
extern void z__b_sha2_256_update(
struct b_hash_ctx *md, const void *src, size_t inlen);
extern void z__b_sha2_256_finish(struct b_hash_ctx *md, void *out, size_t max);
static void sha_init(struct fx_hash_ctx *md)
static void sha_init(struct b_hash_ctx *md)
{
md->ctx_state.sha2_256.curlen = 0;
md->ctx_state.sha2_256.length = 0;
@@ -27,20 +22,20 @@ static void sha_init(struct fx_hash_ctx *md)
md->ctx_state.sha2_256.state[7] = 0xbefa4fa4UL;
}
static void sha_update(struct fx_hash_ctx *md, const void *in, size_t inlen)
static void sha_update(struct b_hash_ctx *md, const void *in, size_t inlen)
{
z__fx_sha2_256_update(md, in, inlen);
z__b_sha2_256_update(md, in, inlen);
}
static void sha_finish(struct fx_hash_ctx *md, void *out, size_t max)
static void sha_finish(struct b_hash_ctx *md, void *out, size_t max)
{
unsigned char res[FX_DIGEST_LENGTH_SHA2_256];
z__fx_sha2_256_finish(md, res, max);
unsigned char res[B_DIGEST_LENGTH_SHA2_256];
z__b_sha2_256_finish(md, res, max);
/* truncate the digest to 224 bits */
memcpy(out, res, fx_min(size_t, max, FX_DIGEST_LENGTH_224));
memcpy(out, res, b_min(size_t, max, B_DIGEST_LENGTH_224));
}
struct fx_hash_function_ops z__fx_sha2_224_ops = {
struct b_hash_function_ops z__b_sha2_224_ops = {
.hash_init = sha_init,
.hash_update = sha_update,
.hash_finish = sha_finish,
+20 -46
View File
@@ -1,7 +1,7 @@
// SHA-256. Adapted from LibTomCrypt. This code is Public Domain
#include "hash.h"
#include <fx/hash.h>
#include <blue/core/hash.h>
#include <string.h>
static const uint32_t K[64] = {
@@ -77,18 +77,9 @@ static uint32_t Gamma1(uint32_t x)
}
static void RND(
uint32_t *t0,
uint32_t *t1,
uint32_t W[],
uint32_t a,
uint32_t b,
uint32_t c,
uint32_t *d,
uint32_t e,
uint32_t f,
uint32_t g,
uint32_t *h,
uint32_t i)
uint32_t *t0, uint32_t *t1, uint32_t W[], uint32_t a, uint32_t b,
uint32_t c, uint32_t *d, uint32_t e, uint32_t f, uint32_t g,
uint32_t *h, uint32_t i)
{
(*t0) = *h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];
(*t1) = Sigma0(a) + Maj(a, b, c);
@@ -96,7 +87,7 @@ static void RND(
(*h) = *t0 + *t1;
}
static void sha_compress(struct fx_hash_ctx *md, const unsigned char *buf)
static void sha_compress(struct b_hash_ctx *md, const unsigned char *buf)
{
uint32_t S[8], W[64], t0, t1, t;
@@ -110,24 +101,13 @@ static void sha_compress(struct fx_hash_ctx *md, const unsigned char *buf)
// Fill W[16..63]
for (int i = 16; i < 64; i++)
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15])
+ W[i - 16];
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
// Compress
for (int i = 0; i < 64; ++i) {
RND(&t0,
&t1,
W,
S[0],
S[1],
S[2],
&S[3],
S[4],
S[5],
S[6],
&S[7],
i);
RND(&t0, &t1, W, S[0], S[1], S[2], &S[3], S[4], S[5], S[6],
&S[7], i);
t = S[7];
S[7] = S[6];
S[6] = S[5];
@@ -147,7 +127,7 @@ static void sha_compress(struct fx_hash_ctx *md, const unsigned char *buf)
// Public interface
static void sha_init(struct fx_hash_ctx *md)
static void sha_init(struct b_hash_ctx *md)
{
md->ctx_state.sha2_256.curlen = 0;
md->ctx_state.sha2_256.length = 0;
@@ -161,10 +141,7 @@ static void sha_init(struct fx_hash_ctx *md)
md->ctx_state.sha2_256.state[7] = 0x5BE0CD19UL;
}
void z__fx_sha2_256_update(
struct fx_hash_ctx *md,
const void *src,
size_t inlen)
void z__b_sha2_256_update(struct b_hash_ctx *md, const void *src, size_t inlen)
{
const uint32_t block_size = sizeof md->ctx_state.sha2_256.buf;
const unsigned char *in = (const unsigned char *)(src);
@@ -181,8 +158,7 @@ void z__fx_sha2_256_update(
(block_size - md->ctx_state.sha2_256.curlen));
memcpy(md->ctx_state.sha2_256.buf
+ md->ctx_state.sha2_256.curlen,
in,
n);
in, n);
md->ctx_state.sha2_256.curlen += n;
in += n;
inlen -= n;
@@ -195,7 +171,7 @@ void z__fx_sha2_256_update(
}
}
}
void z__fx_sha2_256_finish(struct fx_hash_ctx *md, void *out, size_t max)
void z__b_sha2_256_finish(struct b_hash_ctx *md, void *out, size_t max)
{
// Increase the length of the message
md->ctx_state.sha2_256.length += md->ctx_state.sha2_256.curlen * 8;
@@ -204,13 +180,11 @@ void z__fx_sha2_256_finish(struct fx_hash_ctx *md, void *out, size_t max)
md->ctx_state.sha2_256.buf[md->ctx_state.sha2_256.curlen++]
= (unsigned char)(0x80);
// If the length is currently above 56 bytes we append zeros then
// compress. Then we can fall back to padding zeros and length encoding
// like normal.
// If the length is currently above 56 bytes we append zeros then compress.
// Then we can fall back to padding zeros and length encoding like normal.
if (md->ctx_state.sha2_256.curlen > 56) {
while (md->ctx_state.sha2_256.curlen < 64)
md->ctx_state.sha2_256
.buf[md->ctx_state.sha2_256.curlen++]
md->ctx_state.sha2_256.buf[md->ctx_state.sha2_256.curlen++]
= 0;
sha_compress(md, md->ctx_state.sha2_256.buf);
md->ctx_state.sha2_256.curlen = 0;
@@ -224,18 +198,18 @@ void z__fx_sha2_256_finish(struct fx_hash_ctx *md, void *out, size_t max)
store64(md->ctx_state.sha2_256.length, md->ctx_state.sha2_256.buf + 56);
sha_compress(md, md->ctx_state.sha2_256.buf);
unsigned char digest[FX_DIGEST_LENGTH_SHA2_256];
unsigned char digest[B_DIGEST_LENGTH_SHA2_256];
// Copy output
for (int i = 0; i < 8; i++)
store32(md->ctx_state.sha2_256.state[i],
(unsigned char *)&digest[(4 * i)]);
memcpy(out, digest, fx_min(size_t, sizeof digest, max));
memcpy(out, digest, b_min(size_t, sizeof digest, max));
}
struct fx_hash_function_ops z__fx_sha2_256_ops = {
struct b_hash_function_ops z__b_sha2_256_ops = {
.hash_init = sha_init,
.hash_update = z__fx_sha2_256_update,
.hash_finish = z__fx_sha2_256_finish,
.hash_update = z__b_sha2_256_update,
.hash_finish = z__b_sha2_256_finish,
};
+12 -17
View File
@@ -1,19 +1,14 @@
// SHA-384. Adapted from LibTomCrypt. This code is Public Domain
#include "hash.h"
#include <fx/hash.h>
#include <blue/core/hash.h>
#include <string.h>
extern void z__fx_sha2_512_update(
struct fx_hash_ctx *md,
const void *src,
size_t inlen);
extern void z__fx_sha2_512_finish(
struct fx_hash_ctx *md,
void *out,
size_t max);
extern void z__b_sha2_512_update(
struct b_hash_ctx *md, const void *src, size_t inlen);
extern void z__b_sha2_512_finish(struct b_hash_ctx *md, void *out, size_t max);
void sha_init(struct fx_hash_ctx *md)
void sha_init(struct b_hash_ctx *md)
{
md->ctx_state.sha2_512.curlen = 0;
md->ctx_state.sha2_512.length = 0;
@@ -27,20 +22,20 @@ void sha_init(struct fx_hash_ctx *md)
md->ctx_state.sha2_512.state[7] = 0x47b5481dbefa4fa4ULL;
}
static void sha_update(struct fx_hash_ctx *md, const void *in, size_t inlen)
static void sha_update(struct b_hash_ctx *md, const void *in, size_t inlen)
{
z__fx_sha2_512_update(md, in, inlen);
z__b_sha2_512_update(md, in, inlen);
}
static void sha_finish(struct fx_hash_ctx *md, void *out, size_t max)
static void sha_finish(struct b_hash_ctx *md, void *out, size_t max)
{
unsigned char res[FX_DIGEST_LENGTH_SHA2_512];
z__fx_sha2_512_finish(md, res, max);
unsigned char res[B_DIGEST_LENGTH_SHA2_512];
z__b_sha2_512_finish(md, res, max);
/* truncate the digest to 384 bits */
memcpy(out, res, fx_min(size_t, max, FX_DIGEST_LENGTH_384));
memcpy(out, res, b_min(size_t, max, B_DIGEST_LENGTH_384));
}
struct fx_hash_function_ops z__fx_sha2_384_ops = {
struct b_hash_function_ops z__b_sha2_384_ops = {
.hash_init = sha_init,
.hash_update = sha_update,
.hash_finish = sha_finish,
+36 -134
View File
@@ -1,7 +1,7 @@
// SHA-512. Adapted from LibTomCrypt. This code is Public Domain
#include "hash.h"
#include <fx/hash.h>
#include <blue/core/hash.h>
#include <stdint.h>
#include <string.h>
@@ -86,18 +86,9 @@ static uint64_t Gamma1(uint64_t x)
return Rot(x, 19) ^ Rot(x, 61) ^ Sh(x, 6);
}
static void RND(
uint64_t W[],
uint64_t *t0,
uint64_t *t1,
uint64_t a,
uint64_t b,
uint64_t c,
uint64_t *d,
uint64_t e,
uint64_t f,
uint64_t g,
uint64_t *h,
uint64_t i)
uint64_t W[], uint64_t *t0, uint64_t *t1, uint64_t a, uint64_t b,
uint64_t c, uint64_t *d, uint64_t e, uint64_t f, uint64_t g,
uint64_t *h, uint64_t i)
{
*t0 = *h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];
*t1 = Sigma0(a) + Maj(a, b, c);
@@ -105,7 +96,7 @@ static void RND(
*h = *t0 + *t1;
}
static void sha_compress(struct fx_hash_ctx *md, const unsigned char *buf)
static void sha_compress(struct b_hash_ctx *md, const unsigned char *buf)
{
uint64_t S[8], W[80], t0, t1;
@@ -121,109 +112,28 @@ static void sha_compress(struct fx_hash_ctx *md, const unsigned char *buf)
// Fill W[16..79]
for (int i = 16; i < 80; i++) {
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15])
+ W[i - 16];
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
}
// Compress
for (int i = 0; i < 80; i += 8) {
RND(W,
&t0,
&t1,
S[0],
S[1],
S[2],
&S[3],
S[4],
S[5],
S[6],
&S[7],
i + 0);
RND(W,
&t0,
&t1,
S[7],
S[0],
S[1],
&S[2],
S[3],
S[4],
S[5],
&S[6],
i + 1);
RND(W,
&t0,
&t1,
S[6],
S[7],
S[0],
&S[1],
S[2],
S[3],
S[4],
&S[5],
i + 2);
RND(W,
&t0,
&t1,
S[5],
S[6],
S[7],
&S[0],
S[1],
S[2],
S[3],
&S[4],
i + 3);
RND(W,
&t0,
&t1,
S[4],
S[5],
S[6],
&S[7],
S[0],
S[1],
S[2],
&S[3],
i + 4);
RND(W,
&t0,
&t1,
S[3],
S[4],
S[5],
&S[6],
S[7],
S[0],
S[1],
&S[2],
i + 5);
RND(W,
&t0,
&t1,
S[2],
S[3],
S[4],
&S[5],
S[6],
S[7],
S[0],
&S[1],
i + 6);
RND(W,
&t0,
&t1,
S[1],
S[2],
S[3],
&S[4],
S[5],
S[6],
S[7],
&S[0],
i + 7);
RND(W, &t0, &t1, S[0], S[1], S[2], &S[3], S[4], S[5], S[6],
&S[7], i + 0);
RND(W, &t0, &t1, S[7], S[0], S[1], &S[2], S[3], S[4], S[5],
&S[6], i + 1);
RND(W, &t0, &t1, S[6], S[7], S[0], &S[1], S[2], S[3], S[4],
&S[5], i + 2);
RND(W, &t0, &t1, S[5], S[6], S[7], &S[0], S[1], S[2], S[3],
&S[4], i + 3);
RND(W, &t0, &t1, S[4], S[5], S[6], &S[7], S[0], S[1], S[2],
&S[3], i + 4);
RND(W, &t0, &t1, S[3], S[4], S[5], &S[6], S[7], S[0], S[1],
&S[2], i + 5);
RND(W, &t0, &t1, S[2], S[3], S[4], &S[5], S[6], S[7], S[0],
&S[1], i + 6);
RND(W, &t0, &t1, S[1], S[2], S[3], &S[4], S[5], S[6], S[7],
&S[0], i + 7);
}
// Feedback
@@ -234,7 +144,7 @@ static void sha_compress(struct fx_hash_ctx *md, const unsigned char *buf)
// Public interface
static void sha_init(struct fx_hash_ctx *md)
static void sha_init(struct b_hash_ctx *md)
{
md->ctx_state.sha2_512.curlen = 0;
md->ctx_state.sha2_512.length = 0;
@@ -248,10 +158,7 @@ static void sha_init(struct fx_hash_ctx *md)
md->ctx_state.sha2_512.state[7] = 0x5be0cd19137e2179ULL;
}
void z__fx_sha2_512_update(
struct fx_hash_ctx *md,
const void *src,
size_t inlen)
void z__b_sha2_512_update(struct b_hash_ctx *md, const void *src, size_t inlen)
{
const uint32_t block_size = sizeof md->ctx_state.sha2_512.block;
const unsigned char *in = (const unsigned char *)src;
@@ -268,8 +175,7 @@ void z__fx_sha2_512_update(
(block_size - md->ctx_state.sha2_512.curlen));
memcpy(md->ctx_state.sha2_512.block
+ md->ctx_state.sha2_512.curlen,
in,
n);
in, n);
md->ctx_state.sha2_512.curlen += n;
in += n;
inlen -= n;
@@ -283,7 +189,7 @@ void z__fx_sha2_512_update(
}
}
void z__fx_sha2_512_finish(struct fx_hash_ctx *md, void *out, size_t max)
void z__b_sha2_512_finish(struct b_hash_ctx *md, void *out, size_t max)
{
// Increase the length of the message
md->ctx_state.sha2_512.length += md->ctx_state.sha2_512.curlen * 8ULL;
@@ -291,13 +197,11 @@ void z__fx_sha2_512_finish(struct fx_hash_ctx *md, void *out, size_t max)
// Append the '1' bit
md->ctx_state.sha2_512.block[md->ctx_state.sha2_512.curlen++] = 0x80;
// If the length is currently above 112 bytes we append zeros then
// compress. Then we can fall back to padding zeros and length encoding
// like normal.
// If the length is currently above 112 bytes we append zeros then compress.
// Then we can fall back to padding zeros and length encoding like normal.
if (md->ctx_state.sha2_512.curlen > 112) {
while (md->ctx_state.sha2_512.curlen < 128)
md->ctx_state.sha2_512
.block[md->ctx_state.sha2_512.curlen++]
md->ctx_state.sha2_512.block[md->ctx_state.sha2_512.curlen++]
= 0;
sha_compress(md, md->ctx_state.sha2_512.block);
md->ctx_state.sha2_512.curlen = 0;
@@ -307,16 +211,14 @@ void z__fx_sha2_512_finish(struct fx_hash_ctx *md, void *out, size_t max)
// note: that from 112 to 120 is the 64 MSB of the length. We assume
// that you won't hash 2^64 bits of data... :-)
while (md->ctx_state.sha2_512.curlen < 120) {
md->ctx_state.sha2_512.block[md->ctx_state.sha2_512.curlen++]
= 0;
md->ctx_state.sha2_512.block[md->ctx_state.sha2_512.curlen++] = 0;
}
// Store length
store64(md->ctx_state.sha2_512.length,
md->ctx_state.sha2_512.block + 120);
store64(md->ctx_state.sha2_512.length, md->ctx_state.sha2_512.block + 120);
sha_compress(md, md->ctx_state.sha2_512.block);
unsigned char digest[FX_DIGEST_LENGTH_SHA2_512];
unsigned char digest[B_DIGEST_LENGTH_SHA2_512];
// Copy output
for (int i = 0; i < 8; i++) {
@@ -324,11 +226,11 @@ void z__fx_sha2_512_finish(struct fx_hash_ctx *md, void *out, size_t max)
(unsigned char *)&digest[(8 * i)]);
}
memcpy(out, digest, fx_min(size_t, sizeof digest, max));
memcpy(out, digest, b_min(size_t, sizeof digest, max));
}
struct fx_hash_function_ops z__fx_sha2_512_ops = {
struct b_hash_function_ops z__b_sha2_512_ops = {
.hash_init = sha_init,
.hash_update = z__fx_sha2_512_update,
.hash_finish = z__fx_sha2_512_finish,
.hash_update = z__b_sha2_512_update,
.hash_finish = z__b_sha2_512_finish,
};
+45 -46
View File
@@ -30,8 +30,8 @@
#include "hash.h"
#include <fx/hash.h>
#include <fx/misc.h>
#include <blue/core/hash.h>
#include <blue/core/misc.h>
#include <string.h>
#ifndef KECCAKF_ROUNDS
@@ -108,8 +108,7 @@ void sha3_keccakf(uint64_t st[25])
for (i = 0; i < 5; i++)
bc[i] = st[j + i];
for (i = 0; i < 5; i++)
st[j + i]
^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5];
st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5];
}
// Iota
@@ -135,7 +134,7 @@ void sha3_keccakf(uint64_t st[25])
// Initialize the context for SHA3
int sha3_init(struct fx_hash_ctx *c, int mdlen)
int sha3_init(struct b_hash_ctx *c, int mdlen)
{
int i;
@@ -150,7 +149,7 @@ int sha3_init(struct fx_hash_ctx *c, int mdlen)
// update state with more data
void sha3_update(struct fx_hash_ctx *c, const void *data, size_t len)
void sha3_update(struct b_hash_ctx *c, const void *data, size_t len)
{
size_t i;
int j;
@@ -169,7 +168,7 @@ void sha3_update(struct fx_hash_ctx *c, const void *data, size_t len)
// finalize and output a hash
int sha3_final(void *md, struct fx_hash_ctx *c)
int sha3_final(void *md, struct b_hash_ctx *c)
{
int i;
@@ -188,7 +187,7 @@ int sha3_final(void *md, struct fx_hash_ctx *c)
void *sha3(const void *in, size_t inlen, void *md, int mdlen)
{
struct fx_hash_ctx sha3;
struct b_hash_ctx sha3;
sha3_init(&sha3, mdlen);
sha3_update(&sha3, in, inlen);
@@ -199,7 +198,7 @@ void *sha3(const void *in, size_t inlen, void *md, int mdlen)
// SHAKE128 and SHAKE256 extensible-output functionality
void shake_xof(struct fx_hash_ctx *c)
void shake_xof(struct b_hash_ctx *c)
{
c->ctx_state.sha3.st.b[c->ctx_state.sha3.pt] ^= 0x1F;
c->ctx_state.sha3.st.b[c->ctx_state.sha3.rsiz - 1] ^= 0x80;
@@ -207,7 +206,7 @@ void shake_xof(struct fx_hash_ctx *c)
c->ctx_state.sha3.pt = 0;
}
void shake_out(struct fx_hash_ctx *c, void *out, size_t len)
void shake_out(struct b_hash_ctx *c, void *out, size_t len)
{
size_t i;
int j;
@@ -223,111 +222,111 @@ void shake_out(struct fx_hash_ctx *c, void *out, size_t len)
c->ctx_state.sha3.pt = j;
}
static void sha3_224_init(struct fx_hash_ctx *ctx)
static void sha3_224_init(struct b_hash_ctx *ctx)
{
sha3_init(ctx, FX_DIGEST_LENGTH_SHA3_224);
sha3_init(ctx, B_DIGEST_LENGTH_SHA3_224);
}
static void sha3_224_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
static void sha3_224_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{
unsigned char md[FX_DIGEST_LENGTH_SHA3_224];
unsigned char md[B_DIGEST_LENGTH_SHA3_224];
sha3_final(md, ctx);
memcpy(out, md, fx_min(size_t, sizeof md, max));
memcpy(out, md, b_min(size_t, sizeof md, max));
}
static void sha3_256_init(struct fx_hash_ctx *ctx)
static void sha3_256_init(struct b_hash_ctx *ctx)
{
sha3_init(ctx, FX_DIGEST_LENGTH_SHA3_256);
sha3_init(ctx, B_DIGEST_LENGTH_SHA3_256);
}
static void sha3_256_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
static void sha3_256_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{
unsigned char md[FX_DIGEST_LENGTH_SHA3_256];
unsigned char md[B_DIGEST_LENGTH_SHA3_256];
sha3_final(md, ctx);
memcpy(out, md, fx_min(size_t, sizeof md, max));
memcpy(out, md, b_min(size_t, sizeof md, max));
}
static void sha3_384_init(struct fx_hash_ctx *ctx)
static void sha3_384_init(struct b_hash_ctx *ctx)
{
sha3_init(ctx, FX_DIGEST_LENGTH_SHA3_384);
sha3_init(ctx, B_DIGEST_LENGTH_SHA3_384);
}
static void sha3_384_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
static void sha3_384_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{
unsigned char md[FX_DIGEST_LENGTH_SHA3_384];
unsigned char md[B_DIGEST_LENGTH_SHA3_384];
sha3_final(md, ctx);
memcpy(out, md, fx_min(size_t, sizeof md, max));
memcpy(out, md, b_min(size_t, sizeof md, max));
}
static void sha3_512_init(struct fx_hash_ctx *ctx)
static void sha3_512_init(struct b_hash_ctx *ctx)
{
sha3_init(ctx, FX_DIGEST_LENGTH_SHA3_512);
sha3_init(ctx, B_DIGEST_LENGTH_SHA3_512);
}
static void sha3_512_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
static void sha3_512_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{
unsigned char md[FX_DIGEST_LENGTH_SHA3_512];
unsigned char md[B_DIGEST_LENGTH_SHA3_512];
sha3_final(md, ctx);
memcpy(out, md, fx_min(size_t, sizeof md, max));
memcpy(out, md, b_min(size_t, sizeof md, max));
}
static void shake128_init(struct fx_hash_ctx *ctx)
static void shake128_init(struct b_hash_ctx *ctx)
{
sha3_init(ctx, FX_DIGEST_LENGTH_SHAKE128);
sha3_init(ctx, B_DIGEST_LENGTH_SHAKE128);
}
static void shake128_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
static void shake128_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{
unsigned char md[FX_DIGEST_LENGTH_SHAKE128];
unsigned char md[B_DIGEST_LENGTH_SHAKE128];
shake_xof(ctx);
shake_out(ctx, md, sizeof md);
memcpy(out, md, fx_min(size_t, sizeof md, max));
memcpy(out, md, b_min(size_t, sizeof md, max));
}
static void shake256_init(struct fx_hash_ctx *ctx)
static void shake256_init(struct b_hash_ctx *ctx)
{
sha3_init(ctx, FX_DIGEST_LENGTH_SHAKE256);
sha3_init(ctx, B_DIGEST_LENGTH_SHAKE256);
}
static void shake256_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
static void shake256_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{
unsigned char md[FX_DIGEST_LENGTH_SHAKE256];
unsigned char md[B_DIGEST_LENGTH_SHAKE256];
shake_xof(ctx);
shake_out(ctx, md, sizeof md);
memcpy(out, md, fx_min(size_t, sizeof md, max));
memcpy(out, md, b_min(size_t, sizeof md, max));
}
struct fx_hash_function_ops z__fx_sha3_224_ops = {
struct b_hash_function_ops z__b_sha3_224_ops = {
.hash_init = sha3_224_init,
.hash_update = sha3_update,
.hash_finish = sha3_224_finish,
};
struct fx_hash_function_ops z__fx_sha3_256_ops = {
struct b_hash_function_ops z__b_sha3_256_ops = {
.hash_init = sha3_256_init,
.hash_update = sha3_update,
.hash_finish = sha3_256_finish,
};
struct fx_hash_function_ops z__fx_sha3_384_ops = {
struct b_hash_function_ops z__b_sha3_384_ops = {
.hash_init = sha3_384_init,
.hash_update = sha3_update,
.hash_finish = sha3_384_finish,
};
struct fx_hash_function_ops z__fx_sha3_512_ops = {
struct b_hash_function_ops z__b_sha3_512_ops = {
.hash_init = sha3_512_init,
.hash_update = sha3_update,
.hash_finish = sha3_512_finish,
};
struct fx_hash_function_ops z__fx_shake128_ops = {
struct b_hash_function_ops z__b_shake128_ops = {
.hash_init = shake128_init,
.hash_update = sha3_update,
.hash_finish = shake128_finish,
};
struct fx_hash_function_ops z__fx_shake256_ops = {
struct b_hash_function_ops z__b_shake256_ops = {
.hash_init = shake256_init,
.hash_update = sha3_update,
.hash_finish = shake256_finish,
+21
View File
@@ -0,0 +1,21 @@
#ifndef BLUELIB_CORE_BITOP_H_
#define BLUELIB_CORE_BITOP_H_
#include <blue/core/misc.h>
BLUE_API int b_popcountl(long v);
BLUE_API int b_ctzl(long v);
BLUE_API int b_clzl(long v);
#if defined(__GNUC__) || defined(__clang__)
#define b_cmpxchg(v, expected_val, new_val) \
__atomic_compare_exchange_n( \
v, expected_val, new_val, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED)
#elif defined(_MSC_VER)
/* TODO add MSVC support */
#error MSVC intrinsics not yet supported
#else
#error Unsupported compiler
#endif
#endif
+71
View File
@@ -0,0 +1,71 @@
#ifndef BLUE_CORE_BSTR_H_
#define BLUE_CORE_BSTR_H_
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <stdarg.h>
#include <stddef.h>
#define B_BSTR_MAGIC 0x5005500550055005ULL
struct b_rope;
enum b_bstr_flags {
B_BSTR_F_NONE = 0x00u,
B_BSTR_F_ALLOC = 0x01u,
};
typedef struct b_bstr {
uint64_t bstr_magic;
enum b_bstr_flags bstr_flags;
char *bstr_buf;
/* total number of characters in bstr_buf, not including null terminator */
size_t bstr_len;
/* number of bytes allocated for bstr_buf (includes space for the null
* terminator) */
size_t bstr_capacity;
int *bstr_istack;
int bstr_add_indent;
size_t bstr_istack_ptr, bstr_istack_size;
} b_bstr;
BLUE_API void b_bstr_begin(b_bstr *strv, char *buf, size_t max);
BLUE_API void b_bstr_begin_dynamic(b_bstr *strv);
BLUE_API char *b_bstr_end(b_bstr *strv);
BLUE_API b_status b_bstr_reserve(b_bstr *strv, size_t len);
static inline size_t b_bstr_get_size(const b_bstr *str)
{
return str->bstr_len;
}
static inline size_t b_bstr_get_capacity(const b_bstr *str)
{
return str->bstr_capacity;
}
BLUE_API b_status b_bstr_push_indent(b_bstr *strv, int indent);
BLUE_API b_status b_bstr_pop_indent(b_bstr *strv);
BLUE_API b_status b_bstr_write_char(b_bstr *strv, char c);
BLUE_API b_status b_bstr_write_chars(
b_bstr *strv, const char *cs, size_t len, size_t *nr_written);
BLUE_API b_status b_bstr_write_cstr(
b_bstr *strv, const char *str, size_t *nr_written);
BLUE_API b_status b_bstr_write_cstr_list(
b_bstr *strv, const char **strs, size_t *nr_written);
BLUE_API b_status b_bstr_write_cstr_array(
b_bstr *strv, const char **strs, size_t count, size_t *nr_written);
BLUE_API b_status b_bstr_write_cstr_varg(b_bstr *strv, size_t *nr_written, ...);
BLUE_API b_status b_bstr_write_rope(
b_bstr *strv, const struct b_rope *rope, size_t *nr_written);
BLUE_API b_status b_bstr_write_fmt(
b_bstr *strv, size_t *nr_written, const char *format, ...);
BLUE_API b_status b_bstr_write_vfmt(
b_bstr *strv, size_t *nr_written, const char *format, va_list arg);
BLUE_API char *b_bstr_rope(const struct b_rope *rope, size_t *nr_written);
BLUE_API char *b_bstr_fmt(size_t *nr_written, const char *format, ...);
BLUE_API char *b_bstr_vfmt(size_t *nr_written, const char *format, va_list arg);
#endif
+359
View File
@@ -0,0 +1,359 @@
#ifndef BLUELIB_CORE_BTREE_H_
#define BLUELIB_CORE_BTREE_H_
#include <blue/core/iterator.h>
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
B_DECLS_BEGIN;
#define B_BTREE_INIT {0}
#define B_TYPE_BTREE_ITERATOR (b_btree_iterator_get_type())
B_DECLARE_TYPE(b_btree_iterator);
B_TYPE_CLASS_DECLARATION_BEGIN(b_btree_iterator)
B_TYPE_CLASS_DECLARATION_END(b_btree_iterator)
/* defines a simple node insertion function.
this function assumes that your nodes have simple integer keys that can be
compared with the usual operators.
EXAMPLE:
if you have a tree node type like this:
struct my_tree_node {
int key;
b_btree_node base;
}
You would use the following call to generate an insert function for a tree
with this node type:
BTREE_DEFINE_SIMPLE_INSERT(
struct my_tree_node,
base,
key,
my_tree_node_insert);
Which would emit a function defined like:
static void my_tree_node_insert(b_btree *tree, struct my_tree_node *node);
@param node_type your custom tree node type. usually a structure that
contains a b_btree_node member.
@param container_node_member the name of the b_btree_node member variable
within your custom type.
@param container_key_member the name of the key member variable within your
custom type.
@param function_name the name of the function to generate.
*/
#define B_BTREE_DEFINE_SIMPLE_INSERT( \
node_type, container_node_member, container_key_member, function_name) \
void function_name(b_btree *tree, node_type *node) \
{ \
if (!tree->b_root) { \
tree->b_root = &node->container_node_member; \
b_btree_insert_fixup(tree, &node->container_node_member); \
return; \
} \
\
b_btree_node *cur = tree->b_root; \
while (1) { \
node_type *cur_node = b_unbox( \
node_type, cur, container_node_member); \
b_btree_node *next = NULL; \
\
if (node->container_key_member \
>= cur_node->container_key_member) { \
next = b_btree_right(cur); \
\
if (!next) { \
b_btree_put_right( \
cur, \
&node->container_node_member); \
break; \
} \
} else if ( \
node->container_key_member \
< cur_node->container_key_member) { \
next = b_btree_left(cur); \
\
if (!next) { \
b_btree_put_left( \
cur, \
&node->container_node_member); \
break; \
} \
} \
\
cur = next; \
} \
\
b_btree_insert_fixup(tree, &node->container_node_member); \
}
/* defines a node insertion function.
this function should be used for trees with complex node keys that cannot be
directly compared. a comparator for your keys must be supplied.
EXAMPLE:
if you have a tree node type like this:
struct my_tree_node {
complex_key_t key;
b_btree_node base;
}
You would need to define a comparator function or macro with the following
signature:
int my_comparator(struct my_tree_node *a, struct my_tree_node *b);
Which implements the following:
return -1 if a < b
return 0 if a == b
return 1 if a > b
You would use the following call to generate an insert function for a tree
with this node type:
BTREE_DEFINE_INSERT(struct my_tree_node, base, key, my_tree_node_insert,
my_comparator);
Which would emit a function defined like:
static void my_tree_node_insert(b_btree *tree, struct my_tree_node *node);
@param node_type your custom tree node type. usually a structure that
contains a b_btree_node member.
@param container_node_member the name of the b_btree_node member variable
within your custom type.
@param container_key_member the name of the key member variable within your
custom type.
@param function_name the name of the function to generate.
@param comparator the name of a comparator function or functional-macro that
conforms to the requirements listed above.
*/
#define B_BTREE_DEFINE_INSERT( \
node_type, container_node_member, container_key_member, function_name, \
comparator) \
void function_name(b_btree *tree, node_type *node) \
{ \
if (!tree->b_root) { \
tree->b_root = &node->container_node_member; \
b_btree_insert_fixup(tree, &node->container_node_member); \
return; \
} \
\
b_btree_node *cur = tree->b_root; \
while (1) { \
node_type *cur_node = b_unbox( \
node_type, cur, container_node_member); \
b_btree_node *next = NULL; \
int cmp = comparator(node, cur_node); \
\
if (cmp >= 0) { \
next = b_btree_right(cur); \
\
if (!next) { \
b_btree_put_right( \
cur, \
&node->container_node_member); \
break; \
} \
} else if (cmp < 0) { \
next = b_btree_left(cur); \
\
if (!next) { \
b_btree_put_left( \
cur, \
&node->container_node_member); \
break; \
} \
} else { \
return; \
} \
\
cur = next; \
} \
\
b_btree_insert_fixup(tree, &node->container_node_member); \
}
/* defines a simple tree search function.
this function assumes that your nodes have simple integer keys that can be
compared with the usual operators.
EXAMPLE:
if you have a tree node type like this:
struct my_tree_node {
int key;
b_btree_node base;
}
You would use the following call to generate a search function for a tree
with this node type:
BTREE_DEFINE_SIMPLE_GET(struct my_tree_node, int, base, key,
my_tree_node_get);
Which would emit a function defined like:
static struct my_tree_node *my_tree_node_get(b_btree *tree, int key);
@param node_type your custom tree node type. usually a structure that
contains a b_btree_node member.
@param key_type the type name of the key embedded in your custom tree node
type. this type must be compatible with the builtin comparison operators.
@param container_node_member the name of the b_btree_node member variable
within your custom type.
@param container_key_member the name of the key member variable within your
custom type.
@param function_name the name of the function to generate.
*/
#define B_BTREE_DEFINE_SIMPLE_GET( \
node_type, key_type, container_node_member, container_key_member, \
function_name) \
node_type *function_name(const b_btree *tree, key_type key) \
{ \
b_btree_node *cur = tree->b_root; \
while (cur) { \
node_type *cur_node = b_unbox( \
node_type, cur, container_node_member); \
if (key > cur_node->container_key_member) { \
cur = b_btree_right(cur); \
} else if (key < cur_node->container_key_member) { \
cur = b_btree_left(cur); \
} else { \
return cur_node; \
} \
} \
\
return NULL; \
}
#define b_btree_foreach(it, btree) \
for (int z__b_unique_name() = b_btree_iterator_begin(btree, it); \
(it)->node != NULL; b_btree_iterator_next(it))
/* binary tree nodes. this *cannot* be used directly. you need to define a
custom node type that contains a member variable of type b_btree_node.
you would then use the supplied macros to define functions to manipulate your
custom binary tree.
*/
typedef struct b_btree_node {
struct b_btree_node *b_parent, *b_left, *b_right;
unsigned short b_height;
} b_btree_node;
/* binary tree. unlike b_btree_node, you can define variables of type b_btree.
*/
typedef struct b_btree {
b_btree_node *b_root;
} b_btree;
BLUE_API b_type b_btree_iterator_get_type(void);
/* re-balance a binary tree after an insertion operation.
NOTE that, if you define an insertion function using BTREE_DEFINE_INSERT or
similar, this function will automatically called for you.
@param tree the tree to re-balance.
@param node the node that was just inserted into the tree.
*/
BLUE_API void b_btree_insert_fixup(b_btree *tree, b_btree_node *node);
/* delete a node from a binary tree and re-balance the tree afterwards.
@param tree the tree to delete from
@param node the node to delete.
*/
BLUE_API void b_btree_delete(b_btree *tree, b_btree_node *node);
/* get the first node in a binary tree.
this will be the node with the smallest key (i.e. the node that is
furthest-left from the root)
*/
BLUE_API b_btree_node *b_btree_first(const b_btree *tree);
/* get the last node in a binary tree.
this will be the node with the largest key (i.e. the node that is
furthest-right from the root)
*/
BLUE_API b_btree_node *b_btree_last(const b_btree *tree);
/* for any binary tree node, this function returns the node with the
* next-largest key value */
BLUE_API b_btree_node *b_btree_next(const b_btree_node *node);
/* for any binary tree node, this function returns the node with the
* next-smallest key value */
BLUE_API b_btree_node *b_btree_prev(const b_btree_node *node);
/* return true if the btree is empty, false otherwise */
static inline bool b_btree_empty(const b_btree *tree)
{
return tree->b_root == NULL;
}
/* sets `child` as the immediate left-child of `parent` */
static inline void b_btree_put_left(b_btree_node *parent, b_btree_node *child)
{
parent->b_left = child;
child->b_parent = parent;
}
/* sets `child` as the immediate right-child of `parent` */
static inline void b_btree_put_right(b_btree_node *parent, b_btree_node *child)
{
parent->b_right = child;
child->b_parent = parent;
}
/* get the immediate left-child of `node` */
static inline b_btree_node *b_btree_left(b_btree_node *node)
{
return node->b_left;
}
/* get the immediate right-child of `node` */
static inline b_btree_node *b_btree_right(b_btree_node *node)
{
return node->b_right;
}
/* get the immediate parent of `node` */
static inline b_btree_node *b_btree_parent(b_btree_node *node)
{
return node->b_parent;
}
BLUE_API void b_btree_move(b_btree *tree, b_btree_node *dest, b_btree_node *src);
/* get the height of `node`.
the height of a node is defined as the length of the longest path
between the node and a leaf node.
this count includes the node itself, so the height of a leaf node will be 1.
*/
static inline unsigned short b_btree_height(b_btree_node *node)
{
return node->b_height;
}
BLUE_API b_iterator *b_btree_begin(b_btree *tree);
BLUE_API const b_iterator *b_btree_cbegin(const b_btree *tree);
#ifdef __cplusplus
}
#endif
#endif
+15
View File
@@ -0,0 +1,15 @@
#ifndef BLUE_OBJECT_CLASS_H_
#define BLUE_OBJECT_CLASS_H_
#include <blue/core/type.h>
#define B_CLASS_MAGIC 0xDEADFACEDCAFEBEDULL
#define B_CLASS(p) ((b_class *)(p))
typedef struct _b_class b_class;
BLUE_API void *b_class_get(b_type id);
BLUE_API const char *b_class_get_name(const b_class *c);
BLUE_API void *b_class_get_interface(const b_class *c, b_type id);
#endif
+45
View File
@@ -0,0 +1,45 @@
#ifndef BLUE_CORE_ENCODING_H_
#define BLUE_CORE_ENCODING_H_
#include <blue/core/misc.h>
#include <stdbool.h>
#include <stdint.h>
B_DECLS_BEGIN;
#define B_WCHAR_INVALID ((b_wchar) - 1)
typedef int32_t b_wchar;
BLUE_API bool b_wchar_is_alpha(b_wchar c);
BLUE_API bool b_wchar_is_number(b_wchar c);
static inline bool b_wchar_is_bin_digit(b_wchar c)
{
return c >= '0' && c <= '1';
}
static inline bool b_wchar_is_oct_digit(b_wchar c)
{
return c >= '0' && c <= '7';
}
BLUE_API bool b_wchar_is_hex_digit(b_wchar c);
BLUE_API bool b_wchar_is_space(b_wchar c);
static inline bool b_wchar_is_alnum(b_wchar c)
{
return b_wchar_is_alpha(c) || b_wchar_is_number(c);
}
BLUE_API bool b_wchar_is_punct(b_wchar c);
BLUE_API bool b_wchar_utf8_is_valid_scalar(b_wchar c);
BLUE_API unsigned int b_wchar_utf8_header_decode(char c);
BLUE_API unsigned int b_wchar_utf8_codepoint_size(b_wchar c);
BLUE_API b_wchar b_wchar_utf8_codepoint_decode(const char *s);
BLUE_API unsigned int b_wchar_utf8_codepoint_encode(b_wchar c, char s[4]);
BLUE_API unsigned int b_wchar_utf8_codepoint_stride(const char *s);
BLUE_API size_t b_wchar_utf8_codepoint_count(const char *s, size_t nr_bytes);
BLUE_API size_t b_wchar_utf8_string_encoded_size(
const b_wchar *s, size_t nr_codepoints);
B_DECLS_END;
#endif
+49
View File
@@ -0,0 +1,49 @@
#ifndef BLUELIB_CORE_ENDIAN_H_
#define BLUELIB_CORE_ENDIAN_H_
#include <blue/core/misc.h>
#include <stdint.h>
typedef struct {
union {
unsigned char i_bytes[sizeof(uint16_t)];
int16_t i_val;
uint16_t i_uval;
};
} b_i16;
typedef struct {
union {
unsigned char i_bytes[sizeof(uint32_t)];
int32_t i_val;
uint32_t i_uval;
};
} b_i32;
typedef struct {
union {
unsigned char i_bytes[sizeof(uint64_t)];
int64_t i_val;
uint64_t i_uval;
};
} b_i64;
BLUE_API b_i16 b_i16_htob(uint16_t v);
BLUE_API b_i16 b_i16_htos(uint16_t v);
BLUE_API uint16_t b_i16_btoh(b_i16 v);
BLUE_API uint16_t b_i16_stoh(b_i16 v);
BLUE_API b_i32 b_i32_htob(uint32_t v);
BLUE_API b_i32 b_i32_htos(uint32_t v);
BLUE_API uint32_t b_i32_btoh(b_i32 v);
BLUE_API uint32_t b_i32_stoh(b_i32 v);
BLUE_API b_i64 b_i64_htob(uint64_t v);
BLUE_API b_i64 b_i64_htos(uint64_t v);
BLUE_API uint64_t b_i64_btoh(b_i64 v);
BLUE_API uint64_t b_i64_stoh(b_i64 v);
#endif
+418
View File
@@ -0,0 +1,418 @@
#ifndef BLUE_CORE_ERROR_H_
#define BLUE_CORE_ERROR_H_
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <stdarg.h>
#include <stdbool.h>
#define B_ERROR_TEMPLATE_PARAMETER_MAX 4
#define B_ERROR_MSG_ID_INVALID ((unsigned long)-1)
#define B_CATCH(err, expr) ((err = (expr)) != NULL)
#define b_result_is_error(result) ((result) != NULL)
#define b_result_is_success(result) ((result) == NULL)
#define B_RESULT_SUCCESS ((b_result)NULL)
#define B_RESULT_ERR(err_name) \
b_error_with_code(b_error_vendor_get_builtin(), B_ERR_##err_name)
#define B_RESULT_ERR_WITH_STRING(err_name, ...) \
b_error_with_string( \
b_error_vendor_get_builtin(), B_ERR_##err_name, __VA_ARGS__)
#define B_RESULT_STATUS(code) \
((code) == B_SUCCESS \
? B_RESULT_SUCCESS \
: (b_error_with_code(b_error_vendor_get_builtin(), code)))
#define B_RESULT_STATUS_WITH_STRING(code, ...) \
((code) == B_SUCCESS \
? B_RESULT_SUCCESS \
: (b_error_with_string( \
b_error_vendor_get_builtin(), code, __VA_ARGS__)))
#define B_ERRORS_BUILTIN (b_error_vendor_get_builtin())
#define B_ERRORS_ERRNO (b_error_vendor_get_errno())
#define B_ERROR_PARAM(name, value) \
(b_error_template_parameter) \
{ \
.param_name = (name), .param_value = (uintptr_t)(value), \
}
#define B_ERROR_TEMPLATE_PARAM(name, type, format) \
(b_error_template_parameter_definition) \
{ \
.param_name = (name), .param_type = (type), \
.param_format = (format), \
}
#define B_ERROR_DEFINITION(code, name, msg) \
[code] = (b_error_definition) \
{ \
.err_name = (name), .err_message = (msg), \
}
#define B_ERROR_DEFINITION_TEMPLATE(code, name, msg, ...) \
[code] = (b_error_definition) \
{ \
.err_name = (name), .err_message = (msg), \
.err_params = __VA_ARGS__, \
}
#define B_ERROR_MSG(id, content) \
[id] = (b_error_msg) \
{ \
.msg_message = (content), \
}
#define B_ERROR_MSG_TEMPLATE(id, content, ...) \
[id] = (b_error_msg) \
{ \
.msg_message = (content), .msg_params = __VA_ARGS__, \
}
#define z__b_error_create_status(status_code) \
(z__b_error_create( \
b_error_vendor_get_builtin(), status_code, NULL, NULL, 0, \
NULL, NULL))
/* Error creation macros */
#define b_error_with_code(vendor, code) \
(z__b_error_create( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, NULL))
#define b_error_caused_by_error(vendor, code, cause_error) \
(z__b_error_create( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, NULL))
#define b_error_caused_by_status(vendor, code, cause_status) \
(z__b_error_create( \
vendor, code, z__b_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, NULL))
#define b_error_caused_by_code(vendor, code, cause_vendor, cause_code) \
(z__b_error_create( \
vendor, code, b_error_with_code(cause_vendor, cause_code), \
__FILE__, __LINE__, __FUNCTION__, NULL))
#define b_error_with_string(vendor, code, ...) \
(z__b_error_create( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__))
#define b_error_with_string_caused_by_error(vendor, code, cause_error, ...) \
(z__b_error_create( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, \
__VA_ARGS__))
#define b_error_with_string_caused_by_status(vendor, code, cause_status, ...) \
(z__b_error_create( \
vendor, code, z__b_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__))
#define b_error_with_msg(vendor, code, msg_id) \
(z__b_error_create_msg( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, msg_id, \
(b_error_template_parameter[]) {{}}))
#define b_error_with_msg_caused_by_error(vendor, code, cause_error, msg_id) \
(z__b_error_create_msg( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, \
msg_id, (b_error_template_parameter[]) {{}}))
#define b_error_with_msg_caused_by_status(vendor, code, cause_status, msg_id) \
(z__b_error_create_msg( \
vendor, code, z__b_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, msg_id, \
(b_error_template_parameter[]) {{}}))
#define b_error_with_msg_template(vendor, code, msg_id, ...) \
(z__b_error_create_msg( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, msg_id, \
(b_error_template_parameter[]) {__VA_ARGS__, {}}))
#define b_error_with_msg_template_caused_by_error( \
vendor, code, cause_error, msg_id, ...) \
(z__b_error_create_msg( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, \
msg_id, (b_error_template_parameter[]) {__VA_ARGS__, {}}))
#define b_error_with_msg_template_caused_by_status( \
vendor, code, cause_status, msg_id, ...) \
(z__b_error_create_msg( \
vendor, code, z__b_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, msg_id, \
(b_error_template_parameter[]) {__VA_ARGS__, {}}))
#define b_error_with_template(vendor, code, ...) \
(z__b_error_create_template( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, \
(b_error_template_parameter[]) {__VA_ARGS__, {}}))
#define b_error_with_template_caused_by_error(vendor, code, cause_error, ...) \
(z__b_error_create_template( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, \
(b_error_template_parameter[]) {__VA_ARGS__, {}}))
#define b_error_with_template_caused_by_status(vendor, code, cause_status, ...) \
(z__b_error_create_template( \
vendor, code, z__b_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, \
(b_error_template_parameter[]) {__VA_ARGS__, {}}))
/* Error propagation macros */
#define b_result_propagate(err) \
(z__b_error_propagate(err, __FILE__, __LINE__, __FUNCTION__))
#define b_error_caused_by(err, caused_by) (z__b_error_caused_by(err, caused_by))
#define b_error_caused_by_b_status(err, status) \
(z__b_error_caused_by_b_status(err, status))
#define b_error_replace(err, caused_by) \
(z__b_error_propagate(err, __FILE__, __LINE__, __FUNCTION__))
/* Error throw macros */
#define z__b_throw(err) (z__b_error_throw(err, NULL, 0, NULL))
#define b_throw(err) (z__b_error_throw(err, __FILE__, __LINE__, __FUNCTION__))
#define b_throw_status(status) \
(z__b_error_throw( \
z__b_error_create( \
b_error_vendor_get_builtin(), status, NULL, NULL, 0, \
NULL, NULL), \
__FILE__, __LINE__, __FUNCTION__))
#define b_throw_status_string(status, ...) \
(z__b_error_throw( \
z__b_error_create( \
b_error_vendor_get_builtin(), status, NULL, NULL, 0, \
NULL, __VA_ARGS__), \
__FILE__, __LINE__, __FUNCTION__))
#define b_throw_error_code(vendor, code) \
z__b_throw(b_error_with_code(vendor, code))
#define b_throw_error_caused_by_error(vendor, code, cause) \
z__b_throw(b_error_caused_by_error(vendor, code, cause))
#define b_throw_error_caused_by_status(vendor, code, cause) \
z__b_throw(b_error_caused_by_status(vendor, code, cause))
#define b_throw_error_with_string(vendor, code, ...) \
z__b_throw(b_error_with_string(vendor, code, __VA_ARGS__))
#define b_throw_error_with_string_caused_by_error(vendor, code, cause, ...) \
z__b_throw(b_error_with_string_caused_by_error( \
vendor, code, cause, __VA_ARGS__))
#define b_throw_error_with_string_caused_by_status(vendor, code, cause, ...) \
z__b_throw(b_error_with_string_caused_by_status( \
vendor, code, cause, __VA_ARGS__))
#define b_throw_error_with_msg(vendor, code, msg_id) \
z__b_throw(b_error_with_msg(vendor, code, msg_id))
#define b_throw_error_with_msg_caused_by_error(vendor, code, cause, msg_id) \
z__b_throw(b_error_with_msg_caused_by_error(vendor, code, cause, msg_id))
#define b_throw_error_with_msg_caused_by_status(vendor, code, cause, msg_id) \
z__b_throw(b_error_with_msg_caused_by_status(vendor, code, cause, msg_id))
#define b_throw_error_with_msg_template(vendor, code, msg_id, ...) \
z__b_throw(b_error_with_msg_template(vendor, code, msg_id, __VA_ARGS__))
#define b_throw_error_with_msg_template_caused_by_error( \
vendor, code, cause, msg_id, ...) \
z__b_throw(b_error_with_msg_template_caused_by_error( \
vendor, code, cause, msg_id, __VA_ARGS__))
#define b_throw_error_with_msg_template_caused_by_status( \
vendor, code, cause, msg_id, ...) \
z__b_throw(b_error_with_msg_template_caused_by_status( \
vendor, code, cause, msg_id, __VA_ARGS__))
#define b_throw_error_with_template(vendor, code, ...) \
z__b_throw(b_error_with_template(vendor, code, __VA_ARGS__))
#define b_throw_error_with_template_caused_by_error(vendor, code, cause, ...) \
z__b_throw(b_error_with_template_caused_by_error( \
vendor, code, cause, __VA_ARGS__))
#define b_throw_error_with_template_caused_by_status(vendor, code, cause, ...) \
z__b_throw(b_error_with_template_caused_by_status( \
vendor, code, cause, __VA_ARGS__))
#define B_ERR_MSG(s) \
{ \
.msg_type = B_ERROR_MESSAGE_ERROR, \
.msg_content = (s), \
}
#define B_ERR_MSG_WARN(s) \
{ \
.msg_type = B_ERROR_MESSAGE_WARN, \
.msg_content = (s), \
}
#define B_ERR_MSG_INFO(s) \
{ \
.msg_type = B_ERROR_MESSAGE_INFO, \
.msg_content = (s), \
}
#define B_ERR_MSG_END(s) \
{ \
.msg_type = B_ERROR_MESSAGE_NONE, \
.msg_content = NULL, \
}
typedef enum b_error_submsg_type {
B_ERROR_SUBMSG_NONE = 0,
B_ERROR_SUBMSG_ERROR,
B_ERROR_SUBMSG_WARNING,
B_ERROR_SUBMSG_INFO,
} b_error_submsg_type;
typedef enum b_error_report_flags {
B_ERROR_REPORT_NONE = 0,
B_ERROR_REPORT_STATUS = 0x01u,
B_ERROR_REPORT_DESCRIPTION = 0x02u,
B_ERROR_REPORT_SUBMSG = 0x04u,
B_ERROR_REPORT_STACK_TRACE = 0x08u,
B_ERROR_REPORT_CAUSE = 0x10u,
B_ERROR_REPORT_MINIMAL = B_ERROR_REPORT_STATUS | B_ERROR_REPORT_DESCRIPTION,
B_ERROR_REPORT_DEFAULT = B_ERROR_REPORT_MINIMAL | B_ERROR_REPORT_SUBMSG
| B_ERROR_REPORT_CAUSE,
B_ERROR_REPORT_ALL = B_ERROR_REPORT_DEFAULT | B_ERROR_REPORT_STACK_TRACE,
} b_error_report_flags;
typedef enum b_error_template_parameter_type {
B_ERROR_TEMPLATE_PARAM_NONE = 0,
B_ERROR_TEMPLATE_PARAM_STRING,
B_ERROR_TEMPLATE_PARAM_CHAR,
B_ERROR_TEMPLATE_PARAM_INT,
B_ERROR_TEMPLATE_PARAM_UINT,
B_ERROR_TEMPLATE_PARAM_LONG,
B_ERROR_TEMPLATE_PARAM_ULONG,
B_ERROR_TEMPLATE_PARAM_LONGLONG,
B_ERROR_TEMPLATE_PARAM_ULONGLONG,
B_ERROR_TEMPLATE_PARAM_SIZE_T,
B_ERROR_TEMPLATE_PARAM_INTPTR,
B_ERROR_TEMPLATE_PARAM_UINTPTR,
B_ERROR_TEMPLATE_PARAM_PTR,
} b_error_template_parameter_type;
typedef struct b_error_template_parameter_definition {
const char *param_name;
b_error_template_parameter_type param_type;
const char *param_format;
} b_error_template_parameter_definition;
typedef struct b_error_template_parameter {
const char *param_name;
uintptr_t param_value;
const struct b_error_template_parameter_definition *__param_def;
} b_error_template_parameter;
struct b_error_vendor;
typedef struct b_error b_error;
typedef struct b_error *b_result;
typedef struct b_error_submsg b_error_submsg;
typedef struct b_error_stack_frame b_error_stack_frame;
typedef long b_error_status_code;
typedef unsigned long b_error_msg_id;
typedef struct b_error_definition {
const char *err_name;
const char *err_message;
const b_error_template_parameter_definition err_params[B_ERROR_TEMPLATE_PARAMETER_MAX];
} b_error_definition;
typedef struct b_error_msg {
const char *msg_message;
const b_error_template_parameter_definition msg_params[B_ERROR_TEMPLATE_PARAMETER_MAX];
} b_error_msg;
typedef const b_error_definition *(*b_error_status_code_get_definition)(
const struct b_error_vendor *, b_error_status_code);
typedef const b_error_msg *(*b_error_msg_get_definition)(
const struct b_error_vendor *, b_error_msg_id);
typedef void (*b_error_report_function)(
const struct b_error *, b_error_report_flags);
typedef struct b_error_vendor {
const char *v_name;
b_error_status_code_get_definition v_status_get_definition;
b_error_msg_get_definition v_msg_get_definition;
const b_error_definition *v_error_definitions;
size_t v_error_definitions_length;
const b_error_msg *v_msg;
size_t v_msg_length;
} b_error_vendor;
BLUE_API b_error *z__b_error_create_template(
const b_error_vendor *, b_error_status_code, b_error *, const char *,
unsigned int, const char *, const b_error_template_parameter[]);
BLUE_API b_error *z__b_error_create_string(
const b_error_vendor *, b_error_status_code, b_error *, const char *,
unsigned int, const char *, const char *, va_list);
BLUE_API b_error *z__b_error_create_msg(
const b_error_vendor *, b_error_status_code, b_error *, const char *,
unsigned int, const char *, b_error_msg_id,
const b_error_template_parameter[]);
BLUE_API b_error *z__b_error_propagate(
b_error *, const char *, unsigned int, const char *);
BLUE_API b_error *z__b_error_caused_by(b_error *, b_error *);
BLUE_API b_error *z__b_error_caused_by_b_status(b_error *, b_status);
BLUE_API void z__b_error_throw(b_error *, const char *, unsigned int, const char *);
BLUE_API bool b_result_is(
b_result result, const b_error_vendor *vendor, b_error_status_code code);
BLUE_API const b_error_vendor *b_error_vendor_get_builtin(void);
BLUE_API const b_error_vendor *b_error_vendor_get_errno(void);
BLUE_API const b_error_definition *b_error_vendor_get_error_definition(
const b_error_vendor *vendor, b_error_status_code code);
BLUE_API const char *b_error_vendor_get_status_code_name(
const b_error_vendor *vendor, b_error_status_code code);
BLUE_API const char *b_error_vendor_get_status_code_description(
const b_error_vendor *vendor, b_error_status_code code);
BLUE_API const b_error_msg *b_error_vendor_get_msg(
const b_error_vendor *vendor, b_error_msg_id msg_id);
static inline b_error *z__b_error_create(
const b_error_vendor *v, b_error_status_code c, b_error *c2,
const char *f0, unsigned int l, const char *f1, const char *d, ...)
{
va_list arg;
va_start(arg, d);
b_error *err = z__b_error_create_string(v, c, c2, f0, l, f1, d, arg);
va_end(arg);
return err;
}
BLUE_API enum b_status b_error_add_submsg_string(
b_error *error, b_error_submsg_type type, const char *msg, ...);
BLUE_API enum b_status z__b_error_add_submsg_template(
b_error *error, b_error_submsg_type type, b_error_msg_id msg_id,
b_error_template_parameter param[]);
#define b_error_add_submsg(error, type, msg_id) \
(z__b_error_add_submsg_template( \
error, type, msg_id, (b_error_template_parameter[]) {{}}))
#define b_error_add_submsg_template(error, type, msg_id, ...) \
(z__b_error_add_submsg_template( \
error, type, msg_id, \
(b_error_template_parameter[]) {__VA_ARGS__, {}}))
BLUE_API void b_error_discard(b_error *error);
BLUE_API b_error_status_code b_error_get_status_code(const b_error *error);
BLUE_API const b_error_vendor *b_error_get_vendor(const b_error *error);
BLUE_API const b_error_definition *b_error_get_definition(const b_error *error);
BLUE_API const b_error_template_parameter *b_error_get_template_parameter(
const b_error *error, const char *param_name);
BLUE_API const b_error_template_parameter *b_error_get_template_parameters(
const b_error *error);
BLUE_API const char *b_error_get_description(const b_error *error);
BLUE_API const b_error_msg *b_error_get_msg(const b_error *error);
BLUE_API const b_error_submsg *b_error_get_first_submsg(const b_error *error);
BLUE_API const b_error_submsg *b_error_get_next_submsg(
const b_error *error, const b_error_submsg *msg);
BLUE_API const b_error_stack_frame *b_error_get_first_stack_frame(
const b_error *error);
BLUE_API const b_error_stack_frame *b_error_get_next_stack_frame(
const b_error *error, const b_error_stack_frame *frame);
BLUE_API const b_error *b_error_get_caused_by(const b_error *error);
BLUE_API b_error_submsg_type b_error_submsg_get_type(const b_error_submsg *msg);
BLUE_API const char *b_error_submsg_get_content(const b_error_submsg *msg);
BLUE_API const b_error_msg *b_error_submsg_get_msg(const b_error_submsg *msg);
BLUE_API const b_error_template_parameter *b_error_submsg_get_template_parameters(
const b_error_submsg *msg);
BLUE_API const char *b_error_stack_frame_get_filepath(
const b_error_stack_frame *frame);
BLUE_API unsigned int b_error_stack_frame_get_line_number(
const b_error_stack_frame *frame);
BLUE_API const char *b_error_stack_frame_get_function_name(
const b_error_stack_frame *frame);
BLUE_API const b_error_template_parameter_definition *b_error_definition_get_template_parameter(
const b_error_definition *error_def, const char *param_name);
BLUE_API const char *b_error_msg_get_content(const b_error_msg *msg);
BLUE_API const b_error_template_parameter_definition *b_error_msg_get_template_parameter(
const b_error_msg *msg, const char *param_name);
BLUE_API void b_set_error_report_function(
b_error_report_function func, b_error_report_flags flags);
#endif
+111
View File
@@ -0,0 +1,111 @@
#ifndef BLUELIB_CORE_HASH_H_
#define BLUELIB_CORE_HASH_H_
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <stddef.h>
#include <stdint.h>
#define B_DIGEST_LENGTH_128 16
#define B_DIGEST_LENGTH_160 20
#define B_DIGEST_LENGTH_192 24
#define B_DIGEST_LENGTH_224 28
#define B_DIGEST_LENGTH_256 32
#define B_DIGEST_LENGTH_384 48
#define B_DIGEST_LENGTH_512 64
#define B_DIGEST_LENGTH_MD4 B_DIGEST_LENGTH_128
#define B_DIGEST_LENGTH_MD5 B_DIGEST_LENGTH_128
#define B_DIGEST_LENGTH_SHA1 B_DIGEST_LENGTH_160
#define B_DIGEST_LENGTH_SHA2_224 B_DIGEST_LENGTH_224
#define B_DIGEST_LENGTH_SHA2_256 B_DIGEST_LENGTH_256
#define B_DIGEST_LENGTH_SHA2_384 B_DIGEST_LENGTH_384
#define B_DIGEST_LENGTH_SHA2_512 B_DIGEST_LENGTH_512
#define B_DIGEST_LENGTH_SHA3_224 B_DIGEST_LENGTH_224
#define B_DIGEST_LENGTH_SHA3_256 B_DIGEST_LENGTH_256
#define B_DIGEST_LENGTH_SHA3_384 B_DIGEST_LENGTH_384
#define B_DIGEST_LENGTH_SHA3_512 B_DIGEST_LENGTH_512
#define B_DIGEST_LENGTH_SHAKE128 B_DIGEST_LENGTH_128
#define B_DIGEST_LENGTH_SHAKE256 B_DIGEST_LENGTH_256
struct b_hash_function_ops;
struct b_rope;
typedef enum b_hash_function {
B_HASH_NONE = 0,
B_HASH_MD4,
B_HASH_MD5,
B_HASH_SHA1,
B_HASH_SHA2_224,
B_HASH_SHA2_256,
B_HASH_SHA2_384,
B_HASH_SHA2_512,
B_HASH_SHA3_224,
B_HASH_SHA3_256,
B_HASH_SHA3_384,
B_HASH_SHA3_512,
B_HASH_SHAKE128,
B_HASH_SHAKE256,
} b_hash_function;
typedef struct b_hash_ctx {
b_hash_function ctx_func;
const struct b_hash_function_ops *ctx_ops;
union {
struct {
uint32_t lo, hi;
uint32_t a, b, c, d;
uint32_t block[16];
unsigned char buffer[64];
} md4;
struct {
unsigned int count[2];
unsigned int a, b, c, d;
unsigned int block[16];
unsigned char input[64];
} md5;
struct {
uint32_t state[5];
uint32_t count[2];
unsigned char buffer[64];
} sha1;
struct {
uint64_t curlen;
uint64_t length;
unsigned char buf[128];
uint32_t state[8];
} sha2_256;
struct {
uint64_t curlen;
uint64_t length;
unsigned char block[256];
uint64_t state[8];
} sha2_512;
struct {
union {
uint8_t b[200];
uint64_t q[25];
} st;
int pt, rsiz, mdlen;
} sha3;
} ctx_state;
} b_hash_ctx;
BLUE_API uint64_t b_hash_cstr(const char *s);
BLUE_API uint64_t b_hash_cstr_ex(const char *s, size_t *len);
BLUE_API b_status b_hash_ctx_init(b_hash_ctx *ctx, b_hash_function func);
BLUE_API b_status b_hash_ctx_reset(b_hash_ctx *ctx);
BLUE_API b_status b_hash_ctx_update(b_hash_ctx *ctx, const void *p, size_t len);
BLUE_API b_status b_hash_ctx_update_rope(b_hash_ctx *ctx, const struct b_rope *rope);
BLUE_API b_status b_hash_ctx_finish(
b_hash_ctx *ctx, void *out_digest, size_t out_max);
#endif
@@ -1,8 +1,8 @@
#ifndef FX_INIT_H_
#define FX_INIT_H_
#ifndef BLUELIB_INIT_H_
#define BLUELIB_INIT_H_
#ifdef __cplusplus
#define FX_INIT(f) \
#define B_INIT(f) \
static void f(void); \
struct f##_t_ { \
f##_t_(void) \
@@ -14,17 +14,17 @@
static void f(void)
#elif defined(_MSC_VER)
#pragma section(".CRT$XCU", read)
#define FX_INIT2_(f, p) \
#define B_INIT2_(f, p) \
static void f(void); \
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
__pragma(comment(linker, "/include:" p #f "_")) static void f(void)
#ifdef _WIN64
#define FX_INIT(f) FX_INIT2_(f, "")
#define B_INIT(f) B_INIT2_(f, "")
#else
#define FX_INIT(f) FX_INIT2_(f, "_")
#define B_INIT(f) B_INIT2_(f, "_")
#endif
#else
#define FX_INIT(f) \
#define B_INIT(f) \
static void f(void) __attribute__((constructor)); \
static void f(void)
#endif
+93
View File
@@ -0,0 +1,93 @@
#ifndef BLUE_CORE_ITERATOR_H_
#define BLUE_CORE_ITERATOR_H_
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <stdbool.h>
B_DECLS_BEGIN;
#define b_foreach(type, var, iterator) \
for (type var = (type)b_iterator_get_value(iterator).v_int; \
B_OK(b_iterator_get_status(iterator)); \
b_iterator_move_next(iterator), \
var = (type)b_iterator_get_value(iterator).v_int)
#define b_foreach_ptr(type, var, iterator) \
for (type *var = (type *)b_iterator_get_value(iterator).v_ptr; \
B_OK(b_iterator_get_status(iterator)); \
b_iterator_move_next(iterator), \
var = (type *)b_iterator_get_value(iterator).v_ptr)
#define b_foreach_c(type, var, iterator) \
for (type var = (type)b_iterator_get_cvalue(iterator).v_int; \
B_OK(b_iterator_get_status(iterator)); \
b_iterator_move_next(iterator), \
var = (type)b_iterator_get_cvalue(iterator).v_int)
#define b_foreach_cptr(type, var, iterator) \
for (const type *var \
= (const type *)b_iterator_get_cvalue(iterator).v_cptr; \
B_OK(b_iterator_get_status(iterator)); \
b_iterator_move_next(iterator), \
var = (const type *)b_iterator_get_cvalue(iterator).v_cptr)
#define B_ITERATOR_VALUE_INT(v) ((b_iterator_value) {.v_int = (v)})
#define B_ITERATOR_VALUE_PTR(v) ((b_iterator_value) {.v_ptr = (v)})
#define B_ITERATOR_VALUE_CPTR(v) ((const b_iterator_value) {.v_cptr = (v)})
#define B_ITERATOR_VALUE_NULL ((b_iterator_value) {})
#define B_ITERATOR_VALUE_IS_NULL(v) ((v)->v_ptr == NULL)
#define B_TYPE_ITERATOR (b_iterator_get_type())
#define B_TYPE_ITERABLE (b_iterable_get_type())
typedef union b_iterator_value {
uintptr_t v_int;
void *v_ptr;
const void *v_cptr;
} b_iterator_value;
__B_DECLARE_TYPE(b_iterator);
B_DECLARE_TYPE(b_iterable);
B_TYPE_CLASS_DECLARATION_BEGIN(b_iterator)
b_status (*it_move_next)(const b_iterator *);
b_status (*it_erase)(b_iterator *);
b_iterator_value (*it_get_value)(b_iterator *);
const b_iterator_value (*it_get_cvalue)(const b_iterator *);
B_TYPE_CLASS_DECLARATION_END(b_iterator)
B_TYPE_CLASS_DECLARATION_BEGIN(b_iterable)
b_iterator *(*it_begin)(b_iterable *);
const b_iterator *(*it_cbegin)(const b_iterable *);
B_TYPE_CLASS_DECLARATION_END(b_iterable)
BLUE_API b_type b_iterator_get_type(void);
BLUE_API b_type b_iterable_get_type(void);
static inline const b_iterator *b_iterator_ref(const b_iterator *p)
{
return b_object_ref((b_object *)p);
}
static inline void b_iterator_unref(const b_iterator *p)
{
b_object_unref((b_object *)p);
}
BLUE_API b_iterator *b_iterator_begin(b_iterable *it);
BLUE_API const b_iterator *b_iterator_cbegin(const b_iterable *it);
BLUE_API b_status b_iterator_get_status(const b_iterator *it);
BLUE_API b_status b_iterator_set_status(const b_iterator *it, b_status status);
BLUE_API b_status b_iterator_move_next(const b_iterator *it);
BLUE_API b_iterator_value b_iterator_get_value(b_iterator *it);
BLUE_API const b_iterator_value b_iterator_get_cvalue(const b_iterator *it);
BLUE_API b_status b_iterator_erase(b_iterator *it);
static inline bool b_iterator_is_valid(const b_iterator *it)
{
return B_OK(b_iterator_get_status(it));
}
B_DECLS_END;
#endif
+192
View File
@@ -0,0 +1,192 @@
#ifndef BLUE_CORE_MACROS_H_
#define BLUE_CORE_MACROS_H_
#include <blue/core/class.h>
#include <blue/core/misc.h>
#include <blue/core/object.h>
#include <blue/core/thread.h>
#include <blue/core/type.h>
#include <stdlib.h>
#define __B_IFACE_I0(p, x) p##x
#define __B_IFACE_I1(p, x) __B_IFACE_I0(p, x)
#define B_STRUCT_EMPTY char _x
/* Type definitions macros (for use in .c source file) */
#define B_TYPE_CLASS_DEFINITION_BEGIN(type_name) \
static void type_name##_class_init(b_class *p, void *d) \
{
#define B_TYPE_CLASS_DEFINITION_END(type_name) }
#define B_TYPE_CLASS_INTERFACE_BEGIN(interface_name, interface_id) \
interface_name##_class *__B_IFACE_I1(iface, __LINE__) \
= b_class_get_interface(p, interface_id); \
if (!__B_IFACE_I1(iface, __LINE__)) { \
b_throw_error_with_msg_template( \
B_ERRORS_BUILTIN, B_ERR_CLASS_INIT_FAILURE, \
B_MSG_CLASS_SPECIFIES_UNKNOWN_INTERFACE, \
B_ERROR_PARAM("class_name", b_class_get_name(p)), \
B_ERROR_PARAM("interface_name", #interface_name)); \
exit(-1); \
} else { \
interface_name##_class *iface = __B_IFACE_I1(iface, __LINE__);
#define B_TYPE_CLASS_INTERFACE_END(interface_name, interface_id) }
#define B_INTERFACE_ENTRY(slot) iface->slot
#define B_TYPE_DEFINITION_BEGIN(name) \
static b_type_info name##_type_info = {0}; \
static void name##_class_init(b_class *, void *); \
static void name##_type_init(void) \
{ \
b_type_info *type_info = &name##_type_info; \
unsigned int nr_vtables = 0; \
type_info->t_name = #name; \
type_info->t_class_init = name##_class_init;
#define B_TYPE_DEFINITION_END(name) \
b_result result = b_type_register(type_info); \
if (b_result_is_error(result)) { \
b_throw_error_caused_by_error( \
B_ERRORS_BUILTIN, B_ERR_TYPE_REGISTRATION_FAILURE, \
result); \
abort(); \
} \
} \
b_type name##_get_type(void) \
{ \
static b_once static_type_init = B_ONCE_INIT; \
\
if (b_init_once(&static_type_init)) { \
name##_type_init(); \
} \
\
return &name##_type_info.t_id; \
}
#define B_TYPE_ID(a, b, c, d, e) b_type_id_init(&type_info->t_id, a, b, c, d, e)
#define B_TYPE_EXTENDS(parent_id) \
b_type_id_copy(parent_id, &type_info->t_parent_id)
#define B_TYPE_IMPLEMENTS(interface_id) \
b_type_id_copy( \
interface_id, \
&type_info->t_interfaces[type_info->t_nr_interfaces++])
#define B_TYPE_CLASS(class_struct) \
type_info->t_class_size = sizeof(class_struct)
#define B_TYPE_FLAGS(flags) type_info->t_flags = (flags)
#define B_TYPE_INSTANCE_INIT(func) type_info->t_instance_init = (func)
#define B_TYPE_INSTANCE_FINI(func) type_info->t_instance_fini = (func)
#if 0
#define B_TYPE_VTABLE_BEGIN(vtable_struct, interface_id) \
vtable_struct __B_IFACE_I1(iface, __LINE__) = {0}; \
{ \
vtable_struct *iface = &__B_IFACE_I1(iface, __LINE__); \
type_info->t_vtables[nr_vtables].v_vtable = iface; \
type_info->t_vtables[nr_vtables].v_interface_id = interface_id; \
nr_vtables++;
#define B_TYPE_VTABLE_END(vtable_struct, interface_id) }
#endif
#define B_TYPE_INSTANCE_PRIVATE(instance_struct) \
type_info->t_instance_private_size = sizeof(instance_struct)
#define B_TYPE_INSTANCE_PROTECTED(instance_struct) \
type_info->t_instance_protected_size = sizeof(instance_struct)
/* Type declaration macros (for use in .h header file) */
#define __B_DECLARE_TYPE(name) \
typedef B_TYPE_FWDREF(name) name; \
typedef struct _##name##_class name##_class;
#define B_DECLARE_TYPE(name) \
__B_DECLARE_TYPE(name); \
static inline name *name##_ref(name *p) \
{ \
return b_object_ref(p); \
} \
static inline void name##_unref(name *p) \
{ \
b_object_unref(p); \
}
#define B_TYPE_CLASS_DECLARATION_BEGIN(name) struct _##name##_class {
#define B_TYPE_CLASS_DECLARATION_END(name) \
} \
;
#define B_TYPE_VIRTUAL_METHOD(return_type, method_name) \
return_type(*method_name)
#define B_TYPE_DEFAULT_CONSTRUCTOR(type_name, type_id) \
static inline type_name *type_name##_create(void) \
{ \
return b_object_create(type_id); \
}
/* Other macros */
#define B_CLASS_DISPATCH_VIRTUAL( \
type_name, type_id, default_value, func, object, ...) \
do { \
type_name##_class *iface \
= b_object_get_interface(object, type_id); \
if (iface && iface->func) { \
return iface->func(object, __VA_ARGS__); \
} else { \
return default_value; \
} \
} while (0)
#define B_CLASS_DISPATCH_VIRTUAL_0(type_name, type_id, default_value, func, object) \
do { \
type_name##_class *iface \
= b_object_get_interface(object, type_id); \
if (iface && iface->func) { \
return iface->func(object); \
} else { \
return default_value; \
} \
} while (0)
#define B_CLASS_DISPATCH_VIRTUAL_V(type_name, type_id, func, object, ...) \
do { \
type_name##_class *iface \
= b_object_get_interface(object, type_id); \
if (iface && iface->func) { \
iface->func(object, __VA_ARGS__); \
return; \
} \
} while (0)
#define B_CLASS_DISPATCH_VIRTUAL_V0(type_name, type_id, func, object) \
do { \
type_name##_class *iface \
= b_object_get_interface(object, type_id); \
if (iface && iface->func) { \
iface->func(object); \
return; \
} \
} while (0)
#define B_CLASS_DISPATCH_STATIC(type_id, func_name, obj, ...) \
do { \
void *priv = b_object_get_private(obj, type_id); \
return func_name(priv, __VA_ARGS__); \
} while (0)
#define B_CLASS_DISPATCH_STATIC_V(type_id, func_name, obj, ...) \
do { \
void *priv = b_object_get_private(obj, type_id); \
func_name(priv, __VA_ARGS__); \
} while (0)
#define B_CLASS_DISPATCH_STATIC_0(type_id, func_name, obj) \
do { \
void *priv = b_object_get_private(obj, type_id); \
return func_name(priv); \
} while (0)
#define B_CLASS_DISPATCH_STATIC_V0(type_id, func_name, obj) \
do { \
void *priv = b_object_get_private(obj, type_id); \
func_name(priv); \
} while (0)
#endif
+126
View File
@@ -0,0 +1,126 @@
#ifndef BLUE_CORE_MISC_H_
#define BLUE_CORE_MISC_H_
#include <stddef.h>
#include <stdint.h>
#ifndef _Nonnull
#define _Nonnull
#endif
#ifdef __cplusplus
#define B_DECLS_BEGIN extern "C" {
#define B_DECLS_END }
#else
#define B_DECLS_BEGIN
#define B_DECLS_END
#endif
#define B_NPOS ((size_t)-1)
#define b_min(type, x, y) (z__b_min_##type(x, y))
#define b_max(type, x, y) (z__b_max_##type(x, y))
#define b_unbox(type, box, member) \
((type *_Nonnull)((box) ? (uintptr_t)(box) - (offsetof(type, member)) : 0))
#define z__b_merge_(a, b) a##b
#define z__b_label_(a) z__b_merge_(__unique_name_, a)
#define z__b_unique_name() z__b_label_(__LINE__)
#define z__b_numargs(arg_type, ...) \
(sizeof((arg_type[]) {__VA_ARGS__}) / sizeof(arg_type))
#ifdef _MSC_VER
#ifdef BLUELIB_STATIC
#define BLUE_API extern
#else
#ifdef BLUELIB_EXPORT
#define BLUE_API extern __declspec(dllexport)
#else
#define BLUE_API extern __declspec(dllimport)
#endif
#endif
#else
#define BLUE_API extern
#endif
static inline char z__b_min_char(char x, char y)
{
return x < y ? x : y;
}
static inline unsigned char z__b_min_uchar(unsigned char x, unsigned char y)
{
return x < y ? x : y;
}
static inline int z__b_min_int(int x, int y)
{
return x < y ? x : y;
}
static inline unsigned int z__b_min_uint(unsigned int x, unsigned int y)
{
return x < y ? x : y;
}
static inline long z__b_min_long(long x, long y)
{
return x < y ? x : y;
}
static inline unsigned int z__b_min_ulong(unsigned long x, unsigned long y)
{
return x < y ? x : y;
}
static inline long long z__b_min_longlong(long long x, long long y)
{
return x < y ? x : y;
}
static inline unsigned long long z__b_min_ulonglong(
unsigned long long x, unsigned long long y)
{
return x < y ? x : y;
}
static inline size_t z__b_min_size_t(size_t x, size_t y)
{
return x < y ? x : y;
}
static inline char z__b_max_char(char x, char y)
{
return x > y ? x : y;
}
static inline unsigned char z__b_max_uchar(unsigned char x, unsigned char y)
{
return x > y ? x : y;
}
static inline int z__b_max_int(int x, int y)
{
return x > y ? x : y;
}
static inline unsigned int z__b_max_uint(unsigned int x, unsigned int y)
{
return x > y ? x : y;
}
static inline long z__b_max_long(long x, long y)
{
return x > y ? x : y;
}
static inline unsigned int z__b_max_ulong(unsigned long x, unsigned long y)
{
return x > y ? x : y;
}
static inline long long z__b_max_longlong(long long x, long long y)
{
return x > y ? x : y;
}
static inline unsigned long long z__b_max_ulonglong(
unsigned long long x, unsigned long long y)
{
return x > y ? x : y;
}
static inline size_t z__b_max_size_t(size_t x, size_t y)
{
return x > y ? x : y;
}
BLUE_API size_t b_int_length(intptr_t v);
BLUE_API size_t b_uint_length(uintptr_t v);
#endif // BLUE_CORE_MISC_H_
+43
View File
@@ -0,0 +1,43 @@
#ifndef BLUE_CORE_OBJECT_H_
#define BLUE_CORE_OBJECT_H_
#include <blue/core/misc.h>
#include <blue/core/type.h>
B_DECLS_BEGIN;
#define B_OBJECT_MAGIC 0xDECAFC0C0ABEEF13ULL
#define B_OBJECT(p) ((b_object *)(p))
#define B_TYPE_OBJECT (b_object_get_type())
#define B_TYPE_FWDREF(name) struct _b_object
#define B_RV(p) (b_object_make_rvalue(p))
typedef B_TYPE_FWDREF(b_object) b_object;
typedef struct _b_object_class {
void (*to_string)(const b_object *, B_TYPE_FWDREF(b_stream) *);
} b_object_class;
BLUE_API b_type b_object_get_type(void);
BLUE_API void *b_object_get_private(const b_object *object, b_type type);
BLUE_API void *b_object_get_protected(const b_object *object, b_type type);
BLUE_API void *b_object_get_interface(const b_object *object, b_type type);
BLUE_API b_status b_object_get_data(
const b_object *object, b_type type, void **priv, void **prot,
void **iface);
BLUE_API b_object *b_object_ref(b_object *p);
BLUE_API void b_object_unref(b_object *p);
BLUE_API b_object *b_object_make_rvalue(b_object *p);
BLUE_API b_object *b_object_create(b_type type);
BLUE_API void b_object_to_string(const b_object *p, B_TYPE_FWDREF(b_stream) * out);
BLUE_API bool b_object_is_type(const b_object *p, b_type type);
B_DECLS_END;
#endif
+82
View File
@@ -0,0 +1,82 @@
#ifndef BLUE_CORE_QUEUE_H_
#define BLUE_CORE_QUEUE_H_
#include <blue/core/iterator.h>
#include <blue/core/macros.h>
#include <blue/core/status.h>
#include <stdbool.h>
#include <string.h>
B_DECLS_BEGIN;
#define B_TYPE_QUEUE_ITERATOR (b_queue_iterator_get_type())
B_DECLARE_TYPE(b_queue_iterator);
B_TYPE_CLASS_DECLARATION_BEGIN(b_queue_iterator)
B_TYPE_CLASS_DECLARATION_END(b_queue_iterator)
#define B_QUEUE_INIT ((b_queue) {.q_first = NULL, .q_last = NULL})
#define B_QUEUE_ENTRY_INIT ((b_queue_entry) {.qe_next = NULL, .qe_prev = NULL})
typedef struct b_queue_entry {
struct b_queue_entry *qe_next;
struct b_queue_entry *qe_prev;
} b_queue_entry;
typedef struct b_queue {
b_queue_entry *q_first;
b_queue_entry *q_last;
} b_queue;
static inline void b_queue_init(b_queue *q)
{
memset(q, 0x00, sizeof *q);
}
static inline bool b_queue_empty(const b_queue *q)
{
return q ? (q->q_first == NULL) : true;
}
static inline b_queue_entry *b_queue_first(const b_queue *q)
{
return q ? q->q_first : NULL;
}
static inline b_queue_entry *b_queue_last(const b_queue *q)
{
return q ? q->q_last : NULL;
}
static inline b_queue_entry *b_queue_next(const b_queue_entry *entry)
{
return entry ? entry->qe_next : NULL;
}
static inline b_queue_entry *b_queue_prev(const b_queue_entry *entry)
{
return entry ? entry->qe_prev : NULL;
}
BLUE_API b_type b_queue_iterator_get_type(void);
BLUE_API size_t b_queue_length(const b_queue *q);
BLUE_API void b_queue_insert_before(
b_queue *q, b_queue_entry *entry, b_queue_entry *before);
BLUE_API void b_queue_insert_after(
b_queue *q, b_queue_entry *entry, b_queue_entry *after);
BLUE_API void b_queue_push_front(b_queue *q, b_queue_entry *entry);
BLUE_API void b_queue_push_back(b_queue *q, b_queue_entry *entry);
BLUE_API b_queue_entry *b_queue_pop_front(b_queue *q);
BLUE_API b_queue_entry *b_queue_pop_back(b_queue *q);
BLUE_API void b_queue_move(b_queue *q, b_queue_entry *dest, b_queue_entry *src);
BLUE_API void b_queue_delete(b_queue *q, b_queue_entry *entry);
BLUE_API void b_queue_delete_all(b_queue *q);
BLUE_API b_iterator *b_queue_begin(b_queue *q);
BLUE_API b_iterator *b_queue_cbegin(const b_queue *q);
B_DECLS_END;
#endif
+37
View File
@@ -0,0 +1,37 @@
#ifndef BLUELIB_RANDOM_H_
#define BLUELIB_RANDOM_H_
#include <blue/core/status.h>
#include <stddef.h>
struct b_random_algorithm;
typedef enum b_random_flags {
/* algorithm selection */
B_RANDOM_MT19937 = 0x01u,
/* generation flags */
B_RANDOM_SECURE = 0x100u,
} b_random_flags;
typedef struct b_random_ctx {
b_random_flags __f;
struct b_random_algorithm *__a;
union {
struct {
unsigned long long mt[312];
size_t mti;
} __mt19937;
};
} b_random_ctx;
BLUE_API b_random_ctx *b_random_global_ctx(void);
BLUE_API b_status b_random_init(b_random_ctx *ctx, b_random_flags flags);
BLUE_API unsigned long long b_random_next_int64(b_random_ctx *ctx);
BLUE_API double b_random_next_double(b_random_ctx *ctx);
BLUE_API void b_random_next_bytes(
b_random_ctx *ctx, unsigned char *out, size_t nbytes);
#endif
+47
View File
@@ -0,0 +1,47 @@
#ifndef BLUE_CORE_RINGBUFFER_H_
#define BLUE_CORE_RINGBUFFER_H_
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <blue/core/status.h>
B_DECLS_BEGIN;
#define B_TYPE_RINGBUFFER (b_ringbuffer_get_type())
B_DECLARE_TYPE(b_ringbuffer);
B_TYPE_CLASS_DECLARATION_BEGIN(b_ringbuffer)
B_TYPE_CLASS_DECLARATION_END(b_ringbuffer)
BLUE_API b_type b_ringbuffer_get_type(void);
BLUE_API b_ringbuffer *b_ringbuffer_create(size_t capacity);
BLUE_API b_ringbuffer *b_ringbuffer_create_with_buffer(void *ptr, size_t capacity);
BLUE_API b_status b_ringbuffer_clear(b_ringbuffer *buf);
BLUE_API b_status b_ringbuffer_read(
b_ringbuffer *buf, void *p, size_t count, size_t *nr_read);
BLUE_API b_status b_ringbuffer_write(
b_ringbuffer *buf, const void *p, size_t count, size_t *nr_written);
BLUE_API int b_ringbuffer_getc(b_ringbuffer *buf);
BLUE_API b_status b_ringbuffer_putc(b_ringbuffer *buf, int c);
BLUE_API size_t b_ringbuffer_write_capacity_remaining(const b_ringbuffer *buf);
BLUE_API size_t b_ringbuffer_available_data_remaining(const b_ringbuffer *buf);
BLUE_API b_status b_ringbuffer_open_read_buffer(
b_ringbuffer *buf, const void **ptr, size_t *length);
BLUE_API b_status b_ringbuffer_close_read_buffer(
b_ringbuffer *buf, const void **ptr, size_t nr_read);
BLUE_API b_status b_ringbuffer_open_write_buffer(
b_ringbuffer *buf, void **ptr, size_t *capacity);
BLUE_API b_status b_ringbuffer_close_write_buffer(
b_ringbuffer *buf, void **ptr, size_t nr_written);
B_DECLS_END;
#endif
+109
View File
@@ -0,0 +1,109 @@
#ifndef BLUE_CORE_ROPE_H_
#define BLUE_CORE_ROPE_H_
#include <blue/core/hash.h>
#include <blue/core/misc.h>
#include <blue/core/stream.h>
#include <stdint.h>
#include <string.h>
struct b_string;
struct b_bstr;
#define B_ROPE_TYPE(f) ((f) & 0xFF)
#define B_ROPE_CHAR(c) \
\
{ \
.r_flags = B_ROPE_F_CHAR, .r_len_total = 1, \
.r_v = {.v_char = (c) } \
}
#define B_ROPE_CSTR(str) \
{ \
.r_flags = B_ROPE_F_CSTR_BORROWED, \
.r_len_total = strlen(str), \
.r_v = { \
.v_cstr = { \
.s = (str), \
.hash = b_hash_cstr(str), \
}, \
}, \
}
#define B_ROPE_CSTR_STATIC(str) \
{ \
.r_flags = B_ROPE_F_CSTR_STATIC, \
.r_len_total = strlen(str), \
.r_v = { \
.v_cstr = { \
.s = (str), \
.hash = b_hash_cstr(str), \
}, \
}, \
}
#define B_ROPE_INT(v) \
\
{ \
.r_flags = B_ROPE_F_INT, .r_len_total = b_int_length(v), \
.r_v = {.v_int = (v) } \
}
#define B_ROPE_UINT(v) \
\
{ \
.r_flags = B_ROPE_F_UINT, .r_len_total = b_uint_length(v), \
.r_v = {.v_uint = (v) } \
}
typedef enum b_rope_flags {
B_ROPE_F_NONE = 0x0000u,
B_ROPE_F_CHAR = 0x0001u,
B_ROPE_F_CSTR = 0x0002u,
B_ROPE_F_CSTR_BORROWED = 0x0003u,
B_ROPE_F_CSTR_STATIC = 0x0004u,
B_ROPE_F_INT = 0x0005u,
B_ROPE_F_UINT = 0x0006u,
B_ROPE_F_COMPOSITE = 0x0007u,
B_ROPE_F_MALLOC = 0x0100u,
} b_rope_flags;
typedef struct b_rope {
b_rope_flags r_flags;
unsigned long r_len_left, r_len_total;
union {
char v_char;
intptr_t v_int;
uintptr_t v_uint;
struct {
const char *s;
uint64_t hash;
} v_cstr;
struct {
const struct b_rope *r_left, *r_right;
} v_composite;
} r_v;
} b_rope;
BLUE_API void b_rope_init_char(b_rope *rope, char c);
BLUE_API void b_rope_init_cstr(b_rope *rope, const char *s);
BLUE_API void b_rope_init_cstr_borrowed(b_rope *rope, const char *s);
BLUE_API void b_rope_init_cstr_static(b_rope *rope, const char *s);
BLUE_API void b_rope_init_int(b_rope *rope, intptr_t v);
BLUE_API void b_rope_init_uint(b_rope *rope, uintptr_t v);
BLUE_API void b_rope_destroy(b_rope *rope);
BLUE_API void b_rope_iterate(
const b_rope *rope, void (*func)(const b_rope *, void *), void *arg);
BLUE_API size_t b_rope_get_size(const b_rope *rope);
BLUE_API void b_rope_concat(b_rope *result, const b_rope *left, const b_rope *right);
BLUE_API void b_rope_join(b_rope *result, const b_rope **ropes, size_t nr_ropes);
BLUE_API b_status b_rope_to_cstr(const b_rope *rope, char *out, size_t max);
BLUE_API b_status b_rope_to_bstr(const b_rope *rope, struct b_bstr *str);
BLUE_API b_status b_rope_to_string(const b_rope *rope, b_stream *out);
#endif
+48
View File
@@ -0,0 +1,48 @@
#ifndef BLUELIB_CORE_STATUS_H_
#define BLUELIB_CORE_STATUS_H_
#include <blue/core/misc.h>
#define B_OK(status) ((enum b_status)((uintptr_t)(status)) == B_SUCCESS)
#define B_ERR(status) ((status) != B_SUCCESS)
typedef enum b_status {
B_SUCCESS = 0x00u,
B_ERR_NO_MEMORY,
B_ERR_OUT_OF_BOUNDS,
B_ERR_INVALID_ARGUMENT,
B_ERR_NAME_EXISTS,
B_ERR_NOT_SUPPORTED,
B_ERR_BAD_STATE,
B_ERR_NO_ENTRY,
B_ERR_NO_DATA,
B_ERR_NO_SPACE,
B_ERR_UNKNOWN_FUNCTION,
B_ERR_BAD_FORMAT,
B_ERR_IO_FAILURE,
B_ERR_IS_DIRECTORY,
B_ERR_NOT_DIRECTORY,
B_ERR_PERMISSION_DENIED,
B_ERR_BUSY,
/* blue-compress specific code */
B_ERR_COMPRESSION_FAILURE,
/* blue-object specific code */
B_ERR_TYPE_REGISTRATION_FAILURE,
B_ERR_CLASS_INIT_FAILURE,
} b_status;
typedef enum b_status_msg {
B_MSG_SUCCESS = 0,
/* blue-object specific messages */
B_MSG_TYPE_REGISTRATION_FAILURE,
B_MSG_CLASS_INIT_FAILURE,
B_MSG_CLASS_SPECIFIES_UNKNOWN_INTERFACE,
} b_status_msg;
BLUE_API const char *b_status_to_string(b_status status);
BLUE_API const char *b_status_description(b_status status);
#endif
+101
View File
@@ -0,0 +1,101 @@
#ifndef BLUE_CORE_STREAM_H_
#define BLUE_CORE_STREAM_H_
#include <blue/core/encoding.h>
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <stdarg.h>
#include <stdio.h>
B_DECLS_BEGIN;
#define b_stdin (z__b_stream_get_stdin())
#define b_stdout (z__b_stream_get_stdout())
#define b_stderr (z__b_stream_get_stderr())
#define B_TYPE_STREAM (b_stream_get_type())
#define B_TYPE_STREAM_BUFFER (b_stream_buffer_get_type())
B_DECLARE_TYPE(b_stream);
B_DECLARE_TYPE(b_stream_buffer);
typedef enum b_stream_mode {
B_STREAM_READ = 0x01u,
B_STREAM_WRITE = 0x02u,
B_STREAM_BINARY = 0x10u,
Z__B_STREAM_STATIC = 0x80u,
} b_stream_mode;
typedef enum b_stream_seek_origin {
B_STREAM_SEEK_START = 0x01u,
B_STREAM_SEEK_CURRENT = 0x02u,
B_STREAM_SEEK_END = 0x03u,
} b_stream_seek_origin;
typedef struct b_stream_cfg {
b_stream_mode s_mode;
} b_stream_cfg;
B_TYPE_CLASS_DECLARATION_BEGIN(b_stream)
b_status (*s_close)(b_stream *);
b_status (*s_seek)(b_stream *, long long, b_stream_seek_origin);
b_status (*s_tell)(const b_stream *, size_t *);
b_status (*s_getc)(b_stream *, b_wchar *);
b_status (*s_read)(b_stream *, void *, size_t, size_t *);
b_status (*s_write)(b_stream *, const void *, size_t, size_t *);
b_status (*s_reserve)(b_stream *, size_t);
B_TYPE_CLASS_DECLARATION_END(b_stream)
B_TYPE_CLASS_DECLARATION_BEGIN(b_stream_buffer)
B_STRUCT_EMPTY;
B_TYPE_CLASS_DECLARATION_END(b_stream_buffer)
BLUE_API b_type b_stream_get_type();
BLUE_API b_type b_stream_buffer_get_type();
BLUE_API b_stream *z__b_stream_get_stdin(void);
BLUE_API b_stream *z__b_stream_get_stdout(void);
BLUE_API b_stream *z__b_stream_get_stderr(void);
BLUE_API b_stream_buffer *b_stream_buffer_create(void *p, size_t len);
BLUE_API b_stream_buffer *b_stream_buffer_create_dynamic(size_t buffer_size);
BLUE_API b_stream *b_stream_open_fp(FILE *fp);
BLUE_API b_status b_stream_reserve(b_stream *stream, size_t len);
BLUE_API b_status b_stream_seek(
b_stream *stream, long long offset, b_stream_seek_origin origin);
BLUE_API size_t b_stream_cursor(const b_stream *stream);
BLUE_API b_status b_stream_push_indent(b_stream *stream, int indent);
BLUE_API b_status b_stream_pop_indent(b_stream *stream);
BLUE_API b_status b_stream_read_char(b_stream *stream, b_wchar *c);
BLUE_API b_status b_stream_read_bytes(
b_stream *stream, void *buf, size_t count, size_t *nr_read);
BLUE_API b_status b_stream_read_line(b_stream *stream, char *s, size_t max);
BLUE_API b_status b_stream_read_line_s(b_stream *src, b_stream *dest);
BLUE_API b_status b_stream_read_all_bytes(
b_stream *stream, void *p, size_t max, size_t *nr_read);
BLUE_API b_status b_stream_read_all_bytes_s(
b_stream *src, b_stream *dest, b_stream_buffer *buffer, size_t *nr_read);
BLUE_API b_status b_stream_write_char(b_stream *stream, b_wchar c);
BLUE_API b_status b_stream_write_string(
b_stream *stream, const char *s, size_t *nr_written);
BLUE_API b_status b_stream_write_bytes(
b_stream *stream, const void *buf, size_t count, size_t *nr_written);
BLUE_API b_status b_stream_write_fmt(
b_stream *stream, size_t *nr_written, const char *format, ...);
BLUE_API b_status b_stream_write_vfmt(
b_stream *stream, size_t *nr_written, const char *format, va_list arg);
B_DECLS_END;
#endif
+36
View File
@@ -0,0 +1,36 @@
#ifndef BLUE_CORE_STRINGSTREAM_H_
#define BLUE_CORE_STRINGSTREAM_H_
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <blue/core/stream.h>
#include <stddef.h>
B_DECLS_BEGIN;
#define B_TYPE_STRINGSTREAM (b_stringstream_get_type())
B_DECLARE_TYPE(b_stringstream);
B_TYPE_CLASS_DECLARATION_BEGIN(b_stringstream)
B_STRUCT_EMPTY;
B_TYPE_CLASS_DECLARATION_END(b_stringstream)
BLUE_API b_type b_stringstream_get_type(void);
BLUE_API b_stringstream *b_stringstream_create(void);
BLUE_API b_stringstream *b_stringstream_create_with_buffer(char *buf, size_t max);
BLUE_API b_status b_stringstream_reset(b_stringstream *strv);
BLUE_API b_status b_stringstream_reset_with_buffer(
b_stringstream *strv, char *buf, size_t max);
BLUE_API const char *b_stringstream_ptr(const b_stringstream *strv);
BLUE_API char *b_stringstream_steal(b_stringstream *strv);
BLUE_API size_t b_stringstream_get_length(const b_stringstream *strv);
B_DECLS_END;
#endif
+36
View File
@@ -0,0 +1,36 @@
#ifndef BLUELIB_CORE_THREAD_H_
#define BLUELIB_CORE_THREAD_H_
#include <blue/core/bitop.h>
#include <blue/core/misc.h>
#include <stdbool.h>
#if defined(__APPLE__) || defined(__linux__)
#include <pthread.h>
#define B_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
typedef pthread_mutex_t b_mutex;
#else
#error Unsupported compiler/system
#endif
#define B_ONCE_INIT ((b_once)0)
typedef struct b_thread b_thread;
typedef int b_once;
static inline bool b_init_once(b_once *once)
{
int x = 0;
return b_cmpxchg(once, &x, 1);
}
BLUE_API b_thread *b_thread_self(void);
BLUE_API bool b_mutex_lock(b_mutex *mut);
BLUE_API bool b_mutex_trylock(b_mutex *mut);
BLUE_API bool b_mutex_unlock(b_mutex *mut);
#endif
+70
View File
@@ -0,0 +1,70 @@
#ifndef BLUE_CORE_TYPE_H_
#define BLUE_CORE_TYPE_H_
#include <blue/core/error.h>
#include <blue/core/misc.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
B_DECLS_BEGIN;
#define B_TYPE_MAX_INTERFACES 64
struct _b_class;
struct _b_object;
typedef void (*b_class_init_function)(struct _b_class *, void *);
typedef void (*b_instance_init_function)(struct _b_object *, void *);
typedef void (*b_instance_fini_function)(struct _b_object *, void *);
typedef const union b_type_id {
struct {
uint64_t p00, p01;
} a;
unsigned char b[16];
} *b_type;
typedef enum b_type_flags {
B_TYPE_F_ABSTRACT = 0x01u,
} b_type_flags;
typedef struct b_type_info {
union b_type_id t_id;
union b_type_id t_parent_id;
const char *t_name;
b_type_flags t_flags;
union b_type_id t_interfaces[B_TYPE_MAX_INTERFACES];
size_t t_nr_interfaces;
size_t t_class_size;
b_class_init_function t_class_init;
size_t t_instance_private_size;
size_t t_instance_protected_size;
b_instance_init_function t_instance_init;
b_instance_fini_function t_instance_fini;
} b_type_info;
BLUE_API void b_type_id_init(
union b_type_id *out, uint32_t a, uint16_t b, uint16_t c, uint16_t d,
uint64_t e);
static inline void b_type_id_copy(b_type src, union b_type_id *dest)
{
dest->a.p00 = src->a.p00;
dest->a.p01 = src->a.p01;
}
static inline int b_type_id_compare(b_type a, b_type b)
{
if (a == b) {
return 0;
}
return memcmp(a, b, sizeof(union b_type_id));
}
BLUE_API b_result b_type_register(b_type_info *info);
B_DECLS_END;
#endif
+115
View File
@@ -0,0 +1,115 @@
#include <blue/core/iterator.h>
/*** PRIVATE DATA *************************************************************/
struct b_iterator_p {
enum b_status it_status;
};
/*** PRIVATE FUNCTIONS ********************************************************/
static enum b_status iterator_get_status(const struct b_iterator_p *it)
{
return it->it_status;
}
static enum b_status iterator_set_status(struct b_iterator_p *it, b_status status)
{
it->it_status = status;
return B_SUCCESS;
}
/*** PUBLIC FUNCTIONS *********************************************************/
b_iterator *b_iterator_begin(b_iterable *it)
{
B_CLASS_DISPATCH_VIRTUAL_0(b_iterable, B_TYPE_ITERABLE, NULL, it_begin, it);
}
const b_iterator *b_iterator_cbegin(const b_iterable *it)
{
B_CLASS_DISPATCH_VIRTUAL_0(b_iterable, B_TYPE_ITERABLE, NULL, it_cbegin, it);
}
enum b_status b_iterator_get_status(const b_iterator *it)
{
B_CLASS_DISPATCH_STATIC_0(B_TYPE_ITERATOR, iterator_get_status, it);
}
enum b_status b_iterator_set_status(const b_iterator *it, b_status status)
{
B_CLASS_DISPATCH_STATIC(B_TYPE_ITERATOR, iterator_set_status, it, status);
}
enum b_status b_iterator_move_next(const b_iterator *it)
{
enum b_status status = B_ERR_NOT_SUPPORTED;
b_iterator_class *iface = b_object_get_interface(it, B_TYPE_ITERATOR);
if (iface && iface->it_move_next) {
status = iface->it_move_next(it);
}
struct b_iterator_p *p = b_object_get_private(it, B_TYPE_ITERATOR);
p->it_status = status;
return status;
}
b_iterator_value b_iterator_get_value(b_iterator *it)
{
B_CLASS_DISPATCH_VIRTUAL_0(
b_iterator, B_TYPE_ITERATOR, B_ITERATOR_VALUE_NULL,
it_get_value, it);
}
const b_iterator_value b_iterator_get_cvalue(const b_iterator *it)
{
B_CLASS_DISPATCH_VIRTUAL_0(
b_iterator, B_TYPE_ITERATOR, B_ITERATOR_VALUE_NULL,
it_get_cvalue, it);
}
b_status b_iterator_erase(b_iterator *it)
{
enum b_status status = B_ERR_NOT_SUPPORTED;
b_iterator_class *iface = b_object_get_interface(it, B_TYPE_ITERATOR);
if (iface && iface->it_erase) {
status = iface->it_erase(it);
}
struct b_iterator_p *p = b_object_get_private(it, B_TYPE_ITERATOR);
p->it_status = status;
return status;
}
/*** CLASS DEFINITION *********************************************************/
// ---- b_iterator DEFINITION
B_TYPE_CLASS_DEFINITION_BEGIN(b_iterator)
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
B_INTERFACE_ENTRY(to_string) = NULL;
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
B_TYPE_CLASS_DEFINITION_END(b_iterator)
B_TYPE_DEFINITION_BEGIN(b_iterator)
B_TYPE_FLAGS(B_TYPE_F_ABSTRACT);
B_TYPE_ID(0xfd40b67f, 0x7087, 0x40a9, 0x8fd8, 0x8ae27bd58c9e);
B_TYPE_CLASS(b_iterator_class);
B_TYPE_INSTANCE_PRIVATE(struct b_iterator_p);
B_TYPE_DEFINITION_END(b_iterator)
// ---- b_iterable DEFINITION
B_TYPE_CLASS_DEFINITION_BEGIN(b_iterable)
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
B_INTERFACE_ENTRY(to_string) = NULL;
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
B_TYPE_CLASS_DEFINITION_END(b_iterable)
B_TYPE_DEFINITION_BEGIN(b_iterable)
B_TYPE_FLAGS(B_TYPE_F_ABSTRACT);
B_TYPE_ID(0x4bbabf2d, 0xfc5d, 0x40cc, 0x89fc, 0x164085e47f73);
B_TYPE_CLASS(b_iterable_class);
B_TYPE_DEFINITION_END(b_iterable)
+4 -4
View File
@@ -1,10 +1,10 @@
#include <fx/misc.h>
#include <blue/core/misc.h>
#define LENGTH_RET(v, boundary, len) \
if ((v) < (boundary)) \
return (len);
size_t fx_int_length(intptr_t v)
size_t b_int_length(intptr_t v)
{
size_t len = 0;
if (v < 0) {
@@ -12,10 +12,10 @@ size_t fx_int_length(intptr_t v)
len++;
}
return len + fx_uint_length(v);
return len + b_uint_length(v);
}
size_t fx_uint_length(uintptr_t v)
size_t b_uint_length(uintptr_t v)
{
LENGTH_RET(v, 10, 1);
LENGTH_RET(v, 100, 2);
+15 -25
View File
@@ -29,8 +29,8 @@
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
@@ -55,7 +55,7 @@
#include "random.h"
#include <fx/random.h>
#include <blue/core/random.h>
#define NN 312
#define MM 156
@@ -64,17 +64,14 @@
#define LM 0x7FFFFFFFULL /* Least significant 31 bits */
/* initializes mt[NN] with a seed */
static void init_genrand64(
struct fx_random_ctx *context,
unsigned long long seed)
static void init_genrand64(struct b_random_ctx *context, unsigned long long seed)
{
context->__mt19937.mt[0] = seed;
for (context->__mt19937.mti = 1; context->__mt19937.mti < NN;
context->__mt19937.mti++)
context->__mt19937.mt[context->__mt19937.mti]
= (6364136223846793005ULL
* (context->__mt19937
.mt[context->__mt19937.mti - 1]
* (context->__mt19937.mt[context->__mt19937.mti - 1]
^ (context->__mt19937
.mt[context->__mt19937.mti - 1]
>> 62))
@@ -85,8 +82,7 @@ static void init_genrand64(
/* init_key is the array for initializing keys */
/* key_length is its length */
static void init_by_array64(
struct fx_random_ctx *context,
unsigned long long init_key[],
struct b_random_ctx *context, unsigned long long init_key[],
unsigned long long key_length)
{
unsigned long long i, j, k;
@@ -104,8 +100,7 @@ static void init_by_array64(
i++;
j++;
if (i >= NN) {
context->__mt19937.mt[0]
= context->__mt19937.mt[NN - 1];
context->__mt19937.mt[0] = context->__mt19937.mt[NN - 1];
i = 1;
}
if (j >= key_length)
@@ -120,8 +115,7 @@ static void init_by_array64(
- i; /* non linear */
i++;
if (i >= NN) {
context->__mt19937.mt[0]
= context->__mt19937.mt[NN - 1];
context->__mt19937.mt[0] = context->__mt19937.mt[NN - 1];
i = 1;
}
}
@@ -131,7 +125,7 @@ static void init_by_array64(
}
/* generates a random number on [0, 2^64-1]-interval */
static uint64_t genrand64_int64(struct fx_random_ctx *context)
static uint64_t genrand64_int64(struct b_random_ctx *context)
{
#if 0
/* This is the original implementation. It is replaced by the alternate implementation, below. */
@@ -191,14 +185,12 @@ static uint64_t genrand64_int64(struct fx_random_ctx *context)
| (context->__mt19937.mt[i + 1] & LM);
context->__mt19937.mt[i]
= context->__mt19937.mt[i + mid] ^ (x >> 1)
^ ((context->__mt19937.mt[i + 1] & 1)
* MATRIX_A);
^ ((context->__mt19937.mt[i + 1] & 1) * MATRIX_A);
y = (context->__mt19937.mt[j] & UM)
| (context->__mt19937.mt[j + 1] & LM);
context->__mt19937.mt[j]
= context->__mt19937.mt[j - mid] ^ (y >> 1)
^ ((context->__mt19937.mt[j + 1] & 1)
* MATRIX_A);
^ ((context->__mt19937.mt[j + 1] & 1) * MATRIX_A);
}
x = (context->__mt19937.mt[mid - 1] & UM) | (stateMid & LM);
context->__mt19937.mt[mid - 1] = context->__mt19937.mt[NN - 1]
@@ -225,28 +217,26 @@ static uint64_t genrand64_int64(struct fx_random_ctx *context)
#endif
}
#if FX_ENABLE_FLOATING_POINT == 1
/* generates a random number on [0,1]-real-interval */
double genrand64_real1(struct fx_random_ctx *context)
double genrand64_real1(struct b_random_ctx *context)
{
return (genrand64_int64(context) >> 11) * (1.0 / 9007199254740991.0);
}
/* generates a random number on [0,1)-real-interval */
double genrand64_real2(struct fx_random_ctx *context)
double genrand64_real2(struct b_random_ctx *context)
{
return (genrand64_int64(context) >> 11) * (1.0 / 9007199254740992.0);
}
/* generates a random number on (0,1)-real-interval */
double genrand64_real3(struct fx_random_ctx *context)
double genrand64_real3(struct b_random_ctx *context)
{
return ((genrand64_int64(context) >> 12) + 0.5)
* (1.0 / 4503599627370496.0);
}
#endif
struct fx_random_algorithm z__fx_gen_mt19937 = {
struct b_random_algorithm z__b_gen_mt19937 = {
.gen_name = "mt19937",
.gen_init = init_genrand64,
.gen_getrand = genrand64_int64,
+219
View File
@@ -0,0 +1,219 @@
#include "object.h"
#include "type.h"
#include <assert.h>
#include <blue/core/class.h>
#include <blue/core/macros.h>
#include <blue/core/object.h>
#include <blue/core/stream.h>
#include <blue/core/thread.h>
B_TYPE_CLASS_DEFINITION_BEGIN(b_object)
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
B_INTERFACE_ENTRY(to_string) = NULL;
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
B_TYPE_CLASS_DEFINITION_END(b_object)
B_TYPE_DEFINITION_BEGIN(b_object)
B_TYPE_ID(0x45f15a2c, 0x6831, 0x4bef, 0xb350, 0x15c650679211);
B_TYPE_CLASS(b_object_class);
B_TYPE_DEFINITION_END(b_object)
b_result b_object_instantiate(
struct b_type_registration *type, struct _b_object **out_object)
{
struct _b_object *out = malloc(type->r_instance_size);
if (!out) {
return B_RESULT_ERR(NO_MEMORY);
}
memset(out, 0x0, type->r_instance_size);
out->obj_magic = B_OBJECT_MAGIC;
out->obj_type = type;
out->obj_ref = 1;
struct b_queue_entry *entry = b_queue_first(&type->r_class_hierarchy);
while (entry) {
struct b_type_component *comp
= b_unbox(struct b_type_component, entry, c_entry);
const struct b_type_info *class_info = comp->c_type->r_info;
void *private_data
= (char *)out + comp->c_instance_private_data_offset;
if (class_info->t_instance_init) {
class_info->t_instance_init(out, private_data);
}
if (comp->c_type == type) {
out->obj_main_priv_offset
= comp->c_instance_private_data_offset;
}
entry = b_queue_next(entry);
}
*out_object = out;
return B_RESULT_SUCCESS;
}
struct _b_object *b_object_create(b_type type)
{
struct b_type_registration *type_reg = b_type_get_registration(type);
if (!type_reg) {
return NULL;
}
struct _b_object *out = NULL;
b_result result = b_object_instantiate(type_reg, &out);
if (b_result_is_error(result)) {
b_error_discard(result);
return NULL;
}
return out;
}
void b_object_to_string(const struct _b_object *p, b_stream *out)
{
B_CLASS_DISPATCH_VIRTUAL_V(b_object, B_TYPE_OBJECT, to_string, p, out);
b_stream_write_fmt(out, NULL, "<%s@%p>", p->obj_type->r_info->t_name, p);
}
bool b_object_is_type(const struct _b_object *p, b_type type)
{
if (b_type_id_compare(&p->obj_type->r_info->t_id, type) == 0) {
return true;
}
struct b_type_component *comp
= b_type_get_component(&p->obj_type->r_components, type);
return comp != NULL;
}
void *b_object_get_private(const struct _b_object *object, b_type type)
{
if (!object) {
return NULL;
}
assert(object->obj_magic == B_OBJECT_MAGIC);
if (b_type_id_compare(&object->obj_type->r_info->t_id, type) == 0) {
return (char *)object + object->obj_main_priv_offset;
}
struct b_type_component *comp
= b_type_get_component(&object->obj_type->r_components, type);
if (!comp) {
return NULL;
}
return (char *)object + comp->c_instance_private_data_offset;
}
void *b_object_get_protected(const struct _b_object *object, b_type type)
{
if (!object) {
return NULL;
}
assert(object->obj_magic == B_OBJECT_MAGIC);
struct b_type_component *comp
= b_type_get_component(&object->obj_type->r_components, type);
if (!comp) {
return NULL;
}
return (char *)object + comp->c_instance_protected_data_offset;
}
void *b_object_get_interface(const struct _b_object *object, b_type type)
{
if (!object) {
return NULL;
}
assert(object->obj_magic == B_OBJECT_MAGIC);
return b_class_get_interface(object->obj_type->r_class, type);
}
enum b_status b_object_get_data(
const struct _b_object *object, b_type type, void **priv, void **prot,
void **iface)
{
if (!object) {
return B_ERR_INVALID_ARGUMENT;
}
assert(object->obj_magic == B_OBJECT_MAGIC);
struct b_type_component *comp
= b_type_get_component(&object->obj_type->r_components, type);
if (!comp) {
return B_ERR_INVALID_ARGUMENT;
}
if (priv) {
*priv = (char *)object + comp->c_instance_private_data_offset;
}
if (prot) {
*prot = (char *)object + comp->c_instance_protected_data_offset;
}
if (iface) {
*iface = (char *)object->obj_type->r_class
+ comp->c_class_data_offset;
}
return B_SUCCESS;
}
struct _b_object *b_object_ref(struct _b_object *p)
{
p->obj_ref++;
return p;
}
void b_object_unref(struct _b_object *p)
{
if (p->obj_ref > 1) {
p->obj_ref--;
return;
}
p->obj_ref = 0;
const struct b_type_registration *type = p->obj_type;
struct b_queue_entry *cur = b_queue_last(&type->r_class_hierarchy);
while (cur) {
struct b_type_component *comp
= b_unbox(struct b_type_component, cur, c_entry);
const struct b_type_info *class_info = comp->c_type->r_info;
void *private_data
= (char *)p + comp->c_instance_private_data_offset;
if (class_info->t_instance_fini) {
class_info->t_instance_fini(p, private_data);
}
cur = b_queue_prev(cur);
}
p->obj_magic = 0;
p->obj_type = NULL;
free(p);
}
struct _b_object *b_object_make_rvalue(struct _b_object *p)
{
p->obj_ref = 0;
return p;
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef _OBJECT_H_
#define _OBJECT_H_
#include <blue/core/error.h>
#include <blue/core/misc.h>
#include <stdint.h>
struct b_type_registration;
struct _b_object {
uint64_t obj_magic;
const struct b_type_registration *obj_type;
unsigned int obj_ref, obj_main_priv_offset;
};
extern b_result b_object_instantiate(
struct b_type_registration *type, struct _b_object **out);
#endif
+1 -6
View File
@@ -45,11 +45,6 @@
#include "printf.h"
#if FX_ENABLE_FLOATING_POINT == 0
#define PRINTF_SUPPORT_DECIMAL_SPECIFIERS 0
#define PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS 0
#endif
#ifdef __cplusplus
#include <climits>
#include <cstdint>
@@ -1626,7 +1621,7 @@ static int vsnprintf_impl(output_gadget_t *output, const char *format, va_list a
return (int)output->pos;
}
int z__fx_fctprintf(
int z__b_fctprintf(
void (*out)(char c, void *extra_arg), void *extra_arg,
const char *format, va_list arg)
{
+1 -1
View File
@@ -132,7 +132,7 @@ void putchar_(char c);
*
*/
PRINTF_VISIBILITY
int z__fx_fctprintf(
int z__b_fctprintf(
void (*out)(char c, void *extra_arg), void *extra_arg,
const char *format, va_list arg) ATTR_VPRINTF(3);
+245
View File
@@ -0,0 +1,245 @@
#include <blue/core/queue.h>
struct b_queue_iterator_p {
size_t i;
b_queue_entry *entry;
b_queue *_q;
};
size_t b_queue_length(const struct b_queue *q)
{
size_t i = 0;
struct b_queue_entry *x = q->q_first;
while (x) {
i++;
x = x->qe_next;
}
return i;
}
void b_queue_insert_before(
struct b_queue *q, struct b_queue_entry *entry, struct b_queue_entry *before)
{
struct b_queue_entry *x = before->qe_prev;
if (x) {
x->qe_next = entry;
} else {
q->q_first = entry;
}
entry->qe_prev = x;
before->qe_prev = entry;
entry->qe_next = before;
}
void b_queue_insert_after(
struct b_queue *q, struct b_queue_entry *entry, struct b_queue_entry *after)
{
struct b_queue_entry *x = after->qe_next;
if (x) {
x->qe_prev = entry;
} else {
q->q_last = entry;
}
entry->qe_next = x;
after->qe_next = entry;
entry->qe_prev = after;
}
void b_queue_push_front(struct b_queue *q, struct b_queue_entry *entry)
{
if (q->q_first) {
q->q_first->qe_prev = entry;
}
entry->qe_next = q->q_first;
entry->qe_prev = NULL;
q->q_first = entry;
if (!q->q_last) {
q->q_last = entry;
}
}
void b_queue_push_back(struct b_queue *q, struct b_queue_entry *entry)
{
if (q->q_last) {
q->q_last->qe_next = entry;
}
entry->qe_prev = q->q_last;
entry->qe_next = NULL;
q->q_last = entry;
if (!q->q_first) {
q->q_first = entry;
}
}
struct b_queue_entry *b_queue_pop_front(struct b_queue *q)
{
struct b_queue_entry *x = q->q_first;
if (x) {
b_queue_delete(q, x);
}
return x;
}
struct b_queue_entry *b_queue_pop_back(struct b_queue *q)
{
struct b_queue_entry *x = q->q_last;
if (x) {
b_queue_delete(q, x);
}
return x;
}
void b_queue_move(b_queue *q, b_queue_entry *dest, b_queue_entry *src)
{
if (src->qe_next) {
src->qe_next->qe_prev = dest;
}
if (src->qe_prev) {
src->qe_prev->qe_next = dest;
}
if (q->q_first == src) {
q->q_first = dest;
}
if (q->q_last == src) {
q->q_last = dest;
}
memmove(dest, src, sizeof *src);
}
void b_queue_delete(struct b_queue *q, struct b_queue_entry *entry)
{
if (!entry) {
return;
}
if (entry == q->q_first) {
q->q_first = q->q_first->qe_next;
}
if (entry == q->q_last) {
q->q_last = q->q_last->qe_prev;
}
if (entry->qe_next) {
entry->qe_next->qe_prev = entry->qe_prev;
}
if (entry->qe_prev) {
entry->qe_prev->qe_next = entry->qe_next;
}
entry->qe_next = entry->qe_prev = NULL;
}
void b_queue_delete_all(struct b_queue *q)
{
struct b_queue_entry *x = q->q_first;
while (x) {
struct b_queue_entry *next = x->qe_next;
x->qe_next = x->qe_prev = NULL;
x = next;
}
q->q_first = q->q_last = NULL;
}
b_iterator *b_queue_begin(struct b_queue *q)
{
b_queue_iterator *it_obj = b_object_create(B_TYPE_QUEUE_ITERATOR);
struct b_queue_iterator_p *it
= b_object_get_private(it_obj, B_TYPE_QUEUE_ITERATOR);
it->_q = (struct b_queue *)q;
it->entry = q->q_first;
it->i = 0;
if (!it->entry) {
b_iterator_set_status(it_obj, B_ERR_NO_DATA);
}
return it_obj;
}
static enum b_status iterator_move_next(const b_iterator *obj)
{
struct b_queue_iterator_p *it
= b_object_get_private(obj, B_TYPE_QUEUE_ITERATOR);
if (!it->entry) {
return B_ERR_NO_DATA;
}
it->entry = it->entry->qe_next;
it->i++;
return (it->entry != NULL) ? B_SUCCESS : B_ERR_NO_DATA;
}
static enum b_status iterator_erase(b_iterator *obj)
{
struct b_queue_iterator_p *it
= b_object_get_private(obj, B_TYPE_QUEUE_ITERATOR);
if (!it->entry) {
return B_ERR_OUT_OF_BOUNDS;
}
struct b_queue_entry *next = it->entry->qe_next;
b_queue_delete(it->_q, it->entry);
it->entry = next;
return B_SUCCESS;
}
static b_iterator_value iterator_get_value(b_iterator *obj)
{
struct b_queue_iterator_p *it
= b_object_get_private(obj, B_TYPE_QUEUE_ITERATOR);
return B_ITERATOR_VALUE_PTR(it->entry);
}
static const b_iterator_value iterator_get_cvalue(const b_iterator *obj)
{
struct b_queue_iterator_p *it
= b_object_get_private(obj, B_TYPE_QUEUE_ITERATOR);
return B_ITERATOR_VALUE_CPTR(it->entry);
}
B_TYPE_CLASS_DEFINITION_BEGIN(b_queue_iterator)
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
B_INTERFACE_ENTRY(to_string) = NULL;
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
B_TYPE_CLASS_INTERFACE_BEGIN(b_iterator, B_TYPE_ITERATOR)
B_INTERFACE_ENTRY(it_move_next) = iterator_move_next;
B_INTERFACE_ENTRY(it_erase) = iterator_erase;
B_INTERFACE_ENTRY(it_get_value) = iterator_get_value;
B_INTERFACE_ENTRY(it_get_cvalue) = iterator_get_cvalue;
B_TYPE_CLASS_INTERFACE_END(b_iterator, B_TYPE_ITERATOR)
B_TYPE_CLASS_DEFINITION_END(b_queue_iterator)
B_TYPE_DEFINITION_BEGIN(b_queue_iterator)
B_TYPE_ID(0x560dc263, 0xff98, 0x4812, 0x9b29, 0xa1218bd70881);
B_TYPE_EXTENDS(B_TYPE_ITERATOR);
B_TYPE_CLASS(b_queue_iterator_class);
B_TYPE_INSTANCE_PRIVATE(struct b_queue_iterator_p);
B_TYPE_DEFINITION_END(b_queue_iterator)
+20 -25
View File
@@ -1,24 +1,24 @@
#include "random.h"
#include <fx/random.h>
#include <blue/core/random.h>
#define GET_ALGORITHM_ID(flags) ((flags) & 0xFF)
FX_API struct fx_random_algorithm z__fx_gen_mt19937;
BLUE_API struct b_random_algorithm z__b_gen_mt19937;
static struct fx_random_algorithm *generators[] = {
[FX_RANDOM_MT19937] = &z__fx_gen_mt19937,
static struct b_random_algorithm *generators[] = {
[B_RANDOM_MT19937] = &z__b_gen_mt19937,
};
static size_t nr_generators = sizeof generators / sizeof generators[0];
static struct fx_random_ctx g_global_ctx = {0};
static struct b_random_ctx g_global_ctx = {0};
static void init_global_ctx(void)
{
fx_random_init(&g_global_ctx, FX_RANDOM_MT19937);
b_random_init(&g_global_ctx, B_RANDOM_MT19937);
}
struct fx_random_ctx *fx_random_global_ctx(void)
struct b_random_ctx *b_random_global_ctx(void)
{
if (!g_global_ctx.__f) {
init_global_ctx();
@@ -27,31 +27,31 @@ struct fx_random_ctx *fx_random_global_ctx(void)
return &g_global_ctx;
}
fx_status fx_random_init(struct fx_random_ctx *ctx, fx_random_flags flags)
b_status b_random_init(struct b_random_ctx *ctx, b_random_flags flags)
{
unsigned int algorithm_id = GET_ALGORITHM_ID(flags);
if (algorithm_id >= nr_generators || !generators[algorithm_id]) {
return FX_ERR_INVALID_ARGUMENT;
return B_ERR_INVALID_ARGUMENT;
}
struct fx_random_algorithm *algorithm = generators[algorithm_id];
struct b_random_algorithm *algorithm = generators[algorithm_id];
ctx->__f = flags;
ctx->__a = algorithm;
unsigned long long seed;
if (flags & FX_RANDOM_SECURE) {
seed = z__fx_platform_random_seed_secure();
if (flags & B_RANDOM_SECURE) {
seed = z__b_platform_random_seed_secure();
} else {
seed = z__fx_platform_random_seed();
seed = z__b_platform_random_seed();
}
algorithm->gen_init(ctx, seed);
return FX_SUCCESS;
return B_SUCCESS;
}
unsigned long long fx_random_next_int64(struct fx_random_ctx *ctx)
unsigned long long b_random_next_int64(struct b_random_ctx *ctx)
{
if (!ctx->__a || !ctx->__a->gen_getrand) {
return 0;
@@ -60,22 +60,17 @@ unsigned long long fx_random_next_int64(struct fx_random_ctx *ctx)
return ctx->__a->gen_getrand(ctx);
}
#if FX_ENABLE_FLOATING_POINT
double fx_random_next_double(struct fx_random_ctx *ctx)
double b_random_next_double(struct b_random_ctx *ctx)
{
unsigned long long v = fx_random_next_int64(ctx);
unsigned long long v = b_random_next_int64(ctx);
if (!v) {
return 0.0;
}
return (double)(v >> 11) * (1.0 / 9007199254740991.0);
}
#endif
void fx_random_next_bytes(
struct fx_random_ctx *ctx,
unsigned char *out,
size_t nbytes)
void b_random_next_bytes(struct b_random_ctx *ctx, unsigned char *out, size_t nbytes)
{
size_t n_qwords = 0;
n_qwords = nbytes >> 3;
@@ -87,7 +82,7 @@ void fx_random_next_bytes(
size_t bytes_written = 0;
for (size_t i = 0; i < n_qwords; i++) {
uint64_t *dest = (uint64_t *)&out[bytes_written];
*dest = fx_random_next_int64(ctx);
*dest = b_random_next_int64(ctx);
bytes_written += 8;
}
@@ -95,7 +90,7 @@ void fx_random_next_bytes(
return;
}
uint64_t padding = fx_random_next_int64(ctx);
uint64_t padding = b_random_next_int64(ctx);
unsigned char *padding_bytes = (unsigned char *)&padding;
for (size_t i = 0; i < 8; i++) {
+18
View File
@@ -0,0 +1,18 @@
#ifndef _BLUELIB_RANDOM_H_
#define _BLUELIB_RANDOM_H_
#include <stdint.h>
#include <blue/core/misc.h>
struct b_random_ctx;
struct b_random_algorithm {
const char *gen_name;
void(*gen_init)(struct b_random_ctx *, unsigned long long seed);
uint64_t(*gen_getrand)(struct b_random_ctx *);
};
BLUE_API uint64_t z__b_platform_random_seed(void);
BLUE_API uint64_t z__b_platform_random_seed_secure(void);
#endif
+107 -165
View File
@@ -1,4 +1,4 @@
#include <fx/ringbuffer.h>
#include <blue/core/ringbuffer.h>
#include <stdlib.h>
#include <string.h>
@@ -14,7 +14,7 @@ enum ringbuffer_flags {
RINGBUFFER_WRITE_LOCKED = 0x08u,
};
struct fx_ringbuffer_p {
struct b_ringbuffer_p {
enum ringbuffer_flags r_flags;
void *r_buf, *r_opened_buf;
unsigned long r_capacity, r_opened_capacity;
@@ -23,19 +23,18 @@ struct fx_ringbuffer_p {
/*** PRIVATE FUNCTIONS ********************************************************/
static enum fx_status ringbuffer_clear(struct fx_ringbuffer_p *buf)
static enum b_status ringbuffer_clear(struct b_ringbuffer_p *buf)
{
if (BUF_LOCKED(buf)) {
return FX_ERR_BUSY;
return B_ERR_BUSY;
}
buf->r_read_ptr = buf->r_write_ptr = 0;
return FX_SUCCESS;
return B_SUCCESS;
}
static size_t ringbuffer_write_capacity_remaining(
const struct fx_ringbuffer_p *buf)
static size_t ringbuffer_write_capacity_remaining(const struct b_ringbuffer_p *buf)
{
if (buf->r_read_ptr > buf->r_write_ptr) {
return buf->r_read_ptr - buf->r_write_ptr - 1;
@@ -44,8 +43,7 @@ static size_t ringbuffer_write_capacity_remaining(
}
}
static size_t ringbuffer_available_data_remaining(
const struct fx_ringbuffer_p *buf)
static size_t ringbuffer_available_data_remaining(const struct b_ringbuffer_p *buf)
{
if (buf->r_read_ptr < buf->r_write_ptr) {
return buf->r_write_ptr - buf->r_read_ptr;
@@ -56,13 +54,11 @@ static size_t ringbuffer_available_data_remaining(
}
}
static enum fx_status ringbuffer_open_read_buffer(
struct fx_ringbuffer_p *buf,
const void **ptr,
size_t *length)
static enum b_status ringbuffer_open_read_buffer(
struct b_ringbuffer_p *buf, const void **ptr, size_t *length)
{
if (BUF_LOCKED(buf)) {
return FX_ERR_BUSY;
return B_ERR_BUSY;
}
size_t contiguous_capacity = 0;
@@ -73,7 +69,7 @@ static enum fx_status ringbuffer_open_read_buffer(
}
if (contiguous_capacity == 0) {
return FX_ERR_NO_DATA;
return B_ERR_NO_DATA;
}
buf->r_opened_buf = (char *)buf->r_buf + buf->r_read_ptr;
@@ -83,24 +79,22 @@ static enum fx_status ringbuffer_open_read_buffer(
*ptr = buf->r_opened_buf;
*length = contiguous_capacity;
return FX_SUCCESS;
return B_SUCCESS;
}
static enum fx_status ringbuffer_close_read_buffer(
struct fx_ringbuffer_p *buf,
const void **ptr,
size_t nr_read)
static enum b_status ringbuffer_close_read_buffer(
struct b_ringbuffer_p *buf, const void **ptr, size_t nr_read)
{
if (!(buf->r_flags & RINGBUFFER_READ_LOCKED)) {
return FX_ERR_BAD_STATE;
return B_ERR_BAD_STATE;
}
if (*ptr != buf->r_opened_buf) {
return FX_ERR_INVALID_ARGUMENT;
return B_ERR_INVALID_ARGUMENT;
}
if (nr_read > buf->r_opened_capacity) {
return FX_ERR_INVALID_ARGUMENT;
return B_ERR_INVALID_ARGUMENT;
}
buf->r_read_ptr += nr_read;
@@ -120,16 +114,14 @@ static enum fx_status ringbuffer_close_read_buffer(
buf->r_opened_capacity = 0;
buf->r_flags &= ~RINGBUFFER_READ_LOCKED;
return FX_SUCCESS;
return B_SUCCESS;
}
static enum fx_status ringbuffer_open_write_buffer(
struct fx_ringbuffer_p *buf,
void **ptr,
size_t *capacity)
static enum b_status ringbuffer_open_write_buffer(
struct b_ringbuffer_p *buf, void **ptr, size_t *capacity)
{
if (BUF_LOCKED(buf)) {
return FX_ERR_BUSY;
return B_ERR_BUSY;
}
size_t contiguous_capacity = 0;
@@ -144,7 +136,7 @@ static enum fx_status ringbuffer_open_write_buffer(
}
if (contiguous_capacity == 0) {
return FX_ERR_NO_SPACE;
return B_ERR_NO_SPACE;
}
buf->r_opened_buf = (char *)buf->r_buf + buf->r_write_ptr;
@@ -154,24 +146,22 @@ static enum fx_status ringbuffer_open_write_buffer(
*ptr = buf->r_opened_buf;
*capacity = contiguous_capacity;
return FX_SUCCESS;
return B_SUCCESS;
}
static enum fx_status ringbuffer_close_write_buffer(
struct fx_ringbuffer_p *buf,
void **ptr,
size_t nr_written)
static enum b_status ringbuffer_close_write_buffer(
struct b_ringbuffer_p *buf, void **ptr, size_t nr_written)
{
if (!(buf->r_flags & RINGBUFFER_WRITE_LOCKED)) {
return FX_ERR_BAD_STATE;
return B_ERR_BAD_STATE;
}
if (*ptr != buf->r_opened_buf) {
return FX_ERR_INVALID_ARGUMENT;
return B_ERR_INVALID_ARGUMENT;
}
if (nr_written > buf->r_opened_capacity) {
return FX_ERR_INVALID_ARGUMENT;
return B_ERR_INVALID_ARGUMENT;
}
buf->r_write_ptr += nr_written;
@@ -183,17 +173,14 @@ static enum fx_status ringbuffer_close_write_buffer(
buf->r_opened_capacity = 0;
buf->r_flags &= ~RINGBUFFER_WRITE_LOCKED;
return FX_SUCCESS;
return B_SUCCESS;
}
static enum fx_status ringbuffer_read(
struct fx_ringbuffer_p *buf,
void *p,
size_t count,
size_t *nr_read)
static enum b_status ringbuffer_read(
struct b_ringbuffer_p *buf, void *p, size_t count, size_t *nr_read)
{
if (BUF_LOCKED(buf)) {
return FX_ERR_BUSY;
return B_ERR_BUSY;
}
size_t r = 0;
@@ -203,14 +190,14 @@ static enum fx_status ringbuffer_read(
while (remaining > 0) {
const void *src;
size_t available;
enum fx_status status
enum b_status status
= ringbuffer_open_read_buffer(buf, &src, &available);
if (status == FX_ERR_NO_DATA) {
if (status == B_ERR_NO_DATA) {
break;
}
if (!FX_OK(status)) {
if (!B_OK(status)) {
return status;
}
@@ -229,17 +216,14 @@ static enum fx_status ringbuffer_read(
}
*nr_read = r;
return FX_SUCCESS;
return B_SUCCESS;
}
static enum fx_status ringbuffer_write(
struct fx_ringbuffer_p *buf,
const void *p,
size_t count,
size_t *nr_written)
static enum b_status ringbuffer_write(
struct b_ringbuffer_p *buf, const void *p, size_t count, size_t *nr_written)
{
if (BUF_LOCKED(buf)) {
return FX_ERR_BUSY;
return B_ERR_BUSY;
}
size_t w = 0;
@@ -249,14 +233,14 @@ static enum fx_status ringbuffer_write(
while (remaining > 0) {
void *dest;
size_t available;
enum fx_status status
enum b_status status
= ringbuffer_open_write_buffer(buf, &dest, &available);
if (status == FX_ERR_NO_SPACE) {
if (status == B_ERR_NO_SPACE) {
break;
}
if (!FX_OK(status)) {
if (!B_OK(status)) {
return status;
}
@@ -275,10 +259,10 @@ static enum fx_status ringbuffer_write(
}
*nr_written = w;
return FX_SUCCESS;
return B_SUCCESS;
}
static int ringbuffer_getc(struct fx_ringbuffer_p *buf)
static int ringbuffer_getc(struct b_ringbuffer_p *buf)
{
size_t available = ringbuffer_available_data_remaining(buf);
if (available == 0) {
@@ -295,11 +279,11 @@ static int ringbuffer_getc(struct fx_ringbuffer_p *buf)
return c;
}
static enum fx_status ringbuffer_putc(struct fx_ringbuffer_p *buf, int c)
static enum b_status ringbuffer_putc(struct b_ringbuffer_p *buf, int c)
{
size_t available = ringbuffer_write_capacity_remaining(buf);
if (available == 0) {
return FX_ERR_NO_SPACE;
return B_ERR_NO_SPACE;
}
char *p = buf->r_buf;
@@ -314,19 +298,19 @@ static enum fx_status ringbuffer_putc(struct fx_ringbuffer_p *buf, int c)
/*** PUBLIC FUNCTIONS *********************************************************/
fx_ringbuffer *fx_ringbuffer_create(size_t capacity)
b_ringbuffer *b_ringbuffer_create(size_t capacity)
{
fx_ringbuffer *ringbuf = fx_object_create(FX_TYPE_RINGBUFFER);
b_ringbuffer *ringbuf = b_object_create(B_TYPE_RINGBUFFER);
if (!ringbuf) {
return NULL;
}
struct fx_ringbuffer_p *p
= fx_object_get_private(ringbuf, FX_TYPE_RINGBUFFER);
struct b_ringbuffer_p *p
= b_object_get_private(ringbuf, B_TYPE_RINGBUFFER);
void *buffer = malloc(capacity);
if (!buffer) {
fx_ringbuffer_unref(ringbuf);
b_ringbuffer_unref(ringbuf);
return NULL;
}
@@ -337,15 +321,15 @@ fx_ringbuffer *fx_ringbuffer_create(size_t capacity)
return ringbuf;
}
fx_ringbuffer *fx_ringbuffer_create_with_buffer(void *ptr, size_t capacity)
b_ringbuffer *b_ringbuffer_create_with_buffer(void *ptr, size_t capacity)
{
fx_ringbuffer *ringbuf = fx_object_create(FX_TYPE_RINGBUFFER);
b_ringbuffer *ringbuf = b_object_create(B_TYPE_RINGBUFFER);
if (!ringbuf) {
return NULL;
}
struct fx_ringbuffer_p *p
= fx_object_get_private(ringbuf, FX_TYPE_RINGBUFFER);
struct b_ringbuffer_p *p
= b_object_get_private(ringbuf, B_TYPE_RINGBUFFER);
p->r_flags = 0;
p->r_buf = ptr;
@@ -354,129 +338,87 @@ fx_ringbuffer *fx_ringbuffer_create_with_buffer(void *ptr, size_t capacity)
return ringbuf;
}
enum fx_status fx_ringbuffer_clear(fx_ringbuffer *buf)
enum b_status b_ringbuffer_clear(b_ringbuffer *buf)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_RINGBUFFER, ringbuffer_clear, buf);
B_CLASS_DISPATCH_STATIC_0(B_TYPE_RINGBUFFER, ringbuffer_clear, buf);
}
enum fx_status fx_ringbuffer_read(
fx_ringbuffer *buf,
void *p,
size_t count,
size_t *nr_read)
enum b_status b_ringbuffer_read(
b_ringbuffer *buf, void *p, size_t count, size_t *nr_read)
{
FX_CLASS_DISPATCH_STATIC(
FX_TYPE_RINGBUFFER,
ringbuffer_read,
buf,
p,
count,
nr_read);
B_CLASS_DISPATCH_STATIC(
B_TYPE_RINGBUFFER, ringbuffer_read, buf, p, count, nr_read);
}
enum fx_status fx_ringbuffer_write(
fx_ringbuffer *buf,
const void *p,
size_t count,
size_t *nr_written)
enum b_status b_ringbuffer_write(
b_ringbuffer *buf, const void *p, size_t count, size_t *nr_written)
{
FX_CLASS_DISPATCH_STATIC(
FX_TYPE_RINGBUFFER,
ringbuffer_write,
buf,
p,
count,
nr_written);
B_CLASS_DISPATCH_STATIC(
B_TYPE_RINGBUFFER, ringbuffer_write, buf, p, count, nr_written);
}
int fx_ringbuffer_getc(fx_ringbuffer *buf)
int b_ringbuffer_getc(b_ringbuffer *buf)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_RINGBUFFER, ringbuffer_getc, buf);
B_CLASS_DISPATCH_STATIC_0(B_TYPE_RINGBUFFER, ringbuffer_getc, buf);
}
enum fx_status fx_ringbuffer_putc(fx_ringbuffer *buf, int c)
enum b_status b_ringbuffer_putc(b_ringbuffer *buf, int c)
{
FX_CLASS_DISPATCH_STATIC(FX_TYPE_RINGBUFFER, ringbuffer_putc, buf, c);
B_CLASS_DISPATCH_STATIC(B_TYPE_RINGBUFFER, ringbuffer_putc, buf, c);
}
size_t fx_ringbuffer_write_capacity_remaining(const fx_ringbuffer *buf)
size_t b_ringbuffer_write_capacity_remaining(const b_ringbuffer *buf)
{
FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_RINGBUFFER,
ringbuffer_write_capacity_remaining,
buf);
B_CLASS_DISPATCH_STATIC_0(
B_TYPE_RINGBUFFER, ringbuffer_write_capacity_remaining, buf);
}
size_t fx_ringbuffer_available_data_remaining(const fx_ringbuffer *buf)
size_t b_ringbuffer_available_data_remaining(const b_ringbuffer *buf)
{
FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_RINGBUFFER,
ringbuffer_available_data_remaining,
buf);
B_CLASS_DISPATCH_STATIC_0(
B_TYPE_RINGBUFFER, ringbuffer_available_data_remaining, buf);
}
enum fx_status fx_ringbuffer_open_read_buffer(
fx_ringbuffer *buf,
const void **ptr,
size_t *length)
enum b_status b_ringbuffer_open_read_buffer(
b_ringbuffer *buf, const void **ptr, size_t *length)
{
FX_CLASS_DISPATCH_STATIC(
FX_TYPE_RINGBUFFER,
ringbuffer_open_read_buffer,
buf,
ptr,
length);
B_CLASS_DISPATCH_STATIC(
B_TYPE_RINGBUFFER, ringbuffer_open_read_buffer, buf, ptr, length);
}
enum fx_status fx_ringbuffer_close_read_buffer(
fx_ringbuffer *buf,
const void **ptr,
size_t nr_read)
enum b_status b_ringbuffer_close_read_buffer(
b_ringbuffer *buf, const void **ptr, size_t nr_read)
{
FX_CLASS_DISPATCH_STATIC(
FX_TYPE_RINGBUFFER,
ringbuffer_close_read_buffer,
buf,
ptr,
nr_read);
B_CLASS_DISPATCH_STATIC(
B_TYPE_RINGBUFFER, ringbuffer_close_read_buffer, buf, ptr, nr_read);
}
enum fx_status fx_ringbuffer_open_write_buffer(
fx_ringbuffer *buf,
void **ptr,
size_t *capacity)
enum b_status b_ringbuffer_open_write_buffer(
b_ringbuffer *buf, void **ptr, size_t *capacity)
{
FX_CLASS_DISPATCH_STATIC(
FX_TYPE_RINGBUFFER,
ringbuffer_open_write_buffer,
buf,
ptr,
B_CLASS_DISPATCH_STATIC(
B_TYPE_RINGBUFFER, ringbuffer_open_write_buffer, buf, ptr,
capacity);
}
enum fx_status fx_ringbuffer_close_write_buffer(
fx_ringbuffer *buf,
void **ptr,
size_t nr_written)
enum b_status b_ringbuffer_close_write_buffer(
b_ringbuffer *buf, void **ptr, size_t nr_written)
{
FX_CLASS_DISPATCH_STATIC(
FX_TYPE_RINGBUFFER,
ringbuffer_close_write_buffer,
buf,
ptr,
B_CLASS_DISPATCH_STATIC(
B_TYPE_RINGBUFFER, ringbuffer_close_write_buffer, buf, ptr,
nr_written);
}
/*** VIRTUAL FUNCTIONS ********************************************************/
static void ringbuffer_init(fx_object *obj, void *priv)
static void ringbuffer_init(b_object *obj, void *priv)
{
struct fx_ringbuffer_p *buf = priv;
struct b_ringbuffer_p *buf = priv;
}
static void ringbuffer_fini(fx_object *obj, void *priv)
static void ringbuffer_fini(b_object *obj, void *priv)
{
struct fx_ringbuffer_p *buf = priv;
struct b_ringbuffer_p *buf = priv;
if (buf->r_flags & RINGBUFFER_BUFFER_MALLOC) {
free(buf->r_buf);
@@ -485,16 +427,16 @@ static void ringbuffer_fini(fx_object *obj, void *priv)
/*** CLASS DEFINITION *********************************************************/
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_ringbuffer)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = NULL;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_CLASS_DEFINITION_END(fx_ringbuffer)
B_TYPE_CLASS_DEFINITION_BEGIN(b_ringbuffer)
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
B_INTERFACE_ENTRY(to_string) = NULL;
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
B_TYPE_CLASS_DEFINITION_END(b_ringbuffer)
FX_TYPE_DEFINITION_BEGIN(fx_ringbuffer)
FX_TYPE_ID(0xb0493774, 0xef13, 0x4905, 0xa865, 0x1595607ccad9);
FX_TYPE_CLASS(fx_ringbuffer_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_ringbuffer_p);
FX_TYPE_INSTANCE_INIT(ringbuffer_init);
FX_TYPE_INSTANCE_FINI(ringbuffer_fini);
FX_TYPE_DEFINITION_END(fx_ringbuffer)
B_TYPE_DEFINITION_BEGIN(b_ringbuffer)
B_TYPE_ID(0xb0493774, 0xef13, 0x4905, 0xa865, 0x1595607ccad9);
B_TYPE_CLASS(b_ringbuffer_class);
B_TYPE_INSTANCE_PRIVATE(struct b_ringbuffer_p);
B_TYPE_INSTANCE_INIT(ringbuffer_init);
B_TYPE_INSTANCE_FINI(ringbuffer_fini);
B_TYPE_DEFINITION_END(b_ringbuffer)
+275
View File
@@ -0,0 +1,275 @@
#include <blue/core/bstr.h>
#include <blue/core/rope.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void b_rope_init_char(struct b_rope *rope, char c)
{
memset(rope, 0x0, sizeof *rope);
rope->r_flags = B_ROPE_F_CHAR;
rope->r_len_left = rope->r_len_total = 1;
rope->r_v.v_char = c;
}
void b_rope_init_cstr(struct b_rope *rope, const char *s)
{
memset(rope, 0x0, sizeof *rope);
rope->r_flags = B_ROPE_F_CSTR;
rope->r_v.v_cstr.hash = b_hash_cstr_ex(s, &rope->r_len_total);
rope->r_len_left = rope->r_len_total;
char *s2 = malloc(rope->r_len_total + 1);
if (!s2) {
return;
}
strcpy(s2, s);
s2[rope->r_len_total] = '\0';
rope->r_v.v_cstr.s = s2;
}
void b_rope_init_cstr_borrowed(struct b_rope *rope, const char *s)
{
memset(rope, 0x0, sizeof *rope);
rope->r_flags = B_ROPE_F_CSTR_BORROWED;
rope->r_v.v_cstr.s = s;
rope->r_v.v_cstr.hash = b_hash_cstr_ex(s, &rope->r_len_total);
rope->r_len_left = rope->r_len_total;
}
void b_rope_init_cstr_static(struct b_rope *rope, const char *s)
{
memset(rope, 0x0, sizeof *rope);
rope->r_flags = B_ROPE_F_CSTR_STATIC;
rope->r_v.v_cstr.s = s;
rope->r_v.v_cstr.hash = b_hash_cstr_ex(s, &rope->r_len_total);
rope->r_len_left = rope->r_len_total;
}
void b_rope_init_int(struct b_rope *rope, intptr_t v)
{
memset(rope, 0x0, sizeof *rope);
rope->r_flags = B_ROPE_F_INT;
rope->r_len_left = rope->r_len_total = b_int_length(v);
rope->r_v.v_int = v;
}
void b_rope_init_uint(struct b_rope *rope, uintptr_t v)
{
memset(rope, 0x0, sizeof *rope);
rope->r_flags = B_ROPE_F_UINT;
rope->r_len_left = rope->r_len_total = b_uint_length(v);
rope->r_v.v_uint = v;
}
void b_rope_destroy(struct b_rope *rope)
{
unsigned int type = B_ROPE_TYPE(rope->r_flags);
switch (type) {
case B_ROPE_F_CSTR:
free((char *)rope->r_v.v_cstr.s);
break;
case B_ROPE_F_COMPOSITE:
b_rope_destroy((struct b_rope *)rope->r_v.v_composite.r_left);
b_rope_destroy((struct b_rope *)rope->r_v.v_composite.r_right);
break;
default:
break;
}
if (rope->r_flags & B_ROPE_F_MALLOC) {
free(rope);
}
}
void b_rope_iterate(
const struct b_rope *rope, void (*func)(const b_rope *, void *), void *arg)
{
if (B_ROPE_TYPE(rope->r_flags) != B_ROPE_F_COMPOSITE) {
func(rope, arg);
return;
}
if (rope->r_v.v_composite.r_left) {
b_rope_iterate(rope->r_v.v_composite.r_left, func, arg);
}
if (rope->r_v.v_composite.r_right) {
b_rope_iterate(rope->r_v.v_composite.r_right, func, arg);
}
}
size_t b_rope_get_size(const struct b_rope *rope)
{
return rope->r_len_total;
}
void b_rope_concat(
struct b_rope *result, const struct b_rope *left, const struct b_rope *right)
{
memset(result, 0x0, sizeof *result);
result->r_flags = B_ROPE_F_COMPOSITE;
result->r_len_left = left->r_len_total;
result->r_len_total = left->r_len_total + right->r_len_total;
result->r_v.v_composite.r_left = left;
result->r_v.v_composite.r_right = right;
}
static struct b_rope *create_composite_node(void)
{
struct b_rope *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->r_flags = B_ROPE_F_COMPOSITE | B_ROPE_F_MALLOC;
return out;
}
void b_rope_join(b_rope *result, const b_rope **ropes, size_t nr_ropes)
{
if (nr_ropes == 0) {
return;
}
if (nr_ropes == 1) {
*result = *ropes[0];
return;
}
struct b_rope *prev = NULL;
for (size_t i = 0; i < nr_ropes - 1; i++) {
const struct b_rope *left = ropes[i];
const struct b_rope *right = ropes[i + 1];
if (prev) {
left = prev;
}
struct b_rope *composite = create_composite_node();
if (!composite) {
return;
}
composite->r_len_left = left->r_len_total;
composite->r_len_total = left->r_len_total + right->r_len_total;
composite->r_v.v_composite.r_left = left;
composite->r_v.v_composite.r_right = right;
prev = composite;
}
*result = *prev;
result->r_flags &= ~B_ROPE_F_MALLOC;
free(prev);
}
static void rope_iterate(
const struct b_rope *rope,
void (*callback)(const struct b_rope *, void *), void *arg)
{
unsigned int type = B_ROPE_TYPE(rope->r_flags);
switch (type) {
case B_ROPE_F_CHAR:
case B_ROPE_F_CSTR:
case B_ROPE_F_CSTR_BORROWED:
case B_ROPE_F_CSTR_STATIC:
case B_ROPE_F_INT:
case B_ROPE_F_UINT:
callback(rope, arg);
break;
case B_ROPE_F_COMPOSITE:
rope_iterate(rope->r_v.v_composite.r_left, callback, arg);
rope_iterate(rope->r_v.v_composite.r_right, callback, arg);
break;
default:
break;
}
}
static void to_bstr(const struct b_rope *rope, void *arg)
{
b_bstr *str = arg;
unsigned int type = B_ROPE_TYPE(rope->r_flags);
switch (type) {
case B_ROPE_F_CHAR:
b_bstr_write_char(str, rope->r_v.v_char);
break;
case B_ROPE_F_CSTR:
case B_ROPE_F_CSTR_BORROWED:
case B_ROPE_F_CSTR_STATIC:
b_bstr_write_cstr(str, rope->r_v.v_cstr.s, NULL);
break;
case B_ROPE_F_INT:
b_bstr_write_fmt(str, NULL, "%" PRIdPTR, rope->r_v.v_int);
break;
case B_ROPE_F_UINT:
b_bstr_write_fmt(str, NULL, "%" PRIuPTR, rope->r_v.v_uint);
break;
default:
break;
}
}
static void to_stream(const struct b_rope *rope, void *arg)
{
b_stream *out = arg;
unsigned int type = B_ROPE_TYPE(rope->r_flags);
switch (type) {
case B_ROPE_F_CHAR:
b_stream_write_char(out, rope->r_v.v_char);
break;
case B_ROPE_F_CSTR:
case B_ROPE_F_CSTR_BORROWED:
case B_ROPE_F_CSTR_STATIC:
b_stream_write_string(out, rope->r_v.v_cstr.s, NULL);
break;
case B_ROPE_F_INT:
b_stream_write_fmt(out, NULL, "%" PRIdPTR, rope->r_v.v_int);
break;
case B_ROPE_F_UINT:
b_stream_write_fmt(out, NULL, "%" PRIuPTR, rope->r_v.v_uint);
break;
default:
break;
}
}
b_status b_rope_to_cstr(const struct b_rope *rope, char *out, size_t max)
{
b_bstr str;
b_bstr_begin(&str, out, max);
rope_iterate(rope, to_bstr, &str);
return B_SUCCESS;
}
b_status b_rope_to_bstr(const struct b_rope *rope, b_bstr *str)
{
rope_iterate(rope, to_bstr, str);
return B_SUCCESS;
}
b_status b_rope_to_string(const struct b_rope *rope, b_stream *out)
{
rope_iterate(rope, to_stream, out);
return B_SUCCESS;
}
+60
View File
@@ -0,0 +1,60 @@
#include <blue/core/status.h>
#include <stddef.h>
#define ENUM_STR(s) \
case s: \
return #s;
#define ENUM_STR2(c, s) \
case c: \
return s;
const char *b_status_to_string(b_status status)
{
switch (status) {
ENUM_STR(B_SUCCESS);
ENUM_STR(B_ERR_NO_MEMORY);
ENUM_STR(B_ERR_OUT_OF_BOUNDS);
ENUM_STR(B_ERR_INVALID_ARGUMENT);
ENUM_STR(B_ERR_NAME_EXISTS);
ENUM_STR(B_ERR_NOT_SUPPORTED);
ENUM_STR(B_ERR_BAD_STATE);
ENUM_STR(B_ERR_NO_ENTRY);
ENUM_STR(B_ERR_NO_DATA);
ENUM_STR(B_ERR_NO_SPACE);
ENUM_STR(B_ERR_UNKNOWN_FUNCTION);
ENUM_STR(B_ERR_BAD_FORMAT);
ENUM_STR(B_ERR_IO_FAILURE);
ENUM_STR(B_ERR_IS_DIRECTORY);
ENUM_STR(B_ERR_NOT_DIRECTORY);
ENUM_STR(B_ERR_PERMISSION_DENIED);
ENUM_STR(B_ERR_BUSY);
default:
return NULL;
}
}
const char *b_status_description(b_status status)
{
switch (status) {
ENUM_STR2(B_SUCCESS, "Success");
ENUM_STR2(B_ERR_NO_MEMORY, "Out of memory");
ENUM_STR2(B_ERR_OUT_OF_BOUNDS, "Argument out of bounds");
ENUM_STR2(B_ERR_INVALID_ARGUMENT, "Invalid argument");
ENUM_STR2(B_ERR_NAME_EXISTS, "Name already exists");
ENUM_STR2(B_ERR_NOT_SUPPORTED, "Operation not supported");
ENUM_STR2(B_ERR_BAD_STATE, "Bad state");
ENUM_STR2(B_ERR_NO_ENTRY, "No entry");
ENUM_STR2(B_ERR_NO_DATA, "No data available");
ENUM_STR2(B_ERR_NO_SPACE, "No space available");
ENUM_STR2(B_ERR_UNKNOWN_FUNCTION, "Unknown function");
ENUM_STR2(B_ERR_BAD_FORMAT, "Bad format");
ENUM_STR2(B_ERR_IO_FAILURE, "I/O failure");
ENUM_STR2(B_ERR_IS_DIRECTORY, "Object is a directory");
ENUM_STR2(B_ERR_NOT_DIRECTORY, "Object is not a directory");
ENUM_STR2(B_ERR_PERMISSION_DENIED, "Permission denied");
ENUM_STR2(B_ERR_BUSY, "Resource busy or locked");
default:
return NULL;
}
}
+1134
View File
File diff suppressed because it is too large Load Diff
+297
View File
@@ -0,0 +1,297 @@
#include <blue/core/stringstream.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEFAULT_CAPACITY 15
/*** PRIVATE DATA *************************************************************/
struct b_stringstream_p {
char *ss_buf;
size_t ss_ptr;
size_t ss_len;
size_t ss_max;
unsigned char ss_alloc;
};
/*** PRIVATE FUNCTIONS ********************************************************/
static enum b_status __getc(struct b_stringstream_p *ss, b_wchar *out)
{
size_t available = ss->ss_len - ss->ss_ptr;
const char *p = ss->ss_buf + ss->ss_ptr;
size_t to_copy = b_wchar_utf8_codepoint_stride(p);
if (to_copy > available) {
return B_ERR_BAD_STATE;
}
b_wchar c = b_wchar_utf8_codepoint_decode(p);
*out = c;
if (c == B_WCHAR_INVALID) {
return B_ERR_BAD_STATE;
}
ss->ss_ptr += to_copy;
return B_SUCCESS;
}
static enum b_status __gets(
struct b_stringstream_p *ss, char *s, size_t len, size_t *nr_read)
{
size_t available = ss->ss_len - ss->ss_ptr;
size_t to_copy = len;
if (available < to_copy) {
to_copy = available;
}
memcpy(s, ss->ss_buf + ss->ss_ptr, to_copy);
ss->ss_ptr += to_copy;
if (nr_read) {
*nr_read = to_copy;
}
return B_SUCCESS;
}
static enum b_status __puts(
struct b_stringstream_p *ss, const char *s, size_t len, size_t *nr_written)
{
size_t available = ss->ss_max - ss->ss_len;
size_t to_copy = len;
if (to_copy > available && ss->ss_alloc == 1) {
char *new_buf = realloc(ss->ss_buf, ss->ss_len + to_copy + 1);
if (!new_buf) {
return B_ERR_NO_MEMORY;
}
ss->ss_buf = new_buf;
ss->ss_max = ss->ss_len + to_copy;
available = ss->ss_max - ss->ss_len;
}
if (available < to_copy) {
to_copy = available;
}
memcpy(ss->ss_buf + ss->ss_len, s, to_copy);
/* increment the length by the full string length, even if only a
* portion was copied */
ss->ss_len += len;
if (nr_written) {
*nr_written = to_copy;
}
return B_SUCCESS;
}
static enum b_status stringstream_reset(struct b_stringstream_p *ss)
{
ss->ss_len = 0;
if (ss->ss_buf) {
*ss->ss_buf = 0;
}
return B_SUCCESS;
}
static enum b_status stringstream_reset_with_buffer(
struct b_stringstream_p *ss, char *buf, size_t max)
{
ss->ss_len = 0;
if (ss->ss_buf && ss->ss_alloc) {
free(ss->ss_buf);
}
ss->ss_buf = buf;
ss->ss_max = max;
ss->ss_alloc = 0;
return B_SUCCESS;
}
static size_t stringstream_get_length(const struct b_stringstream_p *strv)
{
return strv->ss_len;
}
static const char *stringstream_ptr(const struct b_stringstream_p *ss)
{
return ss->ss_buf;
}
static char *stringstream_steal(struct b_stringstream_p *ss)
{
char *out = ss->ss_buf;
memset(ss, 0x0, sizeof *ss);
ss->ss_alloc = 1;
return out;
}
/*** PUBLIC FUNCTIONS *********************************************************/
b_stringstream *b_stringstream_create_with_buffer(char *buf, size_t max)
{
b_stringstream *s = b_object_create(B_TYPE_STRINGSTREAM);
if (!s) {
return NULL;
}
b_stream_cfg *cfg = b_object_get_protected(s, B_TYPE_STREAM);
struct b_stringstream_p *p = b_object_get_private(s, B_TYPE_STRINGSTREAM);
cfg->s_mode = B_STREAM_READ | B_STREAM_WRITE | Z__B_STREAM_STATIC;
p->ss_buf = buf;
p->ss_max = max;
p->ss_len = 0;
p->ss_alloc = 0;
return s;
}
b_stringstream *b_stringstream_create(void)
{
b_stringstream *s = b_object_create(B_TYPE_STRINGSTREAM);
if (!s) {
return NULL;
}
b_stream_cfg *cfg = b_object_get_protected(s, B_TYPE_STREAM);
struct b_stringstream_p *p = b_object_get_private(s, B_TYPE_STRINGSTREAM);
cfg->s_mode = B_STREAM_READ | B_STREAM_WRITE | Z__B_STREAM_STATIC;
p->ss_buf = malloc(DEFAULT_CAPACITY + 1);
if (!p->ss_buf) {
b_stringstream_unref(s);
return NULL;
}
memset(p->ss_buf, 0x0, DEFAULT_CAPACITY + 1);
p->ss_max = DEFAULT_CAPACITY;
p->ss_len = 0;
p->ss_alloc = 1;
return s;
}
size_t b_stringstream_get_length(const b_stringstream *strv)
{
B_CLASS_DISPATCH_STATIC_0(
B_TYPE_STRINGSTREAM, stringstream_get_length, strv);
}
enum b_status b_stringstream_reset(b_stringstream *strv)
{
B_CLASS_DISPATCH_STATIC_0(B_TYPE_STRINGSTREAM, stringstream_reset, strv);
}
enum b_status b_stringstream_reset_with_buffer(
b_stringstream *strv, char *buf, size_t max)
{
B_CLASS_DISPATCH_STATIC(
B_TYPE_STRINGSTREAM, stringstream_reset_with_buffer, strv, buf,
max);
}
const char *b_stringstream_ptr(const b_stringstream *ss)
{
B_CLASS_DISPATCH_STATIC_0(B_TYPE_STRINGSTREAM, stringstream_ptr, ss);
}
char *b_stringstream_steal(b_stringstream *ss)
{
B_CLASS_DISPATCH_STATIC_0(B_TYPE_STRINGSTREAM, stringstream_steal, ss);
}
/*** PUBLIC ALIAS FUNCTIONS ***************************************************/
/*** VIRTUAL FUNCTIONS ********************************************************/
static void stringstream_init(b_object *obj, void *priv)
{
struct b_stringstream_p *stream = priv;
}
static void stringstream_fini(b_object *obj, void *priv)
{
struct b_stringstream_p *stream = priv;
if (stream->ss_alloc && stream->ss_buf) {
free(stream->ss_buf);
}
}
enum b_status stream_getc(b_stream *stream, b_wchar *c)
{
struct b_stringstream_p *s
= b_object_get_private(stream, B_TYPE_STRINGSTREAM);
enum b_status status = __getc(s, c);
return status;
}
enum b_status stream_read(b_stream *stream, void *buf, size_t count, size_t *nr_read)
{
struct b_stringstream_p *s
= b_object_get_private(stream, B_TYPE_STRINGSTREAM);
enum b_status status = __gets(s, buf, count, nr_read);
return status;
}
enum b_status stream_write(
b_stream *stream, const void *buf, size_t count, size_t *nr_written)
{
struct b_stringstream_p *s
= b_object_get_private(stream, B_TYPE_STRINGSTREAM);
enum b_status status = __puts(s, (const char *)buf, count, nr_written);
return status;
}
/*** CLASS DEFINITION *********************************************************/
B_TYPE_CLASS_DEFINITION_BEGIN(b_stringstream)
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
B_INTERFACE_ENTRY(to_string) = NULL;
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
B_TYPE_CLASS_INTERFACE_BEGIN(b_stream, B_TYPE_STREAM)
B_INTERFACE_ENTRY(s_close) = NULL;
B_INTERFACE_ENTRY(s_seek) = NULL;
B_INTERFACE_ENTRY(s_tell) = NULL;
B_INTERFACE_ENTRY(s_getc) = stream_getc;
B_INTERFACE_ENTRY(s_read) = stream_read;
B_INTERFACE_ENTRY(s_write) = stream_write;
B_INTERFACE_ENTRY(s_reserve) = NULL;
B_TYPE_CLASS_INTERFACE_END(b_stream, B_TYPE_STREAM)
B_TYPE_CLASS_DEFINITION_END(b_stringstream)
B_TYPE_DEFINITION_BEGIN(b_stringstream)
B_TYPE_ID(0x508a609a, 0xfac5, 0x4d31, 0x843a, 0x44b68ad329f3);
B_TYPE_EXTENDS(B_TYPE_STREAM);
B_TYPE_CLASS(b_stringstream_class);
B_TYPE_INSTANCE_PRIVATE(struct b_stringstream_p);
B_TYPE_INSTANCE_INIT(stringstream_init);
B_TYPE_INSTANCE_FINI(stringstream_fini);
B_TYPE_DEFINITION_END(b_stringstream)
@@ -1,16 +1,16 @@
#include <fx/bitop.h>
#include <blue/core/bitop.h>
int fx_popcountl(long v)
int b_popcountl(long v)
{
return __builtin_popcountl(v);
}
int fx_ctzl(long v)
int b_ctzl(long v)
{
return __builtin_ctzl(v);
}
int fx_clzl(long v)
int b_clzl(long v)
{
return __builtin_clzl(v);
}
@@ -2,7 +2,7 @@
#include <stdint.h>
#include <unistd.h>
uint64_t z__fx_platform_random_seed()
uint64_t z__b_platform_random_seed()
{
int fd = open("/dev/urandom", O_RDONLY);
if (fd == -1) {
@@ -18,7 +18,7 @@ uint64_t z__fx_platform_random_seed()
return v;
}
uint64_t z__fx_platform_random_seed_secure()
uint64_t z__b_platform_random_seed_secure()
{
int fd = open("/dev/random", O_RDONLY);
if (fd == -1) {
@@ -1,20 +1,20 @@
#include <assert.h>
#include <fx/core/error.h>
#include <fx/core/thread.h>
#include <blue/core/error.h>
#include <blue/core/thread.h>
#include <stdlib.h>
#include <string.h>
struct fx_thread {
struct b_thread {
pthread_t thr_p;
fx_result thr_result;
b_result thr_result;
};
static fx_once thread_tls_init_once = FX_ONCE_INIT;
static b_once thread_tls_init_once = B_ONCE_INIT;
static pthread_key_t thread_tls_key = {0};
static void thread_dtor(void *p)
{
struct fx_thread *thread = p;
struct b_thread *thread = p;
}
static void thread_tls_init()
@@ -22,13 +22,13 @@ static void thread_tls_init()
pthread_key_create(&thread_tls_key, thread_dtor);
}
struct fx_thread *fx_thread_self(void)
struct b_thread *b_thread_self(void)
{
if (fx_init_once(&thread_tls_init_once)) {
if (b_init_once(&thread_tls_init_once)) {
thread_tls_init();
}
struct fx_thread *thread = pthread_getspecific(thread_tls_key);
struct b_thread *thread = pthread_getspecific(thread_tls_key);
if (thread) {
return thread;
}
@@ -45,17 +45,17 @@ struct fx_thread *fx_thread_self(void)
return thread;
}
bool fx_mutex_lock(fx_mutex *mut)
bool b_mutex_lock(b_mutex *mut)
{
return pthread_mutex_lock(mut) == 0;
}
bool fx_mutex_trylock(fx_mutex *mut)
bool b_mutex_trylock(b_mutex *mut)
{
return pthread_mutex_trylock(mut) == 0;
}
bool fx_mutex_unlock(fx_mutex *mut)
bool b_mutex_unlock(b_mutex *mut)
{
return pthread_mutex_unlock(mut) == 0;
}

Some files were not shown because too many files have changed in this diff Show More