From dfe62dcf8bcefc523b466e127c3edc4dc2756629 Mon Sep 17 00:00:00 2001 From: crupest Date: Sun, 6 Oct 2024 13:57:39 +0800 Subject: Rename common to base. --- src/CMakeLists.txt | 4 +- src/ThemeBuilder/components/Editor.h | 2 +- src/ThemeBuilder/components/HeadBodyEditor.h | 2 +- src/ThemeBuilder/components/StyleRuleSetEditor.cpp | 4 +- .../conditions/CheckedConditionEditor.cpp | 2 +- .../components/conditions/CheckedConditionEditor.h | 2 +- .../conditions/ClickStateConditionEditor.cpp | 2 +- .../conditions/ClickStateConditionEditor.h | 4 +- .../conditions/CompoundConditionEditor.cpp | 2 +- .../conditions/CompoundConditionEditor.h | 4 +- .../components/conditions/ConditionEditor.cpp | 2 +- .../components/conditions/FocusConditionEditor.cpp | 2 +- .../components/conditions/FocusConditionEditor.h | 2 +- .../components/conditions/NoConditionEditor.h | 2 +- .../properties/MeasureLengthPropertyEditor.cpp | 2 +- .../components/properties/PointPropertyEditor.cpp | 2 +- .../components/stylers/BorderStylerEditor.cpp | 2 +- .../components/stylers/BorderStylerEditor.h | 2 +- .../components/stylers/CompoundStylerEditor.cpp | 2 +- .../components/stylers/CompoundStylerEditor.h | 2 +- .../components/stylers/ContentBrushStylerEditor.h | 2 +- .../components/stylers/FontStylerEditor.h | 2 +- .../components/stylers/MarginStylerEditor.h | 2 +- .../components/stylers/PaddingStylerEditor.h | 2 +- .../components/stylers/PreferredSizeStylerEditor.h | 2 +- src/ThemeBuilder/main.cpp | 2 +- src/base/Base.cpp | 7 + src/base/Buffer.cpp | 277 +++++++++ src/base/CMakeLists.txt | 80 +++ src/base/Exception.cpp | 36 ++ src/base/Format.cpp | 111 ++++ src/base/PropertyTree.cpp | 71 +++ src/base/String.cpp | 672 +++++++++++++++++++++ src/base/StringToNumberConverter.cpp | 170 ++++++ src/base/StringUtil.cpp | 243 ++++++++ src/base/SubProcess.cpp | 209 +++++++ src/base/io/AutoReadStream.cpp | 56 ++ src/base/io/BufferStream.cpp | 109 ++++ src/base/io/CFileStream.cpp | 96 +++ src/base/io/MemoryStream.cpp | 74 +++ src/base/io/OpenFileFlag.cpp | 19 + src/base/io/ProxyStream.cpp | 37 ++ src/base/io/Resource.cpp | 48 ++ src/base/io/Stream.cpp | 199 ++++++ src/base/log/Logger.cpp | 88 +++ src/base/log/StdioLogTarget.cpp | 27 + src/base/platform/Exception.cpp | 1 + src/base/platform/osx/Convert.cpp | 29 + src/base/platform/osx/Exception.cpp | 1 + src/base/platform/unix/PosixSpawnSubProcess.cpp | 204 +++++++ src/base/platform/unix/UnixFileStream.cpp | 106 ++++ src/base/platform/unix/UnixPipe.cpp | 51 ++ src/base/platform/web/WebException.cpp | 1 + src/base/platform/win/BridgeComStream.cpp | 106 ++++ src/base/platform/win/BrigdeComStream.h | 43 ++ src/base/platform/win/ComAutoInit.cpp | 15 + src/base/platform/win/DebugLogTarget.cpp | 10 + src/base/platform/win/Exception.cpp | 38 ++ src/base/platform/win/StreamConvert.cpp | 28 + src/base/platform/win/Win32FileStream.cpp | 122 ++++ src/base/platform/win/Win32FileStreamPrivate.h | 13 + src/common/Base.cpp | 7 - src/common/Buffer.cpp | 277 --------- src/common/CMakeLists.txt | 80 --- src/common/Exception.cpp | 36 -- src/common/Format.cpp | 111 ---- src/common/PropertyTree.cpp | 71 --- src/common/String.cpp | 672 --------------------- src/common/StringToNumberConverter.cpp | 170 ------ src/common/StringUtil.cpp | 243 -------- src/common/SubProcess.cpp | 209 ------- src/common/io/AutoReadStream.cpp | 56 -- src/common/io/BufferStream.cpp | 109 ---- src/common/io/CFileStream.cpp | 96 --- src/common/io/MemoryStream.cpp | 74 --- src/common/io/OpenFileFlag.cpp | 19 - src/common/io/ProxyStream.cpp | 37 -- src/common/io/Resource.cpp | 48 -- src/common/io/Stream.cpp | 199 ------ src/common/log/Logger.cpp | 88 --- src/common/log/StdioLogTarget.cpp | 27 - src/common/platform/Exception.cpp | 1 - src/common/platform/osx/Convert.cpp | 29 - src/common/platform/osx/Exception.cpp | 1 - src/common/platform/unix/PosixSpawnSubProcess.cpp | 204 ------- src/common/platform/unix/UnixFileStream.cpp | 106 ---- src/common/platform/unix/UnixPipe.cpp | 51 -- src/common/platform/web/WebException.cpp | 1 - src/common/platform/win/BridgeComStream.cpp | 106 ---- src/common/platform/win/BrigdeComStream.h | 43 -- src/common/platform/win/ComAutoInit.cpp | 15 - src/common/platform/win/DebugLogTarget.cpp | 10 - src/common/platform/win/Exception.cpp | 38 -- src/common/platform/win/StreamConvert.cpp | 28 - src/common/platform/win/Win32FileStream.cpp | 122 ---- src/common/platform/win/Win32FileStreamPrivate.h | 13 - src/parse/Grammar.cpp | 4 +- src/platform/Exception.cpp | 2 +- src/platform/graphics/Geometry.cpp | 2 +- src/platform/graphics/cairo/CairoImageFactory.cpp | 2 +- src/platform/graphics/cairo/CairoPainter.cpp | 2 +- src/platform/graphics/cairo/PangoTextLayout.cpp | 2 +- src/platform/graphics/direct2d/Factory.cpp | 2 +- src/platform/graphics/direct2d/Font.cpp | 2 +- src/platform/graphics/direct2d/Geometry.cpp | 2 +- src/platform/graphics/direct2d/Image.cpp | 2 +- src/platform/graphics/direct2d/ImageFactory.cpp | 4 +- src/platform/graphics/direct2d/Painter.cpp | 2 +- src/platform/graphics/direct2d/TextLayout.cpp | 2 +- src/platform/graphics/quartz/Brush.cpp | 4 +- src/platform/graphics/quartz/Image.cpp | 2 +- src/platform/graphics/quartz/ImageFactory.cpp | 4 +- src/platform/graphics/quartz/TextLayout.cpp | 6 +- src/platform/gui/osx/Clipboard.mm | 2 +- src/platform/gui/osx/ClipboardPrivate.h | 2 +- src/platform/gui/osx/InputMethod.mm | 2 +- src/platform/gui/osx/Menu.mm | 2 +- src/platform/gui/osx/UiApplication.mm | 4 +- src/platform/gui/osx/Window.mm | 4 +- src/platform/gui/osx/WindowPrivate.h | 2 +- src/platform/gui/win/Clipboard.cpp | 2 +- src/platform/gui/win/Cursor.cpp | 2 +- src/platform/gui/win/GodWindow.cpp | 2 +- src/platform/gui/win/InputMethod.cpp | 4 +- src/platform/gui/win/TimerManager.h | 4 +- src/platform/gui/win/UiApplication.cpp | 2 +- src/platform/gui/win/Window.cpp | 2 +- src/platform/gui/win/WindowManager.h | 2 +- src/ui/ThemeManager.cpp | 4 +- src/ui/ThemeResourceDictionary.cpp | 4 +- src/ui/components/Input.cpp | 2 +- src/ui/controls/Control.cpp | 2 +- src/ui/controls/RootControl.cpp | 2 +- src/ui/controls/TextHostControlService.cpp | 8 +- src/ui/document/TextDocumentElement.cpp | 2 +- src/ui/helper/ClickDetector.cpp | 2 +- src/ui/helper/ShortcutHub.cpp | 2 +- src/ui/host/RoutedEventDispatch.h | 4 +- src/ui/host/WindowHost.cpp | 4 +- src/ui/mapper/BorderStyleMapper.cpp | 2 +- src/ui/mapper/CursorMapper.cpp | 2 +- src/ui/mapper/style/AndConditionMapper.cpp | 2 +- src/ui/mapper/style/BorderStylerMapper.cpp | 2 +- src/ui/mapper/style/CheckedConditionMapper.cpp | 2 +- src/ui/mapper/style/ClickStateConditionMapper.cpp | 4 +- src/ui/mapper/style/ContentBrushStylerMapper.cpp | 2 +- src/ui/mapper/style/CursorStylerMapper.cpp | 2 +- src/ui/mapper/style/FocusConditionMapper.cpp | 2 +- src/ui/mapper/style/FontStylerMapper.cpp | 2 +- src/ui/mapper/style/HoverConditionMapper.cpp | 2 +- src/ui/mapper/style/NoConditionMapper.cpp | 2 +- src/ui/mapper/style/OrConditionMapper.cpp | 2 +- src/ui/mapper/style/StyleRuleMapper.cpp | 6 +- src/ui/render/BorderRenderObject.cpp | 2 +- src/ui/render/FlexLayoutRenderObject.cpp | 2 +- src/ui/render/LayoutHelper.cpp | 2 +- src/ui/render/RenderObject.cpp | 4 +- src/ui/render/ScrollBar.cpp | 2 +- src/ui/render/StackLayoutRenderObject.cpp | 2 +- src/ui/render/TextRenderObject.cpp | 2 +- src/ui/style/Condition.cpp | 4 +- src/ui/style/StyleRuleSet.cpp | 2 +- src/ui/style/Styler.cpp | 2 +- 163 files changed, 3515 insertions(+), 3517 deletions(-) create mode 100644 src/base/Base.cpp create mode 100644 src/base/Buffer.cpp create mode 100644 src/base/CMakeLists.txt create mode 100644 src/base/Exception.cpp create mode 100644 src/base/Format.cpp create mode 100644 src/base/PropertyTree.cpp create mode 100644 src/base/String.cpp create mode 100644 src/base/StringToNumberConverter.cpp create mode 100644 src/base/StringUtil.cpp create mode 100644 src/base/SubProcess.cpp create mode 100644 src/base/io/AutoReadStream.cpp create mode 100644 src/base/io/BufferStream.cpp create mode 100644 src/base/io/CFileStream.cpp create mode 100644 src/base/io/MemoryStream.cpp create mode 100644 src/base/io/OpenFileFlag.cpp create mode 100644 src/base/io/ProxyStream.cpp create mode 100644 src/base/io/Resource.cpp create mode 100644 src/base/io/Stream.cpp create mode 100644 src/base/log/Logger.cpp create mode 100644 src/base/log/StdioLogTarget.cpp create mode 100644 src/base/platform/Exception.cpp create mode 100644 src/base/platform/osx/Convert.cpp create mode 100644 src/base/platform/osx/Exception.cpp create mode 100644 src/base/platform/unix/PosixSpawnSubProcess.cpp create mode 100644 src/base/platform/unix/UnixFileStream.cpp create mode 100644 src/base/platform/unix/UnixPipe.cpp create mode 100644 src/base/platform/web/WebException.cpp create mode 100644 src/base/platform/win/BridgeComStream.cpp create mode 100644 src/base/platform/win/BrigdeComStream.h create mode 100644 src/base/platform/win/ComAutoInit.cpp create mode 100644 src/base/platform/win/DebugLogTarget.cpp create mode 100644 src/base/platform/win/Exception.cpp create mode 100644 src/base/platform/win/StreamConvert.cpp create mode 100644 src/base/platform/win/Win32FileStream.cpp create mode 100644 src/base/platform/win/Win32FileStreamPrivate.h delete mode 100644 src/common/Base.cpp delete mode 100644 src/common/Buffer.cpp delete mode 100644 src/common/CMakeLists.txt delete mode 100644 src/common/Exception.cpp delete mode 100644 src/common/Format.cpp delete mode 100644 src/common/PropertyTree.cpp delete mode 100644 src/common/String.cpp delete mode 100644 src/common/StringToNumberConverter.cpp delete mode 100644 src/common/StringUtil.cpp delete mode 100644 src/common/SubProcess.cpp delete mode 100644 src/common/io/AutoReadStream.cpp delete mode 100644 src/common/io/BufferStream.cpp delete mode 100644 src/common/io/CFileStream.cpp delete mode 100644 src/common/io/MemoryStream.cpp delete mode 100644 src/common/io/OpenFileFlag.cpp delete mode 100644 src/common/io/ProxyStream.cpp delete mode 100644 src/common/io/Resource.cpp delete mode 100644 src/common/io/Stream.cpp delete mode 100644 src/common/log/Logger.cpp delete mode 100644 src/common/log/StdioLogTarget.cpp delete mode 100644 src/common/platform/Exception.cpp delete mode 100644 src/common/platform/osx/Convert.cpp delete mode 100644 src/common/platform/osx/Exception.cpp delete mode 100644 src/common/platform/unix/PosixSpawnSubProcess.cpp delete mode 100644 src/common/platform/unix/UnixFileStream.cpp delete mode 100644 src/common/platform/unix/UnixPipe.cpp delete mode 100644 src/common/platform/web/WebException.cpp delete mode 100644 src/common/platform/win/BridgeComStream.cpp delete mode 100644 src/common/platform/win/BrigdeComStream.h delete mode 100644 src/common/platform/win/ComAutoInit.cpp delete mode 100644 src/common/platform/win/DebugLogTarget.cpp delete mode 100644 src/common/platform/win/Exception.cpp delete mode 100644 src/common/platform/win/StreamConvert.cpp delete mode 100644 src/common/platform/win/Win32FileStream.cpp delete mode 100644 src/common/platform/win/Win32FileStreamPrivate.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9cb01e47..959f2dd1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,5 @@ -add_subdirectory(common) - +add_subdirectory(base) add_subdirectory(platform) - add_subdirectory(ui) add_subdirectory(parse) add_subdirectory(toml) diff --git a/src/ThemeBuilder/components/Editor.h b/src/ThemeBuilder/components/Editor.h index 29809c82..2e1db741 100644 --- a/src/ThemeBuilder/components/Editor.h +++ b/src/ThemeBuilder/components/Editor.h @@ -1,5 +1,5 @@ #pragma once -#include "cru/common/Event.h" +#include "cru/base/Event.h" #include "cru/ui/components/Component.h" namespace cru::theme_builder::components { diff --git a/src/ThemeBuilder/components/HeadBodyEditor.h b/src/ThemeBuilder/components/HeadBodyEditor.h index 8119724f..1fcf2f63 100644 --- a/src/ThemeBuilder/components/HeadBodyEditor.h +++ b/src/ThemeBuilder/components/HeadBodyEditor.h @@ -1,6 +1,6 @@ #pragma once #include "Editor.h" -#include "cru/common/Event.h" +#include "cru/base/Event.h" #include "cru/ui/controls/Container.h" #include "cru/ui/controls/FlexLayout.h" #include "cru/ui/controls/IconButton.h" diff --git a/src/ThemeBuilder/components/StyleRuleSetEditor.cpp b/src/ThemeBuilder/components/StyleRuleSetEditor.cpp index 8cf5af6d..a1c19e08 100644 --- a/src/ThemeBuilder/components/StyleRuleSetEditor.cpp +++ b/src/ThemeBuilder/components/StyleRuleSetEditor.cpp @@ -1,6 +1,6 @@ #include "StyleRuleSetEditor.h" -#include "cru/common/Exception.h" -#include "cru/common/String.h" +#include "cru/base/Exception.h" +#include "cru/base/String.h" #include "cru/ui/DeleteLater.h" #include "cru/ui/ThemeManager.h" #include "cru/ui/controls/FlexLayout.h" diff --git a/src/ThemeBuilder/components/conditions/CheckedConditionEditor.cpp b/src/ThemeBuilder/components/conditions/CheckedConditionEditor.cpp index 64370981..57e72a0f 100644 --- a/src/ThemeBuilder/components/conditions/CheckedConditionEditor.cpp +++ b/src/ThemeBuilder/components/conditions/CheckedConditionEditor.cpp @@ -1,5 +1,5 @@ #include "CheckedConditionEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/style/Condition.h" namespace cru::theme_builder::components::conditions { diff --git a/src/ThemeBuilder/components/conditions/CheckedConditionEditor.h b/src/ThemeBuilder/components/conditions/CheckedConditionEditor.h index 7cf14912..b6e740f1 100644 --- a/src/ThemeBuilder/components/conditions/CheckedConditionEditor.h +++ b/src/ThemeBuilder/components/conditions/CheckedConditionEditor.h @@ -1,7 +1,7 @@ #pragma once #include "../properties/CheckBoxPropertyEditor.h" #include "ConditionEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/style/Condition.h" namespace cru::theme_builder::components::conditions { diff --git a/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.cpp b/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.cpp index a8d5cc87..bf0b1d98 100644 --- a/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.cpp +++ b/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.cpp @@ -1,5 +1,5 @@ #include "ClickStateConditionEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/helper/ClickDetector.h" #include "cru/ui/style/Condition.h" diff --git a/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.h b/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.h index 454a1346..2ea4fcf4 100644 --- a/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.h +++ b/src/ThemeBuilder/components/conditions/ClickStateConditionEditor.h @@ -1,8 +1,8 @@ #pragma once #include "../properties/SelectPropertyEditor.h" #include "ConditionEditor.h" -#include "cru/common/ClonablePtr.h" -#include "cru/common/Event.h" +#include "cru/base/ClonablePtr.h" +#include "cru/base/Event.h" #include "cru/ui/style/Condition.h" namespace cru::theme_builder::components::conditions { diff --git a/src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp b/src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp index 69b8ed02..8be3aa0f 100644 --- a/src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp +++ b/src/ThemeBuilder/components/conditions/CompoundConditionEditor.cpp @@ -4,7 +4,7 @@ #include "ConditionEditor.h" #include "FocusConditionEditor.h" #include "NoConditionEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/platform/Color.h" #include "cru/ui/Base.h" #include "cru/ui/ThemeManager.h" diff --git a/src/ThemeBuilder/components/conditions/CompoundConditionEditor.h b/src/ThemeBuilder/components/conditions/CompoundConditionEditor.h index e1398514..2948df36 100644 --- a/src/ThemeBuilder/components/conditions/CompoundConditionEditor.h +++ b/src/ThemeBuilder/components/conditions/CompoundConditionEditor.h @@ -1,7 +1,7 @@ #pragma once #include "ConditionEditor.h" -#include "cru/common/ClonablePtr.h" -#include "cru/common/Event.h" +#include "cru/base/ClonablePtr.h" +#include "cru/base/Event.h" #include "cru/ui/components/Component.h" #include "cru/ui/components/PopupButton.h" #include "cru/ui/controls/Button.h" diff --git a/src/ThemeBuilder/components/conditions/ConditionEditor.cpp b/src/ThemeBuilder/components/conditions/ConditionEditor.cpp index 5b79c639..421bb028 100644 --- a/src/ThemeBuilder/components/conditions/ConditionEditor.cpp +++ b/src/ThemeBuilder/components/conditions/ConditionEditor.cpp @@ -5,7 +5,7 @@ #include "CompoundConditionEditor.h" #include "FocusConditionEditor.h" #include "NoConditionEditor.h" -#include "cru/common/Exception.h" +#include "cru/base/Exception.h" #include "cru/ui/controls/FlexLayout.h" namespace cru::theme_builder::components::conditions { diff --git a/src/ThemeBuilder/components/conditions/FocusConditionEditor.cpp b/src/ThemeBuilder/components/conditions/FocusConditionEditor.cpp index 1fb99d64..78c99b5c 100644 --- a/src/ThemeBuilder/components/conditions/FocusConditionEditor.cpp +++ b/src/ThemeBuilder/components/conditions/FocusConditionEditor.cpp @@ -1,5 +1,5 @@ #include "FocusConditionEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/style/Condition.h" namespace cru::theme_builder::components::conditions { diff --git a/src/ThemeBuilder/components/conditions/FocusConditionEditor.h b/src/ThemeBuilder/components/conditions/FocusConditionEditor.h index 1faf4d7d..d5478653 100644 --- a/src/ThemeBuilder/components/conditions/FocusConditionEditor.h +++ b/src/ThemeBuilder/components/conditions/FocusConditionEditor.h @@ -1,7 +1,7 @@ #pragma once #include "../properties/CheckBoxPropertyEditor.h" #include "ConditionEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/style/Condition.h" namespace cru::theme_builder::components::conditions { diff --git a/src/ThemeBuilder/components/conditions/NoConditionEditor.h b/src/ThemeBuilder/components/conditions/NoConditionEditor.h index 19616319..b38806b5 100644 --- a/src/ThemeBuilder/components/conditions/NoConditionEditor.h +++ b/src/ThemeBuilder/components/conditions/NoConditionEditor.h @@ -1,6 +1,6 @@ #pragma once #include "ConditionEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/style/Condition.h" namespace cru::theme_builder::components::conditions { diff --git a/src/ThemeBuilder/components/properties/MeasureLengthPropertyEditor.cpp b/src/ThemeBuilder/components/properties/MeasureLengthPropertyEditor.cpp index d1f4afce..ad338e78 100644 --- a/src/ThemeBuilder/components/properties/MeasureLengthPropertyEditor.cpp +++ b/src/ThemeBuilder/components/properties/MeasureLengthPropertyEditor.cpp @@ -1,5 +1,5 @@ #include "MeasureLengthPropertyEditor.h" -#include "cru/common/Format.h" +#include "cru/base/Format.h" #include "cru/ui/mapper/MapperRegistry.h" #include "cru/ui/render/MeasureRequirement.h" diff --git a/src/ThemeBuilder/components/properties/PointPropertyEditor.cpp b/src/ThemeBuilder/components/properties/PointPropertyEditor.cpp index 6d4277aa..d8487209 100644 --- a/src/ThemeBuilder/components/properties/PointPropertyEditor.cpp +++ b/src/ThemeBuilder/components/properties/PointPropertyEditor.cpp @@ -1,5 +1,5 @@ #include "PointPropertyEditor.h" -#include "cru/common/Format.h" +#include "cru/base/Format.h" #include "cru/ui/mapper/MapperRegistry.h" #include "cru/ui/mapper/PointMapper.h" diff --git a/src/ThemeBuilder/components/stylers/BorderStylerEditor.cpp b/src/ThemeBuilder/components/stylers/BorderStylerEditor.cpp index 81eb66d3..1329a08a 100644 --- a/src/ThemeBuilder/components/stylers/BorderStylerEditor.cpp +++ b/src/ThemeBuilder/components/stylers/BorderStylerEditor.cpp @@ -1,5 +1,5 @@ #include "BorderStylerEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/platform/graphics/Brush.h" #include "cru/platform/graphics/Factory.h" #include "cru/platform/gui/UiApplication.h" diff --git a/src/ThemeBuilder/components/stylers/BorderStylerEditor.h b/src/ThemeBuilder/components/stylers/BorderStylerEditor.h index 539262d6..c9435ee9 100644 --- a/src/ThemeBuilder/components/stylers/BorderStylerEditor.h +++ b/src/ThemeBuilder/components/stylers/BorderStylerEditor.h @@ -4,7 +4,7 @@ #include "../properties/OptionalPropertyEditor.h" #include "../properties/ThicknessPropertyEditor.h" #include "StylerEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" namespace cru::theme_builder::components::stylers { class BorderStylerEditor : public StylerEditor { diff --git a/src/ThemeBuilder/components/stylers/CompoundStylerEditor.cpp b/src/ThemeBuilder/components/stylers/CompoundStylerEditor.cpp index 6b8a5033..c8b2a871 100644 --- a/src/ThemeBuilder/components/stylers/CompoundStylerEditor.cpp +++ b/src/ThemeBuilder/components/stylers/CompoundStylerEditor.cpp @@ -6,7 +6,7 @@ #include "MarginStylerEditor.h" #include "PaddingStylerEditor.h" #include "PreferredSizeStylerEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/ThemeManager.h" #include "cru/ui/style/Styler.h" diff --git a/src/ThemeBuilder/components/stylers/CompoundStylerEditor.h b/src/ThemeBuilder/components/stylers/CompoundStylerEditor.h index 57150e83..91d2bff5 100644 --- a/src/ThemeBuilder/components/stylers/CompoundStylerEditor.h +++ b/src/ThemeBuilder/components/stylers/CompoundStylerEditor.h @@ -1,6 +1,6 @@ #pragma once #include "StylerEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/DeleteLater.h" #include "cru/ui/components/PopupButton.h" #include "cru/ui/controls/FlexLayout.h" diff --git a/src/ThemeBuilder/components/stylers/ContentBrushStylerEditor.h b/src/ThemeBuilder/components/stylers/ContentBrushStylerEditor.h index 8385b7c3..ec51c041 100644 --- a/src/ThemeBuilder/components/stylers/ContentBrushStylerEditor.h +++ b/src/ThemeBuilder/components/stylers/ContentBrushStylerEditor.h @@ -2,7 +2,7 @@ #include "../Editor.h" #include "../properties/ColorPropertyEditor.h" #include "StylerEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/style/Styler.h" namespace cru::theme_builder::components::stylers { diff --git a/src/ThemeBuilder/components/stylers/FontStylerEditor.h b/src/ThemeBuilder/components/stylers/FontStylerEditor.h index ccd12113..847b0e2a 100644 --- a/src/ThemeBuilder/components/stylers/FontStylerEditor.h +++ b/src/ThemeBuilder/components/stylers/FontStylerEditor.h @@ -2,7 +2,7 @@ #include "../Editor.h" #include "../properties/FontPropertyEditor.h" #include "StylerEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/style/Styler.h" namespace cru::theme_builder::components::stylers { diff --git a/src/ThemeBuilder/components/stylers/MarginStylerEditor.h b/src/ThemeBuilder/components/stylers/MarginStylerEditor.h index 9de6f1a2..9a1ca750 100644 --- a/src/ThemeBuilder/components/stylers/MarginStylerEditor.h +++ b/src/ThemeBuilder/components/stylers/MarginStylerEditor.h @@ -1,7 +1,7 @@ #pragma once #include "../properties/ThicknessPropertyEditor.h" #include "StylerEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/style/Styler.h" namespace cru::theme_builder::components::stylers { diff --git a/src/ThemeBuilder/components/stylers/PaddingStylerEditor.h b/src/ThemeBuilder/components/stylers/PaddingStylerEditor.h index b78d310b..69565cad 100644 --- a/src/ThemeBuilder/components/stylers/PaddingStylerEditor.h +++ b/src/ThemeBuilder/components/stylers/PaddingStylerEditor.h @@ -1,7 +1,7 @@ #pragma once #include "../properties/ThicknessPropertyEditor.h" #include "StylerEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/style/Styler.h" namespace cru::theme_builder::components::stylers { diff --git a/src/ThemeBuilder/components/stylers/PreferredSizeStylerEditor.h b/src/ThemeBuilder/components/stylers/PreferredSizeStylerEditor.h index 4a64da10..36fdc3d6 100644 --- a/src/ThemeBuilder/components/stylers/PreferredSizeStylerEditor.h +++ b/src/ThemeBuilder/components/stylers/PreferredSizeStylerEditor.h @@ -1,7 +1,7 @@ #pragma once #include "../properties/MeasureLengthPropertyEditor.h" #include "StylerEditor.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/style/Styler.h" namespace cru::theme_builder::components::stylers { diff --git a/src/ThemeBuilder/main.cpp b/src/ThemeBuilder/main.cpp index 0c5b2159..4f4ffe4a 100644 --- a/src/ThemeBuilder/main.cpp +++ b/src/ThemeBuilder/main.cpp @@ -1,5 +1,5 @@ #include "components/MainWindow.h" -#include "cru/common/io/Resource.h" +#include "cru/base/io/Resource.h" #include "cru/platform/bootstrap/Bootstrap.h" #include "cru/ui/ThemeManager.h" #include "cru/ui/ThemeResourceDictionary.h" diff --git a/src/base/Base.cpp b/src/base/Base.cpp new file mode 100644 index 00000000..1704f8a9 --- /dev/null +++ b/src/base/Base.cpp @@ -0,0 +1,7 @@ +#include "cru/base/Base.h" + +#include + +namespace cru { +void UnreachableCode() { std::terminate(); } +} // namespace cru diff --git a/src/base/Buffer.cpp b/src/base/Buffer.cpp new file mode 100644 index 00000000..1213364a --- /dev/null +++ b/src/base/Buffer.cpp @@ -0,0 +1,277 @@ +#include "cru/base/Buffer.h" +#include "cru/base/Exception.h" + +#include + +namespace cru { +namespace { +void CheckSize(Index size) { + if (size < 0) { + throw Exception(u"Size of buffer can't be smaller than 0."); + } +} +} // namespace + +Buffer::Buffer() { + ptr_ = nullptr; + size_ = used_begin_ = used_end_ = 0; +} + +Buffer::Buffer(Index size) { + CheckSize(size); + if (size == 0) { + ptr_ = nullptr; + size_ = used_begin_ = used_end_ = 0; + } else { + ptr_ = new std::byte[size]; + size_ = size; + used_begin_ = used_end_ = 0; + } + AssertValid(); +} + +Buffer::Buffer(const Buffer& other) { Copy_(other); } + +Buffer::Buffer(Buffer&& other) noexcept { Move_(std::move(other)); } + +Buffer& Buffer::operator=(const Buffer& other) { + if (this != &other) { + Delete_(); + Copy_(other); + } + return *this; +} + +Buffer& Buffer::operator=(Buffer&& other) noexcept { + if (this != &other) { + Delete_(); + Move_(std::move(other)); + } + return *this; +} + +Buffer::~Buffer() { Delete_(); } + +void Buffer::AssignBytes(Index dst_offset, std::byte* src, Index src_offset, + Index src_size, bool use_memmove) { + CheckSize(src_size); + + AssertValid(); + + (use_memmove ? std::memmove : std::memcpy)(ptr_ + dst_offset, + src + src_offset, src_size); + AssertValid(); +} + +void Buffer::ResizeBuffer(Index new_size, bool preserve_used) { + CheckSize(new_size); + + AssertValid(); + + if (new_size == 0) { + Delete_(); + ptr_ = nullptr; + size_ = used_begin_ = used_end_ = 0; + return; + } + + auto old_ptr = ptr_; + + ptr_ = new std::byte[new_size]; + size_ = new_size; + used_begin_ = std::min(new_size, used_begin_); + used_end_ = std::min(new_size, used_end_); + + if (old_ptr) { + if (preserve_used && used_begin_ < used_end_) { + std::memcpy(ptr_ + used_begin_, old_ptr + used_begin_, + used_end_ - used_begin_); + } + delete[] old_ptr; + } + + AssertValid(); +} + +Index Buffer::PushFront(const std::byte* other, Index other_size, + bool use_memmove) { + CheckSize(other_size); + + AssertValid(); + + auto copy_size = std::min(used_begin_, other_size); + + if (copy_size) { + used_begin_ -= copy_size; + (use_memmove ? std::memmove : std::memcpy)(ptr_ + used_begin_, other, + copy_size); + } + + AssertValid(); + + return copy_size; +} + +bool Buffer::PushBack(std::byte b) { + AssertValid(); + if (IsUsedReachEnd()) { + return false; + } + ptr_[used_end_] = b; + used_end_++; + AssertValid(); + return true; +} + +Index Buffer::PushBack(const std::byte* other, Index other_size, + bool use_memmove) { + CheckSize(other_size); + + AssertValid(); + + auto copy_size = std::min(size_ - used_end_, other_size); + + if (copy_size) { + (use_memmove ? std::memmove : std::memcpy)(ptr_ + used_end_, other, + copy_size); + used_end_ += copy_size; + } + + AssertValid(); + + return copy_size; +} + +void Buffer::PushBackCount(Index count) { + if (count < 0 || count > GetBackFree()) { + throw Exception(u"Count out of range in PushBackCount."); + } + used_end_ += count; +} + +Index Buffer::PopFront(Index size) { + CheckSize(size); + + AssertValid(); + + auto move = std::min(used_begin_, size); + used_begin_ -= move; + + AssertValid(); + + return move; +} + +Index Buffer::PopFront(std::byte* buffer, Index size, bool use_memmove) { + CheckSize(size); + + AssertValid(); + + auto pop_size = std::min(GetUsedSize(), size); + + if (pop_size) { + used_begin_ += pop_size; + (use_memmove ? std::memmove : std::memcpy)( + buffer, GetUsedBeginPtr() - pop_size, pop_size); + } + + AssertValid(); + + return pop_size; +} + +Index Buffer::PopEnd(Index size) { + CheckSize(size); + + AssertValid(); + + auto move = std::min(size_ - used_end_, size); + used_end_ += move; + + AssertValid(); + + return move; +} + +Index Buffer::PopEnd(std::byte* buffer, Index size, bool use_memmove) { + CheckSize(size); + + AssertValid(); + + auto pop_size = std::min(GetUsedSize(), size); + + if (pop_size) { + used_end_ -= pop_size; + (use_memmove ? std::memmove : std::memcpy)(buffer, GetUsedEndPtr(), + pop_size); + } + + AssertValid(); + + return pop_size; +} + +std::byte* Buffer::Detach(Index* size) { + AssertValid(); + + auto ptr = this->ptr_; + if (size) { + *size = this->size_; + } + this->ptr_ = nullptr; + this->size_ = this->used_begin_ = this->used_end_ = 0; + + AssertValid(); + + return ptr; +} + +void Buffer::Copy_(const Buffer& other) { + if (other.ptr_ == nullptr) { + ptr_ = nullptr; + size_ = used_begin_ = used_end_ = 0; + } else { + ptr_ = new std::byte[other.size_]; + size_ = other.size_; + used_begin_ = other.used_begin_; + used_end_ = other.used_end_; + std::memcpy(ptr_ + used_begin_, other.ptr_ + used_begin_, + used_end_ - used_begin_); + } + AssertValid(); +} + +void Buffer::Move_(Buffer&& other) noexcept { + ptr_ = other.ptr_; + size_ = other.size_; + used_begin_ = other.used_begin_; + used_end_ = other.used_end_; + other.ptr_ = nullptr; + other.size_ = other.used_begin_ = other.used_end_ = 0; + AssertValid(); +} + +void Buffer::Delete_() noexcept { + if (ptr_) { + delete[] ptr_; + } +} + +void Buffer::AssertValid() { + assert(size_ >= 0); + assert(used_begin_ >= 0); + assert(used_begin_ <= size_); + assert(used_end_ >= 0); + assert(used_end_ <= size_); + assert(used_end_ >= used_begin_); + assert((ptr_ == nullptr && size_ == 0) || (ptr_ != nullptr && size_ > 0)); +} + +void swap(Buffer& left, Buffer& right) noexcept { + using std::swap; + swap(left.ptr_, right.ptr_); + swap(left.size_, right.size_); + swap(left.used_begin_, right.used_begin_); + swap(left.used_end_, right.used_end_); +} +} // namespace cru diff --git a/src/base/CMakeLists.txt b/src/base/CMakeLists.txt new file mode 100644 index 00000000..19feddba --- /dev/null +++ b/src/base/CMakeLists.txt @@ -0,0 +1,80 @@ +add_library(CruBase + Base.cpp + Buffer.cpp + Exception.cpp + Format.cpp + PropertyTree.cpp + String.cpp + StringToNumberConverter.cpp + StringUtil.cpp + SubProcess.cpp + io/AutoReadStream.cpp + io/BufferStream.cpp + io/CFileStream.cpp + io/Stream.cpp + io/ProxyStream.cpp + io/Resource.cpp + io/MemoryStream.cpp + log/Logger.cpp + log/StdioLogTarget.cpp + platform/Exception.cpp +) +target_compile_definitions(CruBase PRIVATE CRU_BASE_EXPORT_API) +target_include_directories(CruBase PUBLIC ${CRU_INCLUDE_DIR}) +target_compile_definitions(CruBase PUBLIC $<$:CRU_DEBUG>) + +if (UNIX AND NOT EMSCRIPTEN) + target_sources(CruBase PRIVATE + platform/unix/PosixSpawnSubProcess.cpp + platform/unix/UnixFileStream.cpp + platform/unix/UnixPipe.cpp + ) + + if (NOT APPLE) + target_link_libraries(CruBase PUBLIC pthread) + endif() +endif() + +if (APPLE) + find_library(CORE_FOUNDATION CoreFoundation REQUIRED) + target_link_libraries(CruBase PUBLIC ${CORE_FOUNDATION}) + + target_sources(CruBase PRIVATE + platform/osx/Convert.cpp + platform/osx/Exception.cpp + ) +endif() + +if (EMSCRIPTEN) + target_compile_options(CruBase PUBLIC "-fwasm-exceptions") + target_link_options(CruBase PUBLIC "-fwasm-exceptions") + + target_sources(CruBase PRIVATE + platform/web/WebException.cpp + ) +endif() + +if (WIN32) + target_sources(CruBase PRIVATE + platform/win/BridgeComStream.cpp + platform/win/ComAutoInit.cpp + platform/win/DebugLogTarget.cpp + platform/win/Exception.cpp + platform/win/StreamConvert.cpp + platform/win/Win32FileStream.cpp + ) + + target_link_libraries(CruBase PUBLIC Shlwapi.lib) +endif() + +if (WIN32) + target_compile_definitions(CruBase PUBLIC CRU_PLATFORM_WINDOWS) +elseif(APPLE) + target_compile_definitions(CruBase PUBLIC CRU_PLATFORM_OSX) +elseif(EMSCRIPTEN) + target_compile_definitions(CruBase PUBLIC CRU_PLATFORM_EMSCRIPTEN) +else() + target_compile_definitions(CruBase PUBLIC CRU_PLATFORM_LINUX) +endif() + +target_link_libraries(CruBase PUBLIC double-conversion) diff --git a/src/base/Exception.cpp b/src/base/Exception.cpp new file mode 100644 index 00000000..19938970 --- /dev/null +++ b/src/base/Exception.cpp @@ -0,0 +1,36 @@ +#include "cru/base/Exception.h" + +#include "cru/base/Format.h" + +#include + +namespace cru { +Exception::Exception(String message, std::unique_ptr inner) + : message_(std::move(message)), inner_(std::move(inner)) {} + +Exception::~Exception() {} + +const char* Exception::what() const noexcept { + if (!message_.empty() && utf8_message_.empty()) { + utf8_message_ = message_.ToUtf8(); + } + + return utf8_message_.c_str(); +} + +void Exception::AppendMessage(StringView additional_message) { + message_ += u" "; + message_ += additional_message; +} + +void Exception::AppendMessage(std::optional additional_message) { + if (additional_message) AppendMessage(*additional_message); +} + +ErrnoException::ErrnoException(String message) + : ErrnoException(message, errno) {} + +ErrnoException::ErrnoException(String message, int errno_code) + : Exception(Format(u"{}. Errno is {}.", message, errno_code)), + errno_code_(errno_code) {} +} // namespace cru diff --git a/src/base/Format.cpp b/src/base/Format.cpp new file mode 100644 index 00000000..cba4137f --- /dev/null +++ b/src/base/Format.cpp @@ -0,0 +1,111 @@ +#include "cru/base/Format.h" + +namespace cru { +namespace details { +FormatToken ParsePlaceHolder(String place_holder_string) { + if (place_holder_string.empty()) { + return FormatToken::NonePlaceHolder({}); + } + + if (place_holder_string.StartWith(u":")) { + if (place_holder_string.Find(u':', 1) != -1) { + throw Exception(u"Two ':' inside placeholder."); + } + + return FormatToken::NonePlaceHolder(place_holder_string.substr(1)); + } + if (IsDigit(place_holder_string[0])) { + int position = 0; + int index = 0; + while (index < place_holder_string.size() && + IsDigit(place_holder_string[index])) { + position = position * 10 + place_holder_string[index] - '0'; + index++; + } + + String option; + + if (index != place_holder_string.size()) { + if (place_holder_string[index] != ':') { + throw Exception(u"Invalid placeholder in format."); + } + + option = place_holder_string.substr(index + 1); + } + + return FormatToken::PositionedPlaceHolder(position, std::move(option)); + } + + auto separator_index = place_holder_string.Find(':'); + if (separator_index == -1) { + return FormatToken::NamedPlaceHolder(place_holder_string, {}); + } else { + return FormatToken::NamedPlaceHolder( + place_holder_string.substr(0, separator_index), + place_holder_string.substr(separator_index + 1)); + } +} + +std::vector ParseToFormatTokenList(StringView str) { + std::vector result; + + auto push_char = [&result](char16_t c) { + if (result.empty() || result.back().type == FormatTokenType::PlaceHolder) { + result.push_back(FormatToken::Text()); + } + result.back().data.append(c); + }; + + bool try_to_escape = false; + bool is_in_place_holder = false; + String place_holder_string; + + for (auto c : str) { + if (c == u'{') { + if (try_to_escape) { + push_char(u'{'); + try_to_escape = false; + is_in_place_holder = false; + } else { + if (is_in_place_holder) { + throw Exception(u"Invalid format string: '{' inside placeholder."); + } + + try_to_escape = true; + is_in_place_holder = true; + } + } else if (c == u'}') { + if (is_in_place_holder) { + is_in_place_holder = false; + result.push_back(ParsePlaceHolder(std::move(place_holder_string))); + place_holder_string.clear(); + } else { + push_char(u'}'); + } + try_to_escape = false; + } else { + if (is_in_place_holder) { + place_holder_string.push_back(c); + } else { + push_char(c); + } + try_to_escape = false; + } + } + return result; +} + +void FormatAppendFromFormatTokenList( + String& current, const std::vector& format_token_list, + Index index) { + for (Index i = index; i < static_cast(format_token_list.size()); i++) { + const auto& token = format_token_list[i]; + if (token.type == FormatTokenType::PlaceHolder) { + throw Exception(u"More placeholder than args."); + } else { + current += token.data; + } + } +} +} // namespace details +} // namespace cru diff --git a/src/base/PropertyTree.cpp b/src/base/PropertyTree.cpp new file mode 100644 index 00000000..8303a706 --- /dev/null +++ b/src/base/PropertyTree.cpp @@ -0,0 +1,71 @@ +#include "cru/base/PropertyTree.h" +#include +#include "cru/base/Exception.h" + +namespace cru { +String PropertySubTreeRef::CombineKey(StringView left, StringView right) { + return PropertyTree::CombineKey(left, right); +} + +PropertySubTreeRef::PropertySubTreeRef(PropertyTree* tree, String path) + : tree_(tree), path_(std::move(path)) { + Expects(tree); +} + +PropertySubTreeRef PropertySubTreeRef::GetParent() const { + for (Index i = path_.size() - 1; i >= 0; i--) { + if (path_[i] == '.') { + return PropertySubTreeRef(tree_, path_.substr(0, i)); + } + } + + return PropertySubTreeRef(tree_, {}); +} + +PropertySubTreeRef PropertySubTreeRef::GetChild(const String& key) const { + return PropertySubTreeRef(tree_, CombineKey(path_, key)); +} + +String PropertySubTreeRef::GetValue(const String& key) const { + return tree_->GetValue(CombineKey(path_, key)); +} + +void PropertySubTreeRef::SetValue(const String& key, String value) { + tree_->SetValue(CombineKey(path_, key), std::move(value)); +} + +void PropertySubTreeRef::DeleteValue(const String& key) { + tree_->DeleteValue(CombineKey(path_, key)); +} + +String PropertyTree::CombineKey(StringView left, StringView right) { + return String(left) + String(left.empty() ? u"" : u".") + String(right); +} + +PropertyTree::PropertyTree(std::unordered_map values) + : values_(std::move(values)) {} + +String PropertyTree::GetValue(const String& key) const { + auto it = values_.find(key); + if (it == values_.end()) { + throw Exception(u"Property tree has no value."); + } + return it->second; +} + +void PropertyTree::SetValue(const String& key, String value) { + values_[key] = std::move(value); +} + +void PropertyTree::DeleteValue(const String& key) { + auto it = values_.find(key); + if (it != values_.end()) { + values_.erase(it); + } +} + +PropertySubTreeRef PropertyTree::GetSubTreeRef(const String& path) { + return PropertySubTreeRef(this, path); +} + +} // namespace cru diff --git a/src/base/String.cpp b/src/base/String.cpp new file mode 100644 index 00000000..47b64373 --- /dev/null +++ b/src/base/String.cpp @@ -0,0 +1,672 @@ +#include "cru/base/String.h" + +#include "cru/base/Buffer.h" +#include "cru/base/Exception.h" +#include "cru/base/StringToNumberConverter.h" +#include "cru/base/StringUtil.h" + +#include +#include + +#include +#include +#include +#include +#include + +namespace cru { +template +Index GetStrSize(const C* str) { + Index i = 0; + while (str[i]) { + i++; + } + return i; +} + +String String::FromUtf8(const char* str) { + return FromUtf8(str, GetStrSize(str)); +} + +String String::FromUtf8(const char* str, Index size) { + String result; + Utf8CodePointIterator iter(str, size); + for (auto cp : iter) { + Utf16EncodeCodePointAppend( + cp, + std::bind(&String::push_back, std::ref(result), std::placeholders::_1)); + } + return result; +} + +String String::FromUtf8(const std::byte* str, Index size) { + return String::FromUtf8(reinterpret_cast(str), size); +} + +String String::FromUtf8(const Buffer& buffer) { + return String::FromUtf8(buffer.GetUsedBeginPtr(), buffer.GetUsedSize()); +} + +String String::FromStdPath(const std::filesystem::path& path) { + return String::FromUtf8(path.string()); +} + +char16_t String::kEmptyBuffer[1] = {0}; + +String::String(const_pointer str) : String(str, GetStrSize(str)) {} + +String::String(const_pointer str, Index size) { + this->buffer_ = new value_type[size + 1]; + std::memcpy(this->buffer_, str, size * sizeof(char16_t)); + this->buffer_[size] = 0; + this->size_ = size; + this->capacity_ = size; +} + +String::String(size_type size, value_type ch) : String() { + reserve(size); + for (Index i = 0; i < size; i++) { + append(ch); + } +} + +String::String(std::initializer_list l) + : String(l.begin(), l.size()) {} + +#ifdef CRU_PLATFORM_WINDOWS +String::String(const wchar_t* str) : String(str, GetStrSize(str)) {} +String::String(const wchar_t* str, Index size) + : String(reinterpret_cast(str), size) {} +#endif + +String::String(const String& other) { + if (other.size_ == 0) return; + this->buffer_ = new value_type[other.size_ + 1]; + std::memcpy(this->buffer_, other.buffer_, other.size_ * sizeof(value_type)); + this->buffer_[other.size_] = 0; + this->size_ = other.size_; + this->capacity_ = other.size_; +} + +String::String(String&& other) noexcept { + this->buffer_ = other.buffer_; + this->size_ = other.size_; + this->capacity_ = other.capacity_; + other.buffer_ = kEmptyBuffer; + other.size_ = 0; + other.capacity_ = 0; +} + +String& String::operator=(const String& other) { + if (this != &other) { + if (this->buffer_ != kEmptyBuffer) { + delete[] this->buffer_; + } + + if (other.buffer_ == kEmptyBuffer) { + this->buffer_ = kEmptyBuffer; + this->size_ = 0; + this->capacity_ = 0; + } else { + this->buffer_ = new value_type[other.size_ + 1]; + std::memcpy(this->buffer_, other.buffer_, + other.size_ * sizeof(value_type)); + this->buffer_[other.size_] = 0; + this->size_ = other.size_; + this->capacity_ = other.size_; + } + } + return *this; +} + +String& String::operator=(String&& other) noexcept { + if (this != &other) { + if (this->buffer_ != kEmptyBuffer) { + delete[] this->buffer_; + } + + this->buffer_ = other.buffer_; + this->size_ = other.size_; + this->capacity_ = other.capacity_; + other.buffer_ = kEmptyBuffer; + other.size_ = 0; + other.capacity_ = 0; + } + return *this; +} + +String::~String() { + if (this->buffer_ != kEmptyBuffer) { + delete[] this->buffer_; + } +} + +String::String(from_buffer_tag, pointer buffer, Index size, Index capacity) + : buffer_(buffer), size_(size), capacity_(capacity) {} + +void String::clear() { resize(0); } + +void String::resize(Index new_size) { + Expects(new_size >= 0); + + if (new_size == size_) return; + + if (new_size < size_) { + size_ = new_size; + buffer_[size_] = 0; + } else { + reserve(new_size); + std::memset(buffer_ + size_, 0, sizeof(value_type) * (new_size - size_)); + buffer_[new_size] = 0; + size_ = new_size; + } +} + +void String::shrink_to_fit() { + if (capacity_ == size_) return; + if (size_ == 0) { + delete[] buffer_; + buffer_ = kEmptyBuffer; + size_ = 0; + capacity_ = 0; + } else { + auto new_buffer = new value_type[size_ + 1]; + std::memcpy(new_buffer, buffer_, sizeof(value_type) * size_); + delete[] buffer_; + buffer_ = new_buffer; + capacity_ = size_; + } +} + +void String::reserve(Index new_capacity) { + Expects(new_capacity >= 0); + if (new_capacity <= this->capacity_) return; + if (new_capacity > 0) { + pointer new_buffer = new value_type[new_capacity + 1]; + if (this->buffer_ != kEmptyBuffer) { + memcpy(new_buffer, this->buffer_, this->size_ * sizeof(value_type)); + delete[] this->buffer_; + } + new_buffer[this->size_] = 0; + this->buffer_ = new_buffer; + this->capacity_ = new_capacity; + } +} + +String::iterator String::insert(const_iterator pos, const_iterator str, + Index size) { + Expects(pos >= cbegin() && pos <= cend()); + + std::vector backup_buffer; + if (str >= buffer_ && str < buffer_ + size_) { + backup_buffer.resize(size); + std::copy(str, str + size, backup_buffer.begin()); + str = backup_buffer.data(); + } + + Index index = pos - cbegin(); + + Index new_size = size_ + size; + if (new_size > capacity_) { + auto new_capacity = capacity_; + if (new_capacity == 0) { + new_capacity = new_size; + } else { + while (new_capacity < new_size) { + new_capacity *= 2; + } + } + + this->reserve(new_capacity); + } + + std::memmove(begin() + index + size, begin() + index, + (size_ - index) * sizeof(value_type)); + std::memcpy(begin() + index, str, size * sizeof(value_type)); + + buffer_[new_size] = 0; + size_ = new_size; + + return begin() + new_size; +} + +String::iterator String::erase(const_iterator start, const_iterator end) { + Expects(buffer_ <= start && start <= end && end <= buffer_ + size_); + + Index new_size = size_ - (end - start); + + auto s = const_cast(start); + auto e = const_cast(end); + + std::memmove(s, e, (cend() - end) * sizeof(value_type)); + this->size_ = new_size; + this->buffer_[new_size] = 0; + + return s; +} + +String& String::operator+=(StringView other) { + append(other); + return *this; +} + +StringView String::View() const { return *this; } + +Index String::Find(value_type value, Index start) const { + return View().Find(value, start); +} + +std::vector String::Split(value_type separator, + bool remove_space_line) const { + return View().Split(separator, remove_space_line); +} + +std::vector String::SplitToLines(bool remove_space_line) const { + return View().SplitToLines(remove_space_line); +} + +bool String::StartWith(StringView str) const { return View().StartWith(str); } + +bool String::EndWith(StringView str) const { return View().EndWith(str); } + +std::string String::ToUtf8() const { return View().ToUtf8(); } + +Buffer String::ToUtf8Buffer(bool end_zero) const { + return View().ToUtf8Buffer(); +} + +String& String::TrimStart() { + if (size_ == 0) return *this; + + auto start = begin(); + while (start != end() && IsWhitespace(*start)) { + ++start; + } + + if (start == end()) { + clear(); + } else { + erase(begin(), start); + } + + return *this; +} + +String& String::TrimEnd() { + if (size_ == 0) return *this; + while (size_ > 0 && IsWhitespace(buffer_[size_ - 1])) { + size_--; + } + + return *this; +} + +String& String::Trim() { + TrimStart(); + TrimEnd(); + return *this; +} + +void String::AppendCodePoint(CodePoint code_point) { + if (!Utf16EncodeCodePointAppend( + code_point, + std::bind(&String::push_back, this, std::placeholders::_1))) { + throw TextEncodeException(u"Code point out of range."); + } +} + +Index String::IndexFromCodeUnitToCodePoint(Index code_unit_index) const { + return View().IndexFromCodeUnitToCodePoint(code_unit_index); +} + +Index String::IndexFromCodePointToCodeUnit(Index code_point_index) const { + return View().IndexFromCodePointToCodeUnit(code_point_index); +} + +Range String::RangeFromCodeUnitToCodePoint(Range code_unit_range) const { + return View().RangeFromCodeUnitToCodePoint(code_unit_range); +} + +Range String::RangeFromCodePointToCodeUnit(Range code_point_range) const { + return View().RangeFromCodePointToCodeUnit(code_point_range); +} + +int String::ParseToInt(Index* processed_characters_count, + StringToNumberFlag flags, int base) const { + return View().ParseToInt(processed_characters_count, flags, base); +} + +long long String::ParseToLongLong(Index* processed_characters_count, + StringToNumberFlag flags, int base) const { + return View().ParseToLongLong(processed_characters_count, flags, base); +} + +float String::ParseToFloat(Index* processed_characters_count, + StringToNumberFlag flags) const { + return View().ParseToFloat(processed_characters_count, flags); +} + +double String::ParseToDouble(Index* processed_characters_count, + StringToNumberFlag flags) const { + return View().ParseToDouble(processed_characters_count, flags); +} + +std::vector String::ParseToFloatList(value_type separator) const { + return View().ParseToFloatList(separator); +} + +std::vector String::ParseToDoubleList(value_type separator) const { + return View().ParseToDoubleList(separator); +} + +std::ostream& operator<<(std::ostream& os, const String& value) { + os << value.ToUtf8(); + return os; +} + +namespace { +inline int Compare(char16_t left, char16_t right) { + if (left < right) return -1; + if (left > right) return 1; + return 0; +} + +inline int CaseInsensitiveCompare(char16_t left, char16_t right) { + return Compare(ToLower(left), ToLower(right)); +} +} // namespace + +int String::Compare(const String& other) const { return View().Compare(other); } +int String::CaseInsensitiveCompare(const String& other) const { + return View().CaseInsensitiveCompare(other); +} + +int StringView::Compare(const StringView& other) const { + const_iterator i1 = cbegin(); + const_iterator i2 = other.cbegin(); + + const_iterator end1 = cend(); + const_iterator end2 = other.cend(); + + while (i1 != end1 && i2 != end2) { + int r = cru::Compare(*i1, *i2); + if (r != 0) return r; + i1++; + i2++; + } + + if (i1 == end1) { + if (i2 == end2) { + return 0; + } else { + return -1; + } + } else { + return 1; + } +} + +int StringView::CaseInsensitiveCompare(const StringView& other) const { + const_iterator i1 = cbegin(); + const_iterator i2 = other.cbegin(); + + const_iterator end1 = cend(); + const_iterator end2 = other.cend(); + + while (i1 != end1 && i2 != end2) { + int r = cru::CaseInsensitiveCompare(*i1, *i2); + if (r != 0) return r; + i1++; + i2++; + } + + if (i1 == end1) { + if (i2 == end2) { + return 0; + } else { + return -1; + } + } else { + return 1; + } +} + +StringView StringView::substr(Index pos) { + Expects(pos >= 0 && pos < size_); + return StringView(ptr_ + pos, size_ - pos); +} + +StringView StringView::substr(Index pos, Index size) { + Expects(pos >= 0 && pos < size_); + + return StringView(ptr_ + pos, std::min(size, size_ - pos)); +} + +Index StringView::Find(value_type value, Index start) const { + Expects(start >= 0 && start <= size_); + + for (Index i = start; i < size_; ++i) { + if (ptr_[i] == value) return i; + } + return -1; +} + +std::vector StringView::Split(value_type separator, + bool remove_space_line) const { + std::vector result; + + if (size_ == 0) return result; + + Index line_start = 0; + Index line_end = 0; + while (line_end < size_) { + if (ptr_[line_end] == separator) { + if (remove_space_line) { + bool add = false; + for (Index i = line_start; i < line_end; i++) { + if (!IsWhitespace(ptr_[i])) { + add = true; + break; + } + } + if (add) result.emplace_back(begin() + line_start, begin() + line_end); + } else { + result.emplace_back(begin() + line_start, begin() + line_end); + } + line_start = line_end + 1; + line_end = line_start; + } else { + line_end++; + } + } + + if (remove_space_line) { + bool add = false; + for (Index i = line_start; i < size_; i++) { + if (!IsWhitespace(ptr_[i])) { + add = true; + break; + } + } + if (add) result.emplace_back(begin() + line_start, begin() + size_); + } else { + result.emplace_back(begin() + line_start, begin() + size_); + } + + return result; +} + +std::vector StringView::SplitToLines(bool remove_space_line) const { + return Split(u'\n', remove_space_line); +} + +bool StringView::StartWith(StringView str) const { + if (str.size() > size_) return false; + return std::memcmp(str.data(), ptr_, str.size()) == 0; +} + +bool StringView::EndWith(StringView str) const { + if (str.size() > size_) return false; + return std::memcmp(str.data(), ptr_ + size_ - str.size(), str.size()) == 0; +} + +Index StringView::IndexFromCodeUnitToCodePoint(Index code_unit_index) const { + auto iter = CodePointIterator(); + Index result = 0; + while (iter.GetPosition() < code_unit_index && !iter.IsPastEnd()) { + ++iter; + ++result; + } + return result; +} + +Index StringView::IndexFromCodePointToCodeUnit(Index code_point_index) const { + auto iter = CodePointIterator(); + Index cpi = 0; + while (cpi < code_point_index && !iter.IsPastEnd()) { + ++iter; + ++cpi; + } + return iter.GetPosition(); +} + +Range StringView::RangeFromCodeUnitToCodePoint(Range code_unit_range) const { + return Range::FromTwoSides( + IndexFromCodeUnitToCodePoint(code_unit_range.GetStart()), + IndexFromCodeUnitToCodePoint(code_unit_range.GetEnd())); +} + +Range StringView::RangeFromCodePointToCodeUnit(Range code_point_range) const { + return Range::FromTwoSides( + IndexFromCodePointToCodeUnit(code_point_range.GetStart()), + IndexFromCodePointToCodeUnit(code_point_range.GetEnd())); +} + +std::string StringView::ToUtf8() const { + std::string result; + for (auto cp : CodePointIterator()) { + Utf8EncodeCodePointAppend( + cp, std::bind(&std::string::push_back, std::ref(result), + std::placeholders::_1)); + } + return result; +} + +Buffer StringView::ToUtf8Buffer(bool end_zero) const { + const Index grow_step = 10; + Buffer buffer(grow_step); // Maybe another init value is more reasonable. + auto push_back = [&buffer](char c) { + if (buffer.IsUsedReachEnd()) { + buffer.ResizeBuffer(buffer.GetBufferSize() + grow_step, true); + } + buffer.PushBack(static_cast(c)); + }; + for (auto cp : CodePointIterator()) { + Utf8EncodeCodePointAppend(cp, push_back); + } + if (end_zero) { + push_back(0); + } + return buffer; +} + +int StringView::ParseToInt(Index* processed_characters_count, + StringToNumberFlag flags, int base) const { + return ParseToInteger(processed_characters_count, flags, base); +} + +long long StringView::ParseToLongLong(Index* processed_characters_count, + StringToNumberFlag flags, + int base) const { + return ParseToInteger(processed_characters_count, flags, base); +} + +static int MapStringToDoubleFlags(StringToNumberFlag flags) { + int f = double_conversion::StringToDoubleConverter::ALLOW_CASE_INSENSIBILITY; + if (flags & StringToNumberFlags::kAllowLeadingSpaces) { + f |= double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES; + } + if (flags & StringToNumberFlags::kAllowTrailingSpaces) { + f |= double_conversion::StringToDoubleConverter::ALLOW_TRAILING_SPACES; + } + if (flags & StringToNumberFlags::kAllowTrailingJunk) { + f |= double_conversion::StringToDoubleConverter::ALLOW_TRAILING_JUNK; + } + return f; +} + +static double_conversion::StringToDoubleConverter CreateStringToDoubleConverter( + StringToNumberFlag flags) { + return {MapStringToDoubleFlags(flags), 0.0, NAN, "inf", "nan"}; +} + +float StringView::ParseToFloat(Index* processed_characters_count, + StringToNumberFlag flags) const { + int pcc; + auto result = CreateStringToDoubleConverter(flags).StringToFloat( + reinterpret_cast(ptr_), static_cast(size_), &pcc); + if (processed_characters_count != nullptr) { + *processed_characters_count = pcc; + } + + if (flags & StringToNumberFlags::kThrowOnError && std::isnan(result)) { + throw Exception(u"Result of string to float conversion is NaN"); + } + + return result; +} + +double StringView::ParseToDouble(Index* processed_characters_count, + StringToNumberFlag flags) const { + int pcc; + auto result = CreateStringToDoubleConverter(flags).StringToDouble( + reinterpret_cast(ptr_), static_cast(size_), &pcc); + if (processed_characters_count != nullptr) { + *processed_characters_count = pcc; + } + + if (flags & StringToNumberFlags::kThrowOnError && std::isnan(result)) { + throw Exception(u"Result of string to double conversion is NaN"); + } + + return result; +} + +std::vector StringView::ParseToFloatList(value_type separator) const { + std::vector result; + auto list = Split(separator, true); + for (auto& item : list) { + auto value = item.ParseToFloat(); + if (std::isnan(value)) { + throw Exception(u"Invalid double value."); + } + result.push_back(value); + } + return result; +} + +std::vector StringView::ParseToDoubleList(value_type separator) const { + std::vector result; + auto list = Split(separator, true); + for (auto& item : list) { + auto value = item.ParseToDouble(); + if (std::isnan(value)) { + throw Exception(u"Invalid double value."); + } + result.push_back(value); + } + return result; +} + +String ToLower(StringView s) { + String result; + for (auto c : s) result.push_back(ToLower(c)); + return result; +} + +String ToUpper(StringView s) { + String result; + for (auto c : s) result.push_back(ToUpper(c)); + return result; +} +} // namespace cru diff --git a/src/base/StringToNumberConverter.cpp b/src/base/StringToNumberConverter.cpp new file mode 100644 index 00000000..65aec48e --- /dev/null +++ b/src/base/StringToNumberConverter.cpp @@ -0,0 +1,170 @@ +#include "cru/base/StringToNumberConverter.h" +#include "cru/base/Exception.h" + +namespace cru { +bool StringToIntegerConverter::CheckParams() const { + return base == 0 || base >= 2 & base <= 36; +} + +static bool IsSpace(char c) { + return c == ' ' || c == '\t' || c == '\n' || c == '\r'; +} + +StringToIntegerResult StringToIntegerConverter::Parse( + const char* const str, const Index size, + Index* processed_characters_count) const { + if (str == nullptr) throw std::invalid_argument("Invalid str."); + if (size < 0) throw std::invalid_argument("Invalid size."); + if (!CheckParams()) throw std::invalid_argument("Invalid parsing flags."); + + const bool throw_on_error = flags.Has(StringToNumberFlags::kThrowOnError); + + auto const end = str + size; + + auto current = str; + + if (flags & StringToNumberFlags::kAllowLeadingSpaces) { + while (current != end && IsSpace(*current)) { + current++; + } + } + + if (current == end) { + if (processed_characters_count) { + *processed_characters_count = 0; + } + if (throw_on_error) { + throw Exception(u"Empty string (after reading leading spaces)."); + } else { + return {false, 0}; + } + } + + bool negate = false; + + if (*current == '-') { + ++current; + negate = true; + } else if (*current == '+') { + ++current; + } + + if (current == end) { + if (processed_characters_count) { + *processed_characters_count = 0; + } + if (throw_on_error) { + throw Exception(u"Empty string (after reading sign)."); + } else { + return {false, 0}; + } + } + + int real_base = base; + + if (real_base == 0) { + if (*current == '0') { + ++current; + if (current == end) { + if (processed_characters_count) { + *processed_characters_count = current - str; + } + return {negate, 0}; + } else if (*current == 'x' || *current == 'X') { + ++current; + real_base = 16; + } else if (*current == 'b' || *current == 'B') { + ++current; + real_base = 2; + } else { + real_base = 8; + } + } else { + real_base = 10; + } + } + + if (current == end) { + if (processed_characters_count) { + *processed_characters_count = 0; + } + if (throw_on_error) { + throw Exception(u"Empty string (after reading head base indicator)."); + } else { + return {false, 0}; + } + } + + const bool allow_leading_zero = + flags.Has(StringToNumberFlags::kAllowLeadingZeroForInteger); + + while (current != end && *current == '0') { + current++; + } + + if (current == end) { + if (processed_characters_count) { + *processed_characters_count = current - str; + } + return {negate, 0}; + } + + const bool allow_trailing_junk = + flags.Has(StringToNumberFlags::kAllowTrailingJunk); + const bool allow_trailing_spaces = + flags.Has(StringToNumberFlags::kAllowTrailingSpaces); + + unsigned long long result = 0; + + while (current != end) { + const char c = *current; + if (c >= '0' && c <= (real_base > 10 ? '9' : real_base + '0' - 1)) { + result = result * real_base + c - '0'; + current++; + } else if (real_base > 10 && c >= 'a' && c <= (real_base + 'a' - 10 - 1)) { + result = result * real_base + c - 'a' + 10; + current++; + } else if (real_base > 10 && c >= 'A' && c <= (real_base + 'A' - 10 - 1)) { + result = result * real_base + c - 'A' + 10; + current++; + } else if (allow_trailing_junk) { + break; + } else if (allow_trailing_spaces && IsSpace(c)) { + break; + } else { + if (processed_characters_count) { + *processed_characters_count = 0; + } + if (throw_on_error) { + throw Exception(String(u"Read invalid character '") + c + u"'."); + } else { + return {false, 0}; + } + } + } + + if (allow_trailing_spaces) { + while (current != end && IsSpace(*current)) { + current++; + } + + if (current != end) { + if (processed_characters_count) { + *processed_characters_count = 0; + } + if (throw_on_error) { + throw Exception(u"There is trailing junk."); + } else { + return {false, 0}; + } + } + } + + if (processed_characters_count) { + *processed_characters_count = current - str; + } + + return {negate, result}; +} + +} // namespace cru diff --git a/src/base/StringUtil.cpp b/src/base/StringUtil.cpp new file mode 100644 index 00000000..9053f384 --- /dev/null +++ b/src/base/StringUtil.cpp @@ -0,0 +1,243 @@ +#include "cru/base/StringUtil.h" +#include "cru/base/Base.h" +#include "cru/base/Exception.h" + +namespace cru { +using details::ExtractBits; + +CodePoint Utf8NextCodePoint(const char* ptr, Index size, Index current, + Index* next_position) { + CodePoint result; + + if (current >= size) { + result = k_invalid_code_point; + } else { + const auto cu0 = static_cast(ptr[current++]); + + auto read_next_folowing_code = [ptr, size, ¤t]() -> CodePoint { + if (current == size) + throw TextEncodeException( + u"Unexpected end when read continuing byte of multi-byte code " + "point."); + + const auto u = static_cast(ptr[current]); + if (!(u & (1u << 7)) || (u & (1u << 6))) { + throw TextEncodeException( + u"Unexpected bad-format (not 0b10xxxxxx) continuing byte of " + "multi-byte code point."); + } + + return ExtractBits(ptr[current++]); + }; + + if ((1u << 7) & cu0) { + if ((1u << 6) & cu0) { // 2~4-length code point + if ((1u << 5) & cu0) { // 3~4-length code point + if ((1u << 4) & cu0) { // 4-length code point + if (cu0 & (1u << 3)) { + throw TextEncodeException( + u"Unexpected bad-format begin byte (not 0b11110xxx) of 4-byte" + "code point."); + } + + const CodePoint s0 = ExtractBits(cu0) + << (6 * 3); + const CodePoint s1 = read_next_folowing_code() << (6 * 2); + const CodePoint s2 = read_next_folowing_code() << 6; + const CodePoint s3 = read_next_folowing_code(); + result = s0 + s1 + s2 + s3; + } else { // 3-length code point + const CodePoint s0 = ExtractBits(cu0) + << (6 * 2); + const CodePoint s1 = read_next_folowing_code() << 6; + const CodePoint s2 = read_next_folowing_code(); + result = s0 + s1 + s2; + } + } else { // 2-length code point + const CodePoint s0 = ExtractBits(cu0) + << 6; + const CodePoint s1 = read_next_folowing_code(); + result = s0 + s1; + } + } else { + throw TextEncodeException( + u"Unexpected bad-format (0b10xxxxxx) begin byte of a code point."); + } + } else { + result = static_cast(cu0); + } + } + + if (next_position != nullptr) *next_position = current; + return result; +} + +CodePoint Utf16NextCodePoint(const char16_t* ptr, Index size, Index current, + Index* next_position) { + CodePoint result; + + if (current >= size) { + result = k_invalid_code_point; + } else { + const auto cu0 = ptr[current++]; + + if (!IsUtf16SurrogatePairCodeUnit(cu0)) { // 1-length code point + result = static_cast(cu0); + } else if (IsUtf16SurrogatePairLeading(cu0)) { // 2-length code point + if (current >= size) { + throw TextEncodeException( + u"Unexpected end when reading second code unit of surrogate pair."); + } + const auto cu1 = ptr[current++]; + + if (!IsUtf16SurrogatePairTrailing(cu1)) { + throw TextEncodeException( + u"Unexpected bad-range second code unit of surrogate pair."); + } + + const auto s0 = ExtractBits(cu0) << 10; + const auto s1 = ExtractBits(cu1); + + result = s0 + s1 + 0x10000; + + } else { + throw TextEncodeException( + u"Unexpected bad-range first code unit of surrogate pair."); + } + } + + if (next_position != nullptr) *next_position = current; + return result; +} + +CodePoint Utf16PreviousCodePoint(const char16_t* ptr, Index size, Index current, + Index* previous_position) { + CRU_UNUSED(size) + + CodePoint result; + if (current <= 0) { + result = k_invalid_code_point; + } else { + const auto cu0 = ptr[--current]; + + if (!IsUtf16SurrogatePairCodeUnit(cu0)) { // 1-length code point + result = static_cast(cu0); + } else if (IsUtf16SurrogatePairTrailing(cu0)) { // 2-length code point + if (current <= 0) { + throw TextEncodeException( + u"Unexpected end when reading first code unit of surrogate pair."); + } + const auto cu1 = ptr[--current]; + + if (!IsUtf16SurrogatePairLeading(cu1)) { + throw TextEncodeException( + u"Unexpected bad-range first code unit of surrogate pair."); + } + + const auto s0 = ExtractBits(cu1) << 10; + const auto s1 = ExtractBits(cu0); + + result = s0 + s1 + 0x10000; + + } else { + throw TextEncodeException( + u"Unexpected bad-range second code unit of surrogate pair."); + } + } + + if (previous_position != nullptr) *previous_position = current; + return result; +} + +bool Utf16IsValidInsertPosition(const char16_t* ptr, Index size, + Index position) { + if (position < 0) return false; + if (position > size) return false; + if (position == 0) return true; + if (position == size) return true; + return !IsUtf16SurrogatePairTrailing(ptr[position]); +} + +Index Utf16BackwardUntil(const char16_t* ptr, Index size, Index position, + const std::function& predicate) { + if (position <= 0) return position; + while (true) { + Index p = position; + auto c = Utf16PreviousCodePoint(ptr, size, p, &position); + if (predicate(c)) return p; + if (c == k_invalid_code_point) return p; + } + UnreachableCode(); +} + +Index Utf16ForwardUntil(const char16_t* ptr, Index size, Index position, + const std::function& predicate) { + if (position >= size) return position; + while (true) { + Index p = position; + auto c = Utf16NextCodePoint(ptr, size, p, &position); + if (predicate(c)) return p; + if (c == k_invalid_code_point) return p; + } + UnreachableCode(); +} + +inline bool IsSpace(CodePoint c) { return c == 0x20 || c == 0xA; } + +Index Utf16PreviousWord(const char16_t* ptr, Index size, Index position, + bool* is_space) { + if (position <= 0) return position; + auto c = Utf16PreviousCodePoint(ptr, size, position, nullptr); + if (IsSpace(c)) { // TODO: Currently only test against 0x20(space). + if (is_space) *is_space = true; + return Utf16BackwardUntil(ptr, size, position, + [](CodePoint c) { return !IsSpace(c); }); + } else { + if (is_space) *is_space = false; + return Utf16BackwardUntil(ptr, size, position, IsSpace); + } +} + +Index Utf16NextWord(const char16_t* ptr, Index size, Index position, + bool* is_space) { + if (position >= size) return position; + auto c = Utf16NextCodePoint(ptr, size, position, nullptr); + if (IsSpace(c)) { // TODO: Currently only test against 0x20(space). + if (is_space) *is_space = true; + return Utf16ForwardUntil(ptr, size, position, + [](CodePoint c) { return !IsSpace(c); }); + } else { + if (is_space) *is_space = false; + return Utf16ForwardUntil(ptr, size, position, IsSpace); + } +} + +char16_t ToLower(char16_t c) { + if (c >= u'A' && c <= u'Z') { + return c - u'A' + u'a'; + } + return c; +} + +char16_t ToUpper(char16_t c) { + if (c >= u'a' && c <= u'z') { + return c - u'a' + u'A'; + } + return c; +} + +bool IsWhitespace(char16_t c) { + return c == u' ' || c == u'\t' || c == u'\n' || c == u'\r'; +} + +bool IsDigit(char16_t c) { return c >= u'0' && c <= u'9'; } + +Utf8CodePointIterator CreateUtf8Iterator(const std::byte* buffer, Index size) { + return Utf8CodePointIterator(reinterpret_cast(buffer), size); +} + +Utf8CodePointIterator CreateUtf8Iterator(const std::vector& buffer) { + return CreateUtf8Iterator(buffer.data(), buffer.size()); +} + +} // namespace cru diff --git a/src/base/SubProcess.cpp b/src/base/SubProcess.cpp new file mode 100644 index 00000000..1133b848 --- /dev/null +++ b/src/base/SubProcess.cpp @@ -0,0 +1,209 @@ +#include "cru/base/SubProcess.h" + +#include + +#ifdef CRU_PLATFORM_UNIX +#include "cru/base/platform/unix/PosixSpawnSubProcess.h" +#endif + +namespace cru { + +#ifdef CRU_PLATFORM_UNIX +using ThisPlatformSubProcessImpl = platform::unix::PosixSpawnSubProcessImpl; +#endif + +PlatformSubProcess::PlatformSubProcess( + SubProcessStartInfo start_info, + std::shared_ptr impl) + : state_(new State(std::move(start_info), std::move(impl))), + lock_(state_->mutex, std::defer_lock) {} + +PlatformSubProcess::~PlatformSubProcess() {} + +void PlatformSubProcess::Start() { + std::lock_guard lock_guard(this->lock_); + + if (this->state_->status != SubProcessStatus::Prepare) { + throw SubProcessException(u"The process has already tried to start."); + } + + try { + this->state_->impl->PlatformCreateProcess(this->state_->start_info); + this->state_->status = SubProcessStatus::Running; + + auto thread = std::thread([state = state_] { + std::unique_lock lock(state->mutex); + state->exit_result = state->impl->PlatformWaitForProcess(); + state->status = SubProcessStatus::Exited; + state->condition_variable.notify_all(); + }); + + thread.detach(); + } catch (const std::exception& e) { + this->state_->status = SubProcessStatus::FailedToStart; + throw SubProcessFailedToStartException(u"Sub-process failed to start. " + + String::FromUtf8(e.what())); + } +} + +void PlatformSubProcess::Wait( + std::optional wait_time) { + std::lock_guard lock_guard(this->lock_); + + if (this->state_->status == SubProcessStatus::Prepare) { + throw SubProcessException( + u"The process does not start. Can't wait for it."); + } + + if (this->state_->status == SubProcessStatus::FailedToStart) { + throw SubProcessException( + u"The process failed to start. Can't wait for it."); + } + + if (this->state_->status == SubProcessStatus::Exited) { + return; + } + + auto predicate = [this] { + return this->state_->status == SubProcessStatus::Exited; + }; + + if (wait_time) { + this->state_->condition_variable.wait_for(this->lock_, *wait_time, + predicate); + } else { + this->state_->condition_variable.wait(this->lock_, predicate); + } +} + +void PlatformSubProcess::Kill() { + std::lock_guard lock_guard(this->lock_); + + if (this->state_->status == SubProcessStatus::Prepare) { + throw SubProcessException(u"The process does not start. Can't kill it."); + } + + if (this->state_->status == SubProcessStatus::FailedToStart) { + throw SubProcessException(u"The process failed to start. Can't kill it."); + } + + if (this->state_->status == SubProcessStatus::Exited) { + return; + } + + if (this->state_->killed) { + return; + } + + this->state_->impl->PlatformKillProcess(); + this->state_->killed = true; +} + +SubProcessStatus PlatformSubProcess::GetStatus() { + std::lock_guard lock_guard(this->lock_); + return this->state_->status; +} + +SubProcessExitResult PlatformSubProcess::GetExitResult() { + std::lock_guard lock_guard(this->lock_); + + if (this->state_->status == SubProcessStatus::Prepare) { + throw SubProcessException( + u"The process does not start. Can't get exit result."); + } + + if (this->state_->status == SubProcessStatus::FailedToStart) { + throw SubProcessException( + u"The process failed to start. Can't get exit result."); + } + + if (this->state_->status == SubProcessStatus::Running) { + throw SubProcessException( + u"The process is running. Can't get exit result."); + } + + return this->state_->exit_result; +} + +io::Stream* PlatformSubProcess::GetStdinStream() { + return this->state_->impl->GetStdinStream(); +} + +io::Stream* PlatformSubProcess::GetStdoutStream() { + return this->state_->impl->GetStdoutStream(); +} + +io::Stream* PlatformSubProcess::GetStderrStream() { + return this->state_->impl->GetStderrStream(); +} + +SubProcess SubProcess::Create(String program, std::vector arguments, + std::unordered_map environments) { + SubProcessStartInfo start_info; + start_info.program = std::move(program); + start_info.arguments = std::move(arguments); + start_info.environments = std::move(environments); + return SubProcess(std::move(start_info)); +} + +SubProcessExitResult SubProcess::Call( + String program, std::vector arguments, + std::unordered_map environments) { + auto process = + Create(std::move(program), std::move(arguments), std::move(environments)); + process.Wait(); + return process.GetExitResult(); +} + +SubProcess::SubProcess(SubProcessStartInfo start_info) { + platform_process_.reset(new PlatformSubProcess( + std::move(start_info), std::make_shared())); + platform_process_->Start(); +} + +SubProcess::~SubProcess() {} + +void SubProcess::Wait(std::optional wait_time) { + CheckValid(); + platform_process_->Wait(wait_time); +} + +void SubProcess::Kill() { + CheckValid(); + platform_process_->Kill(); +} + +SubProcessStatus SubProcess::GetStatus() { + CheckValid(); + return platform_process_->GetStatus(); +} + +SubProcessExitResult SubProcess::GetExitResult() { + CheckValid(); + return platform_process_->GetExitResult(); +} + +io::Stream* SubProcess::GetStdinStream() { + CheckValid(); + return platform_process_->GetStdinStream(); +} + +io::Stream* SubProcess::GetStdoutStream() { + CheckValid(); + return platform_process_->GetStdoutStream(); +} + +io::Stream* SubProcess::GetStderrStream() { + CheckValid(); + return platform_process_->GetStderrStream(); +} + +void SubProcess::Detach() { auto p = platform_process_.release(); } + +void SubProcess::CheckValid() const { + if (!IsValid()) { + throw SubProcessException(u"SubProcess instance is invalid."); + } +} + +} // namespace cru diff --git a/src/base/io/AutoReadStream.cpp b/src/base/io/AutoReadStream.cpp new file mode 100644 index 00000000..c24f61d1 --- /dev/null +++ b/src/base/io/AutoReadStream.cpp @@ -0,0 +1,56 @@ +#include "cru/base/io/AutoReadStream.h" +#include "cru/base/io/Stream.h" + +#include + +namespace cru::io { + +AutoReadStream::AutoReadStream(Stream* stream, bool auto_delete, + const AutoReadStreamOptions& options) + : Stream(false, true, stream->CanSeek()) { + auto buffer_stream_options = options.GetBufferStreamOptions(); + stream_ = stream; + size_per_read_ = buffer_stream_options.GetBlockSizeOrDefault(); + buffer_stream_ = std::make_unique(buffer_stream_options); + background_thread_ = std::thread(&AutoReadStream::BackgroundThreadRun, this); +} + +AutoReadStream::~AutoReadStream() { + if (auto_delete_) { + delete stream_; + } +} + +Index AutoReadStream::DoRead(std::byte* buffer, Index offset, Index size) { + std::unique_lock lock(buffer_stream_mutex_); + return buffer_stream_->Read(buffer, offset, size); +} + +Index AutoReadStream::DoWrite(const std::byte* buffer, Index offset, + Index size) { + return stream_->Write(buffer, offset, size); +} + +void AutoReadStream::DoFlush() { stream_->Flush(); } + +void AutoReadStream::DoClose() {} + +void AutoReadStream::BackgroundThreadRun() { + std::vector buffer(size_per_read_); + while (true) { + try { + auto read = stream_->Read(buffer.data(), buffer.size()); + if (read == 0) { + buffer_stream_->SetEof(); + break; + } else { + buffer_stream_->Write(buffer.data(), read); + } + } catch (const StreamAlreadyClosedException& exception) { + buffer_stream_->SetEof(); + break; + } + } +} + +} // namespace cru::io diff --git a/src/base/io/BufferStream.cpp b/src/base/io/BufferStream.cpp new file mode 100644 index 00000000..e81731e8 --- /dev/null +++ b/src/base/io/BufferStream.cpp @@ -0,0 +1,109 @@ +#include "cru/base/io/BufferStream.h" +#include "cru/base/io/Stream.h" + +namespace cru::io { +BufferStream::BufferStream(const BufferStreamOptions& options) + : Stream(false, true, true) { + block_size_ = options.GetBlockSizeOrDefault(); + max_block_count_ = options.GetMaxBlockCount(); + + eof_ = false; +} + +BufferStream::~BufferStream() { DoClose(); } + +Index BufferStream::DoRead(std::byte* buffer, Index offset, Index size) { + std::unique_lock lock(mutex_); + + condition_variable_.wait(lock, + [this] { return !buffer_list_.empty() || eof_; }); + + if (buffer_list_.empty() && eof_) { + return 0; + } + + auto full = max_block_count_ > 0 && buffer_list_.size() == max_block_count_; + + Index read = 0; + + while (!buffer_list_.empty()) { + auto& stream_buffer = buffer_list_.front(); + auto this_read = + stream_buffer.PopFront(buffer + offset + read, size - read); + if (stream_buffer.GetUsedSize() == 0) { + buffer_list_.pop_front(); + } + read += this_read; + if (read == size) { + break; + } + } + + if (full && buffer_list_.size() < max_block_count_) { + // By convention, there should be at most one producer waiting. So + // notify_one and notify_all should be the same. + condition_variable_.notify_one(); + } + + return read; +} + +Index BufferStream::DoWrite(const std::byte* buffer, Index offset, Index size) { + std::unique_lock lock(mutex_); + + if (eof_) { + throw WriteAfterEofException( + u"Stream has been set eof. Can't write to it any more."); + } + + condition_variable_.wait(lock, [this] { + return max_block_count_ <= 0 || buffer_list_.size() < max_block_count_ || + buffer_list_.back().GetBackFree() > 0; + }); + + auto empty = buffer_list_.empty(); + + Index written = 0; + + if (empty) { + buffer_list_.push_back(Buffer(block_size_)); + } + + while (true) { + if (buffer_list_.back().GetBackFree() == 0) { + if (max_block_count_ > 0 && buffer_list_.size() == max_block_count_) { + break; + } + buffer_list_.push_back(Buffer(block_size_)); + } + auto& stream_buffer = buffer_list_.back(); + auto this_written = + stream_buffer.PushBack(buffer + offset + written, size - written); + written += this_written; + if (written == size) { + break; + } + } + + if (empty) { + // By convention, there should be at most one consumer waiting. So + // notify_one and notify_all should be the same. + condition_variable_.notify_one(); + } + + return written; +} + +void BufferStream::SetEof() { + std::unique_lock lock(mutex_); + + eof_ = true; + if (buffer_list_.empty()) { + // By convention, there should be at most one consumer waiting. So + // notify_one and notify_all should be the same. + condition_variable_.notify_one(); + } +} + +void BufferStream::DoClose() { CRU_STREAM_BEGIN_CLOSE } +} // namespace cru::io diff --git a/src/base/io/CFileStream.cpp b/src/base/io/CFileStream.cpp new file mode 100644 index 00000000..d5acc707 --- /dev/null +++ b/src/base/io/CFileStream.cpp @@ -0,0 +1,96 @@ +#include "cru/base/io/CFileStream.h" +#include "cru/base/Exception.h" +#include "cru/base/io/Stream.h" + +#include + +namespace cru::io { +static bool ModeCanRead(const char* mode) { + for (const char* p = mode; *p != '\0'; p++) { + if (*p == 'r' || *p == '+') { + return true; + } + } + return false; +} + +static bool ModeCanWrite(const char* mode) { + for (const char* p = mode; *p != '\0'; p++) { + if (*p == 'w' || *p == 'a' || *p == '+') { + return true; + } + } + return false; +} + +CFileStream::CFileStream(const char* path, const char* mode) + : Stream(true, ModeCanRead(mode), ModeCanWrite(mode)), + file_(std::fopen(path, mode)), + auto_close_(true) { + if (file_ == nullptr) { + throw ErrnoException(u"Cannot open file."); + } +} + +CFileStream::CFileStream(std::FILE* file, bool readable, bool writable, + bool auto_close) + : Stream(true, readable, writable), file_(file), auto_close_(auto_close) { + if (file_ == nullptr) { + throw Exception(u"File is NULL."); + } +} + +CFileStream::~CFileStream() { + if (auto_close_ && file_ != nullptr) { + std::fclose(file_); + } +} + +static int ConvertOriginFlag(Stream::SeekOrigin origin) { + switch (origin) { + case Stream::SeekOrigin::Begin: + return SEEK_SET; + case Stream::SeekOrigin::Current: + return SEEK_CUR; + case Stream::SeekOrigin::End: + return SEEK_END; + default: + throw Exception(u"Unknown seek origin."); + } +} + +Index CFileStream::DoSeek(Index offset, SeekOrigin origin) { + if (std::fseek(file_, offset, ConvertOriginFlag(origin))) { + throw ErrnoException(u"Seek failed."); + } + return DoTell(); +} + +Index CFileStream::DoTell() { + long position = std::ftell(file_); + if (position == -1) { + throw ErrnoException(u"Tell failed."); + } + return position; +} + +void CFileStream::DoRewind() { std::rewind(file_); } + +Index CFileStream::DoRead(std::byte* buffer, Index offset, Index size) { + auto count = std::fread(buffer + offset, 1, size, file_); + return count; +} + +Index CFileStream::DoWrite(const std::byte* buffer, Index offset, Index size) { + auto count = std::fwrite(buffer + offset, 1, size, file_); + return count; +} + +void CFileStream::DoFlush() { std::fflush(file_); } + +void CFileStream::DoClose() { + CRU_STREAM_BEGIN_CLOSE + std::fclose(file_); + file_ = nullptr; +} +} // namespace cru::io diff --git a/src/base/io/MemoryStream.cpp b/src/base/io/MemoryStream.cpp new file mode 100644 index 00000000..4c650f3e --- /dev/null +++ b/src/base/io/MemoryStream.cpp @@ -0,0 +1,74 @@ +#include "cru/base/io/MemoryStream.h" + +#include +#include "cru/base/Exception.h" +#include "cru/base/io/Stream.h" + +namespace cru::io { +MemoryStream::MemoryStream( + std::byte* buffer, Index size, bool read_only, + std::function release_func) + : Stream(true, true, !read_only), + buffer_(buffer), + size_(size), + position_(0), + release_func_(std::move(release_func)) { + if (!buffer) { + throw Exception(u"Buffer is nullptr"); + } + if (size <= 0) { + throw Exception(u"Size is 0 or negative."); + } +} + +MemoryStream::~MemoryStream() {} + +void MemoryStream::Close() { DoClose(); } + +Index MemoryStream::DoSeek(Index offset, SeekOrigin origin) { + switch (origin) { + case SeekOrigin::Current: + position_ += offset; + break; + case SeekOrigin::Begin: + position_ = offset; + break; + case SeekOrigin::End: + position_ = size_ + offset; + break; + } + return position_; +} + +Index MemoryStream::DoRead(std::byte* buffer, Index offset, Index size) { + if (position_ + size > size_) { + size = size_ - position_; + } + if (size <= 0) { + return 0; + } + std::memmove(buffer + offset, buffer_ + position_, size); + position_ += size; + return size; +} + +Index MemoryStream::DoWrite(const std::byte* buffer, Index offset, Index size) { + if (position_ + size > size_) { + size = size_ - position_; + } + if (size <= 0) { + return 0; + } + std::memmove(buffer_ + position_, buffer + offset, size); + position_ += size; + return size; +} + +void MemoryStream::DoClose() { + CRU_STREAM_BEGIN_CLOSE + release_func_(buffer_, size_); + buffer_ = nullptr; + release_func_ = {}; +} + +} // namespace cru::io diff --git a/src/base/io/OpenFileFlag.cpp b/src/base/io/OpenFileFlag.cpp new file mode 100644 index 00000000..47069b29 --- /dev/null +++ b/src/base/io/OpenFileFlag.cpp @@ -0,0 +1,19 @@ +#include "cru/base/io/OpenFileFlag.h" + +namespace cru::io { +bool CheckOpenFileFlag(OpenFileFlag flags) { + auto has = [flags](OpenFileFlag flag) { return flags & flag; }; + + if ((has(OpenFileFlags::Append) || has(OpenFileFlags::Truncate) || + has(OpenFileFlags::Create)) && + !has(OpenFileFlags::Write)) { + return false; + } + + if (has(OpenFileFlags::Truncate) && has(OpenFileFlags::Append)) { + return false; + } + + return true; +} +} // namespace cru::io diff --git a/src/base/io/ProxyStream.cpp b/src/base/io/ProxyStream.cpp new file mode 100644 index 00000000..de66169e --- /dev/null +++ b/src/base/io/ProxyStream.cpp @@ -0,0 +1,37 @@ +#include "cru/base/io/ProxyStream.h" +#include "cru/base/io/Stream.h" + +namespace cru::io { +ProxyStream::ProxyStream(ProxyStreamHandlers handlers) + : Stream(static_cast(handlers.seek), static_cast(handlers.read), + static_cast(handlers.write)), + handlers_(std::move(handlers)) {} + +ProxyStream::~ProxyStream() { DoClose(); } + +Index ProxyStream::DoSeek(Index offset, SeekOrigin origin) { + return handlers_.seek(offset, origin); +} + +Index ProxyStream::DoRead(std::byte* buffer, Index offset, Index size) { + return handlers_.read(buffer, offset, size); +} + +Index ProxyStream::DoWrite(const std::byte* buffer, Index offset, Index size) { + return handlers_.write(buffer, offset, size); +} + +void ProxyStream::DoFlush() { + if (handlers_.flush) { + handlers_.flush(); + } +} + +void ProxyStream::DoClose() { + CRU_STREAM_BEGIN_CLOSE + if (handlers_.close) { + handlers_.close(); + } + handlers_ = {}; +} +} // namespace cru::io diff --git a/src/base/io/Resource.cpp b/src/base/io/Resource.cpp new file mode 100644 index 00000000..d369b5f5 --- /dev/null +++ b/src/base/io/Resource.cpp @@ -0,0 +1,48 @@ +#include "cru/base/io/Resource.h" +#include "cru/base/Exception.h" +#include "cru/base/log/Logger.h" + +#if defined(CRU_PLATFORM_OSX) +#include +#elif defined(CRU_PLATFORM_WINDOWS) +#include +#endif + +#include + +namespace cru::io { +std::filesystem::path GetResourceDir() { + constexpr auto kLogTag = u"GetResourceDir"; + +#if defined(CRU_PLATFORM_OSX) + CFBundleRef main_bundle = CFBundleGetMainBundle(); + CFURLRef bundle_url = CFBundleCopyBundleURL(main_bundle); + CFStringRef cf_string_ref = + CFURLCopyFileSystemPath(bundle_url, kCFURLPOSIXPathStyle); + std::filesystem::path bundle_path( + CFStringGetCStringPtr(cf_string_ref, kCFStringEncodingUTF8)); + + CFRelease(bundle_url); + CFRelease(cf_string_ref); + + return bundle_path / "Contents/Resources"; +#elif defined(CRU_PLATFORM_WINDOWS) + wchar_t buffer[MAX_PATH]; + DWORD size = ::GetModuleFileNameW(nullptr, buffer, MAX_PATH); + std::filesystem::path module_path(buffer, buffer + size); + auto p = module_path; + while (p.has_parent_path()) { + p = p.parent_path(); + auto resource_dir_path = p / "assets"; + if (std::filesystem::exists(resource_dir_path) && + std::filesystem::is_directory(resource_dir_path)) { + return resource_dir_path; + } + } + + throw Exception(u"Failed to find resource directory."); +#else + throw Exception(u"Not implemented."); +#endif +} +} // namespace cru::io diff --git a/src/base/io/Stream.cpp b/src/base/io/Stream.cpp new file mode 100644 index 00000000..d65bac46 --- /dev/null +++ b/src/base/io/Stream.cpp @@ -0,0 +1,199 @@ +#include "cru/base/io/Stream.h" +#include "cru/base/Exception.h" +#include "cru/base/Format.h" + +#include + +namespace cru::io { +StreamOperationNotSupportedException::StreamOperationNotSupportedException( + String operation) + : operation_(std::move(operation)) { + SetMessage(Format(u"Stream operation {} not supported.", operation_)); +} + +void StreamOperationNotSupportedException::CheckSeek(bool seekable) { + if (!seekable) throw StreamOperationNotSupportedException(u"seek"); +} + +void StreamOperationNotSupportedException::CheckRead(bool readable) { + if (!readable) throw StreamOperationNotSupportedException(u"read"); +} + +void StreamOperationNotSupportedException::CheckWrite(bool writable) { + if (!writable) throw StreamOperationNotSupportedException(u"write"); +} + +StreamAlreadyClosedException::StreamAlreadyClosedException() + : Exception(u"Stream is already closed.") {} + +void StreamAlreadyClosedException::Check(bool closed) { + if (closed) throw StreamAlreadyClosedException(); +} + +Stream::Stream(SupportedOperations supported_operations) + : supported_operations_(std::move(supported_operations)), closed_(false) {} + +Stream::Stream(std::optional can_seek, std::optional can_read, + std::optional can_write) + : Stream(SupportedOperations{can_seek, can_read, can_write}) {} + +bool Stream::CanSeek() { + CheckClosed(); + return DoCanSeek(); +} + +Index Stream::Seek(Index offset, SeekOrigin origin) { + CheckClosed(); + StreamOperationNotSupportedException::CheckSeek(DoCanSeek()); + return DoSeek(offset, origin); +} + +Index Stream::Tell() { + CheckClosed(); + return DoTell(); +} + +void Stream::Rewind() { + CheckClosed(); + return DoRewind(); +} + +Index Stream::GetSize() { + CheckClosed(); + return DoGetSize(); +} + +bool Stream::CanRead() { + CheckClosed(); + return DoCanRead(); +} + +Index Stream::Read(std::byte* buffer, Index offset, Index size) { + CheckClosed(); + StreamOperationNotSupportedException::CheckRead(DoCanRead()); + return DoRead(buffer, offset, size); +} + +Index Stream::Read(std::byte* buffer, Index size) { + return Read(buffer, 0, size); +} + +Index Stream::Read(char* buffer, Index offset, Index size) { + return Read(reinterpret_cast(buffer), offset, size); +} + +Index Stream::Read(char* buffer, Index size) { + return Read(reinterpret_cast(buffer), 0, size); +} + +bool Stream::CanWrite() { + CheckClosed(); + return DoCanWrite(); +} + +Index Stream::Write(const std::byte* buffer, Index offset, Index size) { + CheckClosed(); + StreamOperationNotSupportedException::CheckWrite(DoCanWrite()); + return DoWrite(buffer, offset, size); +} + +Index Stream::Write(const std::byte* buffer, Index size) { + return Write(buffer, 0, size); +} + +Index Stream::Write(const char* buffer, Index offset, Index size) { + return Write(reinterpret_cast(buffer), offset, size); +} + +Index Stream::Write(const char* buffer, Index size) { + return Write(reinterpret_cast(buffer), size); +} + +void Stream::Flush() { + CheckClosed(); + DoFlush(); +} + +bool Stream::DoCanSeek() { + if (supported_operations_->can_seek) { + return *supported_operations_->can_seek; + } else { + throw Exception( + u"Can seek is neither set in supported_operations nor implemeted in " + u"virtual function."); + } +} + +bool Stream::DoCanRead() { + if (supported_operations_->can_read) { + return *supported_operations_->can_read; + } else { + throw Exception( + u"Can read is neither set in supported_operations nor implemeted in " + u"virtual function."); + } +} + +bool Stream::DoCanWrite() { + if (supported_operations_->can_write) { + return *supported_operations_->can_write; + } else { + throw Exception( + u"Can write is neither set in supported_operations nor implemeted in " + u"virtual function."); + } +} + +Index Stream::DoSeek(Index offset, SeekOrigin origin) { + throw Exception(u"Stream is seekable but DoSeek is not implemented."); +} + +Index Stream::DoTell() { + StreamOperationNotSupportedException::CheckSeek(DoCanSeek()); + return DoSeek(0, SeekOrigin::Current); +} + +void Stream::DoRewind() { + StreamOperationNotSupportedException::CheckSeek(DoCanSeek()); + DoSeek(0, SeekOrigin::Begin); +} + +Index Stream::DoGetSize() { + StreamOperationNotSupportedException::CheckSeek(DoCanSeek()); + Index current_position = DoTell(); + Seek(0, SeekOrigin::End); + Index size = DoTell(); + Seek(current_position, SeekOrigin::Begin); + return size; +} + +Index Stream::DoRead(std::byte* buffer, Index offset, Index size) { + throw Exception(u"Stream is readable but DoSeek is not implemented."); +} + +Index Stream::DoWrite(const std::byte* buffer, Index offset, Index size) { + throw Exception(u"Stream is writable but DoSeek is not implemented."); +} + +void Stream::DoFlush() {} + +Buffer Stream::ReadToEnd(Index grow_size) { + Buffer buffer(grow_size); + while (true) { + auto read = Read(buffer.GetUsedEndPtr(), buffer.GetBackFree()); + buffer.PushBackCount(read); + if (read == 0) { + break; + } + if (buffer.IsUsedReachEnd()) { + buffer.ResizeBuffer(buffer.GetBufferSize() + grow_size, true); + } + } + return buffer; +} + +String Stream::ReadToEndAsUtf8String() { + auto buffer = ReadToEnd(); + return String::FromUtf8(buffer); +} +} // namespace cru::io diff --git a/src/base/log/Logger.cpp b/src/base/log/Logger.cpp new file mode 100644 index 00000000..86c65dbc --- /dev/null +++ b/src/base/log/Logger.cpp @@ -0,0 +1,88 @@ +#include "cru/base/log/Logger.h" +#include "cru/base/log/StdioLogTarget.h" + +#include +#include + +#ifdef CRU_PLATFORM_WINDOWS +#include "cru/base/platform/win/DebugLogTarget.h" +#endif + +namespace cru::log { +Logger *Logger::GetInstance() { + static Logger logger; + + logger.AddLogTarget(std::make_unique()); + +#ifdef CRU_PLATFORM_WINDOWS + logger.AddLogTarget(std::make_unique()); +#endif + + return &logger; +} + +void Logger::AddLogTarget(std::unique_ptr target) { + std::lock_guard lock(target_list_mutex_); + target_list_.push_back(std::move(target)); +} + +void Logger::RemoveLogTarget(ILogTarget *target) { + std::lock_guard lock(target_list_mutex_); + target_list_.erase( + std::remove_if(target_list_.begin(), target_list_.end(), + [target](const auto &t) { return t.get() == target; }), + target_list_.end()); +} + +namespace { +String LogLevelToString(LogLevel level) { + switch (level) { + case LogLevel::Debug: + return u"DEBUG"; + case LogLevel::Info: + return u"INFO"; + case LogLevel::Warn: + return u"WARN"; + case LogLevel::Error: + return u"ERROR"; + default: + std::terminate(); + } +} + +String GetLogTime() { + auto time = std::time(nullptr); + auto calendar = std::localtime(&time); + return Format(u"{}:{}:{}", calendar->tm_hour, calendar->tm_min, + calendar->tm_sec); +} + +String MakeLogFinalMessage(const LogInfo &log_info) { + return Format(u"[{}] {} {}: {}\n", GetLogTime(), + LogLevelToString(log_info.level), log_info.tag, + log_info.message); +} +} // namespace + +Logger::Logger() + : log_thread_([this] { + while (true) { + auto log_info = log_queue_.Pull(); + std::lock_guard lock_guard{target_list_mutex_}; + for (const auto &target : target_list_) { + target->Write(log_info.level, MakeLogFinalMessage(log_info)); + } + } + }) {} + +Logger::~Logger() { log_thread_.detach(); } + +void Logger::Log(LogInfo log_info) { +#ifndef CRU_DEBUG + if (log_info.level == LogLevel::Debug) { + return; + } +#endif + log_queue_.Push(std::move(log_info)); +} +} // namespace cru::log diff --git a/src/base/log/StdioLogTarget.cpp b/src/base/log/StdioLogTarget.cpp new file mode 100644 index 00000000..64ddcacc --- /dev/null +++ b/src/base/log/StdioLogTarget.cpp @@ -0,0 +1,27 @@ +#include "cru/base/log/StdioLogTarget.h" + +#include + +namespace cru::log { +StdioLogTarget::StdioLogTarget() {} + +StdioLogTarget::~StdioLogTarget() {} + +void StdioLogTarget::Write(log::LogLevel level, StringView s) { +#ifdef CRU_PLATFORM_WINDOWS + if (level == log::LogLevel::Error) { + std::wcerr.write(reinterpret_cast(s.data()), s.size()); + } else { + std::wcout.write(reinterpret_cast(s.data()), s.size()); + } +#else + std::string m = s.ToUtf8(); + + if (level == log::LogLevel::Error) { + std::cerr << m; + } else { + std::cout << m; + } +#endif +} +} // namespace cru::log diff --git a/src/base/platform/Exception.cpp b/src/base/platform/Exception.cpp new file mode 100644 index 00000000..b5e8c5b9 --- /dev/null +++ b/src/base/platform/Exception.cpp @@ -0,0 +1 @@ +#include "cru/base/platform/Exception.h" diff --git a/src/base/platform/osx/Convert.cpp b/src/base/platform/osx/Convert.cpp new file mode 100644 index 00000000..1a6deb8f --- /dev/null +++ b/src/base/platform/osx/Convert.cpp @@ -0,0 +1,29 @@ +#include "cru/base/platform/osx/Convert.h" + +namespace cru::platform::osx { +CFStringRef Convert(const String& string) { + return CFStringCreateWithBytes( + nullptr, reinterpret_cast(string.data()), + string.size() * sizeof(std::uint16_t), kCFStringEncodingUTF16, false); +} + +String Convert(CFStringRef string) { + auto length = CFStringGetLength(string); + + String result; + + for (int i = 0; i < length; i++) { + result.AppendCodePoint(CFStringGetCharacterAtIndex(string, i)); + } + + return result; +} + +CFRange Convert(const Range& range) { + return CFRangeMake(range.position, range.count); +} + +Range Convert(const CFRange& range) { + return Range(range.location, range.length); +} +} // namespace cru::platform::osx diff --git a/src/base/platform/osx/Exception.cpp b/src/base/platform/osx/Exception.cpp new file mode 100644 index 00000000..a60448dd --- /dev/null +++ b/src/base/platform/osx/Exception.cpp @@ -0,0 +1 @@ +#include "cru/base/platform//osx/Exception.h" diff --git a/src/base/platform/unix/PosixSpawnSubProcess.cpp b/src/base/platform/unix/PosixSpawnSubProcess.cpp new file mode 100644 index 00000000..75d48cc2 --- /dev/null +++ b/src/base/platform/unix/PosixSpawnSubProcess.cpp @@ -0,0 +1,204 @@ +#include "cru/base/platform/unix/PosixSpawnSubProcess.h" +#include "cru/base/Exception.h" +#include "cru/base/Format.h" +#include "cru/base/Guard.h" +#include "cru/base/String.h" +#include "cru/base/SubProcess.h" +#include "cru/base/log/Logger.h" + +#include +#include +#include +#include +#include +#include + +namespace cru::platform::unix { +PosixSpawnSubProcessImpl::PosixSpawnSubProcessImpl() + : pid_(0), + exit_code_(0), + stdin_pipe_(UnixPipe::Usage::Send, false), + stdout_pipe_(UnixPipe::Usage::Receive, false), + stderr_pipe_(UnixPipe::Usage::Receive, false) { + stdin_stream_ = std::make_unique( + stdin_pipe_.GetSelfFileDescriptor(), false, false, true, true); + stdout_stream_ = std::make_unique( + stdout_pipe_.GetSelfFileDescriptor(), false, true, false, true); + stderr_stream_ = std::make_unique( + stderr_pipe_.GetSelfFileDescriptor(), false, true, false, true); + + stdout_buffer_stream_ = + std::make_unique(stdout_stream_.get(), false); + stderr_buffer_stream_ = + std::make_unique(stderr_stream_.get(), false); +} + +PosixSpawnSubProcessImpl::~PosixSpawnSubProcessImpl() {} + +namespace { +char** CreateCstrArray(const std::vector& argv) { + std::vector utf8_argv; + for (const auto& arg : argv) { + utf8_argv.push_back(arg.ToUtf8Buffer()); + } + char** result = new char*[utf8_argv.size() + 1]; + for (int i = 0; i < utf8_argv.size(); i++) { + result[i] = reinterpret_cast(utf8_argv[i].Detach()); + } + result[utf8_argv.size()] = nullptr; + return result; +} + +char** CreateCstrArray(const std::unordered_map& envp) { + std::vector str_array; + for (auto& [key, value] : envp) { + str_array.push_back(cru::Format(u"{}={}", key, value)); + } + return CreateCstrArray(str_array); +} + +void DestroyCstrArray(char** argv) { + int index = 0; + char* arg = argv[index]; + while (arg) { + delete[] arg; + index++; + arg = argv[index]; + } + delete[] argv; +} +} // namespace + +void PosixSpawnSubProcessImpl::PlatformCreateProcess( + const SubProcessStartInfo& start_info) { + int error; + auto check_error = [&error](String message) { + if (error == 0) return; + std::unique_ptr inner(new ErrnoException({}, error)); + throw SubProcessFailedToStartException(std::move(message), + std::move(inner)); + }; + + posix_spawn_file_actions_t file_actions; + error = posix_spawn_file_actions_init(&file_actions); + check_error(u"Failed to call posix_spawn_file_actions_init."); + Guard file_actions_guard( + [&file_actions] { posix_spawn_file_actions_destroy(&file_actions); }); + + // dup2 stdin/stdout/stderr + error = posix_spawn_file_actions_adddup2( + &file_actions, stdin_pipe_.GetOtherFileDescriptor(), STDIN_FILENO); + check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stdin."); + error = posix_spawn_file_actions_adddup2( + &file_actions, stdout_pipe_.GetOtherFileDescriptor(), STDOUT_FILENO); + check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stdout."); + error = posix_spawn_file_actions_adddup2( + &file_actions, stderr_pipe_.GetOtherFileDescriptor(), STDERR_FILENO); + check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stderr."); + + error = posix_spawn_file_actions_addclose( + &file_actions, stdin_pipe_.GetOtherFileDescriptor()); + check_error( + u"Failed to call posix_spawn_file_actions_addclose on self fd of stdin."); + error = posix_spawn_file_actions_addclose( + &file_actions, stdout_pipe_.GetOtherFileDescriptor()); + check_error( + u"Failed to call posix_spawn_file_actions_addclose on self fd stdout."); + error = posix_spawn_file_actions_addclose( + &file_actions, stderr_pipe_.GetOtherFileDescriptor()); + check_error( + u"Failed to call posix_spawn_file_actions_addclose on self fd stderr."); + + error = posix_spawn_file_actions_addclose( + &file_actions, stdin_pipe_.GetSelfFileDescriptor()); + check_error( + u"Failed to call posix_spawn_file_actions_addclose on parent fd of " + u"stdin."); + error = posix_spawn_file_actions_addclose( + &file_actions, stdout_pipe_.GetSelfFileDescriptor()); + check_error( + u"Failed to call posix_spawn_file_actions_addclose on parent fd of " + u"stdout."); + error = posix_spawn_file_actions_addclose( + &file_actions, stderr_pipe_.GetSelfFileDescriptor()); + check_error( + u"Failed to call posix_spawn_file_actions_addclose on parent fd of " + u"stderr."); + + posix_spawnattr_t attr; + error = posix_spawnattr_init(&attr); + check_error(u"Failed to call posix_spawnattr_init."); + Guard attr_guard([&attr] { posix_spawnattr_destroy(&attr); }); + +#ifdef CRU_PLATFORM_OSX + error = posix_spawnattr_setflags(&attr, POSIX_SPAWN_CLOEXEC_DEFAULT); + check_error(u"Failed to set flag POSIX_SPAWN_CLOEXEC_DEFAULT (osx)."); +#endif + + auto exe = start_info.program.ToUtf8(); + std::vector arguments{start_info.program}; + arguments.insert(arguments.cend(), start_info.arguments.cbegin(), + start_info.arguments.cend()); + + auto argv = CreateCstrArray(arguments); + Guard argv_guard([argv] { DestroyCstrArray(argv); }); + + auto envp = CreateCstrArray(start_info.environments); + Guard envp_guard([envp] { DestroyCstrArray(envp); }); + + error = posix_spawnp(&pid_, exe.c_str(), &file_actions, &attr, argv, envp); + check_error(u"Failed to call posix_spawnp."); + + error = ::close(stdin_pipe_.GetOtherFileDescriptor()); + check_error(u"Failed to close child stdin."); + error = ::close(stdout_pipe_.GetOtherFileDescriptor()); + check_error(u"Failed to close child stdout."); + error = ::close(stderr_pipe_.GetOtherFileDescriptor()); + check_error(u"Failed to close child stderr."); +} + +SubProcessExitResult PosixSpawnSubProcessImpl::PlatformWaitForProcess() { + int wstatus; + + while (waitpid(pid_, &wstatus, 0) == -1) { + if (errno == EINTR) { + CRU_LOG_INFO(u"Waitpid is interrupted by a signal. Call it again."); + continue; + } + + std::unique_ptr inner(new ErrnoException({}, errno)); + + throw SubProcessInternalException( + u"Failed to call waitpid on a subprocess.", std::move(inner)); + } + + if (WIFEXITED(wstatus)) { + return SubProcessExitResult::Normal(WEXITSTATUS(wstatus)); + } else if (WIFEXITED(wstatus)) { + return SubProcessExitResult::Signal(WTERMSIG(wstatus), WCOREDUMP(wstatus)); + } else { + return SubProcessExitResult::Unknown(); + } +} + +void PosixSpawnSubProcessImpl::PlatformKillProcess() { + int error = kill(pid_, SIGKILL); + if (error != 0) { + std::unique_ptr inner(new ErrnoException({}, errno)); + throw SubProcessInternalException(u"Failed to call kill on a subprocess.", + std::move(inner)); + } +} + +io::Stream* PosixSpawnSubProcessImpl::GetStdinStream() { + return stdin_stream_.get(); +} + +io::Stream* PosixSpawnSubProcessImpl::GetStdoutStream() { + return stdout_buffer_stream_.get(); +} + +io::Stream* PosixSpawnSubProcessImpl::GetStderrStream() { + return stderr_buffer_stream_.get(); +} +} // namespace cru::platform::unix diff --git a/src/base/platform/unix/UnixFileStream.cpp b/src/base/platform/unix/UnixFileStream.cpp new file mode 100644 index 00000000..c53bbbaa --- /dev/null +++ b/src/base/platform/unix/UnixFileStream.cpp @@ -0,0 +1,106 @@ +#include "cru/base/platform/unix/UnixFileStream.h" +#include "cru/base/Exception.h" +#include "cru/base/Format.h" +#include "cru/base/io/Stream.h" +#include "cru/base/log/Logger.h" + +#include +#include +#include +#include + +namespace cru::platform::unix { +using namespace cru::io; + +namespace { +bool OflagCanSeek([[maybe_unused]] int oflag) { + // Treat every file seekable. + return true; +} + +bool OflagCanRead(int oflag) { + // There is a problem: O_RDONLY is 0. So we must test it specially. + // If it is not write-only. Then it can read. + return !(oflag & O_WRONLY); +} + +bool OflagCanWrite(int oflag) { return oflag & O_WRONLY || oflag & O_RDWR; } + +int MapSeekOrigin(Stream::SeekOrigin origin) { + switch (origin) { + case Stream::SeekOrigin::Begin: + return SEEK_SET; + case Stream::SeekOrigin::Current: + return SEEK_CUR; + case Stream::SeekOrigin::End: + return SEEK_END; + default: + throw Exception(u"Invalid seek origin."); + } +} +} // namespace + +UnixFileStream::UnixFileStream(const char *path, int oflag, mode_t mode) { + file_descriptor_ = ::open(path, oflag, mode); + if (file_descriptor_ == -1) { + throw ErrnoException( + Format(u"Failed to open file {} with oflag {}, mode {}.", + String::FromUtf8(path), oflag, mode)); + } + + SetSupportedOperations( + {OflagCanSeek(oflag), OflagCanRead(oflag), OflagCanWrite(oflag)}); + + auto_close_ = true; +} + +UnixFileStream::UnixFileStream(int fd, bool can_seek, bool can_read, + bool can_write, bool auto_close) + : Stream(can_seek, can_read, can_write) { + file_descriptor_ = fd; + auto_close_ = auto_close; +} + +UnixFileStream::~UnixFileStream() { + if (auto_close_ && file_descriptor_ >= 0) { + if (::close(file_descriptor_) == -1) { + // We are in destructor, so we can not throw. + CRU_LOG_WARN(u"Failed to close file descriptor {}, errno {}.", + file_descriptor_, errno); + } + } +} + +Index UnixFileStream::DoSeek(Index offset, SeekOrigin origin) { + off_t result = ::lseek(file_descriptor_, offset, MapSeekOrigin(origin)); + if (result == -1) { + throw ErrnoException(u"Failed to seek file."); + } + return result; +} + +Index UnixFileStream::DoRead(std::byte *buffer, Index offset, Index size) { + auto result = ::read(file_descriptor_, buffer + offset, size); + if (result == -1) { + throw ErrnoException(u"Failed to read file."); + } + return result; +} + +Index UnixFileStream::DoWrite(const std::byte *buffer, Index offset, + Index size) { + auto result = ::write(file_descriptor_, buffer + offset, size); + if (result == -1) { + throw ErrnoException(u"Failed to write file."); + } + return result; +} + +void UnixFileStream::DoClose() { + CRU_STREAM_BEGIN_CLOSE + if (auto_close_ && ::close(file_descriptor_) == -1) { + throw ErrnoException(u"Failed to close file."); + } + file_descriptor_ = -1; +} +} // namespace cru::platform::unix diff --git a/src/base/platform/unix/UnixPipe.cpp b/src/base/platform/unix/UnixPipe.cpp new file mode 100644 index 00000000..747efe94 --- /dev/null +++ b/src/base/platform/unix/UnixPipe.cpp @@ -0,0 +1,51 @@ +#include "cru/base/platform/unix/UnixPipe.h" +#include "cru/base/Exception.h" +#include "cru/base/log/Logger.h" + +#include +#include +#include + +namespace cru::platform::unix { +UnixPipe::UnixPipe(Usage usage, bool auto_close, UnixPipeFlag flags) + : usage_(usage), auto_close_(auto_close), flags_(flags) { + int fds[2]; + if (pipe(fds) != 0) { + throw ErrnoException(u"Failed to create unix pipe."); + } + + if (flags & UnixPipeFlags::NonBlock) { + fcntl(fds[0], F_SETFL, O_NONBLOCK); + fcntl(fds[1], F_SETFL, O_NONBLOCK); + } + + read_fd_ = fds[0]; + write_fd_ = fds[1]; +} + +int UnixPipe::GetSelfFileDescriptor() { + if (usage_ == Usage::Send) { + return write_fd_; + } else { + return read_fd_; + } +} + +int UnixPipe::GetOtherFileDescriptor() { + if (usage_ == Usage::Send) { + return read_fd_; + } else { + return write_fd_; + } +} + +UnixPipe::~UnixPipe() { + if (auto_close_) { + auto self_fd = GetSelfFileDescriptor(); + if (::close(self_fd) != 0) { + CRU_LOG_ERROR(u"Failed to close unix pipe file descriptor {}, errno {}.", + self_fd, errno); + } + } +} +} // namespace cru::platform::unix diff --git a/src/base/platform/web/WebException.cpp b/src/base/platform/web/WebException.cpp new file mode 100644 index 00000000..f473bb5b --- /dev/null +++ b/src/base/platform/web/WebException.cpp @@ -0,0 +1 @@ +#include "cru/base/platform/web/WebException.h" diff --git a/src/base/platform/win/BridgeComStream.cpp b/src/base/platform/win/BridgeComStream.cpp new file mode 100644 index 00000000..c6987ab2 --- /dev/null +++ b/src/base/platform/win/BridgeComStream.cpp @@ -0,0 +1,106 @@ +#include "BrigdeComStream.h" +#include "cru/base/io/Stream.h" + +namespace cru::platform::win { +BridgeComStream::BridgeComStream(io::Stream *stream) + : stream_(stream), ref_count_(1) {} + +BridgeComStream::~BridgeComStream() {} + +ULONG BridgeComStream::AddRef() { return ++ref_count_; } + +ULONG BridgeComStream::Release() { + --ref_count_; + + if (ref_count_ == 0) { + delete this; + return 0; + } + + return ref_count_; +} + +HRESULT BridgeComStream::QueryInterface(const IID &riid, void **ppvObject) { + if (riid == IID_IStream) { + *ppvObject = static_cast(this); + AddRef(); + return S_OK; + } else if (riid == IID_ISequentialStream) { + *ppvObject = static_cast(this); + AddRef(); + return S_OK; + } else if (riid == IID_IUnknown) { + *ppvObject = static_cast(this); + AddRef(); + return S_OK; + } else { + return E_NOINTERFACE; + } +} + +HRESULT BridgeComStream::Read(void *pv, ULONG cb, ULONG *pcbRead) { + *pcbRead = stream_->Read(static_cast(pv), cb); + return S_OK; +} + +HRESULT BridgeComStream::Write(const void *pv, ULONG cb, ULONG *pcbWritten) { + *pcbWritten = stream_->Write(static_cast(pv), cb); + return S_OK; +} + +HRESULT BridgeComStream::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, + ULARGE_INTEGER *plibNewPosition) { + io::Stream::SeekOrigin so; + + switch (dwOrigin) { + case STREAM_SEEK_SET: + so = io::Stream::SeekOrigin::Begin; + break; + case STREAM_SEEK_CUR: + so = io::Stream::SeekOrigin::Current; + break; + case STREAM_SEEK_END: + so = io::Stream::SeekOrigin::End; + break; + default: + return STG_E_INVALIDFUNCTION; + }; + + plibNewPosition->QuadPart = stream_->Seek(dlibMove.QuadPart, so); + return S_OK; +} + +HRESULT BridgeComStream::SetSize(ULARGE_INTEGER libNewSize) { + return E_NOTIMPL; +} + +HRESULT BridgeComStream::CopyTo(IStream *pstm, ULARGE_INTEGER cb, + ULARGE_INTEGER *pcbRead, + ULARGE_INTEGER *pcbWritten) { + return E_NOTIMPL; +} + +HRESULT BridgeComStream::Commit(DWORD grfCommitFlags) { return S_OK; } + +HRESULT BridgeComStream::Revert() { return S_OK; } + +HRESULT BridgeComStream::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, + DWORD dwLockType) { + return S_OK; +} + +HRESULT BridgeComStream::UnlockRegion(ULARGE_INTEGER libOffset, + ULARGE_INTEGER cb, DWORD dwLockType) { + return S_OK; +} + +HRESULT BridgeComStream::Stat(STATSTG *pstatstg, DWORD grfStatFlag) { + return E_NOTIMPL; +} + +HRESULT BridgeComStream::Clone(IStream **ppstm) { + *ppstm = new BridgeComStream(stream_); + return S_OK; +} + +} // namespace cru::platform::win diff --git a/src/base/platform/win/BrigdeComStream.h b/src/base/platform/win/BrigdeComStream.h new file mode 100644 index 00000000..1621b567 --- /dev/null +++ b/src/base/platform/win/BrigdeComStream.h @@ -0,0 +1,43 @@ +#pragma once +#include "cru/base/platform/win/WinPreConfig.h" + +#include "cru/base/io/Stream.h" + +#include + +namespace cru::platform::win { +class BridgeComStream : public IStream { + public: + explicit BridgeComStream(io::Stream* stream); + + CRU_DELETE_COPY(BridgeComStream) + CRU_DELETE_MOVE(BridgeComStream) + + ~BridgeComStream(); + + public: + ULONG AddRef() override; + ULONG Release() override; + HRESULT QueryInterface(REFIID riid, void** ppvObject) override; + + HRESULT Read(void* pv, ULONG cb, ULONG* pcbRead) override; + HRESULT Write(const void* pv, ULONG cb, ULONG* pcbWritten) override; + HRESULT Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, + ULARGE_INTEGER* plibNewPosition) override; + HRESULT SetSize(ULARGE_INTEGER libNewSize) override; + HRESULT CopyTo(IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, + ULARGE_INTEGER* pcbWritten) override; + HRESULT Commit(DWORD grfCommitFlags) override; + HRESULT Revert() override; + HRESULT LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, + DWORD dwLockType) override; + HRESULT UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, + DWORD dwLockType) override; + HRESULT Stat(STATSTG* pstatstg, DWORD grfStatFlag) override; + HRESULT Clone(IStream** ppstm) override; + + private: + io::Stream* stream_; + ULONG ref_count_; +}; +} // namespace cru::platform::win diff --git a/src/base/platform/win/ComAutoInit.cpp b/src/base/platform/win/ComAutoInit.cpp new file mode 100644 index 00000000..548a7bea --- /dev/null +++ b/src/base/platform/win/ComAutoInit.cpp @@ -0,0 +1,15 @@ +#include "cru/base/platform/win/ComAutoInit.h" +#include "cru/base/platform/win/Exception.h" + +#include + +namespace cru::platform::win { +ComAutoInit::ComAutoInit() { + const auto hresult = ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + if (FAILED(hresult)) { + throw HResultError(hresult, "Failed to call CoInitializeEx."); + } +} + +ComAutoInit::~ComAutoInit() { ::CoUninitialize(); } +} // namespace cru::platform::win diff --git a/src/base/platform/win/DebugLogTarget.cpp b/src/base/platform/win/DebugLogTarget.cpp new file mode 100644 index 00000000..89bd3d19 --- /dev/null +++ b/src/base/platform/win/DebugLogTarget.cpp @@ -0,0 +1,10 @@ +#include "cru/base/platform/win/DebugLogTarget.h" + +namespace cru::platform::win { +void WinDebugLogTarget::Write(::cru::log::LogLevel level, StringView s) { + CRU_UNUSED(level) + + String m = s.ToString(); + ::OutputDebugStringW(reinterpret_cast(m.c_str())); +} +} // namespace cru::platform::win diff --git a/src/base/platform/win/Exception.cpp b/src/base/platform/win/Exception.cpp new file mode 100644 index 00000000..5ff6146b --- /dev/null +++ b/src/base/platform/win/Exception.cpp @@ -0,0 +1,38 @@ +#include "cru/base/platform/win/Exception.h" +#include "cru/base/Format.h" + +#include + +namespace cru::platform::win { + +inline String HResultMakeMessage(HRESULT h_result, + std::optional message) { + if (message.has_value()) + return Format(u"HRESULT: {}. Message: {}", h_result, message->WinCStr()); + else + return Format(u"HRESULT: {}.", h_result); +} + +HResultError::HResultError(HRESULT h_result) + : PlatformException(HResultMakeMessage(h_result, std::nullopt)), + h_result_(h_result) {} + +HResultError::HResultError(HRESULT h_result, + std::string_view additional_message) + : PlatformException(HResultMakeMessage( + h_result, String::FromUtf8(additional_message.data(), + additional_message.size()))), + h_result_(h_result) {} + +inline String Win32MakeMessage(DWORD error_code, String message) { + return Format(u"Last error code: {}.\nMessage: {}\n", error_code, + message.WinCStr()); +} + +Win32Error::Win32Error(String message) + : Win32Error(::GetLastError(), message) {} + +Win32Error::Win32Error(DWORD error_code, String message) + : PlatformException(Win32MakeMessage(error_code, message)), + error_code_(error_code) {} +} // namespace cru::platform::win diff --git a/src/base/platform/win/StreamConvert.cpp b/src/base/platform/win/StreamConvert.cpp new file mode 100644 index 00000000..f7a0537c --- /dev/null +++ b/src/base/platform/win/StreamConvert.cpp @@ -0,0 +1,28 @@ +#include "cru/base/platform/win/StreamConvert.h" +#include "BrigdeComStream.h" +#include "Win32FileStreamPrivate.h" +#include "cru/base/Exception.h" +#include "cru/base/io/MemoryStream.h" +#include "cru/base/io/OpenFileFlag.h" +#include "cru/base/platform/win/ComAutoInit.h" +#include "cru/base/platform/win/Exception.h" +#include "cru/base/platform/win/Win32FileStream.h" + +#include +#include + +namespace cru::platform::win { +IStream* ConvertStreamToComStream(io::Stream* stream) { + static ComAutoInit com_auto_init; + + if (auto memory_stream = dynamic_cast(stream)) { + return SHCreateMemStream( + reinterpret_cast(memory_stream->GetBuffer()), + memory_stream->GetSize()); + } else if (auto file_stream = dynamic_cast(stream)) { + return file_stream->GetPrivate_()->stream_; + } else { + return new BridgeComStream(stream); + } +} +} // namespace cru::platform::win diff --git a/src/base/platform/win/Win32FileStream.cpp b/src/base/platform/win/Win32FileStream.cpp new file mode 100644 index 00000000..54e6ae45 --- /dev/null +++ b/src/base/platform/win/Win32FileStream.cpp @@ -0,0 +1,122 @@ +#include "cru/base/platform/win/Win32FileStream.h" + +#include "Win32FileStreamPrivate.h" +#include "cru/base/io/OpenFileFlag.h" +#include "cru/base/platform/win/Exception.h" + +#include +#include +#include +#include +#include + +namespace cru::platform::win { +using namespace cru::io; + +Win32FileStream::Win32FileStream(String path, OpenFileFlag flags) + : path_(std::move(path)), + flags_(flags), + p_(new details::Win32FileStreamPrivate()) { + DWORD grfMode = STGM_SHARE_DENY_NONE; + if (flags & io::OpenFileFlags::Read) { + if (flags & io::OpenFileFlags::Write) { + grfMode |= STGM_READWRITE; + } else { + grfMode |= STGM_READ; + } + } else { + if (flags & io::OpenFileFlags::Write) { + grfMode |= STGM_WRITE; + } else { + throw Exception(u"Stream must be readable or writable."); + } + } + + if (flags & io::OpenFileFlags::Truncate) { + grfMode |= STGM_CREATE; + } + + IStream* stream; + + ThrowIfFailed(SHCreateStreamOnFileEx( + path_.WinCStr(), grfMode, FILE_ATTRIBUTE_NORMAL, + flags & io::OpenFileFlags::Create ? TRUE : FALSE, NULL, &stream)); + + p_->stream_ = stream; +} + +Win32FileStream::~Win32FileStream() { + Close(); + delete p_; +} + +bool Win32FileStream::CanSeek() { return true; } + +Index Win32FileStream::Seek(Index offset, SeekOrigin origin) { + CheckClosed(); + + DWORD dwOrigin = 0; + + if (origin == SeekOrigin::Current) { + dwOrigin = STREAM_SEEK_CUR; + } else if (origin == SeekOrigin::End) { + dwOrigin = STREAM_SEEK_END; + } else { + dwOrigin = STREAM_SEEK_SET; + } + + LARGE_INTEGER n_offset; + n_offset.QuadPart = offset; + ULARGE_INTEGER n_new_offset; + + ThrowIfFailed(p_->stream_->Seek(n_offset, dwOrigin, &n_new_offset)); + + return n_new_offset.QuadPart; +} + +bool Win32FileStream::CanRead() { return true; } + +Index Win32FileStream::Read(std::byte* buffer, Index offset, Index size) { + if (size < 0) { + throw Exception(u"Size must be greater than 0."); + } + + CheckClosed(); + + ULONG n_read; + ThrowIfFailed(p_->stream_->Read(buffer + offset, size, &n_read)); + return n_read; +} + +bool Win32FileStream::CanWrite() { return true; } + +Index Win32FileStream::Write(const std::byte* buffer, Index offset, + Index size) { + if (size < 0) { + throw Exception(u"Size must be greater than 0."); + } + + CheckClosed(); + + ULONG n_written; + ThrowIfFailed(p_->stream_->Write(buffer + offset, size, &n_written)); + + return n_written; +} + +void Win32FileStream::Close() { + if (closed_) return; + + if (p_->stream_) { + p_->stream_->Release(); + p_->stream_ = nullptr; + } + + closed_ = true; +} + +void Win32FileStream::CheckClosed() { + if (closed_) throw Exception(u"Stream is closed."); +} + +} // namespace cru::platform::win diff --git a/src/base/platform/win/Win32FileStreamPrivate.h b/src/base/platform/win/Win32FileStreamPrivate.h new file mode 100644 index 00000000..718f8d9a --- /dev/null +++ b/src/base/platform/win/Win32FileStreamPrivate.h @@ -0,0 +1,13 @@ +#include "cru/base/platform/win/WinPreConfig.h" + +#include + +namespace cru::platform::win { + +namespace details { +struct Win32FileStreamPrivate { + IStream* stream_ = nullptr; +}; +} // namespace details + +} // namespace cru::platform::win diff --git a/src/common/Base.cpp b/src/common/Base.cpp deleted file mode 100644 index ba4077b4..00000000 --- a/src/common/Base.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "cru/common/Base.h" - -#include - -namespace cru { -void UnreachableCode() { std::terminate(); } -} // namespace cru diff --git a/src/common/Buffer.cpp b/src/common/Buffer.cpp deleted file mode 100644 index 7b4248c7..00000000 --- a/src/common/Buffer.cpp +++ /dev/null @@ -1,277 +0,0 @@ -#include "cru/common/Buffer.h" -#include "cru/common/Exception.h" - -#include - -namespace cru { -namespace { -void CheckSize(Index size) { - if (size < 0) { - throw Exception(u"Size of buffer can't be smaller than 0."); - } -} -} // namespace - -Buffer::Buffer() { - ptr_ = nullptr; - size_ = used_begin_ = used_end_ = 0; -} - -Buffer::Buffer(Index size) { - CheckSize(size); - if (size == 0) { - ptr_ = nullptr; - size_ = used_begin_ = used_end_ = 0; - } else { - ptr_ = new std::byte[size]; - size_ = size; - used_begin_ = used_end_ = 0; - } - AssertValid(); -} - -Buffer::Buffer(const Buffer& other) { Copy_(other); } - -Buffer::Buffer(Buffer&& other) noexcept { Move_(std::move(other)); } - -Buffer& Buffer::operator=(const Buffer& other) { - if (this != &other) { - Delete_(); - Copy_(other); - } - return *this; -} - -Buffer& Buffer::operator=(Buffer&& other) noexcept { - if (this != &other) { - Delete_(); - Move_(std::move(other)); - } - return *this; -} - -Buffer::~Buffer() { Delete_(); } - -void Buffer::AssignBytes(Index dst_offset, std::byte* src, Index src_offset, - Index src_size, bool use_memmove) { - CheckSize(src_size); - - AssertValid(); - - (use_memmove ? std::memmove : std::memcpy)(ptr_ + dst_offset, - src + src_offset, src_size); - AssertValid(); -} - -void Buffer::ResizeBuffer(Index new_size, bool preserve_used) { - CheckSize(new_size); - - AssertValid(); - - if (new_size == 0) { - Delete_(); - ptr_ = nullptr; - size_ = used_begin_ = used_end_ = 0; - return; - } - - auto old_ptr = ptr_; - - ptr_ = new std::byte[new_size]; - size_ = new_size; - used_begin_ = std::min(new_size, used_begin_); - used_end_ = std::min(new_size, used_end_); - - if (old_ptr) { - if (preserve_used && used_begin_ < used_end_) { - std::memcpy(ptr_ + used_begin_, old_ptr + used_begin_, - used_end_ - used_begin_); - } - delete[] old_ptr; - } - - AssertValid(); -} - -Index Buffer::PushFront(const std::byte* other, Index other_size, - bool use_memmove) { - CheckSize(other_size); - - AssertValid(); - - auto copy_size = std::min(used_begin_, other_size); - - if (copy_size) { - used_begin_ -= copy_size; - (use_memmove ? std::memmove : std::memcpy)(ptr_ + used_begin_, other, - copy_size); - } - - AssertValid(); - - return copy_size; -} - -bool Buffer::PushBack(std::byte b) { - AssertValid(); - if (IsUsedReachEnd()) { - return false; - } - ptr_[used_end_] = b; - used_end_++; - AssertValid(); - return true; -} - -Index Buffer::PushBack(const std::byte* other, Index other_size, - bool use_memmove) { - CheckSize(other_size); - - AssertValid(); - - auto copy_size = std::min(size_ - used_end_, other_size); - - if (copy_size) { - (use_memmove ? std::memmove : std::memcpy)(ptr_ + used_end_, other, - copy_size); - used_end_ += copy_size; - } - - AssertValid(); - - return copy_size; -} - -void Buffer::PushBackCount(Index count) { - if (count < 0 || count > GetBackFree()) { - throw Exception(u"Count out of range in PushBackCount."); - } - used_end_ += count; -} - -Index Buffer::PopFront(Index size) { - CheckSize(size); - - AssertValid(); - - auto move = std::min(used_begin_, size); - used_begin_ -= move; - - AssertValid(); - - return move; -} - -Index Buffer::PopFront(std::byte* buffer, Index size, bool use_memmove) { - CheckSize(size); - - AssertValid(); - - auto pop_size = std::min(GetUsedSize(), size); - - if (pop_size) { - used_begin_ += pop_size; - (use_memmove ? std::memmove : std::memcpy)( - buffer, GetUsedBeginPtr() - pop_size, pop_size); - } - - AssertValid(); - - return pop_size; -} - -Index Buffer::PopEnd(Index size) { - CheckSize(size); - - AssertValid(); - - auto move = std::min(size_ - used_end_, size); - used_end_ += move; - - AssertValid(); - - return move; -} - -Index Buffer::PopEnd(std::byte* buffer, Index size, bool use_memmove) { - CheckSize(size); - - AssertValid(); - - auto pop_size = std::min(GetUsedSize(), size); - - if (pop_size) { - used_end_ -= pop_size; - (use_memmove ? std::memmove : std::memcpy)(buffer, GetUsedEndPtr(), - pop_size); - } - - AssertValid(); - - return pop_size; -} - -std::byte* Buffer::Detach(Index* size) { - AssertValid(); - - auto ptr = this->ptr_; - if (size) { - *size = this->size_; - } - this->ptr_ = nullptr; - this->size_ = this->used_begin_ = this->used_end_ = 0; - - AssertValid(); - - return ptr; -} - -void Buffer::Copy_(const Buffer& other) { - if (other.ptr_ == nullptr) { - ptr_ = nullptr; - size_ = used_begin_ = used_end_ = 0; - } else { - ptr_ = new std::byte[other.size_]; - size_ = other.size_; - used_begin_ = other.used_begin_; - used_end_ = other.used_end_; - std::memcpy(ptr_ + used_begin_, other.ptr_ + used_begin_, - used_end_ - used_begin_); - } - AssertValid(); -} - -void Buffer::Move_(Buffer&& other) noexcept { - ptr_ = other.ptr_; - size_ = other.size_; - used_begin_ = other.used_begin_; - used_end_ = other.used_end_; - other.ptr_ = nullptr; - other.size_ = other.used_begin_ = other.used_end_ = 0; - AssertValid(); -} - -void Buffer::Delete_() noexcept { - if (ptr_) { - delete[] ptr_; - } -} - -void Buffer::AssertValid() { - assert(size_ >= 0); - assert(used_begin_ >= 0); - assert(used_begin_ <= size_); - assert(used_end_ >= 0); - assert(used_end_ <= size_); - assert(used_end_ >= used_begin_); - assert((ptr_ == nullptr && size_ == 0) || (ptr_ != nullptr && size_ > 0)); -} - -void swap(Buffer& left, Buffer& right) noexcept { - using std::swap; - swap(left.ptr_, right.ptr_); - swap(left.size_, right.size_); - swap(left.used_begin_, right.used_begin_); - swap(left.used_end_, right.used_end_); -} -} // namespace cru diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt deleted file mode 100644 index 19feddba..00000000 --- a/src/common/CMakeLists.txt +++ /dev/null @@ -1,80 +0,0 @@ -add_library(CruBase - Base.cpp - Buffer.cpp - Exception.cpp - Format.cpp - PropertyTree.cpp - String.cpp - StringToNumberConverter.cpp - StringUtil.cpp - SubProcess.cpp - io/AutoReadStream.cpp - io/BufferStream.cpp - io/CFileStream.cpp - io/Stream.cpp - io/ProxyStream.cpp - io/Resource.cpp - io/MemoryStream.cpp - log/Logger.cpp - log/StdioLogTarget.cpp - platform/Exception.cpp -) -target_compile_definitions(CruBase PRIVATE CRU_BASE_EXPORT_API) -target_include_directories(CruBase PUBLIC ${CRU_INCLUDE_DIR}) -target_compile_definitions(CruBase PUBLIC $<$:CRU_DEBUG>) - -if (UNIX AND NOT EMSCRIPTEN) - target_sources(CruBase PRIVATE - platform/unix/PosixSpawnSubProcess.cpp - platform/unix/UnixFileStream.cpp - platform/unix/UnixPipe.cpp - ) - - if (NOT APPLE) - target_link_libraries(CruBase PUBLIC pthread) - endif() -endif() - -if (APPLE) - find_library(CORE_FOUNDATION CoreFoundation REQUIRED) - target_link_libraries(CruBase PUBLIC ${CORE_FOUNDATION}) - - target_sources(CruBase PRIVATE - platform/osx/Convert.cpp - platform/osx/Exception.cpp - ) -endif() - -if (EMSCRIPTEN) - target_compile_options(CruBase PUBLIC "-fwasm-exceptions") - target_link_options(CruBase PUBLIC "-fwasm-exceptions") - - target_sources(CruBase PRIVATE - platform/web/WebException.cpp - ) -endif() - -if (WIN32) - target_sources(CruBase PRIVATE - platform/win/BridgeComStream.cpp - platform/win/ComAutoInit.cpp - platform/win/DebugLogTarget.cpp - platform/win/Exception.cpp - platform/win/StreamConvert.cpp - platform/win/Win32FileStream.cpp - ) - - target_link_libraries(CruBase PUBLIC Shlwapi.lib) -endif() - -if (WIN32) - target_compile_definitions(CruBase PUBLIC CRU_PLATFORM_WINDOWS) -elseif(APPLE) - target_compile_definitions(CruBase PUBLIC CRU_PLATFORM_OSX) -elseif(EMSCRIPTEN) - target_compile_definitions(CruBase PUBLIC CRU_PLATFORM_EMSCRIPTEN) -else() - target_compile_definitions(CruBase PUBLIC CRU_PLATFORM_LINUX) -endif() - -target_link_libraries(CruBase PUBLIC double-conversion) diff --git a/src/common/Exception.cpp b/src/common/Exception.cpp deleted file mode 100644 index 4110ad56..00000000 --- a/src/common/Exception.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "cru/common/Exception.h" - -#include "cru/common/Format.h" - -#include - -namespace cru { -Exception::Exception(String message, std::unique_ptr inner) - : message_(std::move(message)), inner_(std::move(inner)) {} - -Exception::~Exception() {} - -const char* Exception::what() const noexcept { - if (!message_.empty() && utf8_message_.empty()) { - utf8_message_ = message_.ToUtf8(); - } - - return utf8_message_.c_str(); -} - -void Exception::AppendMessage(StringView additional_message) { - message_ += u" "; - message_ += additional_message; -} - -void Exception::AppendMessage(std::optional additional_message) { - if (additional_message) AppendMessage(*additional_message); -} - -ErrnoException::ErrnoException(String message) - : ErrnoException(message, errno) {} - -ErrnoException::ErrnoException(String message, int errno_code) - : Exception(Format(u"{}. Errno is {}.", message, errno_code)), - errno_code_(errno_code) {} -} // namespace cru diff --git a/src/common/Format.cpp b/src/common/Format.cpp deleted file mode 100644 index d58c90b7..00000000 --- a/src/common/Format.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "cru/common/Format.h" - -namespace cru { -namespace details { -FormatToken ParsePlaceHolder(String place_holder_string) { - if (place_holder_string.empty()) { - return FormatToken::NonePlaceHolder({}); - } - - if (place_holder_string.StartWith(u":")) { - if (place_holder_string.Find(u':', 1) != -1) { - throw Exception(u"Two ':' inside placeholder."); - } - - return FormatToken::NonePlaceHolder(place_holder_string.substr(1)); - } - if (IsDigit(place_holder_string[0])) { - int position = 0; - int index = 0; - while (index < place_holder_string.size() && - IsDigit(place_holder_string[index])) { - position = position * 10 + place_holder_string[index] - '0'; - index++; - } - - String option; - - if (index != place_holder_string.size()) { - if (place_holder_string[index] != ':') { - throw Exception(u"Invalid placeholder in format."); - } - - option = place_holder_string.substr(index + 1); - } - - return FormatToken::PositionedPlaceHolder(position, std::move(option)); - } - - auto separator_index = place_holder_string.Find(':'); - if (separator_index == -1) { - return FormatToken::NamedPlaceHolder(place_holder_string, {}); - } else { - return FormatToken::NamedPlaceHolder( - place_holder_string.substr(0, separator_index), - place_holder_string.substr(separator_index + 1)); - } -} - -std::vector ParseToFormatTokenList(StringView str) { - std::vector result; - - auto push_char = [&result](char16_t c) { - if (result.empty() || result.back().type == FormatTokenType::PlaceHolder) { - result.push_back(FormatToken::Text()); - } - result.back().data.append(c); - }; - - bool try_to_escape = false; - bool is_in_place_holder = false; - String place_holder_string; - - for (auto c : str) { - if (c == u'{') { - if (try_to_escape) { - push_char(u'{'); - try_to_escape = false; - is_in_place_holder = false; - } else { - if (is_in_place_holder) { - throw Exception(u"Invalid format string: '{' inside placeholder."); - } - - try_to_escape = true; - is_in_place_holder = true; - } - } else if (c == u'}') { - if (is_in_place_holder) { - is_in_place_holder = false; - result.push_back(ParsePlaceHolder(std::move(place_holder_string))); - place_holder_string.clear(); - } else { - push_char(u'}'); - } - try_to_escape = false; - } else { - if (is_in_place_holder) { - place_holder_string.push_back(c); - } else { - push_char(c); - } - try_to_escape = false; - } - } - return result; -} - -void FormatAppendFromFormatTokenList( - String& current, const std::vector& format_token_list, - Index index) { - for (Index i = index; i < static_cast(format_token_list.size()); i++) { - const auto& token = format_token_list[i]; - if (token.type == FormatTokenType::PlaceHolder) { - throw Exception(u"More placeholder than args."); - } else { - current += token.data; - } - } -} -} // namespace details -} // namespace cru diff --git a/src/common/PropertyTree.cpp b/src/common/PropertyTree.cpp deleted file mode 100644 index b587becb..00000000 --- a/src/common/PropertyTree.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "cru/common/PropertyTree.h" -#include -#include "cru/common/Exception.h" - -namespace cru { -String PropertySubTreeRef::CombineKey(StringView left, StringView right) { - return PropertyTree::CombineKey(left, right); -} - -PropertySubTreeRef::PropertySubTreeRef(PropertyTree* tree, String path) - : tree_(tree), path_(std::move(path)) { - Expects(tree); -} - -PropertySubTreeRef PropertySubTreeRef::GetParent() const { - for (Index i = path_.size() - 1; i >= 0; i--) { - if (path_[i] == '.') { - return PropertySubTreeRef(tree_, path_.substr(0, i)); - } - } - - return PropertySubTreeRef(tree_, {}); -} - -PropertySubTreeRef PropertySubTreeRef::GetChild(const String& key) const { - return PropertySubTreeRef(tree_, CombineKey(path_, key)); -} - -String PropertySubTreeRef::GetValue(const String& key) const { - return tree_->GetValue(CombineKey(path_, key)); -} - -void PropertySubTreeRef::SetValue(const String& key, String value) { - tree_->SetValue(CombineKey(path_, key), std::move(value)); -} - -void PropertySubTreeRef::DeleteValue(const String& key) { - tree_->DeleteValue(CombineKey(path_, key)); -} - -String PropertyTree::CombineKey(StringView left, StringView right) { - return String(left) + String(left.empty() ? u"" : u".") + String(right); -} - -PropertyTree::PropertyTree(std::unordered_map values) - : values_(std::move(values)) {} - -String PropertyTree::GetValue(const String& key) const { - auto it = values_.find(key); - if (it == values_.end()) { - throw Exception(u"Property tree has no value."); - } - return it->second; -} - -void PropertyTree::SetValue(const String& key, String value) { - values_[key] = std::move(value); -} - -void PropertyTree::DeleteValue(const String& key) { - auto it = values_.find(key); - if (it != values_.end()) { - values_.erase(it); - } -} - -PropertySubTreeRef PropertyTree::GetSubTreeRef(const String& path) { - return PropertySubTreeRef(this, path); -} - -} // namespace cru diff --git a/src/common/String.cpp b/src/common/String.cpp deleted file mode 100644 index 27712f01..00000000 --- a/src/common/String.cpp +++ /dev/null @@ -1,672 +0,0 @@ -#include "cru/common/String.h" - -#include "cru/common/Buffer.h" -#include "cru/common/Exception.h" -#include "cru/common/StringToNumberConverter.h" -#include "cru/common/StringUtil.h" - -#include -#include - -#include -#include -#include -#include -#include - -namespace cru { -template -Index GetStrSize(const C* str) { - Index i = 0; - while (str[i]) { - i++; - } - return i; -} - -String String::FromUtf8(const char* str) { - return FromUtf8(str, GetStrSize(str)); -} - -String String::FromUtf8(const char* str, Index size) { - String result; - Utf8CodePointIterator iter(str, size); - for (auto cp : iter) { - Utf16EncodeCodePointAppend( - cp, - std::bind(&String::push_back, std::ref(result), std::placeholders::_1)); - } - return result; -} - -String String::FromUtf8(const std::byte* str, Index size) { - return String::FromUtf8(reinterpret_cast(str), size); -} - -String String::FromUtf8(const Buffer& buffer) { - return String::FromUtf8(buffer.GetUsedBeginPtr(), buffer.GetUsedSize()); -} - -String String::FromStdPath(const std::filesystem::path& path) { - return String::FromUtf8(path.string()); -} - -char16_t String::kEmptyBuffer[1] = {0}; - -String::String(const_pointer str) : String(str, GetStrSize(str)) {} - -String::String(const_pointer str, Index size) { - this->buffer_ = new value_type[size + 1]; - std::memcpy(this->buffer_, str, size * sizeof(char16_t)); - this->buffer_[size] = 0; - this->size_ = size; - this->capacity_ = size; -} - -String::String(size_type size, value_type ch) : String() { - reserve(size); - for (Index i = 0; i < size; i++) { - append(ch); - } -} - -String::String(std::initializer_list l) - : String(l.begin(), l.size()) {} - -#ifdef CRU_PLATFORM_WINDOWS -String::String(const wchar_t* str) : String(str, GetStrSize(str)) {} -String::String(const wchar_t* str, Index size) - : String(reinterpret_cast(str), size) {} -#endif - -String::String(const String& other) { - if (other.size_ == 0) return; - this->buffer_ = new value_type[other.size_ + 1]; - std::memcpy(this->buffer_, other.buffer_, other.size_ * sizeof(value_type)); - this->buffer_[other.size_] = 0; - this->size_ = other.size_; - this->capacity_ = other.size_; -} - -String::String(String&& other) noexcept { - this->buffer_ = other.buffer_; - this->size_ = other.size_; - this->capacity_ = other.capacity_; - other.buffer_ = kEmptyBuffer; - other.size_ = 0; - other.capacity_ = 0; -} - -String& String::operator=(const String& other) { - if (this != &other) { - if (this->buffer_ != kEmptyBuffer) { - delete[] this->buffer_; - } - - if (other.buffer_ == kEmptyBuffer) { - this->buffer_ = kEmptyBuffer; - this->size_ = 0; - this->capacity_ = 0; - } else { - this->buffer_ = new value_type[other.size_ + 1]; - std::memcpy(this->buffer_, other.buffer_, - other.size_ * sizeof(value_type)); - this->buffer_[other.size_] = 0; - this->size_ = other.size_; - this->capacity_ = other.size_; - } - } - return *this; -} - -String& String::operator=(String&& other) noexcept { - if (this != &other) { - if (this->buffer_ != kEmptyBuffer) { - delete[] this->buffer_; - } - - this->buffer_ = other.buffer_; - this->size_ = other.size_; - this->capacity_ = other.capacity_; - other.buffer_ = kEmptyBuffer; - other.size_ = 0; - other.capacity_ = 0; - } - return *this; -} - -String::~String() { - if (this->buffer_ != kEmptyBuffer) { - delete[] this->buffer_; - } -} - -String::String(from_buffer_tag, pointer buffer, Index size, Index capacity) - : buffer_(buffer), size_(size), capacity_(capacity) {} - -void String::clear() { resize(0); } - -void String::resize(Index new_size) { - Expects(new_size >= 0); - - if (new_size == size_) return; - - if (new_size < size_) { - size_ = new_size; - buffer_[size_] = 0; - } else { - reserve(new_size); - std::memset(buffer_ + size_, 0, sizeof(value_type) * (new_size - size_)); - buffer_[new_size] = 0; - size_ = new_size; - } -} - -void String::shrink_to_fit() { - if (capacity_ == size_) return; - if (size_ == 0) { - delete[] buffer_; - buffer_ = kEmptyBuffer; - size_ = 0; - capacity_ = 0; - } else { - auto new_buffer = new value_type[size_ + 1]; - std::memcpy(new_buffer, buffer_, sizeof(value_type) * size_); - delete[] buffer_; - buffer_ = new_buffer; - capacity_ = size_; - } -} - -void String::reserve(Index new_capacity) { - Expects(new_capacity >= 0); - if (new_capacity <= this->capacity_) return; - if (new_capacity > 0) { - pointer new_buffer = new value_type[new_capacity + 1]; - if (this->buffer_ != kEmptyBuffer) { - memcpy(new_buffer, this->buffer_, this->size_ * sizeof(value_type)); - delete[] this->buffer_; - } - new_buffer[this->size_] = 0; - this->buffer_ = new_buffer; - this->capacity_ = new_capacity; - } -} - -String::iterator String::insert(const_iterator pos, const_iterator str, - Index size) { - Expects(pos >= cbegin() && pos <= cend()); - - std::vector backup_buffer; - if (str >= buffer_ && str < buffer_ + size_) { - backup_buffer.resize(size); - std::copy(str, str + size, backup_buffer.begin()); - str = backup_buffer.data(); - } - - Index index = pos - cbegin(); - - Index new_size = size_ + size; - if (new_size > capacity_) { - auto new_capacity = capacity_; - if (new_capacity == 0) { - new_capacity = new_size; - } else { - while (new_capacity < new_size) { - new_capacity *= 2; - } - } - - this->reserve(new_capacity); - } - - std::memmove(begin() + index + size, begin() + index, - (size_ - index) * sizeof(value_type)); - std::memcpy(begin() + index, str, size * sizeof(value_type)); - - buffer_[new_size] = 0; - size_ = new_size; - - return begin() + new_size; -} - -String::iterator String::erase(const_iterator start, const_iterator end) { - Expects(buffer_ <= start && start <= end && end <= buffer_ + size_); - - Index new_size = size_ - (end - start); - - auto s = const_cast(start); - auto e = const_cast(end); - - std::memmove(s, e, (cend() - end) * sizeof(value_type)); - this->size_ = new_size; - this->buffer_[new_size] = 0; - - return s; -} - -String& String::operator+=(StringView other) { - append(other); - return *this; -} - -StringView String::View() const { return *this; } - -Index String::Find(value_type value, Index start) const { - return View().Find(value, start); -} - -std::vector String::Split(value_type separator, - bool remove_space_line) const { - return View().Split(separator, remove_space_line); -} - -std::vector String::SplitToLines(bool remove_space_line) const { - return View().SplitToLines(remove_space_line); -} - -bool String::StartWith(StringView str) const { return View().StartWith(str); } - -bool String::EndWith(StringView str) const { return View().EndWith(str); } - -std::string String::ToUtf8() const { return View().ToUtf8(); } - -Buffer String::ToUtf8Buffer(bool end_zero) const { - return View().ToUtf8Buffer(); -} - -String& String::TrimStart() { - if (size_ == 0) return *this; - - auto start = begin(); - while (start != end() && IsWhitespace(*start)) { - ++start; - } - - if (start == end()) { - clear(); - } else { - erase(begin(), start); - } - - return *this; -} - -String& String::TrimEnd() { - if (size_ == 0) return *this; - while (size_ > 0 && IsWhitespace(buffer_[size_ - 1])) { - size_--; - } - - return *this; -} - -String& String::Trim() { - TrimStart(); - TrimEnd(); - return *this; -} - -void String::AppendCodePoint(CodePoint code_point) { - if (!Utf16EncodeCodePointAppend( - code_point, - std::bind(&String::push_back, this, std::placeholders::_1))) { - throw TextEncodeException(u"Code point out of range."); - } -} - -Index String::IndexFromCodeUnitToCodePoint(Index code_unit_index) const { - return View().IndexFromCodeUnitToCodePoint(code_unit_index); -} - -Index String::IndexFromCodePointToCodeUnit(Index code_point_index) const { - return View().IndexFromCodePointToCodeUnit(code_point_index); -} - -Range String::RangeFromCodeUnitToCodePoint(Range code_unit_range) const { - return View().RangeFromCodeUnitToCodePoint(code_unit_range); -} - -Range String::RangeFromCodePointToCodeUnit(Range code_point_range) const { - return View().RangeFromCodePointToCodeUnit(code_point_range); -} - -int String::ParseToInt(Index* processed_characters_count, - StringToNumberFlag flags, int base) const { - return View().ParseToInt(processed_characters_count, flags, base); -} - -long long String::ParseToLongLong(Index* processed_characters_count, - StringToNumberFlag flags, int base) const { - return View().ParseToLongLong(processed_characters_count, flags, base); -} - -float String::ParseToFloat(Index* processed_characters_count, - StringToNumberFlag flags) const { - return View().ParseToFloat(processed_characters_count, flags); -} - -double String::ParseToDouble(Index* processed_characters_count, - StringToNumberFlag flags) const { - return View().ParseToDouble(processed_characters_count, flags); -} - -std::vector String::ParseToFloatList(value_type separator) const { - return View().ParseToFloatList(separator); -} - -std::vector String::ParseToDoubleList(value_type separator) const { - return View().ParseToDoubleList(separator); -} - -std::ostream& operator<<(std::ostream& os, const String& value) { - os << value.ToUtf8(); - return os; -} - -namespace { -inline int Compare(char16_t left, char16_t right) { - if (left < right) return -1; - if (left > right) return 1; - return 0; -} - -inline int CaseInsensitiveCompare(char16_t left, char16_t right) { - return Compare(ToLower(left), ToLower(right)); -} -} // namespace - -int String::Compare(const String& other) const { return View().Compare(other); } -int String::CaseInsensitiveCompare(const String& other) const { - return View().CaseInsensitiveCompare(other); -} - -int StringView::Compare(const StringView& other) const { - const_iterator i1 = cbegin(); - const_iterator i2 = other.cbegin(); - - const_iterator end1 = cend(); - const_iterator end2 = other.cend(); - - while (i1 != end1 && i2 != end2) { - int r = cru::Compare(*i1, *i2); - if (r != 0) return r; - i1++; - i2++; - } - - if (i1 == end1) { - if (i2 == end2) { - return 0; - } else { - return -1; - } - } else { - return 1; - } -} - -int StringView::CaseInsensitiveCompare(const StringView& other) const { - const_iterator i1 = cbegin(); - const_iterator i2 = other.cbegin(); - - const_iterator end1 = cend(); - const_iterator end2 = other.cend(); - - while (i1 != end1 && i2 != end2) { - int r = cru::CaseInsensitiveCompare(*i1, *i2); - if (r != 0) return r; - i1++; - i2++; - } - - if (i1 == end1) { - if (i2 == end2) { - return 0; - } else { - return -1; - } - } else { - return 1; - } -} - -StringView StringView::substr(Index pos) { - Expects(pos >= 0 && pos < size_); - return StringView(ptr_ + pos, size_ - pos); -} - -StringView StringView::substr(Index pos, Index size) { - Expects(pos >= 0 && pos < size_); - - return StringView(ptr_ + pos, std::min(size, size_ - pos)); -} - -Index StringView::Find(value_type value, Index start) const { - Expects(start >= 0 && start <= size_); - - for (Index i = start; i < size_; ++i) { - if (ptr_[i] == value) return i; - } - return -1; -} - -std::vector StringView::Split(value_type separator, - bool remove_space_line) const { - std::vector result; - - if (size_ == 0) return result; - - Index line_start = 0; - Index line_end = 0; - while (line_end < size_) { - if (ptr_[line_end] == separator) { - if (remove_space_line) { - bool add = false; - for (Index i = line_start; i < line_end; i++) { - if (!IsWhitespace(ptr_[i])) { - add = true; - break; - } - } - if (add) result.emplace_back(begin() + line_start, begin() + line_end); - } else { - result.emplace_back(begin() + line_start, begin() + line_end); - } - line_start = line_end + 1; - line_end = line_start; - } else { - line_end++; - } - } - - if (remove_space_line) { - bool add = false; - for (Index i = line_start; i < size_; i++) { - if (!IsWhitespace(ptr_[i])) { - add = true; - break; - } - } - if (add) result.emplace_back(begin() + line_start, begin() + size_); - } else { - result.emplace_back(begin() + line_start, begin() + size_); - } - - return result; -} - -std::vector StringView::SplitToLines(bool remove_space_line) const { - return Split(u'\n', remove_space_line); -} - -bool StringView::StartWith(StringView str) const { - if (str.size() > size_) return false; - return std::memcmp(str.data(), ptr_, str.size()) == 0; -} - -bool StringView::EndWith(StringView str) const { - if (str.size() > size_) return false; - return std::memcmp(str.data(), ptr_ + size_ - str.size(), str.size()) == 0; -} - -Index StringView::IndexFromCodeUnitToCodePoint(Index code_unit_index) const { - auto iter = CodePointIterator(); - Index result = 0; - while (iter.GetPosition() < code_unit_index && !iter.IsPastEnd()) { - ++iter; - ++result; - } - return result; -} - -Index StringView::IndexFromCodePointToCodeUnit(Index code_point_index) const { - auto iter = CodePointIterator(); - Index cpi = 0; - while (cpi < code_point_index && !iter.IsPastEnd()) { - ++iter; - ++cpi; - } - return iter.GetPosition(); -} - -Range StringView::RangeFromCodeUnitToCodePoint(Range code_unit_range) const { - return Range::FromTwoSides( - IndexFromCodeUnitToCodePoint(code_unit_range.GetStart()), - IndexFromCodeUnitToCodePoint(code_unit_range.GetEnd())); -} - -Range StringView::RangeFromCodePointToCodeUnit(Range code_point_range) const { - return Range::FromTwoSides( - IndexFromCodePointToCodeUnit(code_point_range.GetStart()), - IndexFromCodePointToCodeUnit(code_point_range.GetEnd())); -} - -std::string StringView::ToUtf8() const { - std::string result; - for (auto cp : CodePointIterator()) { - Utf8EncodeCodePointAppend( - cp, std::bind(&std::string::push_back, std::ref(result), - std::placeholders::_1)); - } - return result; -} - -Buffer StringView::ToUtf8Buffer(bool end_zero) const { - const Index grow_step = 10; - Buffer buffer(grow_step); // Maybe another init value is more reasonable. - auto push_back = [&buffer](char c) { - if (buffer.IsUsedReachEnd()) { - buffer.ResizeBuffer(buffer.GetBufferSize() + grow_step, true); - } - buffer.PushBack(static_cast(c)); - }; - for (auto cp : CodePointIterator()) { - Utf8EncodeCodePointAppend(cp, push_back); - } - if (end_zero) { - push_back(0); - } - return buffer; -} - -int StringView::ParseToInt(Index* processed_characters_count, - StringToNumberFlag flags, int base) const { - return ParseToInteger(processed_characters_count, flags, base); -} - -long long StringView::ParseToLongLong(Index* processed_characters_count, - StringToNumberFlag flags, - int base) const { - return ParseToInteger(processed_characters_count, flags, base); -} - -static int MapStringToDoubleFlags(StringToNumberFlag flags) { - int f = double_conversion::StringToDoubleConverter::ALLOW_CASE_INSENSIBILITY; - if (flags & StringToNumberFlags::kAllowLeadingSpaces) { - f |= double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES; - } - if (flags & StringToNumberFlags::kAllowTrailingSpaces) { - f |= double_conversion::StringToDoubleConverter::ALLOW_TRAILING_SPACES; - } - if (flags & StringToNumberFlags::kAllowTrailingJunk) { - f |= double_conversion::StringToDoubleConverter::ALLOW_TRAILING_JUNK; - } - return f; -} - -static double_conversion::StringToDoubleConverter CreateStringToDoubleConverter( - StringToNumberFlag flags) { - return {MapStringToDoubleFlags(flags), 0.0, NAN, "inf", "nan"}; -} - -float StringView::ParseToFloat(Index* processed_characters_count, - StringToNumberFlag flags) const { - int pcc; - auto result = CreateStringToDoubleConverter(flags).StringToFloat( - reinterpret_cast(ptr_), static_cast(size_), &pcc); - if (processed_characters_count != nullptr) { - *processed_characters_count = pcc; - } - - if (flags & StringToNumberFlags::kThrowOnError && std::isnan(result)) { - throw Exception(u"Result of string to float conversion is NaN"); - } - - return result; -} - -double StringView::ParseToDouble(Index* processed_characters_count, - StringToNumberFlag flags) const { - int pcc; - auto result = CreateStringToDoubleConverter(flags).StringToDouble( - reinterpret_cast(ptr_), static_cast(size_), &pcc); - if (processed_characters_count != nullptr) { - *processed_characters_count = pcc; - } - - if (flags & StringToNumberFlags::kThrowOnError && std::isnan(result)) { - throw Exception(u"Result of string to double conversion is NaN"); - } - - return result; -} - -std::vector StringView::ParseToFloatList(value_type separator) const { - std::vector result; - auto list = Split(separator, true); - for (auto& item : list) { - auto value = item.ParseToFloat(); - if (std::isnan(value)) { - throw Exception(u"Invalid double value."); - } - result.push_back(value); - } - return result; -} - -std::vector StringView::ParseToDoubleList(value_type separator) const { - std::vector result; - auto list = Split(separator, true); - for (auto& item : list) { - auto value = item.ParseToDouble(); - if (std::isnan(value)) { - throw Exception(u"Invalid double value."); - } - result.push_back(value); - } - return result; -} - -String ToLower(StringView s) { - String result; - for (auto c : s) result.push_back(ToLower(c)); - return result; -} - -String ToUpper(StringView s) { - String result; - for (auto c : s) result.push_back(ToUpper(c)); - return result; -} -} // namespace cru diff --git a/src/common/StringToNumberConverter.cpp b/src/common/StringToNumberConverter.cpp deleted file mode 100644 index 7a926d3d..00000000 --- a/src/common/StringToNumberConverter.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include "cru/common/StringToNumberConverter.h" -#include "cru/common/Exception.h" - -namespace cru { -bool StringToIntegerConverter::CheckParams() const { - return base == 0 || base >= 2 & base <= 36; -} - -static bool IsSpace(char c) { - return c == ' ' || c == '\t' || c == '\n' || c == '\r'; -} - -StringToIntegerResult StringToIntegerConverter::Parse( - const char* const str, const Index size, - Index* processed_characters_count) const { - if (str == nullptr) throw std::invalid_argument("Invalid str."); - if (size < 0) throw std::invalid_argument("Invalid size."); - if (!CheckParams()) throw std::invalid_argument("Invalid parsing flags."); - - const bool throw_on_error = flags.Has(StringToNumberFlags::kThrowOnError); - - auto const end = str + size; - - auto current = str; - - if (flags & StringToNumberFlags::kAllowLeadingSpaces) { - while (current != end && IsSpace(*current)) { - current++; - } - } - - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception(u"Empty string (after reading leading spaces)."); - } else { - return {false, 0}; - } - } - - bool negate = false; - - if (*current == '-') { - ++current; - negate = true; - } else if (*current == '+') { - ++current; - } - - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception(u"Empty string (after reading sign)."); - } else { - return {false, 0}; - } - } - - int real_base = base; - - if (real_base == 0) { - if (*current == '0') { - ++current; - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = current - str; - } - return {negate, 0}; - } else if (*current == 'x' || *current == 'X') { - ++current; - real_base = 16; - } else if (*current == 'b' || *current == 'B') { - ++current; - real_base = 2; - } else { - real_base = 8; - } - } else { - real_base = 10; - } - } - - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception(u"Empty string (after reading head base indicator)."); - } else { - return {false, 0}; - } - } - - const bool allow_leading_zero = - flags.Has(StringToNumberFlags::kAllowLeadingZeroForInteger); - - while (current != end && *current == '0') { - current++; - } - - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = current - str; - } - return {negate, 0}; - } - - const bool allow_trailing_junk = - flags.Has(StringToNumberFlags::kAllowTrailingJunk); - const bool allow_trailing_spaces = - flags.Has(StringToNumberFlags::kAllowTrailingSpaces); - - unsigned long long result = 0; - - while (current != end) { - const char c = *current; - if (c >= '0' && c <= (real_base > 10 ? '9' : real_base + '0' - 1)) { - result = result * real_base + c - '0'; - current++; - } else if (real_base > 10 && c >= 'a' && c <= (real_base + 'a' - 10 - 1)) { - result = result * real_base + c - 'a' + 10; - current++; - } else if (real_base > 10 && c >= 'A' && c <= (real_base + 'A' - 10 - 1)) { - result = result * real_base + c - 'A' + 10; - current++; - } else if (allow_trailing_junk) { - break; - } else if (allow_trailing_spaces && IsSpace(c)) { - break; - } else { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception(String(u"Read invalid character '") + c + u"'."); - } else { - return {false, 0}; - } - } - } - - if (allow_trailing_spaces) { - while (current != end && IsSpace(*current)) { - current++; - } - - if (current != end) { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception(u"There is trailing junk."); - } else { - return {false, 0}; - } - } - } - - if (processed_characters_count) { - *processed_characters_count = current - str; - } - - return {negate, result}; -} - -} // namespace cru diff --git a/src/common/StringUtil.cpp b/src/common/StringUtil.cpp deleted file mode 100644 index f584fd4e..00000000 --- a/src/common/StringUtil.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include "cru/common/StringUtil.h" -#include "cru/common/Base.h" -#include "cru/common/Exception.h" - -namespace cru { -using details::ExtractBits; - -CodePoint Utf8NextCodePoint(const char* ptr, Index size, Index current, - Index* next_position) { - CodePoint result; - - if (current >= size) { - result = k_invalid_code_point; - } else { - const auto cu0 = static_cast(ptr[current++]); - - auto read_next_folowing_code = [ptr, size, ¤t]() -> CodePoint { - if (current == size) - throw TextEncodeException( - u"Unexpected end when read continuing byte of multi-byte code " - "point."); - - const auto u = static_cast(ptr[current]); - if (!(u & (1u << 7)) || (u & (1u << 6))) { - throw TextEncodeException( - u"Unexpected bad-format (not 0b10xxxxxx) continuing byte of " - "multi-byte code point."); - } - - return ExtractBits(ptr[current++]); - }; - - if ((1u << 7) & cu0) { - if ((1u << 6) & cu0) { // 2~4-length code point - if ((1u << 5) & cu0) { // 3~4-length code point - if ((1u << 4) & cu0) { // 4-length code point - if (cu0 & (1u << 3)) { - throw TextEncodeException( - u"Unexpected bad-format begin byte (not 0b11110xxx) of 4-byte" - "code point."); - } - - const CodePoint s0 = ExtractBits(cu0) - << (6 * 3); - const CodePoint s1 = read_next_folowing_code() << (6 * 2); - const CodePoint s2 = read_next_folowing_code() << 6; - const CodePoint s3 = read_next_folowing_code(); - result = s0 + s1 + s2 + s3; - } else { // 3-length code point - const CodePoint s0 = ExtractBits(cu0) - << (6 * 2); - const CodePoint s1 = read_next_folowing_code() << 6; - const CodePoint s2 = read_next_folowing_code(); - result = s0 + s1 + s2; - } - } else { // 2-length code point - const CodePoint s0 = ExtractBits(cu0) - << 6; - const CodePoint s1 = read_next_folowing_code(); - result = s0 + s1; - } - } else { - throw TextEncodeException( - u"Unexpected bad-format (0b10xxxxxx) begin byte of a code point."); - } - } else { - result = static_cast(cu0); - } - } - - if (next_position != nullptr) *next_position = current; - return result; -} - -CodePoint Utf16NextCodePoint(const char16_t* ptr, Index size, Index current, - Index* next_position) { - CodePoint result; - - if (current >= size) { - result = k_invalid_code_point; - } else { - const auto cu0 = ptr[current++]; - - if (!IsUtf16SurrogatePairCodeUnit(cu0)) { // 1-length code point - result = static_cast(cu0); - } else if (IsUtf16SurrogatePairLeading(cu0)) { // 2-length code point - if (current >= size) { - throw TextEncodeException( - u"Unexpected end when reading second code unit of surrogate pair."); - } - const auto cu1 = ptr[current++]; - - if (!IsUtf16SurrogatePairTrailing(cu1)) { - throw TextEncodeException( - u"Unexpected bad-range second code unit of surrogate pair."); - } - - const auto s0 = ExtractBits(cu0) << 10; - const auto s1 = ExtractBits(cu1); - - result = s0 + s1 + 0x10000; - - } else { - throw TextEncodeException( - u"Unexpected bad-range first code unit of surrogate pair."); - } - } - - if (next_position != nullptr) *next_position = current; - return result; -} - -CodePoint Utf16PreviousCodePoint(const char16_t* ptr, Index size, Index current, - Index* previous_position) { - CRU_UNUSED(size) - - CodePoint result; - if (current <= 0) { - result = k_invalid_code_point; - } else { - const auto cu0 = ptr[--current]; - - if (!IsUtf16SurrogatePairCodeUnit(cu0)) { // 1-length code point - result = static_cast(cu0); - } else if (IsUtf16SurrogatePairTrailing(cu0)) { // 2-length code point - if (current <= 0) { - throw TextEncodeException( - u"Unexpected end when reading first code unit of surrogate pair."); - } - const auto cu1 = ptr[--current]; - - if (!IsUtf16SurrogatePairLeading(cu1)) { - throw TextEncodeException( - u"Unexpected bad-range first code unit of surrogate pair."); - } - - const auto s0 = ExtractBits(cu1) << 10; - const auto s1 = ExtractBits(cu0); - - result = s0 + s1 + 0x10000; - - } else { - throw TextEncodeException( - u"Unexpected bad-range second code unit of surrogate pair."); - } - } - - if (previous_position != nullptr) *previous_position = current; - return result; -} - -bool Utf16IsValidInsertPosition(const char16_t* ptr, Index size, - Index position) { - if (position < 0) return false; - if (position > size) return false; - if (position == 0) return true; - if (position == size) return true; - return !IsUtf16SurrogatePairTrailing(ptr[position]); -} - -Index Utf16BackwardUntil(const char16_t* ptr, Index size, Index position, - const std::function& predicate) { - if (position <= 0) return position; - while (true) { - Index p = position; - auto c = Utf16PreviousCodePoint(ptr, size, p, &position); - if (predicate(c)) return p; - if (c == k_invalid_code_point) return p; - } - UnreachableCode(); -} - -Index Utf16ForwardUntil(const char16_t* ptr, Index size, Index position, - const std::function& predicate) { - if (position >= size) return position; - while (true) { - Index p = position; - auto c = Utf16NextCodePoint(ptr, size, p, &position); - if (predicate(c)) return p; - if (c == k_invalid_code_point) return p; - } - UnreachableCode(); -} - -inline bool IsSpace(CodePoint c) { return c == 0x20 || c == 0xA; } - -Index Utf16PreviousWord(const char16_t* ptr, Index size, Index position, - bool* is_space) { - if (position <= 0) return position; - auto c = Utf16PreviousCodePoint(ptr, size, position, nullptr); - if (IsSpace(c)) { // TODO: Currently only test against 0x20(space). - if (is_space) *is_space = true; - return Utf16BackwardUntil(ptr, size, position, - [](CodePoint c) { return !IsSpace(c); }); - } else { - if (is_space) *is_space = false; - return Utf16BackwardUntil(ptr, size, position, IsSpace); - } -} - -Index Utf16NextWord(const char16_t* ptr, Index size, Index position, - bool* is_space) { - if (position >= size) return position; - auto c = Utf16NextCodePoint(ptr, size, position, nullptr); - if (IsSpace(c)) { // TODO: Currently only test against 0x20(space). - if (is_space) *is_space = true; - return Utf16ForwardUntil(ptr, size, position, - [](CodePoint c) { return !IsSpace(c); }); - } else { - if (is_space) *is_space = false; - return Utf16ForwardUntil(ptr, size, position, IsSpace); - } -} - -char16_t ToLower(char16_t c) { - if (c >= u'A' && c <= u'Z') { - return c - u'A' + u'a'; - } - return c; -} - -char16_t ToUpper(char16_t c) { - if (c >= u'a' && c <= u'z') { - return c - u'a' + u'A'; - } - return c; -} - -bool IsWhitespace(char16_t c) { - return c == u' ' || c == u'\t' || c == u'\n' || c == u'\r'; -} - -bool IsDigit(char16_t c) { return c >= u'0' && c <= u'9'; } - -Utf8CodePointIterator CreateUtf8Iterator(const std::byte* buffer, Index size) { - return Utf8CodePointIterator(reinterpret_cast(buffer), size); -} - -Utf8CodePointIterator CreateUtf8Iterator(const std::vector& buffer) { - return CreateUtf8Iterator(buffer.data(), buffer.size()); -} - -} // namespace cru diff --git a/src/common/SubProcess.cpp b/src/common/SubProcess.cpp deleted file mode 100644 index 33926f39..00000000 --- a/src/common/SubProcess.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#include "cru/common/SubProcess.h" - -#include - -#ifdef CRU_PLATFORM_UNIX -#include "cru/common/platform/unix/PosixSpawnSubProcess.h" -#endif - -namespace cru { - -#ifdef CRU_PLATFORM_UNIX -using ThisPlatformSubProcessImpl = platform::unix::PosixSpawnSubProcessImpl; -#endif - -PlatformSubProcess::PlatformSubProcess( - SubProcessStartInfo start_info, - std::shared_ptr impl) - : state_(new State(std::move(start_info), std::move(impl))), - lock_(state_->mutex, std::defer_lock) {} - -PlatformSubProcess::~PlatformSubProcess() {} - -void PlatformSubProcess::Start() { - std::lock_guard lock_guard(this->lock_); - - if (this->state_->status != SubProcessStatus::Prepare) { - throw SubProcessException(u"The process has already tried to start."); - } - - try { - this->state_->impl->PlatformCreateProcess(this->state_->start_info); - this->state_->status = SubProcessStatus::Running; - - auto thread = std::thread([state = state_] { - std::unique_lock lock(state->mutex); - state->exit_result = state->impl->PlatformWaitForProcess(); - state->status = SubProcessStatus::Exited; - state->condition_variable.notify_all(); - }); - - thread.detach(); - } catch (const std::exception& e) { - this->state_->status = SubProcessStatus::FailedToStart; - throw SubProcessFailedToStartException(u"Sub-process failed to start. " + - String::FromUtf8(e.what())); - } -} - -void PlatformSubProcess::Wait( - std::optional wait_time) { - std::lock_guard lock_guard(this->lock_); - - if (this->state_->status == SubProcessStatus::Prepare) { - throw SubProcessException( - u"The process does not start. Can't wait for it."); - } - - if (this->state_->status == SubProcessStatus::FailedToStart) { - throw SubProcessException( - u"The process failed to start. Can't wait for it."); - } - - if (this->state_->status == SubProcessStatus::Exited) { - return; - } - - auto predicate = [this] { - return this->state_->status == SubProcessStatus::Exited; - }; - - if (wait_time) { - this->state_->condition_variable.wait_for(this->lock_, *wait_time, - predicate); - } else { - this->state_->condition_variable.wait(this->lock_, predicate); - } -} - -void PlatformSubProcess::Kill() { - std::lock_guard lock_guard(this->lock_); - - if (this->state_->status == SubProcessStatus::Prepare) { - throw SubProcessException(u"The process does not start. Can't kill it."); - } - - if (this->state_->status == SubProcessStatus::FailedToStart) { - throw SubProcessException(u"The process failed to start. Can't kill it."); - } - - if (this->state_->status == SubProcessStatus::Exited) { - return; - } - - if (this->state_->killed) { - return; - } - - this->state_->impl->PlatformKillProcess(); - this->state_->killed = true; -} - -SubProcessStatus PlatformSubProcess::GetStatus() { - std::lock_guard lock_guard(this->lock_); - return this->state_->status; -} - -SubProcessExitResult PlatformSubProcess::GetExitResult() { - std::lock_guard lock_guard(this->lock_); - - if (this->state_->status == SubProcessStatus::Prepare) { - throw SubProcessException( - u"The process does not start. Can't get exit result."); - } - - if (this->state_->status == SubProcessStatus::FailedToStart) { - throw SubProcessException( - u"The process failed to start. Can't get exit result."); - } - - if (this->state_->status == SubProcessStatus::Running) { - throw SubProcessException( - u"The process is running. Can't get exit result."); - } - - return this->state_->exit_result; -} - -io::Stream* PlatformSubProcess::GetStdinStream() { - return this->state_->impl->GetStdinStream(); -} - -io::Stream* PlatformSubProcess::GetStdoutStream() { - return this->state_->impl->GetStdoutStream(); -} - -io::Stream* PlatformSubProcess::GetStderrStream() { - return this->state_->impl->GetStderrStream(); -} - -SubProcess SubProcess::Create(String program, std::vector arguments, - std::unordered_map environments) { - SubProcessStartInfo start_info; - start_info.program = std::move(program); - start_info.arguments = std::move(arguments); - start_info.environments = std::move(environments); - return SubProcess(std::move(start_info)); -} - -SubProcessExitResult SubProcess::Call( - String program, std::vector arguments, - std::unordered_map environments) { - auto process = - Create(std::move(program), std::move(arguments), std::move(environments)); - process.Wait(); - return process.GetExitResult(); -} - -SubProcess::SubProcess(SubProcessStartInfo start_info) { - platform_process_.reset(new PlatformSubProcess( - std::move(start_info), std::make_shared())); - platform_process_->Start(); -} - -SubProcess::~SubProcess() {} - -void SubProcess::Wait(std::optional wait_time) { - CheckValid(); - platform_process_->Wait(wait_time); -} - -void SubProcess::Kill() { - CheckValid(); - platform_process_->Kill(); -} - -SubProcessStatus SubProcess::GetStatus() { - CheckValid(); - return platform_process_->GetStatus(); -} - -SubProcessExitResult SubProcess::GetExitResult() { - CheckValid(); - return platform_process_->GetExitResult(); -} - -io::Stream* SubProcess::GetStdinStream() { - CheckValid(); - return platform_process_->GetStdinStream(); -} - -io::Stream* SubProcess::GetStdoutStream() { - CheckValid(); - return platform_process_->GetStdoutStream(); -} - -io::Stream* SubProcess::GetStderrStream() { - CheckValid(); - return platform_process_->GetStderrStream(); -} - -void SubProcess::Detach() { auto p = platform_process_.release(); } - -void SubProcess::CheckValid() const { - if (!IsValid()) { - throw SubProcessException(u"SubProcess instance is invalid."); - } -} - -} // namespace cru diff --git a/src/common/io/AutoReadStream.cpp b/src/common/io/AutoReadStream.cpp deleted file mode 100644 index 18bc18da..00000000 --- a/src/common/io/AutoReadStream.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "cru/common/io/AutoReadStream.h" -#include "cru/common/io/Stream.h" - -#include - -namespace cru::io { - -AutoReadStream::AutoReadStream(Stream* stream, bool auto_delete, - const AutoReadStreamOptions& options) - : Stream(false, true, stream->CanSeek()) { - auto buffer_stream_options = options.GetBufferStreamOptions(); - stream_ = stream; - size_per_read_ = buffer_stream_options.GetBlockSizeOrDefault(); - buffer_stream_ = std::make_unique(buffer_stream_options); - background_thread_ = std::thread(&AutoReadStream::BackgroundThreadRun, this); -} - -AutoReadStream::~AutoReadStream() { - if (auto_delete_) { - delete stream_; - } -} - -Index AutoReadStream::DoRead(std::byte* buffer, Index offset, Index size) { - std::unique_lock lock(buffer_stream_mutex_); - return buffer_stream_->Read(buffer, offset, size); -} - -Index AutoReadStream::DoWrite(const std::byte* buffer, Index offset, - Index size) { - return stream_->Write(buffer, offset, size); -} - -void AutoReadStream::DoFlush() { stream_->Flush(); } - -void AutoReadStream::DoClose() {} - -void AutoReadStream::BackgroundThreadRun() { - std::vector buffer(size_per_read_); - while (true) { - try { - auto read = stream_->Read(buffer.data(), buffer.size()); - if (read == 0) { - buffer_stream_->SetEof(); - break; - } else { - buffer_stream_->Write(buffer.data(), read); - } - } catch (const StreamAlreadyClosedException& exception) { - buffer_stream_->SetEof(); - break; - } - } -} - -} // namespace cru::io diff --git a/src/common/io/BufferStream.cpp b/src/common/io/BufferStream.cpp deleted file mode 100644 index 73e5719b..00000000 --- a/src/common/io/BufferStream.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "cru/common/io/BufferStream.h" -#include "cru/common/io/Stream.h" - -namespace cru::io { -BufferStream::BufferStream(const BufferStreamOptions& options) - : Stream(false, true, true) { - block_size_ = options.GetBlockSizeOrDefault(); - max_block_count_ = options.GetMaxBlockCount(); - - eof_ = false; -} - -BufferStream::~BufferStream() { DoClose(); } - -Index BufferStream::DoRead(std::byte* buffer, Index offset, Index size) { - std::unique_lock lock(mutex_); - - condition_variable_.wait(lock, - [this] { return !buffer_list_.empty() || eof_; }); - - if (buffer_list_.empty() && eof_) { - return 0; - } - - auto full = max_block_count_ > 0 && buffer_list_.size() == max_block_count_; - - Index read = 0; - - while (!buffer_list_.empty()) { - auto& stream_buffer = buffer_list_.front(); - auto this_read = - stream_buffer.PopFront(buffer + offset + read, size - read); - if (stream_buffer.GetUsedSize() == 0) { - buffer_list_.pop_front(); - } - read += this_read; - if (read == size) { - break; - } - } - - if (full && buffer_list_.size() < max_block_count_) { - // By convention, there should be at most one producer waiting. So - // notify_one and notify_all should be the same. - condition_variable_.notify_one(); - } - - return read; -} - -Index BufferStream::DoWrite(const std::byte* buffer, Index offset, Index size) { - std::unique_lock lock(mutex_); - - if (eof_) { - throw WriteAfterEofException( - u"Stream has been set eof. Can't write to it any more."); - } - - condition_variable_.wait(lock, [this] { - return max_block_count_ <= 0 || buffer_list_.size() < max_block_count_ || - buffer_list_.back().GetBackFree() > 0; - }); - - auto empty = buffer_list_.empty(); - - Index written = 0; - - if (empty) { - buffer_list_.push_back(Buffer(block_size_)); - } - - while (true) { - if (buffer_list_.back().GetBackFree() == 0) { - if (max_block_count_ > 0 && buffer_list_.size() == max_block_count_) { - break; - } - buffer_list_.push_back(Buffer(block_size_)); - } - auto& stream_buffer = buffer_list_.back(); - auto this_written = - stream_buffer.PushBack(buffer + offset + written, size - written); - written += this_written; - if (written == size) { - break; - } - } - - if (empty) { - // By convention, there should be at most one consumer waiting. So - // notify_one and notify_all should be the same. - condition_variable_.notify_one(); - } - - return written; -} - -void BufferStream::SetEof() { - std::unique_lock lock(mutex_); - - eof_ = true; - if (buffer_list_.empty()) { - // By convention, there should be at most one consumer waiting. So - // notify_one and notify_all should be the same. - condition_variable_.notify_one(); - } -} - -void BufferStream::DoClose() { CRU_STREAM_BEGIN_CLOSE } -} // namespace cru::io diff --git a/src/common/io/CFileStream.cpp b/src/common/io/CFileStream.cpp deleted file mode 100644 index 01456437..00000000 --- a/src/common/io/CFileStream.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "cru/common/io/CFileStream.h" -#include "cru/common/Exception.h" -#include "cru/common/io/Stream.h" - -#include - -namespace cru::io { -static bool ModeCanRead(const char* mode) { - for (const char* p = mode; *p != '\0'; p++) { - if (*p == 'r' || *p == '+') { - return true; - } - } - return false; -} - -static bool ModeCanWrite(const char* mode) { - for (const char* p = mode; *p != '\0'; p++) { - if (*p == 'w' || *p == 'a' || *p == '+') { - return true; - } - } - return false; -} - -CFileStream::CFileStream(const char* path, const char* mode) - : Stream(true, ModeCanRead(mode), ModeCanWrite(mode)), - file_(std::fopen(path, mode)), - auto_close_(true) { - if (file_ == nullptr) { - throw ErrnoException(u"Cannot open file."); - } -} - -CFileStream::CFileStream(std::FILE* file, bool readable, bool writable, - bool auto_close) - : Stream(true, readable, writable), file_(file), auto_close_(auto_close) { - if (file_ == nullptr) { - throw Exception(u"File is NULL."); - } -} - -CFileStream::~CFileStream() { - if (auto_close_ && file_ != nullptr) { - std::fclose(file_); - } -} - -static int ConvertOriginFlag(Stream::SeekOrigin origin) { - switch (origin) { - case Stream::SeekOrigin::Begin: - return SEEK_SET; - case Stream::SeekOrigin::Current: - return SEEK_CUR; - case Stream::SeekOrigin::End: - return SEEK_END; - default: - throw Exception(u"Unknown seek origin."); - } -} - -Index CFileStream::DoSeek(Index offset, SeekOrigin origin) { - if (std::fseek(file_, offset, ConvertOriginFlag(origin))) { - throw ErrnoException(u"Seek failed."); - } - return DoTell(); -} - -Index CFileStream::DoTell() { - long position = std::ftell(file_); - if (position == -1) { - throw ErrnoException(u"Tell failed."); - } - return position; -} - -void CFileStream::DoRewind() { std::rewind(file_); } - -Index CFileStream::DoRead(std::byte* buffer, Index offset, Index size) { - auto count = std::fread(buffer + offset, 1, size, file_); - return count; -} - -Index CFileStream::DoWrite(const std::byte* buffer, Index offset, Index size) { - auto count = std::fwrite(buffer + offset, 1, size, file_); - return count; -} - -void CFileStream::DoFlush() { std::fflush(file_); } - -void CFileStream::DoClose() { - CRU_STREAM_BEGIN_CLOSE - std::fclose(file_); - file_ = nullptr; -} -} // namespace cru::io diff --git a/src/common/io/MemoryStream.cpp b/src/common/io/MemoryStream.cpp deleted file mode 100644 index 4b33d780..00000000 --- a/src/common/io/MemoryStream.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "cru/common/io/MemoryStream.h" - -#include -#include "cru/common/Exception.h" -#include "cru/common/io/Stream.h" - -namespace cru::io { -MemoryStream::MemoryStream( - std::byte* buffer, Index size, bool read_only, - std::function release_func) - : Stream(true, true, !read_only), - buffer_(buffer), - size_(size), - position_(0), - release_func_(std::move(release_func)) { - if (!buffer) { - throw Exception(u"Buffer is nullptr"); - } - if (size <= 0) { - throw Exception(u"Size is 0 or negative."); - } -} - -MemoryStream::~MemoryStream() {} - -void MemoryStream::Close() { DoClose(); } - -Index MemoryStream::DoSeek(Index offset, SeekOrigin origin) { - switch (origin) { - case SeekOrigin::Current: - position_ += offset; - break; - case SeekOrigin::Begin: - position_ = offset; - break; - case SeekOrigin::End: - position_ = size_ + offset; - break; - } - return position_; -} - -Index MemoryStream::DoRead(std::byte* buffer, Index offset, Index size) { - if (position_ + size > size_) { - size = size_ - position_; - } - if (size <= 0) { - return 0; - } - std::memmove(buffer + offset, buffer_ + position_, size); - position_ += size; - return size; -} - -Index MemoryStream::DoWrite(const std::byte* buffer, Index offset, Index size) { - if (position_ + size > size_) { - size = size_ - position_; - } - if (size <= 0) { - return 0; - } - std::memmove(buffer_ + position_, buffer + offset, size); - position_ += size; - return size; -} - -void MemoryStream::DoClose() { - CRU_STREAM_BEGIN_CLOSE - release_func_(buffer_, size_); - buffer_ = nullptr; - release_func_ = {}; -} - -} // namespace cru::io diff --git a/src/common/io/OpenFileFlag.cpp b/src/common/io/OpenFileFlag.cpp deleted file mode 100644 index 6b9957fe..00000000 --- a/src/common/io/OpenFileFlag.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "cru/common/io/OpenFileFlag.h" - -namespace cru::io { -bool CheckOpenFileFlag(OpenFileFlag flags) { - auto has = [flags](OpenFileFlag flag) { return flags & flag; }; - - if ((has(OpenFileFlags::Append) || has(OpenFileFlags::Truncate) || - has(OpenFileFlags::Create)) && - !has(OpenFileFlags::Write)) { - return false; - } - - if (has(OpenFileFlags::Truncate) && has(OpenFileFlags::Append)) { - return false; - } - - return true; -} -} // namespace cru::io diff --git a/src/common/io/ProxyStream.cpp b/src/common/io/ProxyStream.cpp deleted file mode 100644 index c2e64056..00000000 --- a/src/common/io/ProxyStream.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "cru/common/io/ProxyStream.h" -#include "cru/common/io/Stream.h" - -namespace cru::io { -ProxyStream::ProxyStream(ProxyStreamHandlers handlers) - : Stream(static_cast(handlers.seek), static_cast(handlers.read), - static_cast(handlers.write)), - handlers_(std::move(handlers)) {} - -ProxyStream::~ProxyStream() { DoClose(); } - -Index ProxyStream::DoSeek(Index offset, SeekOrigin origin) { - return handlers_.seek(offset, origin); -} - -Index ProxyStream::DoRead(std::byte* buffer, Index offset, Index size) { - return handlers_.read(buffer, offset, size); -} - -Index ProxyStream::DoWrite(const std::byte* buffer, Index offset, Index size) { - return handlers_.write(buffer, offset, size); -} - -void ProxyStream::DoFlush() { - if (handlers_.flush) { - handlers_.flush(); - } -} - -void ProxyStream::DoClose() { - CRU_STREAM_BEGIN_CLOSE - if (handlers_.close) { - handlers_.close(); - } - handlers_ = {}; -} -} // namespace cru::io diff --git a/src/common/io/Resource.cpp b/src/common/io/Resource.cpp deleted file mode 100644 index b847e1cf..00000000 --- a/src/common/io/Resource.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "cru/common/io/Resource.h" -#include "cru/common/Exception.h" -#include "cru/common/log/Logger.h" - -#if defined(CRU_PLATFORM_OSX) -#include -#elif defined(CRU_PLATFORM_WINDOWS) -#include -#endif - -#include - -namespace cru::io { -std::filesystem::path GetResourceDir() { - constexpr auto kLogTag = u"GetResourceDir"; - -#if defined(CRU_PLATFORM_OSX) - CFBundleRef main_bundle = CFBundleGetMainBundle(); - CFURLRef bundle_url = CFBundleCopyBundleURL(main_bundle); - CFStringRef cf_string_ref = - CFURLCopyFileSystemPath(bundle_url, kCFURLPOSIXPathStyle); - std::filesystem::path bundle_path( - CFStringGetCStringPtr(cf_string_ref, kCFStringEncodingUTF8)); - - CFRelease(bundle_url); - CFRelease(cf_string_ref); - - return bundle_path / "Contents/Resources"; -#elif defined(CRU_PLATFORM_WINDOWS) - wchar_t buffer[MAX_PATH]; - DWORD size = ::GetModuleFileNameW(nullptr, buffer, MAX_PATH); - std::filesystem::path module_path(buffer, buffer + size); - auto p = module_path; - while (p.has_parent_path()) { - p = p.parent_path(); - auto resource_dir_path = p / "assets"; - if (std::filesystem::exists(resource_dir_path) && - std::filesystem::is_directory(resource_dir_path)) { - return resource_dir_path; - } - } - - throw Exception(u"Failed to find resource directory."); -#else - throw Exception(u"Not implemented."); -#endif -} -} // namespace cru::io diff --git a/src/common/io/Stream.cpp b/src/common/io/Stream.cpp deleted file mode 100644 index 6b0a513c..00000000 --- a/src/common/io/Stream.cpp +++ /dev/null @@ -1,199 +0,0 @@ -#include "cru/common/io/Stream.h" -#include "cru/common/Exception.h" -#include "cru/common/Format.h" - -#include - -namespace cru::io { -StreamOperationNotSupportedException::StreamOperationNotSupportedException( - String operation) - : operation_(std::move(operation)) { - SetMessage(Format(u"Stream operation {} not supported.", operation_)); -} - -void StreamOperationNotSupportedException::CheckSeek(bool seekable) { - if (!seekable) throw StreamOperationNotSupportedException(u"seek"); -} - -void StreamOperationNotSupportedException::CheckRead(bool readable) { - if (!readable) throw StreamOperationNotSupportedException(u"read"); -} - -void StreamOperationNotSupportedException::CheckWrite(bool writable) { - if (!writable) throw StreamOperationNotSupportedException(u"write"); -} - -StreamAlreadyClosedException::StreamAlreadyClosedException() - : Exception(u"Stream is already closed.") {} - -void StreamAlreadyClosedException::Check(bool closed) { - if (closed) throw StreamAlreadyClosedException(); -} - -Stream::Stream(SupportedOperations supported_operations) - : supported_operations_(std::move(supported_operations)), closed_(false) {} - -Stream::Stream(std::optional can_seek, std::optional can_read, - std::optional can_write) - : Stream(SupportedOperations{can_seek, can_read, can_write}) {} - -bool Stream::CanSeek() { - CheckClosed(); - return DoCanSeek(); -} - -Index Stream::Seek(Index offset, SeekOrigin origin) { - CheckClosed(); - StreamOperationNotSupportedException::CheckSeek(DoCanSeek()); - return DoSeek(offset, origin); -} - -Index Stream::Tell() { - CheckClosed(); - return DoTell(); -} - -void Stream::Rewind() { - CheckClosed(); - return DoRewind(); -} - -Index Stream::GetSize() { - CheckClosed(); - return DoGetSize(); -} - -bool Stream::CanRead() { - CheckClosed(); - return DoCanRead(); -} - -Index Stream::Read(std::byte* buffer, Index offset, Index size) { - CheckClosed(); - StreamOperationNotSupportedException::CheckRead(DoCanRead()); - return DoRead(buffer, offset, size); -} - -Index Stream::Read(std::byte* buffer, Index size) { - return Read(buffer, 0, size); -} - -Index Stream::Read(char* buffer, Index offset, Index size) { - return Read(reinterpret_cast(buffer), offset, size); -} - -Index Stream::Read(char* buffer, Index size) { - return Read(reinterpret_cast(buffer), 0, size); -} - -bool Stream::CanWrite() { - CheckClosed(); - return DoCanWrite(); -} - -Index Stream::Write(const std::byte* buffer, Index offset, Index size) { - CheckClosed(); - StreamOperationNotSupportedException::CheckWrite(DoCanWrite()); - return DoWrite(buffer, offset, size); -} - -Index Stream::Write(const std::byte* buffer, Index size) { - return Write(buffer, 0, size); -} - -Index Stream::Write(const char* buffer, Index offset, Index size) { - return Write(reinterpret_cast(buffer), offset, size); -} - -Index Stream::Write(const char* buffer, Index size) { - return Write(reinterpret_cast(buffer), size); -} - -void Stream::Flush() { - CheckClosed(); - DoFlush(); -} - -bool Stream::DoCanSeek() { - if (supported_operations_->can_seek) { - return *supported_operations_->can_seek; - } else { - throw Exception( - u"Can seek is neither set in supported_operations nor implemeted in " - u"virtual function."); - } -} - -bool Stream::DoCanRead() { - if (supported_operations_->can_read) { - return *supported_operations_->can_read; - } else { - throw Exception( - u"Can read is neither set in supported_operations nor implemeted in " - u"virtual function."); - } -} - -bool Stream::DoCanWrite() { - if (supported_operations_->can_write) { - return *supported_operations_->can_write; - } else { - throw Exception( - u"Can write is neither set in supported_operations nor implemeted in " - u"virtual function."); - } -} - -Index Stream::DoSeek(Index offset, SeekOrigin origin) { - throw Exception(u"Stream is seekable but DoSeek is not implemented."); -} - -Index Stream::DoTell() { - StreamOperationNotSupportedException::CheckSeek(DoCanSeek()); - return DoSeek(0, SeekOrigin::Current); -} - -void Stream::DoRewind() { - StreamOperationNotSupportedException::CheckSeek(DoCanSeek()); - DoSeek(0, SeekOrigin::Begin); -} - -Index Stream::DoGetSize() { - StreamOperationNotSupportedException::CheckSeek(DoCanSeek()); - Index current_position = DoTell(); - Seek(0, SeekOrigin::End); - Index size = DoTell(); - Seek(current_position, SeekOrigin::Begin); - return size; -} - -Index Stream::DoRead(std::byte* buffer, Index offset, Index size) { - throw Exception(u"Stream is readable but DoSeek is not implemented."); -} - -Index Stream::DoWrite(const std::byte* buffer, Index offset, Index size) { - throw Exception(u"Stream is writable but DoSeek is not implemented."); -} - -void Stream::DoFlush() {} - -Buffer Stream::ReadToEnd(Index grow_size) { - Buffer buffer(grow_size); - while (true) { - auto read = Read(buffer.GetUsedEndPtr(), buffer.GetBackFree()); - buffer.PushBackCount(read); - if (read == 0) { - break; - } - if (buffer.IsUsedReachEnd()) { - buffer.ResizeBuffer(buffer.GetBufferSize() + grow_size, true); - } - } - return buffer; -} - -String Stream::ReadToEndAsUtf8String() { - auto buffer = ReadToEnd(); - return String::FromUtf8(buffer); -} -} // namespace cru::io diff --git a/src/common/log/Logger.cpp b/src/common/log/Logger.cpp deleted file mode 100644 index 4b07ed87..00000000 --- a/src/common/log/Logger.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "cru/common/log/Logger.h" -#include "cru/common/log/StdioLogTarget.h" - -#include -#include - -#ifdef CRU_PLATFORM_WINDOWS -#include "cru/common/platform/win/DebugLogTarget.h" -#endif - -namespace cru::log { -Logger *Logger::GetInstance() { - static Logger logger; - - logger.AddLogTarget(std::make_unique()); - -#ifdef CRU_PLATFORM_WINDOWS - logger.AddLogTarget(std::make_unique()); -#endif - - return &logger; -} - -void Logger::AddLogTarget(std::unique_ptr target) { - std::lock_guard lock(target_list_mutex_); - target_list_.push_back(std::move(target)); -} - -void Logger::RemoveLogTarget(ILogTarget *target) { - std::lock_guard lock(target_list_mutex_); - target_list_.erase( - std::remove_if(target_list_.begin(), target_list_.end(), - [target](const auto &t) { return t.get() == target; }), - target_list_.end()); -} - -namespace { -String LogLevelToString(LogLevel level) { - switch (level) { - case LogLevel::Debug: - return u"DEBUG"; - case LogLevel::Info: - return u"INFO"; - case LogLevel::Warn: - return u"WARN"; - case LogLevel::Error: - return u"ERROR"; - default: - std::terminate(); - } -} - -String GetLogTime() { - auto time = std::time(nullptr); - auto calendar = std::localtime(&time); - return Format(u"{}:{}:{}", calendar->tm_hour, calendar->tm_min, - calendar->tm_sec); -} - -String MakeLogFinalMessage(const LogInfo &log_info) { - return Format(u"[{}] {} {}: {}\n", GetLogTime(), - LogLevelToString(log_info.level), log_info.tag, - log_info.message); -} -} // namespace - -Logger::Logger() - : log_thread_([this] { - while (true) { - auto log_info = log_queue_.Pull(); - std::lock_guard lock_guard{target_list_mutex_}; - for (const auto &target : target_list_) { - target->Write(log_info.level, MakeLogFinalMessage(log_info)); - } - } - }) {} - -Logger::~Logger() { log_thread_.detach(); } - -void Logger::Log(LogInfo log_info) { -#ifndef CRU_DEBUG - if (log_info.level == LogLevel::Debug) { - return; - } -#endif - log_queue_.Push(std::move(log_info)); -} -} // namespace cru::log diff --git a/src/common/log/StdioLogTarget.cpp b/src/common/log/StdioLogTarget.cpp deleted file mode 100644 index 7f99dbd1..00000000 --- a/src/common/log/StdioLogTarget.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "cru/common/log/StdioLogTarget.h" - -#include - -namespace cru::log { -StdioLogTarget::StdioLogTarget() {} - -StdioLogTarget::~StdioLogTarget() {} - -void StdioLogTarget::Write(log::LogLevel level, StringView s) { -#ifdef CRU_PLATFORM_WINDOWS - if (level == log::LogLevel::Error) { - std::wcerr.write(reinterpret_cast(s.data()), s.size()); - } else { - std::wcout.write(reinterpret_cast(s.data()), s.size()); - } -#else - std::string m = s.ToUtf8(); - - if (level == log::LogLevel::Error) { - std::cerr << m; - } else { - std::cout << m; - } -#endif -} -} // namespace cru::log diff --git a/src/common/platform/Exception.cpp b/src/common/platform/Exception.cpp deleted file mode 100644 index 1c5db390..00000000 --- a/src/common/platform/Exception.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "cru/common/platform/Exception.h" diff --git a/src/common/platform/osx/Convert.cpp b/src/common/platform/osx/Convert.cpp deleted file mode 100644 index 4792df1f..00000000 --- a/src/common/platform/osx/Convert.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "cru/common/platform/osx/Convert.h" - -namespace cru::platform::osx { -CFStringRef Convert(const String& string) { - return CFStringCreateWithBytes( - nullptr, reinterpret_cast(string.data()), - string.size() * sizeof(std::uint16_t), kCFStringEncodingUTF16, false); -} - -String Convert(CFStringRef string) { - auto length = CFStringGetLength(string); - - String result; - - for (int i = 0; i < length; i++) { - result.AppendCodePoint(CFStringGetCharacterAtIndex(string, i)); - } - - return result; -} - -CFRange Convert(const Range& range) { - return CFRangeMake(range.position, range.count); -} - -Range Convert(const CFRange& range) { - return Range(range.location, range.length); -} -} // namespace cru::platform::osx diff --git a/src/common/platform/osx/Exception.cpp b/src/common/platform/osx/Exception.cpp deleted file mode 100644 index e03faa4c..00000000 --- a/src/common/platform/osx/Exception.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "cru/common/platform//osx/Exception.h" diff --git a/src/common/platform/unix/PosixSpawnSubProcess.cpp b/src/common/platform/unix/PosixSpawnSubProcess.cpp deleted file mode 100644 index b5d68845..00000000 --- a/src/common/platform/unix/PosixSpawnSubProcess.cpp +++ /dev/null @@ -1,204 +0,0 @@ -#include "cru/common/platform/unix/PosixSpawnSubProcess.h" -#include "cru/common/Exception.h" -#include "cru/common/Format.h" -#include "cru/common/Guard.h" -#include "cru/common/String.h" -#include "cru/common/SubProcess.h" -#include "cru/common/log/Logger.h" - -#include -#include -#include -#include -#include -#include - -namespace cru::platform::unix { -PosixSpawnSubProcessImpl::PosixSpawnSubProcessImpl() - : pid_(0), - exit_code_(0), - stdin_pipe_(UnixPipe::Usage::Send, false), - stdout_pipe_(UnixPipe::Usage::Receive, false), - stderr_pipe_(UnixPipe::Usage::Receive, false) { - stdin_stream_ = std::make_unique( - stdin_pipe_.GetSelfFileDescriptor(), false, false, true, true); - stdout_stream_ = std::make_unique( - stdout_pipe_.GetSelfFileDescriptor(), false, true, false, true); - stderr_stream_ = std::make_unique( - stderr_pipe_.GetSelfFileDescriptor(), false, true, false, true); - - stdout_buffer_stream_ = - std::make_unique(stdout_stream_.get(), false); - stderr_buffer_stream_ = - std::make_unique(stderr_stream_.get(), false); -} - -PosixSpawnSubProcessImpl::~PosixSpawnSubProcessImpl() {} - -namespace { -char** CreateCstrArray(const std::vector& argv) { - std::vector utf8_argv; - for (const auto& arg : argv) { - utf8_argv.push_back(arg.ToUtf8Buffer()); - } - char** result = new char*[utf8_argv.size() + 1]; - for (int i = 0; i < utf8_argv.size(); i++) { - result[i] = reinterpret_cast(utf8_argv[i].Detach()); - } - result[utf8_argv.size()] = nullptr; - return result; -} - -char** CreateCstrArray(const std::unordered_map& envp) { - std::vector str_array; - for (auto& [key, value] : envp) { - str_array.push_back(cru::Format(u"{}={}", key, value)); - } - return CreateCstrArray(str_array); -} - -void DestroyCstrArray(char** argv) { - int index = 0; - char* arg = argv[index]; - while (arg) { - delete[] arg; - index++; - arg = argv[index]; - } - delete[] argv; -} -} // namespace - -void PosixSpawnSubProcessImpl::PlatformCreateProcess( - const SubProcessStartInfo& start_info) { - int error; - auto check_error = [&error](String message) { - if (error == 0) return; - std::unique_ptr inner(new ErrnoException({}, error)); - throw SubProcessFailedToStartException(std::move(message), - std::move(inner)); - }; - - posix_spawn_file_actions_t file_actions; - error = posix_spawn_file_actions_init(&file_actions); - check_error(u"Failed to call posix_spawn_file_actions_init."); - Guard file_actions_guard( - [&file_actions] { posix_spawn_file_actions_destroy(&file_actions); }); - - // dup2 stdin/stdout/stderr - error = posix_spawn_file_actions_adddup2( - &file_actions, stdin_pipe_.GetOtherFileDescriptor(), STDIN_FILENO); - check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stdin."); - error = posix_spawn_file_actions_adddup2( - &file_actions, stdout_pipe_.GetOtherFileDescriptor(), STDOUT_FILENO); - check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stdout."); - error = posix_spawn_file_actions_adddup2( - &file_actions, stderr_pipe_.GetOtherFileDescriptor(), STDERR_FILENO); - check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stderr."); - - error = posix_spawn_file_actions_addclose( - &file_actions, stdin_pipe_.GetOtherFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on self fd of stdin."); - error = posix_spawn_file_actions_addclose( - &file_actions, stdout_pipe_.GetOtherFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on self fd stdout."); - error = posix_spawn_file_actions_addclose( - &file_actions, stderr_pipe_.GetOtherFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on self fd stderr."); - - error = posix_spawn_file_actions_addclose( - &file_actions, stdin_pipe_.GetSelfFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on parent fd of " - u"stdin."); - error = posix_spawn_file_actions_addclose( - &file_actions, stdout_pipe_.GetSelfFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on parent fd of " - u"stdout."); - error = posix_spawn_file_actions_addclose( - &file_actions, stderr_pipe_.GetSelfFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on parent fd of " - u"stderr."); - - posix_spawnattr_t attr; - error = posix_spawnattr_init(&attr); - check_error(u"Failed to call posix_spawnattr_init."); - Guard attr_guard([&attr] { posix_spawnattr_destroy(&attr); }); - -#ifdef CRU_PLATFORM_OSX - error = posix_spawnattr_setflags(&attr, POSIX_SPAWN_CLOEXEC_DEFAULT); - check_error(u"Failed to set flag POSIX_SPAWN_CLOEXEC_DEFAULT (osx)."); -#endif - - auto exe = start_info.program.ToUtf8(); - std::vector arguments{start_info.program}; - arguments.insert(arguments.cend(), start_info.arguments.cbegin(), - start_info.arguments.cend()); - - auto argv = CreateCstrArray(arguments); - Guard argv_guard([argv] { DestroyCstrArray(argv); }); - - auto envp = CreateCstrArray(start_info.environments); - Guard envp_guard([envp] { DestroyCstrArray(envp); }); - - error = posix_spawnp(&pid_, exe.c_str(), &file_actions, &attr, argv, envp); - check_error(u"Failed to call posix_spawnp."); - - error = ::close(stdin_pipe_.GetOtherFileDescriptor()); - check_error(u"Failed to close child stdin."); - error = ::close(stdout_pipe_.GetOtherFileDescriptor()); - check_error(u"Failed to close child stdout."); - error = ::close(stderr_pipe_.GetOtherFileDescriptor()); - check_error(u"Failed to close child stderr."); -} - -SubProcessExitResult PosixSpawnSubProcessImpl::PlatformWaitForProcess() { - int wstatus; - - while (waitpid(pid_, &wstatus, 0) == -1) { - if (errno == EINTR) { - CRU_LOG_INFO(u"Waitpid is interrupted by a signal. Call it again."); - continue; - } - - std::unique_ptr inner(new ErrnoException({}, errno)); - - throw SubProcessInternalException( - u"Failed to call waitpid on a subprocess.", std::move(inner)); - } - - if (WIFEXITED(wstatus)) { - return SubProcessExitResult::Normal(WEXITSTATUS(wstatus)); - } else if (WIFEXITED(wstatus)) { - return SubProcessExitResult::Signal(WTERMSIG(wstatus), WCOREDUMP(wstatus)); - } else { - return SubProcessExitResult::Unknown(); - } -} - -void PosixSpawnSubProcessImpl::PlatformKillProcess() { - int error = kill(pid_, SIGKILL); - if (error != 0) { - std::unique_ptr inner(new ErrnoException({}, errno)); - throw SubProcessInternalException(u"Failed to call kill on a subprocess.", - std::move(inner)); - } -} - -io::Stream* PosixSpawnSubProcessImpl::GetStdinStream() { - return stdin_stream_.get(); -} - -io::Stream* PosixSpawnSubProcessImpl::GetStdoutStream() { - return stdout_buffer_stream_.get(); -} - -io::Stream* PosixSpawnSubProcessImpl::GetStderrStream() { - return stderr_buffer_stream_.get(); -} -} // namespace cru::platform::unix diff --git a/src/common/platform/unix/UnixFileStream.cpp b/src/common/platform/unix/UnixFileStream.cpp deleted file mode 100644 index 804e24f0..00000000 --- a/src/common/platform/unix/UnixFileStream.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "cru/common/platform/unix/UnixFileStream.h" -#include "cru/common/Exception.h" -#include "cru/common/Format.h" -#include "cru/common/io/Stream.h" -#include "cru/common/log/Logger.h" - -#include -#include -#include -#include - -namespace cru::platform::unix { -using namespace cru::io; - -namespace { -bool OflagCanSeek([[maybe_unused]] int oflag) { - // Treat every file seekable. - return true; -} - -bool OflagCanRead(int oflag) { - // There is a problem: O_RDONLY is 0. So we must test it specially. - // If it is not write-only. Then it can read. - return !(oflag & O_WRONLY); -} - -bool OflagCanWrite(int oflag) { return oflag & O_WRONLY || oflag & O_RDWR; } - -int MapSeekOrigin(Stream::SeekOrigin origin) { - switch (origin) { - case Stream::SeekOrigin::Begin: - return SEEK_SET; - case Stream::SeekOrigin::Current: - return SEEK_CUR; - case Stream::SeekOrigin::End: - return SEEK_END; - default: - throw Exception(u"Invalid seek origin."); - } -} -} // namespace - -UnixFileStream::UnixFileStream(const char *path, int oflag, mode_t mode) { - file_descriptor_ = ::open(path, oflag, mode); - if (file_descriptor_ == -1) { - throw ErrnoException( - Format(u"Failed to open file {} with oflag {}, mode {}.", - String::FromUtf8(path), oflag, mode)); - } - - SetSupportedOperations( - {OflagCanSeek(oflag), OflagCanRead(oflag), OflagCanWrite(oflag)}); - - auto_close_ = true; -} - -UnixFileStream::UnixFileStream(int fd, bool can_seek, bool can_read, - bool can_write, bool auto_close) - : Stream(can_seek, can_read, can_write) { - file_descriptor_ = fd; - auto_close_ = auto_close; -} - -UnixFileStream::~UnixFileStream() { - if (auto_close_ && file_descriptor_ >= 0) { - if (::close(file_descriptor_) == -1) { - // We are in destructor, so we can not throw. - CRU_LOG_WARN(u"Failed to close file descriptor {}, errno {}.", - file_descriptor_, errno); - } - } -} - -Index UnixFileStream::DoSeek(Index offset, SeekOrigin origin) { - off_t result = ::lseek(file_descriptor_, offset, MapSeekOrigin(origin)); - if (result == -1) { - throw ErrnoException(u"Failed to seek file."); - } - return result; -} - -Index UnixFileStream::DoRead(std::byte *buffer, Index offset, Index size) { - auto result = ::read(file_descriptor_, buffer + offset, size); - if (result == -1) { - throw ErrnoException(u"Failed to read file."); - } - return result; -} - -Index UnixFileStream::DoWrite(const std::byte *buffer, Index offset, - Index size) { - auto result = ::write(file_descriptor_, buffer + offset, size); - if (result == -1) { - throw ErrnoException(u"Failed to write file."); - } - return result; -} - -void UnixFileStream::DoClose() { - CRU_STREAM_BEGIN_CLOSE - if (auto_close_ && ::close(file_descriptor_) == -1) { - throw ErrnoException(u"Failed to close file."); - } - file_descriptor_ = -1; -} -} // namespace cru::platform::unix diff --git a/src/common/platform/unix/UnixPipe.cpp b/src/common/platform/unix/UnixPipe.cpp deleted file mode 100644 index f30c599e..00000000 --- a/src/common/platform/unix/UnixPipe.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "cru/common/platform/unix/UnixPipe.h" -#include "cru/common/Exception.h" -#include "cru/common/log/Logger.h" - -#include -#include -#include - -namespace cru::platform::unix { -UnixPipe::UnixPipe(Usage usage, bool auto_close, UnixPipeFlag flags) - : usage_(usage), auto_close_(auto_close), flags_(flags) { - int fds[2]; - if (pipe(fds) != 0) { - throw ErrnoException(u"Failed to create unix pipe."); - } - - if (flags & UnixPipeFlags::NonBlock) { - fcntl(fds[0], F_SETFL, O_NONBLOCK); - fcntl(fds[1], F_SETFL, O_NONBLOCK); - } - - read_fd_ = fds[0]; - write_fd_ = fds[1]; -} - -int UnixPipe::GetSelfFileDescriptor() { - if (usage_ == Usage::Send) { - return write_fd_; - } else { - return read_fd_; - } -} - -int UnixPipe::GetOtherFileDescriptor() { - if (usage_ == Usage::Send) { - return read_fd_; - } else { - return write_fd_; - } -} - -UnixPipe::~UnixPipe() { - if (auto_close_) { - auto self_fd = GetSelfFileDescriptor(); - if (::close(self_fd) != 0) { - CRU_LOG_ERROR(u"Failed to close unix pipe file descriptor {}, errno {}.", - self_fd, errno); - } - } -} -} // namespace cru::platform::unix diff --git a/src/common/platform/web/WebException.cpp b/src/common/platform/web/WebException.cpp deleted file mode 100644 index 30f9d1f0..00000000 --- a/src/common/platform/web/WebException.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "cru/common/platform/web/WebException.h" diff --git a/src/common/platform/win/BridgeComStream.cpp b/src/common/platform/win/BridgeComStream.cpp deleted file mode 100644 index 4c83fd45..00000000 --- a/src/common/platform/win/BridgeComStream.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "BrigdeComStream.h" -#include "cru/common/io/Stream.h" - -namespace cru::platform::win { -BridgeComStream::BridgeComStream(io::Stream *stream) - : stream_(stream), ref_count_(1) {} - -BridgeComStream::~BridgeComStream() {} - -ULONG BridgeComStream::AddRef() { return ++ref_count_; } - -ULONG BridgeComStream::Release() { - --ref_count_; - - if (ref_count_ == 0) { - delete this; - return 0; - } - - return ref_count_; -} - -HRESULT BridgeComStream::QueryInterface(const IID &riid, void **ppvObject) { - if (riid == IID_IStream) { - *ppvObject = static_cast(this); - AddRef(); - return S_OK; - } else if (riid == IID_ISequentialStream) { - *ppvObject = static_cast(this); - AddRef(); - return S_OK; - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast(this); - AddRef(); - return S_OK; - } else { - return E_NOINTERFACE; - } -} - -HRESULT BridgeComStream::Read(void *pv, ULONG cb, ULONG *pcbRead) { - *pcbRead = stream_->Read(static_cast(pv), cb); - return S_OK; -} - -HRESULT BridgeComStream::Write(const void *pv, ULONG cb, ULONG *pcbWritten) { - *pcbWritten = stream_->Write(static_cast(pv), cb); - return S_OK; -} - -HRESULT BridgeComStream::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, - ULARGE_INTEGER *plibNewPosition) { - io::Stream::SeekOrigin so; - - switch (dwOrigin) { - case STREAM_SEEK_SET: - so = io::Stream::SeekOrigin::Begin; - break; - case STREAM_SEEK_CUR: - so = io::Stream::SeekOrigin::Current; - break; - case STREAM_SEEK_END: - so = io::Stream::SeekOrigin::End; - break; - default: - return STG_E_INVALIDFUNCTION; - }; - - plibNewPosition->QuadPart = stream_->Seek(dlibMove.QuadPart, so); - return S_OK; -} - -HRESULT BridgeComStream::SetSize(ULARGE_INTEGER libNewSize) { - return E_NOTIMPL; -} - -HRESULT BridgeComStream::CopyTo(IStream *pstm, ULARGE_INTEGER cb, - ULARGE_INTEGER *pcbRead, - ULARGE_INTEGER *pcbWritten) { - return E_NOTIMPL; -} - -HRESULT BridgeComStream::Commit(DWORD grfCommitFlags) { return S_OK; } - -HRESULT BridgeComStream::Revert() { return S_OK; } - -HRESULT BridgeComStream::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, - DWORD dwLockType) { - return S_OK; -} - -HRESULT BridgeComStream::UnlockRegion(ULARGE_INTEGER libOffset, - ULARGE_INTEGER cb, DWORD dwLockType) { - return S_OK; -} - -HRESULT BridgeComStream::Stat(STATSTG *pstatstg, DWORD grfStatFlag) { - return E_NOTIMPL; -} - -HRESULT BridgeComStream::Clone(IStream **ppstm) { - *ppstm = new BridgeComStream(stream_); - return S_OK; -} - -} // namespace cru::platform::win diff --git a/src/common/platform/win/BrigdeComStream.h b/src/common/platform/win/BrigdeComStream.h deleted file mode 100644 index 7c8a79d1..00000000 --- a/src/common/platform/win/BrigdeComStream.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -#include "cru/common/platform/win/WinPreConfig.h" - -#include "cru/common/io/Stream.h" - -#include - -namespace cru::platform::win { -class BridgeComStream : public IStream { - public: - explicit BridgeComStream(io::Stream* stream); - - CRU_DELETE_COPY(BridgeComStream) - CRU_DELETE_MOVE(BridgeComStream) - - ~BridgeComStream(); - - public: - ULONG AddRef() override; - ULONG Release() override; - HRESULT QueryInterface(REFIID riid, void** ppvObject) override; - - HRESULT Read(void* pv, ULONG cb, ULONG* pcbRead) override; - HRESULT Write(const void* pv, ULONG cb, ULONG* pcbWritten) override; - HRESULT Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, - ULARGE_INTEGER* plibNewPosition) override; - HRESULT SetSize(ULARGE_INTEGER libNewSize) override; - HRESULT CopyTo(IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, - ULARGE_INTEGER* pcbWritten) override; - HRESULT Commit(DWORD grfCommitFlags) override; - HRESULT Revert() override; - HRESULT LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, - DWORD dwLockType) override; - HRESULT UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, - DWORD dwLockType) override; - HRESULT Stat(STATSTG* pstatstg, DWORD grfStatFlag) override; - HRESULT Clone(IStream** ppstm) override; - - private: - io::Stream* stream_; - ULONG ref_count_; -}; -} // namespace cru::platform::win diff --git a/src/common/platform/win/ComAutoInit.cpp b/src/common/platform/win/ComAutoInit.cpp deleted file mode 100644 index 55a53a8d..00000000 --- a/src/common/platform/win/ComAutoInit.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "cru/common/platform/win/ComAutoInit.h" -#include "cru/common/platform/win/Exception.h" - -#include - -namespace cru::platform::win { -ComAutoInit::ComAutoInit() { - const auto hresult = ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); - if (FAILED(hresult)) { - throw HResultError(hresult, "Failed to call CoInitializeEx."); - } -} - -ComAutoInit::~ComAutoInit() { ::CoUninitialize(); } -} // namespace cru::platform::win diff --git a/src/common/platform/win/DebugLogTarget.cpp b/src/common/platform/win/DebugLogTarget.cpp deleted file mode 100644 index 92d26449..00000000 --- a/src/common/platform/win/DebugLogTarget.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "cru/common/platform/win/DebugLogTarget.h" - -namespace cru::platform::win { -void WinDebugLogTarget::Write(::cru::log::LogLevel level, StringView s) { - CRU_UNUSED(level) - - String m = s.ToString(); - ::OutputDebugStringW(reinterpret_cast(m.c_str())); -} -} // namespace cru::platform::win diff --git a/src/common/platform/win/Exception.cpp b/src/common/platform/win/Exception.cpp deleted file mode 100644 index a20e8a31..00000000 --- a/src/common/platform/win/Exception.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "cru/common/platform/win/Exception.h" -#include "cru/common/Format.h" - -#include - -namespace cru::platform::win { - -inline String HResultMakeMessage(HRESULT h_result, - std::optional message) { - if (message.has_value()) - return Format(u"HRESULT: {}. Message: {}", h_result, message->WinCStr()); - else - return Format(u"HRESULT: {}.", h_result); -} - -HResultError::HResultError(HRESULT h_result) - : PlatformException(HResultMakeMessage(h_result, std::nullopt)), - h_result_(h_result) {} - -HResultError::HResultError(HRESULT h_result, - std::string_view additional_message) - : PlatformException(HResultMakeMessage( - h_result, String::FromUtf8(additional_message.data(), - additional_message.size()))), - h_result_(h_result) {} - -inline String Win32MakeMessage(DWORD error_code, String message) { - return Format(u"Last error code: {}.\nMessage: {}\n", error_code, - message.WinCStr()); -} - -Win32Error::Win32Error(String message) - : Win32Error(::GetLastError(), message) {} - -Win32Error::Win32Error(DWORD error_code, String message) - : PlatformException(Win32MakeMessage(error_code, message)), - error_code_(error_code) {} -} // namespace cru::platform::win diff --git a/src/common/platform/win/StreamConvert.cpp b/src/common/platform/win/StreamConvert.cpp deleted file mode 100644 index d547caa5..00000000 --- a/src/common/platform/win/StreamConvert.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "cru/common/platform/win/StreamConvert.h" -#include "BrigdeComStream.h" -#include "Win32FileStreamPrivate.h" -#include "cru/common/Exception.h" -#include "cru/common/io/MemoryStream.h" -#include "cru/common/io/OpenFileFlag.h" -#include "cru/common/platform/win/ComAutoInit.h" -#include "cru/common/platform/win/Exception.h" -#include "cru/common/platform/win/Win32FileStream.h" - -#include -#include - -namespace cru::platform::win { -IStream* ConvertStreamToComStream(io::Stream* stream) { - static ComAutoInit com_auto_init; - - if (auto memory_stream = dynamic_cast(stream)) { - return SHCreateMemStream( - reinterpret_cast(memory_stream->GetBuffer()), - memory_stream->GetSize()); - } else if (auto file_stream = dynamic_cast(stream)) { - return file_stream->GetPrivate_()->stream_; - } else { - return new BridgeComStream(stream); - } -} -} // namespace cru::platform::win diff --git a/src/common/platform/win/Win32FileStream.cpp b/src/common/platform/win/Win32FileStream.cpp deleted file mode 100644 index a118dc02..00000000 --- a/src/common/platform/win/Win32FileStream.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "cru/common/platform/win/Win32FileStream.h" - -#include "Win32FileStreamPrivate.h" -#include "cru/common/io/OpenFileFlag.h" -#include "cru/common/platform/win/Exception.h" - -#include -#include -#include -#include -#include - -namespace cru::platform::win { -using namespace cru::io; - -Win32FileStream::Win32FileStream(String path, OpenFileFlag flags) - : path_(std::move(path)), - flags_(flags), - p_(new details::Win32FileStreamPrivate()) { - DWORD grfMode = STGM_SHARE_DENY_NONE; - if (flags & io::OpenFileFlags::Read) { - if (flags & io::OpenFileFlags::Write) { - grfMode |= STGM_READWRITE; - } else { - grfMode |= STGM_READ; - } - } else { - if (flags & io::OpenFileFlags::Write) { - grfMode |= STGM_WRITE; - } else { - throw Exception(u"Stream must be readable or writable."); - } - } - - if (flags & io::OpenFileFlags::Truncate) { - grfMode |= STGM_CREATE; - } - - IStream* stream; - - ThrowIfFailed(SHCreateStreamOnFileEx( - path_.WinCStr(), grfMode, FILE_ATTRIBUTE_NORMAL, - flags & io::OpenFileFlags::Create ? TRUE : FALSE, NULL, &stream)); - - p_->stream_ = stream; -} - -Win32FileStream::~Win32FileStream() { - Close(); - delete p_; -} - -bool Win32FileStream::CanSeek() { return true; } - -Index Win32FileStream::Seek(Index offset, SeekOrigin origin) { - CheckClosed(); - - DWORD dwOrigin = 0; - - if (origin == SeekOrigin::Current) { - dwOrigin = STREAM_SEEK_CUR; - } else if (origin == SeekOrigin::End) { - dwOrigin = STREAM_SEEK_END; - } else { - dwOrigin = STREAM_SEEK_SET; - } - - LARGE_INTEGER n_offset; - n_offset.QuadPart = offset; - ULARGE_INTEGER n_new_offset; - - ThrowIfFailed(p_->stream_->Seek(n_offset, dwOrigin, &n_new_offset)); - - return n_new_offset.QuadPart; -} - -bool Win32FileStream::CanRead() { return true; } - -Index Win32FileStream::Read(std::byte* buffer, Index offset, Index size) { - if (size < 0) { - throw Exception(u"Size must be greater than 0."); - } - - CheckClosed(); - - ULONG n_read; - ThrowIfFailed(p_->stream_->Read(buffer + offset, size, &n_read)); - return n_read; -} - -bool Win32FileStream::CanWrite() { return true; } - -Index Win32FileStream::Write(const std::byte* buffer, Index offset, - Index size) { - if (size < 0) { - throw Exception(u"Size must be greater than 0."); - } - - CheckClosed(); - - ULONG n_written; - ThrowIfFailed(p_->stream_->Write(buffer + offset, size, &n_written)); - - return n_written; -} - -void Win32FileStream::Close() { - if (closed_) return; - - if (p_->stream_) { - p_->stream_->Release(); - p_->stream_ = nullptr; - } - - closed_ = true; -} - -void Win32FileStream::CheckClosed() { - if (closed_) throw Exception(u"Stream is closed."); -} - -} // namespace cru::platform::win diff --git a/src/common/platform/win/Win32FileStreamPrivate.h b/src/common/platform/win/Win32FileStreamPrivate.h deleted file mode 100644 index 24492f8d..00000000 --- a/src/common/platform/win/Win32FileStreamPrivate.h +++ /dev/null @@ -1,13 +0,0 @@ -#include "cru/common/platform/win/WinPreConfig.h" - -#include - -namespace cru::platform::win { - -namespace details { -struct Win32FileStreamPrivate { - IStream* stream_ = nullptr; -}; -} // namespace details - -} // namespace cru::platform::win diff --git a/src/parse/Grammar.cpp b/src/parse/Grammar.cpp index 17978adc..12617de3 100644 --- a/src/parse/Grammar.cpp +++ b/src/parse/Grammar.cpp @@ -1,7 +1,7 @@ #include "cru/parse/Grammar.h" -#include "cru/common/String.h" +#include "cru/base/String.h" #include "cru/parse/Symbol.h" -#include "cru/common/Format.h" +#include "cru/base/Format.h" #include #include diff --git a/src/platform/Exception.cpp b/src/platform/Exception.cpp index 7aef3b7f..948345e0 100644 --- a/src/platform/Exception.cpp +++ b/src/platform/Exception.cpp @@ -1,5 +1,5 @@ #include "cru/platform/Exception.h" -#include "cru/common/Format.h" +#include "cru/base/Format.h" #include diff --git a/src/platform/graphics/Geometry.cpp b/src/platform/graphics/Geometry.cpp index 0c98b456..25dfba6e 100644 --- a/src/platform/graphics/Geometry.cpp +++ b/src/platform/graphics/Geometry.cpp @@ -1,6 +1,6 @@ #include "cru/platform/graphics/Geometry.h" -#include "cru/common/Exception.h" +#include "cru/base/Exception.h" #include "cru/platform/Exception.h" #include "cru/platform/graphics/Factory.h" diff --git a/src/platform/graphics/cairo/CairoImageFactory.cpp b/src/platform/graphics/cairo/CairoImageFactory.cpp index 99994226..912226d9 100644 --- a/src/platform/graphics/cairo/CairoImageFactory.cpp +++ b/src/platform/graphics/cairo/CairoImageFactory.cpp @@ -1,5 +1,5 @@ #include "cru/platform/graphics/cairo/CairoImageFactory.h" -#include "cru/common/Exception.h" +#include "cru/base/Exception.h" #include "cru/platform/Check.h" #include "cru/platform/graphics/cairo/CairoImage.h" #include "cru/platform/graphics/cairo/CairoResource.h" diff --git a/src/platform/graphics/cairo/CairoPainter.cpp b/src/platform/graphics/cairo/CairoPainter.cpp index 00c8187c..b9ab50c4 100644 --- a/src/platform/graphics/cairo/CairoPainter.cpp +++ b/src/platform/graphics/cairo/CairoPainter.cpp @@ -1,5 +1,5 @@ #include "cru/platform/graphics/cairo/CairoPainter.h" -#include "cru/common/Exception.h" +#include "cru/base/Exception.h" #include "cru/platform/Check.h" #include "cru/platform/Exception.h" #include "cru/platform/graphics/cairo/Base.h" diff --git a/src/platform/graphics/cairo/PangoTextLayout.cpp b/src/platform/graphics/cairo/PangoTextLayout.cpp index 25e84707..1033ce9e 100644 --- a/src/platform/graphics/cairo/PangoTextLayout.cpp +++ b/src/platform/graphics/cairo/PangoTextLayout.cpp @@ -1,5 +1,5 @@ #include "cru/platform/graphics/cairo/PangoTextLayout.h" -#include "cru/common/StringUtil.h" +#include "cru/base/StringUtil.h" #include "cru/platform/Check.h" #include "cru/platform/GraphicsBase.h" #include "cru/platform/graphics/Base.h" diff --git a/src/platform/graphics/direct2d/Factory.cpp b/src/platform/graphics/direct2d/Factory.cpp index c35c53cf..cf65c2a5 100644 --- a/src/platform/graphics/direct2d/Factory.cpp +++ b/src/platform/graphics/direct2d/Factory.cpp @@ -1,6 +1,6 @@ #include "cru/platform/graphics/direct2d/Factory.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/graphics/direct2d/Brush.h" #include "cru/platform/graphics/direct2d/Exception.h" #include "cru/platform/graphics/direct2d/Font.h" diff --git a/src/platform/graphics/direct2d/Font.cpp b/src/platform/graphics/direct2d/Font.cpp index afbc9049..b1c03751 100644 --- a/src/platform/graphics/direct2d/Font.cpp +++ b/src/platform/graphics/direct2d/Font.cpp @@ -1,6 +1,6 @@ #include "cru/platform/graphics/direct2d/Font.h" -#include "cru/common/Format.h" +#include "cru/base/Format.h" #include "cru/platform/graphics/direct2d/Exception.h" #include "cru/platform/graphics/direct2d/Factory.h" diff --git a/src/platform/graphics/direct2d/Geometry.cpp b/src/platform/graphics/direct2d/Geometry.cpp index b84a901e..a2377400 100644 --- a/src/platform/graphics/direct2d/Geometry.cpp +++ b/src/platform/graphics/direct2d/Geometry.cpp @@ -1,6 +1,6 @@ #include "cru/platform/graphics/direct2d/Geometry.h" -#include "cru/common/platform/win/Exception.h" +#include "cru/base/platform/win/Exception.h" #include "cru/platform/graphics/direct2d/ConvertUtil.h" #include "cru/platform/graphics/direct2d/Exception.h" #include "cru/platform/graphics/direct2d/Factory.h" diff --git a/src/platform/graphics/direct2d/Image.cpp b/src/platform/graphics/direct2d/Image.cpp index 78cccd6a..2f60b373 100644 --- a/src/platform/graphics/direct2d/Image.cpp +++ b/src/platform/graphics/direct2d/Image.cpp @@ -1,6 +1,6 @@ #include "cru/platform/graphics/direct2d/Image.h" #include -#include "cru/common/platform/win/Exception.h" +#include "cru/base/platform/win/Exception.h" #include "cru/platform/graphics/direct2d/ConvertUtil.h" #include "cru/platform/graphics/direct2d/Exception.h" #include "cru/platform/graphics/direct2d/Factory.h" diff --git a/src/platform/graphics/direct2d/ImageFactory.cpp b/src/platform/graphics/direct2d/ImageFactory.cpp index 7cbc0ad4..113f70c8 100644 --- a/src/platform/graphics/direct2d/ImageFactory.cpp +++ b/src/platform/graphics/direct2d/ImageFactory.cpp @@ -1,6 +1,6 @@ #include "cru/platform/graphics/direct2d/ImageFactory.h" -#include "cru/common/platform/win/Exception.h" -#include "cru/common/platform/win/StreamConvert.h" +#include "cru/base/platform/win/Exception.h" +#include "cru/base/platform/win/StreamConvert.h" #include "cru/platform/Check.h" #include "cru/platform/graphics/direct2d/Exception.h" #include "cru/platform/graphics/direct2d/Factory.h" diff --git a/src/platform/graphics/direct2d/Painter.cpp b/src/platform/graphics/direct2d/Painter.cpp index dea3ba03..95b0bb4e 100644 --- a/src/platform/graphics/direct2d/Painter.cpp +++ b/src/platform/graphics/direct2d/Painter.cpp @@ -1,6 +1,6 @@ #include "cru/platform/graphics/direct2d/Painter.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/Check.h" #include "cru/platform/graphics/direct2d/Brush.h" #include "cru/platform/graphics/direct2d/ConvertUtil.h" diff --git a/src/platform/graphics/direct2d/TextLayout.cpp b/src/platform/graphics/direct2d/TextLayout.cpp index 5bc392de..06bbcaa6 100644 --- a/src/platform/graphics/direct2d/TextLayout.cpp +++ b/src/platform/graphics/direct2d/TextLayout.cpp @@ -1,7 +1,7 @@ #include "cru/platform/graphics/direct2d/TextLayout.h" #include -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/Check.h" #include "cru/platform/graphics/direct2d/Exception.h" #include "cru/platform/graphics/direct2d/Factory.h" diff --git a/src/platform/graphics/quartz/Brush.cpp b/src/platform/graphics/quartz/Brush.cpp index 2aa31bd8..ea740eb3 100644 --- a/src/platform/graphics/quartz/Brush.cpp +++ b/src/platform/graphics/quartz/Brush.cpp @@ -1,6 +1,6 @@ #include "cru/platform/graphics/quartz/Brush.h" -#include "cru/common/String.h" -#include "cru/common/Format.h" +#include "cru/base/String.h" +#include "cru/base/Format.h" namespace cru::platform::graphics::quartz { QuartzSolidColorBrush::QuartzSolidColorBrush(IGraphicsFactory* graphics_factory, diff --git a/src/platform/graphics/quartz/Image.cpp b/src/platform/graphics/quartz/Image.cpp index 3fa40937..966ce6be 100644 --- a/src/platform/graphics/quartz/Image.cpp +++ b/src/platform/graphics/quartz/Image.cpp @@ -1,5 +1,5 @@ #include "cru/platform/graphics/quartz/Image.h" -#include "cru/common/Exception.h" +#include "cru/base/Exception.h" #include "cru/platform/graphics/quartz/Convert.h" #include "cru/platform/graphics/quartz/Painter.h" diff --git a/src/platform/graphics/quartz/ImageFactory.cpp b/src/platform/graphics/quartz/ImageFactory.cpp index a48b4b86..0557afa9 100644 --- a/src/platform/graphics/quartz/ImageFactory.cpp +++ b/src/platform/graphics/quartz/ImageFactory.cpp @@ -1,6 +1,6 @@ #include "cru/platform/graphics/quartz/ImageFactory.h" -#include "cru/common/Exception.h" -#include "cru/common/platform/osx/Convert.h" +#include "cru/base/Exception.h" +#include "cru/base/platform/osx/Convert.h" #include "cru/platform/graphics/quartz/Convert.h" #include "cru/platform/graphics/quartz/Image.h" #include "cru/platform/Check.h" diff --git a/src/platform/graphics/quartz/TextLayout.cpp b/src/platform/graphics/quartz/TextLayout.cpp index 24fd71ef..9e18ac85 100644 --- a/src/platform/graphics/quartz/TextLayout.cpp +++ b/src/platform/graphics/quartz/TextLayout.cpp @@ -1,7 +1,7 @@ #include "cru/platform/graphics/quartz/TextLayout.h" -#include "cru/common/Base.h" -#include "cru/common/Format.h" -#include "cru/common/StringUtil.h" +#include "cru/base/Base.h" +#include "cru/base/Format.h" +#include "cru/base/StringUtil.h" #include "cru/platform/osx/Convert.h" #include "cru/platform/graphics/quartz/Convert.h" #include "cru/platform/graphics/quartz/Resource.h" diff --git a/src/platform/gui/osx/Clipboard.mm b/src/platform/gui/osx/Clipboard.mm index 068771c8..5d498d0e 100644 --- a/src/platform/gui/osx/Clipboard.mm +++ b/src/platform/gui/osx/Clipboard.mm @@ -1,7 +1,7 @@ #include "cru/platform/gui/osx/Clipboard.h" #include "ClipboardPrivate.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/osx/Convert.h" #include diff --git a/src/platform/gui/osx/ClipboardPrivate.h b/src/platform/gui/osx/ClipboardPrivate.h index e00c59dc..766026b6 100644 --- a/src/platform/gui/osx/ClipboardPrivate.h +++ b/src/platform/gui/osx/ClipboardPrivate.h @@ -1,5 +1,5 @@ #pragma once -#include "cru/common/Base.h" +#include "cru/base/Base.h" #include "cru/platform/gui/osx/Clipboard.h" #include diff --git a/src/platform/gui/osx/InputMethod.mm b/src/platform/gui/osx/InputMethod.mm index 50ff80de..af2d1ec2 100644 --- a/src/platform/gui/osx/InputMethod.mm +++ b/src/platform/gui/osx/InputMethod.mm @@ -3,7 +3,7 @@ #import #include "InputMethodPrivate.h" #include "WindowPrivate.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/osx/Convert.h" #include "cru/platform/gui/osx/Window.h" diff --git a/src/platform/gui/osx/Menu.mm b/src/platform/gui/osx/Menu.mm index 568a5208..e74ec23b 100644 --- a/src/platform/gui/osx/Menu.mm +++ b/src/platform/gui/osx/Menu.mm @@ -2,7 +2,7 @@ #import "MenuPrivate.h" #include "KeyboardPrivate.h" -#include "cru/common/platform/osx/Convert.h" +#include "cru/base/platform/osx/Convert.h" #import diff --git a/src/platform/gui/osx/UiApplication.mm b/src/platform/gui/osx/UiApplication.mm index ef62af58..fd6e8ef0 100644 --- a/src/platform/gui/osx/UiApplication.mm +++ b/src/platform/gui/osx/UiApplication.mm @@ -1,8 +1,8 @@ #include "cru/platform/gui/osx/UiApplication.h" #include "ClipboardPrivate.h" -#include "cru/common/log/Logger.h" -#include "cru/common/platform/osx/Convert.h" +#include "cru/base/log/Logger.h" +#include "cru/base/platform/osx/Convert.h" #include "cru/platform/graphics/quartz/Factory.h" #include "cru/platform/gui/osx/Clipboard.h" #include "cru/platform/gui/osx/Cursor.h" diff --git a/src/platform/gui/osx/Window.mm b/src/platform/gui/osx/Window.mm index d6bee564..8c059a12 100644 --- a/src/platform/gui/osx/Window.mm +++ b/src/platform/gui/osx/Window.mm @@ -3,8 +3,8 @@ #include "CursorPrivate.h" #include "InputMethodPrivate.h" -#include "cru/common/Range.h" -#include "cru/common/log/Logger.h" +#include "cru/base/Range.h" +#include "cru/base/log/Logger.h" #include "cru/platform/Check.h" #include "cru/platform/graphics/NullPainter.h" #include "cru/platform/graphics/quartz/Convert.h" diff --git a/src/platform/gui/osx/WindowPrivate.h b/src/platform/gui/osx/WindowPrivate.h index 00e15084..478ce4e5 100644 --- a/src/platform/gui/osx/WindowPrivate.h +++ b/src/platform/gui/osx/WindowPrivate.h @@ -1,7 +1,7 @@ #pragma once #include "cru/platform/gui/osx/Window.h" -#include "cru/common/Event.h" +#include "cru/base/Event.h" #include "cru/platform/gui/TimerHelper.h" #include "cru/platform/gui/Window.h" #include "cru/platform/gui/osx/Cursor.h" diff --git a/src/platform/gui/win/Clipboard.cpp b/src/platform/gui/win/Clipboard.cpp index 26850d3d..a0914a0b 100644 --- a/src/platform/gui/win/Clipboard.cpp +++ b/src/platform/gui/win/Clipboard.cpp @@ -1,5 +1,5 @@ #include "cru/platform/gui/win/Clipboard.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/gui/win/GodWindow.h" #include "cru/platform/gui/win/UiApplication.h" diff --git a/src/platform/gui/win/Cursor.cpp b/src/platform/gui/win/Cursor.cpp index c2efff1b..d7692c2d 100644 --- a/src/platform/gui/win/Cursor.cpp +++ b/src/platform/gui/win/Cursor.cpp @@ -1,6 +1,6 @@ #include "cru/platform/gui/win/Cursor.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/gui/win/Exception.h" #include diff --git a/src/platform/gui/win/GodWindow.cpp b/src/platform/gui/win/GodWindow.cpp index 4a062369..364688e5 100644 --- a/src/platform/gui/win/GodWindow.cpp +++ b/src/platform/gui/win/GodWindow.cpp @@ -1,6 +1,6 @@ #include "cru/platform/gui/win/GodWindow.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/gui/win/Exception.h" #include "cru/platform/gui/win/UiApplication.h" #include "cru/platform/gui/win/WindowClass.h" diff --git a/src/platform/gui/win/InputMethod.cpp b/src/platform/gui/win/InputMethod.cpp index 4c5b3b8c..44b5681d 100644 --- a/src/platform/gui/win/InputMethod.cpp +++ b/src/platform/gui/win/InputMethod.cpp @@ -1,7 +1,7 @@ #include "cru/platform/gui/win/InputMethod.h" -#include "cru/common/StringUtil.h" -#include "cru/common/log/Logger.h" +#include "cru/base/StringUtil.h" +#include "cru/base/log/Logger.h" #include "cru/platform/Check.h" #include "cru/platform/gui/DebugFlags.h" #include "cru/platform/gui/win/Exception.h" diff --git a/src/platform/gui/win/TimerManager.h b/src/platform/gui/win/TimerManager.h index 21c00690..b3f4aa38 100644 --- a/src/platform/gui/win/TimerManager.h +++ b/src/platform/gui/win/TimerManager.h @@ -1,8 +1,8 @@ #pragma once -#include "cru/common/Event.h" +#include "cru/base/Event.h" #include "cru/platform/win/WinPreConfig.h" -#include "cru/common/Base.h" +#include "cru/base/Base.h" #include "cru/platform/gui/win/GodWindow.h" #include "cru/platform/gui/win/WindowNativeMessageEventArgs.h" diff --git a/src/platform/gui/win/UiApplication.cpp b/src/platform/gui/win/UiApplication.cpp index 94d6b9c5..5be1a5d2 100644 --- a/src/platform/gui/win/UiApplication.cpp +++ b/src/platform/gui/win/UiApplication.cpp @@ -2,7 +2,7 @@ #include "TimerManager.h" #include "WindowManager.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/Check.h" #include "cru/platform/graphics/direct2d/Factory.h" #include "cru/platform/gui/win/Base.h" diff --git a/src/platform/gui/win/Window.cpp b/src/platform/gui/win/Window.cpp index 79ae02e2..47ca93f8 100644 --- a/src/platform/gui/win/Window.cpp +++ b/src/platform/gui/win/Window.cpp @@ -1,7 +1,7 @@ #include "cru/platform/gui/win/Window.h" #include "WindowManager.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/Check.h" #include "cru/platform/graphics/NullPainter.h" #include "cru/platform/gui/Base.h" diff --git a/src/platform/gui/win/WindowManager.h b/src/platform/gui/win/WindowManager.h index afc4a5f5..062f2002 100644 --- a/src/platform/gui/win/WindowManager.h +++ b/src/platform/gui/win/WindowManager.h @@ -1,7 +1,7 @@ #pragma once #include "cru/platform/win/WinPreConfig.h" -#include "cru/common/Base.h" +#include "cru/base/Base.h" #include #include diff --git a/src/ui/ThemeManager.cpp b/src/ui/ThemeManager.cpp index 7358637e..c1b2167e 100644 --- a/src/ui/ThemeManager.cpp +++ b/src/ui/ThemeManager.cpp @@ -1,8 +1,8 @@ #include "cru/ui/ThemeManager.h" #include "Helper.h" -#include "cru/common/StringUtil.h" -#include "cru/common/io/Resource.h" +#include "cru/base/StringUtil.h" +#include "cru/base/io/Resource.h" #include "cru/platform/graphics/Brush.h" #include "cru/platform/graphics/Factory.h" #include "cru/platform/gui/UiApplication.h" diff --git a/src/ui/ThemeResourceDictionary.cpp b/src/ui/ThemeResourceDictionary.cpp index 86a19083..c5986962 100644 --- a/src/ui/ThemeResourceDictionary.cpp +++ b/src/ui/ThemeResourceDictionary.cpp @@ -1,6 +1,6 @@ #include "cru/ui/ThemeResourceDictionary.h" -#include "cru/common/io/CFileStream.h" -#include "cru/common/log/Logger.h" +#include "cru/base/io/CFileStream.h" +#include "cru/base/log/Logger.h" #include "cru/xml/XmlNode.h" #include "cru/xml/XmlParser.h" diff --git a/src/ui/components/Input.cpp b/src/ui/components/Input.cpp index daca68c4..b308ed51 100644 --- a/src/ui/components/Input.cpp +++ b/src/ui/components/Input.cpp @@ -1,7 +1,7 @@ #include "cru/ui/components/Input.h" #include #include -#include "cru/common/StringToNumberConverter.h" +#include "cru/base/StringToNumberConverter.h" #include "cru/ui/controls/Control.h" namespace cru::ui::components { diff --git a/src/ui/controls/Control.cpp b/src/ui/controls/Control.cpp index 3b0d4be3..17633e3d 100644 --- a/src/ui/controls/Control.cpp +++ b/src/ui/controls/Control.cpp @@ -1,6 +1,6 @@ #include "cru/ui/controls/Control.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/gui/Cursor.h" #include "cru/platform/gui/UiApplication.h" #include "cru/ui/host/WindowHost.h" diff --git a/src/ui/controls/RootControl.cpp b/src/ui/controls/RootControl.cpp index 2d23bb36..1bb2e7ee 100644 --- a/src/ui/controls/RootControl.cpp +++ b/src/ui/controls/RootControl.cpp @@ -1,6 +1,6 @@ #include "cru/ui/controls/RootControl.h" -#include "cru/common/Base.h" +#include "cru/base/Base.h" #include "cru/platform/gui/Base.h" #include "cru/platform/gui/Window.h" #include "cru/ui/Base.h" diff --git a/src/ui/controls/TextHostControlService.cpp b/src/ui/controls/TextHostControlService.cpp index 36703986..3e885bd3 100644 --- a/src/ui/controls/TextHostControlService.cpp +++ b/src/ui/controls/TextHostControlService.cpp @@ -1,10 +1,10 @@ #include "cru/ui/controls/TextHostControlService.h" #include "../Helper.h" -#include "cru/common/Base.h" -#include "cru/common/String.h" -#include "cru/common/StringUtil.h" -#include "cru/common/log/Logger.h" +#include "cru/base/Base.h" +#include "cru/base/String.h" +#include "cru/base/StringUtil.h" +#include "cru/base/log/Logger.h" #include "cru/platform/graphics/Font.h" #include "cru/platform/gui/Base.h" #include "cru/platform/gui/Clipboard.h" diff --git a/src/ui/document/TextDocumentElement.cpp b/src/ui/document/TextDocumentElement.cpp index ab79823d..1ba39849 100644 --- a/src/ui/document/TextDocumentElement.cpp +++ b/src/ui/document/TextDocumentElement.cpp @@ -1,5 +1,5 @@ #include "cru/ui/document/TextDocumentElement.h" -#include "cru/common/String.h" +#include "cru/base/String.h" #include "cru/ui/document/DocumentElement.h" #include "cru/ui/document/DocumentElementType.h" diff --git a/src/ui/helper/ClickDetector.cpp b/src/ui/helper/ClickDetector.cpp index f76f8af4..de39f14e 100644 --- a/src/ui/helper/ClickDetector.cpp +++ b/src/ui/helper/ClickDetector.cpp @@ -1,6 +1,6 @@ #include "cru/ui/helper/ClickDetector.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/ui/DebugFlags.h" #include "cru/ui/controls/Control.h" #include "cru/ui/host/WindowHost.h" diff --git a/src/ui/helper/ShortcutHub.cpp b/src/ui/helper/ShortcutHub.cpp index 8fbf0b8d..30a563ed 100644 --- a/src/ui/helper/ShortcutHub.cpp +++ b/src/ui/helper/ShortcutHub.cpp @@ -1,6 +1,6 @@ #include "cru/ui/helper/ShortcutHub.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/ui/DebugFlags.h" #include "cru/ui/controls/Control.h" diff --git a/src/ui/host/RoutedEventDispatch.h b/src/ui/host/RoutedEventDispatch.h index 5d1c8ce5..207e1ee6 100644 --- a/src/ui/host/RoutedEventDispatch.h +++ b/src/ui/host/RoutedEventDispatch.h @@ -1,6 +1,6 @@ #pragma once -#include "cru/common/SelfResolvable.h" -#include "cru/common/log/Logger.h" +#include "cru/base/SelfResolvable.h" +#include "cru/base/log/Logger.h" #include "cru/ui/DebugFlags.h" #include "cru/ui/controls/Control.h" #include "cru/ui/host/WindowHost.h" diff --git a/src/ui/host/WindowHost.cpp b/src/ui/host/WindowHost.cpp index 283224b1..616803b6 100644 --- a/src/ui/host/WindowHost.cpp +++ b/src/ui/host/WindowHost.cpp @@ -1,8 +1,8 @@ #include "cru/ui/host/WindowHost.h" #include "RoutedEventDispatch.h" -#include "cru/common/Base.h" -#include "cru/common/log/Logger.h" +#include "cru/base/Base.h" +#include "cru/base/log/Logger.h" #include "cru/platform/graphics/Painter.h" #include "cru/platform/gui/InputMethod.h" #include "cru/platform/gui/UiApplication.h" diff --git a/src/ui/mapper/BorderStyleMapper.cpp b/src/ui/mapper/BorderStyleMapper.cpp index 462a07a1..a51651bd 100644 --- a/src/ui/mapper/BorderStyleMapper.cpp +++ b/src/ui/mapper/BorderStyleMapper.cpp @@ -1,6 +1,6 @@ #include "cru/ui/mapper/BorderStyleMapper.h" #include "../Helper.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/graphics/Brush.h" #include "cru/platform/graphics/Factory.h" #include "cru/ui/mapper/MapperRegistry.h" diff --git a/src/ui/mapper/CursorMapper.cpp b/src/ui/mapper/CursorMapper.cpp index 7de422e8..ed3c91ec 100644 --- a/src/ui/mapper/CursorMapper.cpp +++ b/src/ui/mapper/CursorMapper.cpp @@ -1,6 +1,6 @@ #include "cru/ui/mapper/CursorMapper.h" #include "../Helper.h" -#include "cru/common/Exception.h" +#include "cru/base/Exception.h" #include "cru/platform/gui/Cursor.h" #include "cru/platform/gui/UiApplication.h" diff --git a/src/ui/mapper/style/AndConditionMapper.cpp b/src/ui/mapper/style/AndConditionMapper.cpp index dd8784d5..d57c4927 100644 --- a/src/ui/mapper/style/AndConditionMapper.cpp +++ b/src/ui/mapper/style/AndConditionMapper.cpp @@ -1,5 +1,5 @@ #include "cru/ui/mapper/style/AndConditionMapper.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/mapper/MapperRegistry.h" #include "cru/ui/mapper/style/IConditionMapper.h" #include "cru/ui/style/Condition.h" diff --git a/src/ui/mapper/style/BorderStylerMapper.cpp b/src/ui/mapper/style/BorderStylerMapper.cpp index 95dd28ee..e6e33053 100644 --- a/src/ui/mapper/style/BorderStylerMapper.cpp +++ b/src/ui/mapper/style/BorderStylerMapper.cpp @@ -1,5 +1,5 @@ #include "cru/ui/mapper/style/BorderStylerMapper.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/mapper/MapperRegistry.h" #include "cru/ui/style/ApplyBorderStyleInfo.h" #include "cru/ui/style/Styler.h" diff --git a/src/ui/mapper/style/CheckedConditionMapper.cpp b/src/ui/mapper/style/CheckedConditionMapper.cpp index f61a3d44..74e0a3c5 100644 --- a/src/ui/mapper/style/CheckedConditionMapper.cpp +++ b/src/ui/mapper/style/CheckedConditionMapper.cpp @@ -1,4 +1,4 @@ -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/mapper/style/CheckedConditionMapper.h" #include "cru/ui/style/Condition.h" #include "cru/xml/XmlNode.h" diff --git a/src/ui/mapper/style/ClickStateConditionMapper.cpp b/src/ui/mapper/style/ClickStateConditionMapper.cpp index 5b25de2c..d6b403c9 100644 --- a/src/ui/mapper/style/ClickStateConditionMapper.cpp +++ b/src/ui/mapper/style/ClickStateConditionMapper.cpp @@ -1,6 +1,6 @@ #include "cru/ui/mapper/style/ClickStateConditionMapper.h" -#include "cru/common/ClonablePtr.h" -#include "cru/common/Exception.h" +#include "cru/base/ClonablePtr.h" +#include "cru/base/Exception.h" #include "cru/ui/helper/ClickDetector.h" #include "cru/ui/style/Condition.h" diff --git a/src/ui/mapper/style/ContentBrushStylerMapper.cpp b/src/ui/mapper/style/ContentBrushStylerMapper.cpp index e83f4988..b3571374 100644 --- a/src/ui/mapper/style/ContentBrushStylerMapper.cpp +++ b/src/ui/mapper/style/ContentBrushStylerMapper.cpp @@ -1,5 +1,5 @@ #include "cru/ui/mapper/style/ContentBrushStylerMapper.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/platform/graphics/Brush.h" #include "cru/ui/mapper/MapperRegistry.h" #include "cru/ui/style/Styler.h" diff --git a/src/ui/mapper/style/CursorStylerMapper.cpp b/src/ui/mapper/style/CursorStylerMapper.cpp index 6798798c..3b060c25 100644 --- a/src/ui/mapper/style/CursorStylerMapper.cpp +++ b/src/ui/mapper/style/CursorStylerMapper.cpp @@ -1,5 +1,5 @@ #include "cru/ui/mapper/style/CursorStylerMapper.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/platform/gui/Cursor.h" #include "cru/ui/mapper/MapperRegistry.h" #include "cru/ui/style/Styler.h" diff --git a/src/ui/mapper/style/FocusConditionMapper.cpp b/src/ui/mapper/style/FocusConditionMapper.cpp index b9e89e2e..dfefb921 100644 --- a/src/ui/mapper/style/FocusConditionMapper.cpp +++ b/src/ui/mapper/style/FocusConditionMapper.cpp @@ -1,4 +1,4 @@ -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/mapper/style/FocusConditionMapper.h" #include "cru/ui/style/Condition.h" #include "cru/xml/XmlNode.h" diff --git a/src/ui/mapper/style/FontStylerMapper.cpp b/src/ui/mapper/style/FontStylerMapper.cpp index 884832ee..3b1817ac 100644 --- a/src/ui/mapper/style/FontStylerMapper.cpp +++ b/src/ui/mapper/style/FontStylerMapper.cpp @@ -1,5 +1,5 @@ #include "cru/ui/mapper/style/FontStylerMapper.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/mapper/MapperRegistry.h" namespace cru::ui::mapper::style { diff --git a/src/ui/mapper/style/HoverConditionMapper.cpp b/src/ui/mapper/style/HoverConditionMapper.cpp index 97767b14..0110edd9 100644 --- a/src/ui/mapper/style/HoverConditionMapper.cpp +++ b/src/ui/mapper/style/HoverConditionMapper.cpp @@ -1,5 +1,5 @@ #include "cru/ui/mapper/style/HoverConditionMapper.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/style/Condition.h" namespace cru::ui::mapper::style { diff --git a/src/ui/mapper/style/NoConditionMapper.cpp b/src/ui/mapper/style/NoConditionMapper.cpp index 397162f1..a36e70d2 100644 --- a/src/ui/mapper/style/NoConditionMapper.cpp +++ b/src/ui/mapper/style/NoConditionMapper.cpp @@ -1,5 +1,5 @@ #include "cru/ui/mapper/style/NoConditionMapper.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/xml/XmlNode.h" namespace cru::ui::mapper::style { diff --git a/src/ui/mapper/style/OrConditionMapper.cpp b/src/ui/mapper/style/OrConditionMapper.cpp index 7b932dbc..521c57ae 100644 --- a/src/ui/mapper/style/OrConditionMapper.cpp +++ b/src/ui/mapper/style/OrConditionMapper.cpp @@ -1,5 +1,5 @@ #include "cru/ui/mapper/style/OrConditionMapper.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/ui/mapper/MapperRegistry.h" #include "cru/ui/mapper/style/IConditionMapper.h" #include "cru/ui/style/Condition.h" diff --git a/src/ui/mapper/style/StyleRuleMapper.cpp b/src/ui/mapper/style/StyleRuleMapper.cpp index 2ab13c90..2eb5b0a2 100644 --- a/src/ui/mapper/style/StyleRuleMapper.cpp +++ b/src/ui/mapper/style/StyleRuleMapper.cpp @@ -1,7 +1,7 @@ #include "cru/ui/mapper/style/StyleRuleMapper.h" -#include "cru/common/ClonablePtr.h" -#include "cru/common/Exception.h" -#include "cru/common/log/Logger.h" +#include "cru/base/ClonablePtr.h" +#include "cru/base/Exception.h" +#include "cru/base/log/Logger.h" #include "cru/ui/mapper/MapperRegistry.h" #include "cru/ui/mapper/style/IConditionMapper.h" #include "cru/ui/mapper/style/IStylerMapper.h" diff --git a/src/ui/render/BorderRenderObject.cpp b/src/ui/render/BorderRenderObject.cpp index 1392af1e..81a1aa60 100644 --- a/src/ui/render/BorderRenderObject.cpp +++ b/src/ui/render/BorderRenderObject.cpp @@ -1,7 +1,7 @@ #include "cru/ui/render/BorderRenderObject.h" #include "../Helper.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/graphics/Factory.h" #include "cru/platform/graphics/Geometry.h" #include "cru/platform/graphics/Painter.h" diff --git a/src/ui/render/FlexLayoutRenderObject.cpp b/src/ui/render/FlexLayoutRenderObject.cpp index 988e7590..7bbf9d57 100644 --- a/src/ui/render/FlexLayoutRenderObject.cpp +++ b/src/ui/render/FlexLayoutRenderObject.cpp @@ -1,6 +1,6 @@ #include "cru/ui/render/FlexLayoutRenderObject.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/ui/render/LayoutHelper.h" #include diff --git a/src/ui/render/LayoutHelper.cpp b/src/ui/render/LayoutHelper.cpp index a9121321..bbd3c116 100644 --- a/src/ui/render/LayoutHelper.cpp +++ b/src/ui/render/LayoutHelper.cpp @@ -1,6 +1,6 @@ #include "cru/ui/render/LayoutHelper.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" namespace cru::ui::render { float CalculateAnchorByAlignment(Alignment alignment, float start_point, diff --git a/src/ui/render/RenderObject.cpp b/src/ui/render/RenderObject.cpp index a370f749..64411036 100644 --- a/src/ui/render/RenderObject.cpp +++ b/src/ui/render/RenderObject.cpp @@ -1,7 +1,7 @@ #include "cru/ui/render/RenderObject.h" -#include "cru/common/Exception.h" -#include "cru/common/log/Logger.h" +#include "cru/base/Exception.h" +#include "cru/base/log/Logger.h" #include "cru/platform/GraphicsBase.h" #include "cru/ui/DebugFlags.h" #include "cru/ui/controls/Control.h" diff --git a/src/ui/render/ScrollBar.cpp b/src/ui/render/ScrollBar.cpp index 3e578d37..326f7504 100644 --- a/src/ui/render/ScrollBar.cpp +++ b/src/ui/render/ScrollBar.cpp @@ -1,7 +1,7 @@ #include "cru/ui/render/ScrollBar.h" #include "../Helper.h" -#include "cru/common/Base.h" +#include "cru/base/Base.h" #include "cru/platform/GraphicsBase.h" #include "cru/platform/graphics/Factory.h" #include "cru/platform/graphics/Geometry.h" diff --git a/src/ui/render/StackLayoutRenderObject.cpp b/src/ui/render/StackLayoutRenderObject.cpp index 9ca9bf02..d71c5749 100644 --- a/src/ui/render/StackLayoutRenderObject.cpp +++ b/src/ui/render/StackLayoutRenderObject.cpp @@ -1,6 +1,6 @@ #include "cru/ui/render/StackLayoutRenderObject.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/ui/render/LayoutHelper.h" #include "cru/ui/render/MeasureRequirement.h" diff --git a/src/ui/render/TextRenderObject.cpp b/src/ui/render/TextRenderObject.cpp index 135c2d02..14e45080 100644 --- a/src/ui/render/TextRenderObject.cpp +++ b/src/ui/render/TextRenderObject.cpp @@ -1,7 +1,7 @@ #include "cru/ui/render/TextRenderObject.h" #include "../Helper.h" -#include "cru/common/log/Logger.h" +#include "cru/base/log/Logger.h" #include "cru/platform/graphics/Factory.h" #include "cru/platform/graphics/Painter.h" #include "cru/platform/graphics/TextLayout.h" diff --git a/src/ui/style/Condition.cpp b/src/ui/style/Condition.cpp index f7cdf7fd..a0de03dc 100644 --- a/src/ui/style/Condition.cpp +++ b/src/ui/style/Condition.cpp @@ -1,8 +1,8 @@ #include "cru/ui/style/Condition.h" #include -#include "cru/common/ClonablePtr.h" -#include "cru/common/Event.h" +#include "cru/base/ClonablePtr.h" +#include "cru/base/Event.h" #include "cru/ui/controls/Control.h" #include "cru/ui/controls/ICheckableControl.h" #include "cru/ui/controls/IClickableControl.h" diff --git a/src/ui/style/StyleRuleSet.cpp b/src/ui/style/StyleRuleSet.cpp index 7b6454ec..ab3a2d01 100644 --- a/src/ui/style/StyleRuleSet.cpp +++ b/src/ui/style/StyleRuleSet.cpp @@ -1,5 +1,5 @@ #include "cru/ui/style/StyleRuleSet.h" -#include "cru/common/Event.h" +#include "cru/base/Event.h" #include "cru/ui/controls/Control.h" #include "cru/ui/model/IListChangeNotify.h" diff --git a/src/ui/style/Styler.cpp b/src/ui/style/Styler.cpp index 3d7ff1f9..a4e3ac25 100644 --- a/src/ui/style/Styler.cpp +++ b/src/ui/style/Styler.cpp @@ -1,7 +1,7 @@ #include "cru/ui/style/Styler.h" #include "../Helper.h" -#include "cru/common/ClonablePtr.h" +#include "cru/base/ClonablePtr.h" #include "cru/platform/gui/Cursor.h" #include "cru/platform/gui/UiApplication.h" #include "cru/ui/controls/Control.h" -- cgit v1.2.3