diff --git a/.Config.cmake.in.kate-swp b/.Config.cmake.in.kate-swp new file mode 100644 index 0000000..a5870a7 Binary files /dev/null and b/.Config.cmake.in.kate-swp differ diff --git a/CMakeLists.txt b/CMakeLists.txt index 08cb616..2059cf5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,8 @@ src/Streams/MemoryStream.cpp src/Streams/NetworkStream.cpp src/Streams/Stream.cpp src/Streams/BufferedStream.cpp +src/Streams/ByteReader.cpp +src/Streams/ByteWriter.cpp src/TextStreams/StreamReader.cpp src/TextStreams/StreamWriter.cpp src/TextStreams/TextReader.cpp @@ -32,13 +34,24 @@ src/Filesystem/NullFilesystem.cpp src/Filesystem/MountableFilesystem.cpp src/Crypto/ClientTLSStream.cpp src/Crypto/MbedHelpers.cpp +src/Graphics/ImageFormats/Bitmap.cpp +src/Graphics/ImageFormats/ImageFormat.cpp +src/Graphics/Renderers/ImageRenderer.cpp +src/Graphics/Renderers/Renderer.cpp +src/Graphics/Color.cpp +src/Graphics/Image.cpp src/TF_Init.cpp src/wrapper.cpp +src/HiddenField.cpp ) set(TESSESFRAMEWORK_CERT_BUNDLE_FILE "/etc/ssl/certs/ca-certificates.crt" CACHE FILEPATH "Path to ca-chain") option(TESSESFRAMEWORK_EMBED_CERT_BUNDLE "Embed the certificate chain bundle" ON) option(TESSESFRAMEWORK_ENABLE_MBED "Enable Tesses Framework mbedtls" ON) +option(TESSESFRAMEWORK_ENABLE_LIBWEBCAM "Enable LibWebCam" ON) +option(TESSESFRAMEWORK_ENABLE_NETWORKING "Enable Networking" ON) +option(TESSESFRAMEWORK_ENABLE_THREADING "Enable Threading" ON) + option(TESSESFRAMEWORK_ENABLE_EXAMPLES "Enable Tesses Framework examples" ON) option(TESSESFRAMEWORK_ENABLE_APPS "Enable Tesses Framework cli apps" ON) option(TESSESFRAMEWORK_INSTALL_DEVELOPMENT "Enable Installing Tesses Framework Development Packages" ON) @@ -62,6 +75,17 @@ endif() set(MBEDTLS_DIR "" CACHE PATH "Mbed tls directory") function(link_deps TessesFramework_TARGET) +if(TESSESFRAMEWORK_ENABLE_THREADING) +target_compile_definitions(${TessesFramework_TARGET} PUBLIC TESSESFRAMEWORK_ENABLE_THREADING) +endif() +if(TESSESFRAMEWORK_ENABLE_NETWORKING) +target_compile_definitions(${TessesFramework_TARGET} PUBLIC TESSESFRAMEWORK_ENABLE_NETWORKING) +endif() +if(TESSESFRAMEWORK_ENABLE_LIBWEBCAM) +target_compile_definitions(${TessesFramework_TARGET} PUBLIC TESSESFRAMEWORK_ENABLE_LIBWEBCAM) +find_package(libwebcam REQUIRED) +target_link_libraries(${TessesFramework_TARGET} PUBLIC libwebcam) +endif() if(TESSESFRAMEWORK_ENABLE_MBED) target_compile_definitions(${TessesFramework_TARGET} PUBLIC TESSESFRAMEWORK_ENABLE_MBED) if(TESSESFRAMEWORK_EMBED_CERT_BUNDLE) @@ -165,7 +189,14 @@ if(TESSESFRAMEWORK_ENABLE_EXAMPLES) add_executable(mountabletest examples/mountabletest.cpp) target_link_libraries(mountabletest PUBLIC tessesframework) - + add_executable(bmp examples/bmp.cpp) + target_link_libraries(bmp PUBLIC tessesframework) + add_executable(bmp2 examples/bmp2.cpp) + target_link_libraries(bmp2 PUBLIC tessesframework) + add_executable(bmp3 examples/bmp3.cpp) + target_link_libraries(bmp3 PUBLIC tessesframework) + add_executable(bmp4 examples/bmp4.cpp) + target_link_libraries(bmp4 PUBLIC tessesframework) endif() if(TESSESFRAMEWORK_ENABLE_APPS) @@ -185,4 +216,4 @@ set(CPACK_PACKAGE_VERSION_MAJOR "${TessesFramework_VERSION_MAJOR}") set(CPACK_PACKAGE_VERSION_MINOR "${TessesFramework_VERSION_MINOR}") set(CPACK_DEBIAN_PACKAGE_DEPENDS "libmbedtls-dev (>= 2.28.8)") -include(CPack) \ No newline at end of file +include(CPack) diff --git a/Config.cmake.in b/Config.cmake.in index 73cf1d6..50714d7 100644 --- a/Config.cmake.in +++ b/Config.cmake.in @@ -8,4 +8,13 @@ if(NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows" OR "${CMAKE_SYSTEM_NAME}" STRE set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) -endif() \ No newline at end of file +endif() + +set(TESSESFRAMEWORK_ENABLE_LIBWEBCAM @TESSESFRAMEWORK_ENABLE_LIBWEBCAM@) + +if(${TESSESFRAMEWORK_ENABLE_LIBWEBCAM}) +find_package(libwebcam) +endif() + +set(TESSESFRAMEWORK_ENABLE_NETWORKING @TESSESFRAMEWORK_ENABLE_NETWORKING@) +set(TESSESFRAMEWORK_ENABLE_THREADING @TESSESFRAMEWORK_ENABLE_THREADING@) diff --git a/TessesFrameworkFeatures.h.in b/TessesFrameworkFeatures.h.in index 7fa1ba1..2c0110e 100644 --- a/TessesFrameworkFeatures.h.in +++ b/TessesFrameworkFeatures.h.in @@ -4,5 +4,15 @@ #if TESSES_FRAMEWORK_FLAG_@TESSESFRAMEWORK_ENABLE_MBED@ #define TESSESFRAMEWORK_ENABLE_MBED #endif +#if TESSES_FRAMEWORK_FLAG_@TESSESFRAMEWORK_ENABLE_LIBWEBCAM@ +#define TESSESFRAMEWORK_ENABLE_MINIFB +#endif +#if TESSES_FRAMEWORK_FLAG_@TESSESFRAMEWORK_ENABLE_NETWORKING@ +#define TESSESFRAMEWORK_ENABLE_NETWORKING +#endif + +#if TESSES_FRAMEWORK_FLAG_@TESSESFRAMEWORK_ENABLE_THREADING@ +#define TESSESFRAMEWORK_ENABLE_THREADING +#endif #undef TESSES_FRAMEWORK_FLAG_OFF -#undef TESSES_FRAMEWORK_FLAG_ON \ No newline at end of file +#undef TESSES_FRAMEWORK_FLAG_ON diff --git a/examples/bmp.cpp b/examples/bmp.cpp new file mode 100644 index 0000000..b4c177d --- /dev/null +++ b/examples/bmp.cpp @@ -0,0 +1,47 @@ +#include "TessesFramework/TessesFramework.hpp" +#include + +using namespace Tesses::Framework; +using namespace Tesses::Framework::Graphics; +using namespace Tesses::Framework::Graphics::ImageFormats; +using namespace Tesses::Framework::Streams; + +void doIt(const char* n) +{ + std::string p = n; + srand(std::stoi(p)); + p.append(".bmp"); + FileStream* strm = new FileStream(p,"wb"); + Image image(320,240); + + std::vector colors = { + Colors::Crimson, + Colors::Chartreuse, + Colors::FireBrick, + Colors::Turquoise, + Colors::DarkOrange, + Colors::Orange + }; + + + + for(uint32_t y = 0; y < image.Height(); y++) + { + for(uint32_t x = 0; x < image.Width(); x++) + { + image.SetPixel(x,y,colors[rand() % (int)colors.size()]); + } + } + + ImageFormats::Bitmap bmp; + bmp.Save(strm,&image); + delete strm; +} + +int main(int argc, char** argv) +{ + for(int i = 1; i < argc; i++) + { + doIt(argv[i]); + } +} \ No newline at end of file diff --git a/examples/bmp2.cpp b/examples/bmp2.cpp new file mode 100644 index 0000000..8bf282d --- /dev/null +++ b/examples/bmp2.cpp @@ -0,0 +1,72 @@ +#include "TessesFramework/TessesFramework.hpp" +#include + +using namespace Tesses::Framework; +using namespace Tesses::Framework::Graphics; +using namespace Tesses::Framework::Graphics::ImageFormats; +using namespace Tesses::Framework::Streams; + +#define WIDTH 19 +#define HEIGHT 12 +#define A 0x0A +#define B 0x0B +#define C 0x0C +char house[] = { +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //1 +0,0,0,0,0,0,0,0,9,9,0,0,0,7,0,0,B,B,0, //2 +0,0,0,8,8,0,0,0,9,9,0,0,7,6,7,0,A,0,B, //3 +0,0,0,8,8,0,0,0,0,0,0,7,C,C,C,7,A,0,0, //4 +0,8,8,8,8,8,8,0,0,0,7,C,C,C,C,C,7,0,0, //5 +0,8,8,8,8,8,8,0,0,7,7,7,7,7,7,7,7,7,0, //6 +0,0,0,8,8,0,0,0,0,1,5,5,5,5,5,5,5,1,0, //7 +0,0,0,8,8,0,0,0,0,1,6,5,3,3,3,5,6,1,0, //8 +4,4,4,8,8,4,4,4,4,1,6,5,3,2,3,5,6,1,4, //9 +4,4,4,8,8,4,4,4,4,1,5,5,3,2,3,5,5,1,4, //10 +4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,4, //11 +4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 //12 + +}; + +int main(int argc, char** argv) +{ + Color pallete[] = { + Colors::SkyBlue, + Colors::Grey, + Colors::Crimson, + Colors::Lime, + Colors::LawnGreen, + Colors::DarkOliveGreen, + Colors::DimGrey, + Colors::BurlyWood, + Colors::White, + Colors::Yellow, + Colors::FireBrick, + Colors::WhiteSmoke, + Colors::DarkGoldenRod + }; + + Image img(WIDTH*32,HEIGHT*32); + + for(uint32_t y = 0; y < HEIGHT; y++) + { + for(uint32_t x = 0; x < WIDTH; x++) + { + char c = house[y * WIDTH + x]; + for(uint32_t y0 = 0; y0 < 32; y0++) + { + uint32_t y1 = y * 32 + y0; + for(uint32_t x0 = 0; x0 < 32;x0++) + { + uint32_t x1 = x * 32 + x0; + + img.SetPixel(x1,y1, pallete[c]); + } + } + } + } + + FileStream* strm = new FileStream("house.bmp","wb"); + ImageFormats::Bitmap bmp; + bmp.Save(strm,&img); + delete strm; +} \ No newline at end of file diff --git a/examples/bmp3.cpp b/examples/bmp3.cpp new file mode 100644 index 0000000..ae6c80e --- /dev/null +++ b/examples/bmp3.cpp @@ -0,0 +1,23 @@ +#include "TessesFramework/TessesFramework.hpp" +#include +using namespace Tesses::Framework; +using namespace Tesses::Framework::Graphics; +using namespace Tesses::Framework::Graphics::ImageFormats; +using namespace Tesses::Framework::Streams; + +int main(int argc,char** argv) +{ + if(argc < 3) { + std::cout << "INBMP OUTBMP" << std::endl; + return 1; + } + FileStream* src = new FileStream(argv[1],"rb"); + + Image img; + Bitmap bmp; + bmp.Load(src,&img); + delete src; + FileStream* dest = new FileStream(argv[2],"wb"); + bmp.Save(dest,&img); + delete dest; +} \ No newline at end of file diff --git a/examples/bmp4.cpp b/examples/bmp4.cpp new file mode 100644 index 0000000..a7b80e7 --- /dev/null +++ b/examples/bmp4.cpp @@ -0,0 +1,31 @@ +#include "TessesFramework/TessesFramework.hpp" +#include +using namespace Tesses::Framework; +using namespace Tesses::Framework::Graphics; +using namespace Tesses::Framework::Graphics::ImageFormats; +using namespace Tesses::Framework::Streams; + +int main(int argc,char** argv) +{ + if(argc < 3) { + std::cout << "INBMP OUTBMP" << std::endl; + return 1; + } + FileStream* src = new FileStream(argv[1],"rb"); + + Image img; + Bitmap bmp; + bmp.Load(src,&img); + + delete src; + + Image img2(img.Width()+64,img.Height()+64); + Renderers::ImageRenderer irdr(&img2); + irdr.DrawRectangle(Rectangle(0,0,(int32_t)img2.Width(),(int32_t)img2.Height()),Colors::Crimson,false); + irdr.DrawRectangle(Rectangle(1,1,(int32_t)img2.Width()-2,(int32_t)img2.Height()-2),Colors::Chartreuse,true); + irdr.DrawImage(Point(32,32),&img); + + FileStream* dest = new FileStream(argv[2],"wb"); + bmp.Save(dest,&img2); + delete dest; +} \ No newline at end of file diff --git a/include/TessesFramework/Graphics/Color.hpp b/include/TessesFramework/Graphics/Color.hpp new file mode 100644 index 0000000..9a7e808 --- /dev/null +++ b/include/TessesFramework/Graphics/Color.hpp @@ -0,0 +1,176 @@ +#pragma once +#include "../Common.hpp" +namespace Tesses::Framework::Graphics { + + struct Color { + uint8_t Red=0; + uint8_t Green=0; + uint8_t Blue=0; + uint8_t Alpha=255; + Color(); + Color(uint8_t r, uint8_t g, uint8_t b); + Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a); + Color(Color c, uint8_t a); + Color(uint8_t* color_data); + + std::string ToString(bool alphaIf255=false); + + void ToArray(uint8_t* color_data); + + static bool TryParse(std::string color, Color& col); + + static Color Parse(std::string color); + bool operator!=(Color other); + bool operator==(Color other); + }; + namespace Colors { + extern const Color AliceBlue; + extern const Color AntiqueWhite; + extern const Color Aqua; + extern const Color Aquamarine; + extern const Color Azure; + extern const Color Beige; + extern const Color Bisque; + extern const Color Black; + extern const Color BlanchedAlmond; + extern const Color Blue; + extern const Color BlueViolet; + extern const Color Brown; + extern const Color BurlyWood; + extern const Color CadetBlue; + extern const Color Chartreuse; + extern const Color Chocolate; + extern const Color Coral; + extern const Color CornflowerBlue; + extern const Color Cornsilk; + extern const Color Crimson; + extern const Color Cyan; + extern const Color DarkBlue; + extern const Color DarkCyan; + extern const Color DarkGoldenRod; + extern const Color DarkGray; + extern const Color DarkGrey; + extern const Color DarkGreen; + extern const Color DarkKhaki; + extern const Color DarkMagenta; + extern const Color DarkOliveGreen; + extern const Color DarkOrange; + extern const Color DarkOrchid; + extern const Color DarkRed; + extern const Color DarkSalmon; + extern const Color DarkSeaGreen; + extern const Color DarkSlateBlue; + extern const Color DarkSlateGray; + extern const Color DarkSlateGrey; + extern const Color DarkTurquoise; + extern const Color DarkViolet; + extern const Color DeepPink; + extern const Color DeepSkyBlue; + extern const Color DimGray; + extern const Color DimGrey; + extern const Color DodgerBlue; + extern const Color FireBrick; + extern const Color FloralWhite; + extern const Color ForestGreen; + extern const Color Fuchsia; + extern const Color Gainsboro; + extern const Color GhostWhite; + extern const Color Gold; + extern const Color GoldenRod; + extern const Color Gray; + extern const Color Grey; + extern const Color Green; + extern const Color GreenYellow; + extern const Color HoneyDew; + extern const Color HotPink; + extern const Color IndianRed; + extern const Color Indigo; + extern const Color Ivory; + extern const Color Khaki; + extern const Color Lavender; + extern const Color LavenderBlush; + extern const Color LawnGreen; + extern const Color LemonChiffon; + extern const Color LightBlue; + extern const Color LightCoral; + extern const Color LightCyan; + extern const Color LightGoldenRodYellow; + extern const Color LightGray; + extern const Color LightGrey; + extern const Color LightGreen; + extern const Color LightPink; + extern const Color LightSalmon; + extern const Color LightSeaGreen; + extern const Color LightSkyBlue; + extern const Color LightSlateGray; + extern const Color LightSlateGrey; + extern const Color LightSteelBlue; + extern const Color LightYellow; + extern const Color Lime; + extern const Color LimeGreen; + extern const Color Linen; + extern const Color Magenta; + extern const Color Maroon; + extern const Color MediumAquaMarine; + extern const Color MediumBlue; + extern const Color MediumOrchid; + extern const Color MediumPurple; + extern const Color MediumSeaGreen; + extern const Color MediumSlateBlue; + extern const Color MediumSpringGreen; + extern const Color MediumTurquoise; + extern const Color MediumVioletRed; + extern const Color MidnightBlue; + extern const Color MintCream; + extern const Color MistyRose; + extern const Color Moccasin; + extern const Color NavajoWhite; + extern const Color Navy; + extern const Color OldLace; + extern const Color Olive; + extern const Color OliveDrab; + extern const Color Orange; + extern const Color OrangeRed; + extern const Color Orchid; + extern const Color PaleGoldenRod; + extern const Color PaleGreen; + extern const Color PaleTurquoise; + extern const Color PaleVioletRed; + extern const Color PapayaWhip; + extern const Color PeachPuff; + extern const Color Peru; + extern const Color Pink; + extern const Color Plum; + extern const Color PowderBlue; + extern const Color Purple; + extern const Color RebeccaPurple; + extern const Color Red; + extern const Color RosyBrown; + extern const Color SaddleBrown; + extern const Color Salmon; + extern const Color SandyBrown; + extern const Color SeaGreen; + extern const Color SeaShell; + extern const Color Sienna; + extern const Color Silver; + extern const Color SkyBlue; + extern const Color SlateBlue; + extern const Color SlateGray; + extern const Color SlateGrey; + extern const Color Snow; + extern const Color SpringGreen; + extern const Color SteelBlue; + extern const Color Tan; + extern const Color Teal; + extern const Color Thistle; + extern const Color Tomato; + extern const Color Turquoise; + extern const Color Violet; + extern const Color Wheat; + extern const Color White; + extern const Color WhiteSmoke; + extern const Color Yellow; + extern const Color YellowGreen; + + }; +}; \ No newline at end of file diff --git a/include/TessesFramework/Graphics/Image.hpp b/include/TessesFramework/Graphics/Image.hpp new file mode 100644 index 0000000..affef76 --- /dev/null +++ b/include/TessesFramework/Graphics/Image.hpp @@ -0,0 +1,24 @@ +#pragma once +#include "Color.hpp" +#include +namespace Tesses::Framework::Graphics { + class Image { + uint32_t w=0; + uint32_t h=0; + std::vector data={}; + public: + Image(); + Image(uint32_t w, uint32_t h); + Image(uint32_t w,uint32_t h,std::vector data); + uint32_t Width(); + uint32_t Height(); + void SetSize(uint32_t w, uint32_t h); + void SetSize(uint32_t w, uint32_t h, Color c); + void SetPixel(uint32_t x, uint32_t y, Color c); + Color GetPixel(uint32_t x, uint32_t y); + + std::vector& Data(); + + + }; +} \ No newline at end of file diff --git a/include/TessesFramework/Graphics/ImageFormats/Bitmap.hpp b/include/TessesFramework/Graphics/ImageFormats/Bitmap.hpp new file mode 100644 index 0000000..c6a6d37 --- /dev/null +++ b/include/TessesFramework/Graphics/ImageFormats/Bitmap.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "ImageFormat.hpp" +namespace Tesses::Framework::Graphics::ImageFormats { + class Bitmap : public ImageFormat { + public: + Bitmap(); + void Load(Tesses::Framework::Streams::Stream* strm, Image* image); + void Save(Tesses::Framework::Streams::Stream* strm, Image* image,std::string flags=""); + }; +}; \ No newline at end of file diff --git a/include/TessesFramework/Graphics/ImageFormats/ImageFormat.hpp b/include/TessesFramework/Graphics/ImageFormats/ImageFormat.hpp new file mode 100644 index 0000000..92086a6 --- /dev/null +++ b/include/TessesFramework/Graphics/ImageFormats/ImageFormat.hpp @@ -0,0 +1,13 @@ +#pragma once +#include "../../Streams/Stream.hpp" +#include "../Image.hpp" + +namespace Tesses::Framework::Graphics::ImageFormats { + class ImageFormat { + public: + virtual void Load(Tesses::Framework::Streams::Stream* strm, Image* image)=0; + virtual void Save(Tesses::Framework::Streams::Stream* strm, Image* image,std::string flags="")=0; + + virtual ~ImageFormat(); + }; +} \ No newline at end of file diff --git a/include/TessesFramework/Graphics/Point.hpp b/include/TessesFramework/Graphics/Point.hpp new file mode 100644 index 0000000..e46f215 --- /dev/null +++ b/include/TessesFramework/Graphics/Point.hpp @@ -0,0 +1,23 @@ +#pragma once +#include +#include +namespace Tesses::Framework::Graphics { + class Point { + public: + Point() + { + + } + Point(int32_t x, int32_t y) + { + this->X = x; + this->Y = y; + } + int32_t X=0; + int32_t Y=0; + std::string ToString() + { + return std::to_string(X) + ", " + std::to_string(Y); + } + }; +}; \ No newline at end of file diff --git a/include/TessesFramework/Graphics/Rectangle.hpp b/include/TessesFramework/Graphics/Rectangle.hpp new file mode 100644 index 0000000..0d0a631 --- /dev/null +++ b/include/TessesFramework/Graphics/Rectangle.hpp @@ -0,0 +1,42 @@ +#pragma once +#include "Point.hpp" +#include "Size.hpp" +namespace Tesses::Framework::Graphics { + class Rectangle { + public: + Rectangle() + { + + } + Rectangle(Point pt, int32_t square) : Rectangle(pt, Graphics::Size(square)) + { + + } + Rectangle(int32_t x, int32_t y, int32_t square) : Rectangle(Point(x,y),square) + { + + } + Rectangle(int32_t x, int32_t y, int32_t width, int32_t height) : Rectangle(Point(x,y),Graphics::Size(width,height)) + { + + } + Rectangle(Point pt, Size sz) + { + this->Location = pt; + this->Size = sz; + } + + Graphics::Point Location; + Graphics::Size Size; + + std::string ToString() + { + return std::to_string(Location.X) + ", " + std::to_string(Location.Y) + ", " + std::to_string(Size.Width) + ", " + std::to_string(Size.Height); + } + + bool Intersects(Point pt) + { + + } + }; +}; \ No newline at end of file diff --git a/include/TessesFramework/Graphics/Renderers/ImageRenderer.hpp b/include/TessesFramework/Graphics/Renderers/ImageRenderer.hpp new file mode 100644 index 0000000..bbea187 --- /dev/null +++ b/include/TessesFramework/Graphics/Renderers/ImageRenderer.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "Renderer.hpp" + +namespace Tesses::Framework::Graphics::Renderers { + + +class ImageRenderer : public Renderer { + Image* image; + public: + ImageRenderer(Image* image); + uint32_t Width(); + uint32_t Height(); + void SetPixel(Point pt,Color c); + +}; +}; \ No newline at end of file diff --git a/include/TessesFramework/Graphics/Renderers/Renderer.hpp b/include/TessesFramework/Graphics/Renderers/Renderer.hpp new file mode 100644 index 0000000..7073ded --- /dev/null +++ b/include/TessesFramework/Graphics/Renderers/Renderer.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "../Image.hpp" +#include "../Rectangle.hpp" +namespace Tesses::Framework::Graphics::Renderers { + + +class Renderer { + public: + virtual uint32_t Width()=0; + virtual uint32_t Height()=0; + virtual void SetPixel(Point pt,Color c) = 0; + virtual void DrawRectangle(Rectangle rect,Color c,bool fill); + virtual void DrawImage(Point pt, Image* image); + virtual ~Renderer(); +}; +}; \ No newline at end of file diff --git a/include/TessesFramework/Graphics/Size.hpp b/include/TessesFramework/Graphics/Size.hpp new file mode 100644 index 0000000..51b131c --- /dev/null +++ b/include/TessesFramework/Graphics/Size.hpp @@ -0,0 +1,32 @@ +#pragma once +#include +#include +namespace Tesses::Framework::Graphics { + class Size { + public: + Size() + { + + } + Size(int32_t square) + { + this->Width = square; + this->Height = square; + } + Size(int32_t width, int32_t height) + { + this->Width = width; + this->Height = height; + } + int32_t Width=0; + int32_t Height=0; + bool IsSquare() + { + return Width == Height; + } + std::string ToString() + { + return std::to_string(Width) + "x" + std::to_string(Height); + } + }; +}; \ No newline at end of file diff --git a/include/TessesFramework/HiddenField.hpp b/include/TessesFramework/HiddenField.hpp new file mode 100644 index 0000000..f370c2b --- /dev/null +++ b/include/TessesFramework/HiddenField.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include + +namespace Tesses::Framework { +class HiddenFieldData { + public: + virtual ~HiddenFieldData(); +}; + +class HiddenField { + private: + HiddenFieldData* ptr; + public: + HiddenField(); + HiddenField(HiddenFieldData* data); + void SetField(HiddenFieldData* data); + template + T GetField() + { + return dynamic_cast(ptr); + } + template + T AllocField() + { + auto v = new T(); + SetField(v); + return v; + } + ~HiddenField(); +}; +} \ No newline at end of file diff --git a/include/TessesFramework/Http/HttpUtils.hpp b/include/TessesFramework/Http/HttpUtils.hpp index 0cdb7ca..0b78f31 100644 --- a/include/TessesFramework/Http/HttpUtils.hpp +++ b/include/TessesFramework/Http/HttpUtils.hpp @@ -68,14 +68,9 @@ namespace Tesses::Framework::Http NotExtended=510, NetworkAuthenticationRequired=511 } StatusCode; + struct CaseInsensitiveLess { - bool operator() (const std::string& s1, const std::string& s2) const { - std::string str1(s1.length(),' '); - std::string str2(s2.length(),' '); - std::transform(s1.begin(), s1.end(), str1.begin(), tolower); - std::transform(s2.begin(), s2.end(), str2.begin(), tolower); - return str1 < str2; - } + bool operator() (const std::string& s1, const std::string& s2) const; }; class HttpDictionary { public: @@ -146,6 +141,8 @@ struct CaseInsensitiveLess { static std::string HtmlEncode(std::string v); static std::vector SplitString(std::string text, std::string delimiter,std::size_t maxCnt = std::string::npos); static std::string StatusCodeString(StatusCode code); + static std::string ToLower(std::string str); + static std::string ToUpper(std::string str); }; diff --git a/include/TessesFramework/Streams/ByteReader.hpp b/include/TessesFramework/Streams/ByteReader.hpp new file mode 100644 index 0000000..0f205fd --- /dev/null +++ b/include/TessesFramework/Streams/ByteReader.hpp @@ -0,0 +1,33 @@ +#pragma once +#include "Stream.hpp" + +namespace Tesses::Framework::Streams +{ + class ByteReader { + Stream* strm; + bool owns; + public: + Stream* GetStream(); + ByteReader(Stream* strm, bool owns); + ByteReader(Stream& strm); + uint8_t ReadU8(); + uint16_t ReadU16BE(); + uint16_t ReadU16LE(); + uint32_t ReadU32BE(); + uint32_t ReadU32LE(); + uint64_t ReadU64BE(); + uint64_t ReadU64LE(); + int8_t ReadI8(); + int16_t ReadI16BE(); + int16_t ReadI16LE(); + int32_t ReadI32BE(); + int32_t ReadI32LE(); + int64_t ReadI64BE(); + int64_t ReadI64LE(); + float ReadF32BE(); + float ReadF32LE(); + double ReadF64BE(); + double ReadF64LE(); + ~ByteReader(); + }; +} \ No newline at end of file diff --git a/include/TessesFramework/Streams/ByteWriter.hpp b/include/TessesFramework/Streams/ByteWriter.hpp new file mode 100644 index 0000000..b8c8813 --- /dev/null +++ b/include/TessesFramework/Streams/ByteWriter.hpp @@ -0,0 +1,33 @@ +#pragma once +#include "Stream.hpp" + +namespace Tesses::Framework::Streams +{ + class ByteWriter { + Stream* strm; + bool owns; + public: + Stream* GetStream(); + ByteWriter(Stream* strm, bool owns); + ByteWriter(Stream& strm); + void WriteU8(uint8_t v); + void WriteU16BE(uint16_t v); + void WriteU16LE(uint16_t v); + void WriteU32BE(uint32_t v); + void WriteU32LE(uint32_t v); + void WriteU64BE(uint64_t v); + void WriteU64LE(uint64_t v); + void WriteI8(int8_t v); + void WriteI16BE(int16_t v); + void WriteI16LE(int16_t v); + void WriteI32BE(int32_t v); + void WriteI32LE(int32_t v); + void WriteI64BE(int64_t v); + void WriteI64LE(int64_t v); + void WriteF32BE(float v); + void WriteF32LE(float v); + void WriteF64BE(double v); + void WriteF64LE(double v); + ~ByteWriter(); + }; +} \ No newline at end of file diff --git a/include/TessesFramework/TessesFramework.hpp b/include/TessesFramework/TessesFramework.hpp index 34e4b7b..c0171d0 100644 --- a/include/TessesFramework/TessesFramework.hpp +++ b/include/TessesFramework/TessesFramework.hpp @@ -9,6 +9,8 @@ #include "Streams/MemoryStream.hpp" #include "Streams/NetworkStream.hpp" #include "Streams/BufferedStream.hpp" +#include "Streams/ByteReader.hpp" +#include "Streams/ByteWriter.hpp" #include "TextStreams/StreamReader.hpp" #include "TextStreams/StreamWriter.hpp" #include "Threading/Thread.hpp" @@ -21,4 +23,11 @@ #include "Filesystem/MemoryFilesystem.hpp" #include "Crypto/ClientTLSStream.hpp" #include "Crypto/MbedHelpers.hpp" -#include "Lazy.hpp" \ No newline at end of file +#include "Lazy.hpp" +#include "Graphics/ImageFormats/ImageFormat.hpp" +#include "Graphics/ImageFormats/Bitmap.hpp" +#include "Graphics/Renderers/ImageRenderer.hpp" +#include "Graphics/Renderers/Renderer.hpp" +#include "Graphics/Image.hpp" +#include "Graphics/Color.hpp" +#include "HiddenField.hpp" \ No newline at end of file diff --git a/include/TessesFramework/Threading/Mutex.hpp b/include/TessesFramework/Threading/Mutex.hpp index 8d91963..50114c3 100644 --- a/include/TessesFramework/Threading/Mutex.hpp +++ b/include/TessesFramework/Threading/Mutex.hpp @@ -1,22 +1,10 @@ #pragma once -#if defined(_WIN32) -#include -#elif defined(GEKKO) -#include -#else -#include -#endif + +#include "../HiddenField.hpp" namespace Tesses::Framework::Threading { class Mutex { - #if defined(_WIN32) - HANDLE mtx; - #elif defined(GEKKO) - mutex_t mtx; - #else - pthread_mutex_t mtx; - pthread_mutexattr_t attr; - #endif + HiddenField data; public: Mutex(); void Lock(); diff --git a/include/TessesFramework/Threading/Thread.hpp b/include/TessesFramework/Threading/Thread.hpp index 02fb4d0..cb9a51b 100644 --- a/include/TessesFramework/Threading/Thread.hpp +++ b/include/TessesFramework/Threading/Thread.hpp @@ -8,26 +8,13 @@ #include #endif #include +#include "../HiddenField.hpp" namespace Tesses::Framework::Threading { class Thread { - #if defined(_WIN32) - - HANDLE thrd; - DWORD thrdId; - - public: - #elif defined(GEKKO) - lwp_t thrd; - static void* cb(void* ptr); - #else - pthread_t thrd; - static void* cb(void* ptr); - #endif - std::function fn; - - std::atomic hasInvoked; + HiddenField data; + public: Thread(std::function fn); void Join(); diff --git a/src/Graphics/Color.cpp b/src/Graphics/Color.cpp new file mode 100644 index 0000000..a17079a --- /dev/null +++ b/src/Graphics/Color.cpp @@ -0,0 +1,432 @@ +#include "TessesFramework/Graphics/Color.hpp" +#include "TessesFramework/Http/HttpUtils.hpp" +using HttpUtils = Tesses::Framework::Http::HttpUtils; +namespace Tesses::Framework::Graphics { + namespace Colors { + const Color AliceBlue(240,248,255); + const Color AntiqueWhite(250,235,215); + const Color Aqua(0,255,255); + const Color Aquamarine(127,255,212); + const Color Azure(240,255,255); + const Color Beige(245,245,220); + const Color Bisque(255,228,196); + const Color Black(0,0,0); + const Color BlanchedAlmond(255,235,205); + const Color Blue(0,0,255); + const Color BlueViolet(138,43,226); + const Color Brown(165,42,42); + const Color BurlyWood(222,184,135); + const Color CadetBlue(95,158,160); + const Color Chartreuse(127,255,0); + const Color Chocolate(210,105,30); + const Color Coral(255,127,80); + const Color CornflowerBlue(100,149,237); + const Color Cornsilk(255,248,220); + const Color Crimson(220,20,60); + const Color Cyan(0,255,255); + const Color DarkBlue(0,0,139); + const Color DarkCyan(0,139,139); + const Color DarkGoldenRod(184,134,11); + const Color DarkGray(169,169,169); + const Color DarkGrey(169,169,169); + const Color DarkGreen(0,100,0); + const Color DarkKhaki(189,183,107); + const Color DarkMagenta(139,0,139); + const Color DarkOliveGreen(85,107,47); + const Color DarkOrange(255,140,0); + const Color DarkOrchid(153,50,204); + const Color DarkRed(139,0,0); + const Color DarkSalmon(233,150,122); + const Color DarkSeaGreen(143,188,143); + const Color DarkSlateBlue(72,61,139); + const Color DarkSlateGray(47,79,79); + const Color DarkSlateGrey(47,79,79); + const Color DarkTurquoise(0,206,209); + const Color DarkViolet(148,0,211); + const Color DeepPink(255,20,147); + const Color DeepSkyBlue(0,191,255); + const Color DimGray(105,105,105); + const Color DimGrey(105,105,105); + const Color DodgerBlue(30,144,255); + const Color FireBrick(178,34,34); + const Color FloralWhite(255,250,240); + const Color ForestGreen(34,139,34); + const Color Fuchsia(255,0,255); + const Color Gainsboro(220,220,220); + const Color GhostWhite(248,248,255); + const Color Gold(255,215,0); + const Color GoldenRod(218,165,32); + const Color Gray(128,128,128); + const Color Grey(128,128,128); + const Color Green(0,128,0); + const Color GreenYellow(173,255,47); + const Color HoneyDew(240,255,240); + const Color HotPink(255,105,180); + const Color IndianRed(205,92,92); + const Color Indigo(75,0,130); + const Color Ivory(255,255,240); + const Color Khaki(240,230,140); + const Color Lavender(230,230,250); + const Color LavenderBlush(255,240,245); + const Color LawnGreen(124,252,0); + const Color LemonChiffon(255,250,205); + const Color LightBlue(173,216,230); + const Color LightCoral(240,128,128); + const Color LightCyan(224,255,255); + const Color LightGoldenRodYellow(250,250,210); + const Color LightGray(211,211,211); + const Color LightGrey(211,211,211); + const Color LightGreen(144,238,144); + const Color LightPink(255,182,193); + const Color LightSalmon(255,160,122); + const Color LightSeaGreen(32,178,170); + const Color LightSkyBlue(135,206,250); + const Color LightSlateGray(119,136,153); + const Color LightSlateGrey(119,136,153); + const Color LightSteelBlue(176,196,222); + const Color LightYellow(255,255,224); + const Color Lime(0,255,0); + const Color LimeGreen(50,205,50); + const Color Linen(250,240,230); + const Color Magenta(255,0,255); + const Color Maroon(128,0,0); + const Color MediumAquaMarine(102,205,170); + const Color MediumBlue(0,0,205); + const Color MediumOrchid(186,85,211); + const Color MediumPurple(147,112,219); + const Color MediumSeaGreen(60,179,113); + const Color MediumSlateBlue(123,104,238); + const Color MediumSpringGreen(0,250,154); + const Color MediumTurquoise(72,209,204); + const Color MediumVioletRed(199,21,133); + const Color MidnightBlue(25,25,112); + const Color MintCream(245,255,250); + const Color MistyRose(255,228,225); + const Color Moccasin(255,228,181); + const Color NavajoWhite(255,222,173); + const Color Navy(0,0,128); + const Color OldLace(253,245,230); + const Color Olive(128,128,0); + const Color OliveDrab(107,142,35); + const Color Orange(255,165,0); + const Color OrangeRed(255,69,0); + const Color Orchid(218,112,214); + const Color PaleGoldenRod(238,232,170); + const Color PaleGreen(152,251,152); + const Color PaleTurquoise(175,238,238); + const Color PaleVioletRed(219,112,147); + const Color PapayaWhip(255,239,213); + const Color PeachPuff(255,218,185); + const Color Peru(205,133,63); + const Color Pink(255,192,203); + const Color Plum(221,160,221); + const Color PowderBlue(176,224,230); + const Color Purple(128,0,128); + const Color RebeccaPurple(102,51,153); + const Color Red(255,0,0); + const Color RosyBrown(188,143,143); + const Color SaddleBrown(139,69,19); + const Color Salmon(250,128,114); + const Color SandyBrown(244,164,96); + const Color SeaGreen(46,139,87); + const Color SeaShell(255,245,238); + const Color Sienna(160,82,45); + const Color Silver(192,192,192); + const Color SkyBlue(135,206,235); + const Color SlateBlue(106,90,205); + const Color SlateGray(112,128,144); + const Color SlateGrey(112,128,144); + const Color Snow(255,250,250); + const Color SpringGreen(0,255,127); + const Color SteelBlue(70,130,180); + const Color Tan(210,180,140); + const Color Teal(0,128,128); + const Color Thistle(216,191,216); + const Color Tomato(255,99,71); + const Color Turquoise(64,224,208); + const Color Violet(238,130,238); + const Color Wheat(245,222,179); + const Color White(255,255,255); + const Color WhiteSmoke(245,245,245); + const Color Yellow(255,255,0); + const Color YellowGreen(154,205,50); + } + Color::Color() + { + + } + Color::Color(uint8_t r, uint8_t g, uint8_t b) : Color(r,g,b,255) + { + } + Color::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) + { + this->Red = r; + this->Green = g; + this->Blue = b; + this->Alpha = a; + } + Color::Color(Color c, uint8_t a) : Color(c.Red,c.Green,c.Blue,a) + { + + } + Color::Color(uint8_t* color_data) : Color(color_data[0],color_data[1],color_data[2],color_data[3]) + { + + } + + std::string Color::ToString(bool alphaIf255) + { + std::string str={ + '#', + HttpUtils::NibbleToHex((Red >> 4) & 0x0F), + HttpUtils::NibbleToHex(Red & 0x0F), + HttpUtils::NibbleToHex((Green >> 4) & 0x0F), + HttpUtils::NibbleToHex(Green & 0x0F), + HttpUtils::NibbleToHex((Blue >> 4) & 0x0F), + HttpUtils::NibbleToHex(Blue & 0x0F) + }; + if(alphaIf255 || this->Alpha < 255) + { + str.push_back(HttpUtils::NibbleToHex((Blue >> 4) & 0x0F)); + str.push_back(HttpUtils::NibbleToHex(Blue & 0x0F)); + } + return str; + } + + void Color::ToArray(uint8_t* color_data) + { + color_data[0] = Red; + color_data[1] = Green; + color_data[2] = Blue; + color_data[3] = Alpha; + } + + bool Color::TryParse(std::string color, Color& col) + { + color = HttpUtils::ToLower(color); + + + if(color.size() < 1) return false; + else if(color[0] != '#') { + if(color == "aliceblue") {col = Colors::AliceBlue; return true;} + else if(color == "antiquewhite") {col = Colors::AntiqueWhite; return true;} + else if(color == "aqua") {col = Colors::Aqua; return true;} + else if(color == "aquamarine") {col = Colors::Aquamarine; return true;} + else if(color == "azure"){ col = Colors::Azure; return true; } +else if(color == "beige"){ col = Colors::Beige; return true; } +else if(color == "bisque"){ col = Colors::Bisque; return true; } +else if(color == "black"){ col = Colors::Black; return true; } +else if(color == "blanchedalmond"){ col = Colors::BlanchedAlmond; return true; } +else if(color == "blue"){ col = Colors::Blue; return true; } +else if(color == "blueviolet"){ col = Colors::BlueViolet; return true; } +else if(color == "brown"){ col = Colors::Brown; return true; } +else if(color == "burlywood"){ col = Colors::BurlyWood; return true; } +else if(color == "cadetblue"){ col = Colors::CadetBlue; return true; } +else if(color == "chartreuse"){ col = Colors::Chartreuse; return true; } +else if(color == "chocolate"){ col = Colors::Chocolate; return true; } +else if(color == "coral"){ col = Colors::Coral; return true; } +else if(color == "cornflowerblue"){ col = Colors::CornflowerBlue; return true; } +else if(color == "cornsilk"){ col = Colors::Cornsilk; return true; } +else if(color == "crimson"){ col = Colors::Crimson; return true; } +else if(color == "cyan"){ col = Colors::Cyan; return true; } +else if(color == "darkblue"){ col = Colors::DarkBlue; return true; } +else if(color == "darkcyan"){ col = Colors::DarkCyan; return true; } +else if(color == "darkgoldenrod"){ col = Colors::DarkGoldenRod; return true; } +else if(color == "darkgray"){ col = Colors::DarkGray; return true; } +else if(color == "darkgrey"){ col = Colors::DarkGrey; return true; } +else if(color == "darkgreen"){ col = Colors::DarkGreen; return true; } +else if(color == "darkkhaki"){ col = Colors::DarkKhaki; return true; } +else if(color == "darkmagenta"){ col = Colors::DarkMagenta; return true; } +else if(color == "darkolivegreen"){ col = Colors::DarkOliveGreen; return true; } +else if(color == "darkorange"){ col = Colors::DarkOrange; return true; } +else if(color == "darkorchid"){ col = Colors::DarkOrchid; return true; } +else if(color == "darkred"){ col = Colors::DarkRed; return true; } +else if(color == "darksalmon"){ col = Colors::DarkSalmon; return true; } +else if(color == "darkseagreen"){ col = Colors::DarkSeaGreen; return true; } +else if(color == "darkslateblue"){ col = Colors::DarkSlateBlue; return true; } +else if(color == "darkslategray"){ col = Colors::DarkSlateGray; return true; } +else if(color == "darkslategrey"){ col = Colors::DarkSlateGrey; return true; } +else if(color == "darkturquoise"){ col = Colors::DarkTurquoise; return true; } +else if(color == "darkviolet"){ col = Colors::DarkViolet; return true; } +else if(color == "deeppink"){ col = Colors::DeepPink; return true; } +else if(color == "deepskyblue"){ col = Colors::DeepSkyBlue; return true; } +else if(color == "dimgray"){ col = Colors::DimGray; return true; } +else if(color == "dimgrey"){ col = Colors::DimGrey; return true; } +else if(color == "dodgerblue"){ col = Colors::DodgerBlue; return true; } +else if(color == "firebrick"){ col = Colors::FireBrick; return true; } +else if(color == "floralwhite"){ col = Colors::FloralWhite; return true; } +else if(color == "forestgreen"){ col = Colors::ForestGreen; return true; } +else if(color == "fuchsia"){ col = Colors::Fuchsia; return true; } +else if(color == "gainsboro"){ col = Colors::Gainsboro; return true; } +else if(color == "ghostwhite"){ col = Colors::GhostWhite; return true; } +else if(color == "gold"){ col = Colors::Gold; return true; } +else if(color == "goldenrod"){ col = Colors::GoldenRod; return true; } +else if(color == "gray"){ col = Colors::Gray; return true; } +else if(color == "grey"){ col = Colors::Grey; return true; } +else if(color == "green"){ col = Colors::Green; return true; } +else if(color == "greenyellow"){ col = Colors::GreenYellow; return true; } +else if(color == "honeydew"){ col = Colors::HoneyDew; return true; } +else if(color == "hotpink"){ col = Colors::HotPink; return true; } +else if(color == "indianred"){ col = Colors::IndianRed; return true; } +else if(color == "indigo"){ col = Colors::Indigo; return true; } +else if(color == "ivory"){ col = Colors::Ivory; return true; } +else if(color == "khaki"){ col = Colors::Khaki; return true; } +else if(color == "lavender"){ col = Colors::Lavender; return true; } +else if(color == "lavenderblush"){ col = Colors::LavenderBlush; return true; } +else if(color == "lawngreen"){ col = Colors::LawnGreen; return true; } +else if(color == "lemonchiffon"){ col = Colors::LemonChiffon; return true; } +else if(color == "lightblue"){ col = Colors::LightBlue; return true; } +else if(color == "lightcoral"){ col = Colors::LightCoral; return true; } +else if(color == "lightcyan"){ col = Colors::LightCyan; return true; } +else if(color == "lightgoldenrodyellow"){ col = Colors::LightGoldenRodYellow; return true; } +else if(color == "lightgray"){ col = Colors::LightGray; return true; } +else if(color == "lightgrey"){ col = Colors::LightGrey; return true; } +else if(color == "lightgreen"){ col = Colors::LightGreen; return true; } +else if(color == "lightpink"){ col = Colors::LightPink; return true; } +else if(color == "lightsalmon"){ col = Colors::LightSalmon; return true; } +else if(color == "lightseagreen"){ col = Colors::LightSeaGreen; return true; } +else if(color == "lightskyblue"){ col = Colors::LightSkyBlue; return true; } +else if(color == "lightslategray"){ col = Colors::LightSlateGray; return true; } +else if(color == "lightslategrey"){ col = Colors::LightSlateGrey; return true; } +else if(color == "lightsteelblue"){ col = Colors::LightSteelBlue; return true; } +else if(color == "lightyellow"){ col = Colors::LightYellow; return true; } +else if(color == "lime"){ col = Colors::Lime; return true; } +else if(color == "limegreen"){ col = Colors::LimeGreen; return true; } +else if(color == "linen"){ col = Colors::Linen; return true; } +else if(color == "magenta"){ col = Colors::Magenta; return true; } +else if(color == "maroon"){ col = Colors::Maroon; return true; } +else if(color == "mediumaquamarine"){ col = Colors::MediumAquaMarine; return true; } +else if(color == "mediumblue"){ col = Colors::MediumBlue; return true; } +else if(color == "mediumorchid"){ col = Colors::MediumOrchid; return true; } +else if(color == "mediumpurple"){ col = Colors::MediumPurple; return true; } +else if(color == "mediumseagreen"){ col = Colors::MediumSeaGreen; return true; } +else if(color == "mediumslateblue"){ col = Colors::MediumSlateBlue; return true; } +else if(color == "mediumspringgreen"){ col = Colors::MediumSpringGreen; return true; } +else if(color == "mediumturquoise"){ col = Colors::MediumTurquoise; return true; } +else if(color == "mediumvioletred"){ col = Colors::MediumVioletRed; return true; } +else if(color == "midnightblue"){ col = Colors::MidnightBlue; return true; } +else if(color == "mintcream"){ col = Colors::MintCream; return true; } +else if(color == "mistyrose"){ col = Colors::MistyRose; return true; } +else if(color == "moccasin"){ col = Colors::Moccasin; return true; } +else if(color == "navajowhite"){ col = Colors::NavajoWhite; return true; } +else if(color == "navy"){ col = Colors::Navy; return true; } +else if(color == "oldlace"){ col = Colors::OldLace; return true; } +else if(color == "olive"){ col = Colors::Olive; return true; } +else if(color == "olivedrab"){ col = Colors::OliveDrab; return true; } +else if(color == "orange"){ col = Colors::Orange; return true; } +else if(color == "orangered"){ col = Colors::OrangeRed; return true; } +else if(color == "orchid"){ col = Colors::Orchid; return true; } +else if(color == "palegoldenrod"){ col = Colors::PaleGoldenRod; return true; } +else if(color == "palegreen"){ col = Colors::PaleGreen; return true; } +else if(color == "paleturquoise"){ col = Colors::PaleTurquoise; return true; } +else if(color == "palevioletred"){ col = Colors::PaleVioletRed; return true; } +else if(color == "papayawhip"){ col = Colors::PapayaWhip; return true; } +else if(color == "peachpuff"){ col = Colors::PeachPuff; return true; } +else if(color == "peru"){ col = Colors::Peru; return true; } +else if(color == "pink"){ col = Colors::Pink; return true; } +else if(color == "plum"){ col = Colors::Plum; return true; } +else if(color == "powderblue"){ col = Colors::PowderBlue; return true; } +else if(color == "purple"){ col = Colors::Purple; return true; } +else if(color == "rebeccapurple"){ col = Colors::RebeccaPurple; return true; } +else if(color == "red"){ col = Colors::Red; return true; } +else if(color == "rosybrown"){ col = Colors::RosyBrown; return true; } +else if(color == "saddlebrown"){ col = Colors::SaddleBrown; return true; } +else if(color == "salmon"){ col = Colors::Salmon; return true; } +else if(color == "sandybrown"){ col = Colors::SandyBrown; return true; } +else if(color == "seagreen"){ col = Colors::SeaGreen; return true; } +else if(color == "seashell"){ col = Colors::SeaShell; return true; } +else if(color == "sienna"){ col = Colors::Sienna; return true; } +else if(color == "silver"){ col = Colors::Silver; return true; } +else if(color == "skyblue"){ col = Colors::SkyBlue; return true; } +else if(color == "slateblue"){ col = Colors::SlateBlue; return true; } +else if(color == "slategray"){ col = Colors::SlateGray; return true; } +else if(color == "slategrey"){ col = Colors::SlateGrey; return true; } +else if(color == "snow"){ col = Colors::Snow; return true; } +else if(color == "springgreen"){ col = Colors::SpringGreen; return true; } +else if(color == "steelblue"){ col = Colors::SteelBlue; return true; } +else if(color == "tan"){ col = Colors::Tan; return true; } +else if(color == "teal"){ col = Colors::Teal; return true; } +else if(color == "thistle"){ col = Colors::Thistle; return true; } +else if(color == "tomato"){ col = Colors::Tomato; return true; } +else if(color == "turquoise"){ col = Colors::Turquoise; return true; } +else if(color == "violet"){ col = Colors::Violet; return true; } +else if(color == "wheat"){ col = Colors::Wheat; return true; } +else if(color == "white"){ col = Colors::White; return true; } +else if(color == "whitesmoke"){ col = Colors::WhiteSmoke; return true; } +else if(color == "yellow"){ col = Colors::Yellow; return true; } +else if(color == "yellowgreen"){ col = Colors::YellowGreen; return true; } + } + else if(color.size() == 4) + { + for(size_t i = 1; i < 4; i++) + if((color[i] < 'a' || color[i] > 'f') && (color[i] < '0' || color[i] > '9')) return false; + uint8_t r = HttpUtils::HexToNibble(color[1]); + uint8_t g = HttpUtils::HexToNibble(color[2]); + uint8_t b = HttpUtils::HexToNibble(color[3]); + col.Red = r | r << 4; + col.Green = g | g << 4; + col.Blue = b | b << 4; + col.Alpha = 255; + return true; + } + else if(color.size() == 5) + { + for(size_t i = 1; i < 5; i++) + if((color[i] < 'a' || color[i] > 'f') && (color[i] < '0' || color[i] > '9')) return false; + uint8_t r = HttpUtils::HexToNibble(color[1]); + uint8_t g = HttpUtils::HexToNibble(color[2]); + uint8_t b = HttpUtils::HexToNibble(color[3]); + uint8_t a = HttpUtils::HexToNibble(color[4]); + col.Red = r | r << 4; + col.Green = g | g << 4; + col.Blue = b | b << 4; + col.Alpha = a | a << 4; + return true; + } + else if(color.size() == 7) + { + for(size_t i = 1; i < 7; i++) + if((color[i] < 'a' || color[i] > 'f') && (color[i] < '0' || color[i] > '9')) return false; + uint8_t r = (HttpUtils::HexToNibble(color[1]) << 4) | HttpUtils::HexToNibble(color[2]); + uint8_t g = (HttpUtils::HexToNibble(color[3]) << 4) | HttpUtils::HexToNibble(color[4]); + uint8_t b = (HttpUtils::HexToNibble(color[5]) << 4) | HttpUtils::HexToNibble(color[6]); + col.Red = r; + col.Green = g; + col.Blue = b; + col.Alpha = 255; + return true; + } + else if(color.size() == 9) + { + for(size_t i = 1; i < 9; i++) + if((color[i] < 'a' || color[i] > 'f') && (color[i] < '0' || color[i] > '9')) return false; + uint8_t r = (HttpUtils::HexToNibble(color[1]) << 4) | HttpUtils::HexToNibble(color[2]); + uint8_t g = (HttpUtils::HexToNibble(color[3]) << 4) | HttpUtils::HexToNibble(color[4]); + uint8_t b = (HttpUtils::HexToNibble(color[5]) << 4) | HttpUtils::HexToNibble(color[6]); + uint8_t a = (HttpUtils::HexToNibble(color[7]) << 4) | HttpUtils::HexToNibble(color[8]); + + col.Red = r; + col.Green = g; + col.Blue = b; + col.Alpha = a; + return true; + return true; + } + return false; + } + + Color Color::Parse(std::string color) + { + Color c; + if(Color::TryParse(color,c)) return c; + throw TextException("Could not parse color"); + } + bool Color::operator!=(Color other) + { + return !(*this == other); + } + bool Color::operator==(Color other) + { + return Red == other.Red && Green == other.Green && Blue == other.Blue && Alpha == other.Alpha; + } +} \ No newline at end of file diff --git a/src/Graphics/Image.cpp b/src/Graphics/Image.cpp new file mode 100644 index 0000000..8146920 --- /dev/null +++ b/src/Graphics/Image.cpp @@ -0,0 +1,56 @@ +#include "TessesFramework/Graphics/Image.hpp" + +namespace Tesses::Framework::Graphics { + + Image::Image() + { + + } + Image::Image(uint32_t w, uint32_t h) + { + this->w = w; + this->h = h; + SetSize(w,h); + } + Image::Image(uint32_t w,uint32_t h,std::vector data) + { + this->w = w; + this->h = h; + this->data = data; + if(this->data.size() != w * h) throw TextException("data size does not match the factor of width and height"); + } + uint32_t Image::Width() + { + return this->w; + } + uint32_t Image::Height() + { + return this->h; + } + void Image::SetSize(uint32_t w, uint32_t h) + { + this->w = w; + this->h = h; + this->data.resize(w * h); + } + void Image::SetSize(uint32_t w, uint32_t h, Color c) + { + this->w = w; + this->h = h; + this->data.resize(w * h); + for(size_t i = 0; i < this->data.size(); i++) this->data[i] = c; + } + void Image::SetPixel(uint32_t x, uint32_t y, Color c) + { + this->data[y*w+x] = c; + } + Color Image::GetPixel(uint32_t x, uint32_t y) + { + return this->data[y*w+x]; + } + + std::vector& Image::Data() + { + return this->data; + } +} \ No newline at end of file diff --git a/src/Graphics/ImageFormats/Bitmap.cpp b/src/Graphics/ImageFormats/Bitmap.cpp new file mode 100644 index 0000000..da65e95 --- /dev/null +++ b/src/Graphics/ImageFormats/Bitmap.cpp @@ -0,0 +1,201 @@ +#include "TessesFramework/Graphics/ImageFormats/Bitmap.hpp" +#include "TessesFramework/Streams/ByteWriter.hpp" +#include "TessesFramework/Streams/MemoryStream.hpp" +#include +namespace Tesses::Framework::Graphics::ImageFormats { + Bitmap::Bitmap() + { + + } + void Bitmap::Load(Tesses::Framework::Streams::Stream* strm, Image* image) + { + uint8_t header[14]; + if(strm->ReadBlock(header,14) < 14) throw TextException("Invalid bmp file, header to small."); + if(header[0] != 0x42 || header[1] != 0x4D) throw TextException("Invalid bmp file, does not start with BM."); + uint8_t info_header[40]; + if(strm->ReadBlock(info_header,40) < 40) throw TextException("Invalid bmp file, info header is too small."); + if(info_header[0] != 40 || info_header[1] != 0 || info_header[2] != 0 || info_header[3] != 0) throw TextException("Invald bmp file, info header size is corrupt."); + uint32_t width = 0; + width |= (uint32_t)info_header[4]; + width |= (uint32_t)info_header[5] << 8; + width |= (uint32_t)info_header[6] << 16; + width |= (uint32_t)info_header[7] << 24; + uint32_t height = 0; + height |= (uint32_t)info_header[8]; + height |= (uint32_t)info_header[9] << 8; + height |= (uint32_t)info_header[10] << 16; + height |= (uint32_t)info_header[11] << 24; + + int32_t h0= *(int32_t*)&height; + bool isInverted=h0 < 0; + if(isInverted) height = (uint32_t)(-h0); + + image->SetSize(width,height); + uint16_t planes = 0; + planes |= (uint16_t)info_header[12]; + planes |= (uint16_t)info_header[13] << 8; + if(planes != 1) throw TextException("Planes is not 1"); + uint16_t bpp = 0; + bpp |= (uint16_t)info_header[14]; + bpp |= (uint16_t)info_header[15] << 8; + uint32_t compression = 0; + compression |= (uint32_t)info_header[16]; + compression |= (uint32_t)info_header[17] << 8; + compression |= (uint32_t)info_header[18] << 16; + compression |= (uint32_t)info_header[19] << 24; + + if(compression != 0) throw TextException("This bmp decoder does not support compression"); + uint32_t imageSize = 0; + imageSize |= (uint32_t)info_header[20]; + imageSize |= (uint32_t)info_header[21] << 8; + imageSize |= (uint32_t)info_header[22] << 16; + imageSize |= (uint32_t)info_header[23] << 24; + + uint32_t colorsUsed = 0; + colorsUsed |= (uint32_t)info_header[32]; + colorsUsed |= (uint32_t)info_header[33] << 8; + colorsUsed |= (uint32_t)info_header[34] << 16; + colorsUsed |= (uint32_t)info_header[35] << 24; + + std::vector col={}; + + if(colorsUsed > 0) + { + col.resize(colorsUsed); + uint8_t* buff = new uint8_t[colorsUsed*4]; + if(strm->ReadBlock(buff,colorsUsed*4) != colorsUsed*4) { delete buff; throw TextException("Could not read colors");} + for(size_t i = 0; i < colorsUsed; i++) + { + col[i].Red = buff[i * 4 + 2]; + col[i].Green = buff[i * 4 + 1]; + col[i].Blue = buff[i * 4]; + col[i].Alpha = 255; + } + delete buff; + } + std::vector& pixel_out = image->Data(); + if(bpp == 24) + { + uint32_t stride = 3 * width; + uint32_t m = stride % 4; + if(m != 0) stride += 4 - (m % 4); + + uint8_t* buffer = new uint8_t[stride]; + for(uint32_t y = 0; y < height; y++) + { + + uint32_t yOut = isInverted ? y : ((height - y)-1); + if(strm->ReadBlock(buffer,stride) != stride) + { + delete buffer; + throw TextException("Bmp image data is truncated"); + } + for(uint32_t x = 0; x < width; x++) + { + pixel_out[yOut * width + x].Red = buffer[x*3+2]; + pixel_out[yOut * width + x].Green = buffer[x*3+1]; + pixel_out[yOut * width + x].Blue = buffer[x*3]; + pixel_out[yOut * width + x].Alpha=255; + } + } + delete buffer; + } + else if(bpp == 16) + { + uint32_t stride = 2 * width; + uint32_t m = stride % 4; + if(m != 0) stride += 4 - (m % 4); + + uint8_t* buffer = new uint8_t[stride]; + for(uint32_t y = 0; y < height; y++) + { + uint32_t yOut =isInverted ? y : ((height - y)-1); + if(strm->ReadBlock(buffer,stride) != stride) + { + delete buffer; + throw TextException("Bmp image data is truncated"); + } + for(uint32_t x = 0; x < width; x++) + { + uint16_t px = (uint16_t)(buffer[x*2+1] << 8) | (uint16_t)buffer[x*2]; + uint16_t red = (px & 0xF800) >> 11; + uint16_t green = (px & 0x07E0) >> 5; + uint16_t blue = (px & 0x001F); + red = (red * 255 + 15) / 31; + green = (green * 255 + 31) / 63; + blue = (blue * 255 + 15) / 31; + pixel_out[yOut * width + x].Red = red; + pixel_out[yOut * width + x].Green = green; + pixel_out[yOut * width + x].Blue = blue; + pixel_out[yOut * width + x].Alpha=255; + } + } + delete buffer; + } + else if(bpp == 8) + { + uint32_t stride = width; + + uint8_t* buffer = new uint8_t[stride]; + for(uint32_t y = 0; y < height; y++) + { + uint32_t yOut =isInverted ? y : ((height - y)-1); + if(strm->ReadBlock(buffer,stride) != stride) + { + delete buffer; + throw TextException("Bmp image data is truncated"); + } + for(uint32_t x = 0; x < width; x++) + { + pixel_out[yOut * width + x] = col.at (buffer[x]); + } + } + delete buffer; + } + else throw TextException("Bitdepth " + std::to_string(bpp) + "bpp is not supported yet."); + } + void Bitmap::Save(Tesses::Framework::Streams::Stream* strm, Image* image,std::string flags) + { + Tesses::Framework::Streams::MemoryStream memStrm(true); + Tesses::Framework::Streams::ByteWriter writer(memStrm); + uint32_t stride = image->Width() * 3; + uint32_t m = stride % 4; + if(m != 0) stride += 4 - (m % 4); + uint32_t sz = (stride * image->Height())+14+40; + memStrm.WriteBlock((const uint8_t*)"BM",2); + + writer.WriteU32LE(sz); + writer.WriteU32LE(0); + writer.WriteU32LE(14+40); + writer.WriteU32LE(40); + writer.WriteU32LE(image->Width()); + writer.WriteU32LE(image->Height()); + writer.WriteU16LE(1); + writer.WriteU16LE(24); + writer.WriteU32LE(0); + writer.WriteU32LE(0); + writer.WriteU32LE(0); + writer.WriteU32LE(0); + writer.WriteU32LE(0); + writer.WriteU32LE(0); + memStrm.Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin); + memStrm.CopyTo(strm); + uint8_t* buffer = new uint8_t[stride]; + memset(buffer,0,stride); + auto width = image->Width(); + auto height = image->Height(); + for(uint32_t y = 0; y < height; y++) + { + + uint32_t yOut = (height - y)-1; + for(uint32_t x = 0; x < width; x++) + { + auto c = image->GetPixel(x,yOut); + buffer[x*3+2] = c.Red; + buffer[x*3+1] = c.Green; + buffer[x*3] = c.Blue; + } + strm->WriteBlock(buffer,stride); + } + } +} \ No newline at end of file diff --git a/src/Graphics/ImageFormats/ImageFormat.cpp b/src/Graphics/ImageFormats/ImageFormat.cpp new file mode 100644 index 0000000..849486b --- /dev/null +++ b/src/Graphics/ImageFormats/ImageFormat.cpp @@ -0,0 +1,11 @@ +#include "TessesFramework/Graphics/ImageFormats/ImageFormat.hpp" + +namespace Tesses::Framework::Graphics::ImageFormats +{ + + + ImageFormat::~ImageFormat() + { + + } +}; \ No newline at end of file diff --git a/src/Graphics/Renderers/ImageRenderer.cpp b/src/Graphics/Renderers/ImageRenderer.cpp new file mode 100644 index 0000000..c8644be --- /dev/null +++ b/src/Graphics/Renderers/ImageRenderer.cpp @@ -0,0 +1,24 @@ + + +#include "TessesFramework/Graphics/Renderers/ImageRenderer.hpp" + +namespace Tesses::Framework::Graphics::Renderers { + + + ImageRenderer::ImageRenderer(Image* image) + { + this->image = image; + } + uint32_t ImageRenderer::Width() + { + return this->image->Width(); + } + uint32_t ImageRenderer::Height() + { + return this->image->Height(); + } + void ImageRenderer::SetPixel(Point pt,Color c) + { + this->image->SetPixel(pt.X,pt.Y,c); + } +}; \ No newline at end of file diff --git a/src/Graphics/Renderers/Renderer.cpp b/src/Graphics/Renderers/Renderer.cpp new file mode 100644 index 0000000..348baf9 --- /dev/null +++ b/src/Graphics/Renderers/Renderer.cpp @@ -0,0 +1,53 @@ + + +#include "TessesFramework/Graphics/Renderers/Renderer.hpp" +namespace Tesses::Framework::Graphics::Renderers { + + void Renderer::DrawImage(Point pt, Image* image) + { + auto width = std::min(image->Width(),Width()- pt.X); + auto height = std::min(image->Height(),Height()-pt.Y); + for(uint32_t y = 0; y < height; y++) + { + for(uint32_t x = 0; x < width; x++) + { + this->SetPixel(Point(x+pt.X,y+pt.Y),image->GetPixel(x,y)); + } + } + } + void Renderer::DrawRectangle(Rectangle rect, Color c, bool fill) + { + + int32_t xMin = rect.Location.X; + int32_t xMax = (rect.Size.Width + xMin)-1; + int64_t yMin = rect.Location.Y; + int64_t yMax = (rect.Size.Height + yMin)-1; + if(fill) + { + for(int32_t y = yMin; y <= yMax;y++) + { + for(int32_t x = xMin; x <=xMax;x++) + { + SetPixel(Point(x,y),c); + } + } + } + else + { + for(int32_t x = xMin; x <=xMax;x++) + { + SetPixel(Point(x,yMin),c); + SetPixel(Point(x,yMax),c); + } + for(int32_t y = yMin; y <= yMax;y++) + { + SetPixel(Point(xMin,y),c); + SetPixel(Point(xMax,y),c); + } + } + } + Renderer::~Renderer() + { + + } +}; \ No newline at end of file diff --git a/src/HiddenField.cpp b/src/HiddenField.cpp new file mode 100644 index 0000000..ae6c9e1 --- /dev/null +++ b/src/HiddenField.cpp @@ -0,0 +1,30 @@ +#include "TessesFramework/HiddenField.hpp" + +namespace Tesses::Framework +{ + +HiddenFieldData::~HiddenFieldData() +{ + +} + + + +HiddenField::HiddenField() +{ + this->ptr = nullptr; +} +HiddenField::HiddenField(HiddenFieldData* data) +{ + this->ptr = data; +} +void HiddenField::SetField(HiddenFieldData* data) +{ + if(this->ptr != nullptr) delete this->ptr; + this->ptr = data; +} +HiddenField::~HiddenField() +{ + if(this->ptr != nullptr) delete this->ptr; +} +} \ No newline at end of file diff --git a/src/Http/HttpServer.cpp b/src/Http/HttpServer.cpp index 76730a9..58cd048 100644 --- a/src/Http/HttpServer.cpp +++ b/src/Http/HttpServer.cpp @@ -923,15 +923,17 @@ namespace Tesses::Framework::Http std::string connection; if(ctx.requestHeaders.TryGetFirst("Connection", connection)) { - if(connection != "keep-alive") return; + if(HttpUtils::ToLower(connection) != "keep-alive") return; } if(ctx.responseHeaders.TryGetFirst("Connection", connection)) { - if(connection != "keep-alive") return; + if(HttpUtils::ToLower(connection) != "keep-alive") return; } - if(bStrm.EndOfStream()) return; + if(bStrm.EndOfStream()) { + return; + } } } diff --git a/src/Http/HttpUtils.cpp b/src/Http/HttpUtils.cpp index ceff92a..8c6cdaf 100644 --- a/src/Http/HttpUtils.cpp +++ b/src/Http/HttpUtils.cpp @@ -2,6 +2,7 @@ #include "TessesFramework/Filesystem/VFS.hpp" using VFSPath = Tesses::Framework::Filesystem::VFSPath; namespace Tesses::Framework::Http { + bool Uri::Relative(std::string url, Uri& uri) { auto index = url.find_first_of("//"); @@ -727,6 +728,24 @@ namespace Tesses::Framework::Http { } return true; } + bool CaseInsensitiveLess::operator() (const std::string& s1, const std::string& s2) const { + return HttpUtils::ToLower(s1) < HttpUtils::ToLower(s2); + + } + + std::string HttpUtils::ToLower(std::string str) + { + std::string str1(str.length(),' '); + std::transform(str.begin(), str.end(), str1.begin(), tolower); + return str1; + } + + std::string HttpUtils::ToUpper(std::string str) + { + std::string str1(str.length(),' '); + std::transform(str.begin(), str.end(), str1.begin(), toupper); + return str1; + } bool HttpDictionary::GetFirstBoolean(std::string key) { diff --git a/src/Streams/ByteReader.cpp b/src/Streams/ByteReader.cpp new file mode 100644 index 0000000..6a286d0 --- /dev/null +++ b/src/Streams/ByteReader.cpp @@ -0,0 +1,160 @@ +#include "TessesFramework/Streams/ByteReader.hpp" +namespace Tesses::Framework::Streams +{ + Stream* ByteReader::GetStream() + { + return this->strm; + } + ByteReader::ByteReader(Stream* strm, bool owns) + { + this->strm = strm; + this->owns = owns; + } + ByteReader::ByteReader(Stream& strm) : ByteReader(&strm,false) + { + + } + uint8_t ByteReader::ReadU8() + { + auto r = this->strm->ReadByte(); + if(r < 0) throw TextException("End of file"); + return (uint8_t)r; + } + uint16_t ByteReader::ReadU16BE() + { + uint8_t data[2]; + if(this->strm->ReadBlock(data,2) != 2) throw TextException("End of file"); + uint16_t n = 0; + n |= (uint16_t)data[0] << 8; + n |= (uint16_t)data[1]; + + return n; + } + uint16_t ByteReader::ReadU16LE() + { + uint8_t data[2]; + if(this->strm->ReadBlock(data,2) != 2) throw TextException("End of file"); + uint16_t n = 0; + n |= (uint16_t)data[0]; + n |= (uint16_t)data[1] << 8; + + + return n; + } + uint32_t ByteReader::ReadU32BE() + { + + uint8_t data[4]; + if(this->strm->ReadBlock(data,4) != 4) throw TextException("End of file"); + uint32_t n = 0; + n |= (uint32_t)data[0] << 24; + n |= (uint32_t)data[1] << 16; + n |= (uint32_t)data[2] << 8; + n |= (uint32_t)data[3]; + + return n; + } + uint32_t ByteReader::ReadU32LE() + { + uint8_t data[4]; + if(this->strm->ReadBlock(data,4) != 4) throw TextException("End of file"); + uint32_t n = 0; + n |= (uint32_t)data[0]; + n |= (uint32_t)data[1] << 8; + n |= (uint32_t)data[2] << 16; + n |= (uint32_t)data[3] << 24; + return n; + } + uint64_t ByteReader::ReadU64BE() + { + uint8_t data[8]; + if(this->strm->ReadBlock(data,8) != 8) throw TextException("End of file"); + uint64_t n = 0; + n |= (uint64_t)data[0] << 56; + n |= (uint64_t)data[1] << 48; + n |= (uint64_t)data[2] << 40; + n |= (uint64_t)data[3] << 32; + n |= (uint64_t)data[4] << 24; + n |= (uint64_t)data[5] << 16; + n |= (uint64_t)data[6] << 8; + n |= (uint64_t)data[7]; + + return n; + } + uint64_t ByteReader::ReadU64LE() + { + uint8_t data[8]; + if(this->strm->ReadBlock(data,8) != 8) throw TextException("End of file"); + uint64_t n = 0; + n |= (uint64_t)data[0]; + n |= (uint64_t)data[1] << 8; + n |= (uint64_t)data[2] << 16; + n |= (uint64_t)data[3] << 24; + n |= (uint64_t)data[4] << 32; + n |= (uint64_t)data[5] << 40; + n |= (uint64_t)data[6] << 48; + n |= (uint64_t)data[7] << 56; + + + return n; + } + int8_t ByteReader::ReadI8() + { + auto v=ReadU8(); + return *(int8_t*)&v; + } + int16_t ByteReader::ReadI16BE() + { + auto v=ReadU16BE(); + return *(int16_t*)&v; + } + int16_t ByteReader::ReadI16LE() + { + auto v=ReadU16BE(); + return *(int16_t*)&v; + } + int32_t ByteReader::ReadI32BE() + { + auto v=ReadU32BE(); + return *(int32_t*)&v; + } + int32_t ByteReader::ReadI32LE() + { + auto v=ReadU32LE(); + return *(int32_t*)&v; + } + int64_t ByteReader::ReadI64BE() + { + auto v=ReadU64BE(); + return *(int64_t*)&v; + } + int64_t ByteReader::ReadI64LE() + { + auto v=ReadU64LE(); + return *(int64_t*)&v; + } + float ByteReader::ReadF32BE() + { + auto v=ReadU32BE(); + return *(float*)&v; + } + float ByteReader::ReadF32LE() + { + auto v=ReadU32LE(); + return *(float*)&v; + } + double ByteReader::ReadF64BE() + { + auto v=ReadU64BE(); + return *(double*)&v; + } + double ByteReader::ReadF64LE() + { + auto v=ReadU64LE(); + return *(double*)&v; + } + ByteReader::~ByteReader() + { + if(this->owns) delete this->strm; + } +} \ No newline at end of file diff --git a/src/Streams/ByteWriter.cpp b/src/Streams/ByteWriter.cpp new file mode 100644 index 0000000..38f5530 --- /dev/null +++ b/src/Streams/ByteWriter.cpp @@ -0,0 +1,140 @@ +#include "TessesFramework/Streams/ByteWriter.hpp" +namespace Tesses::Framework::Streams +{ + Stream* ByteWriter::GetStream() + { + return this->strm; + } + ByteWriter::ByteWriter(Stream* strm, bool owns) + { + this->strm = strm; + this->owns = owns; + } + ByteWriter::ByteWriter(Stream& strm) : ByteWriter(&strm,false) + { + + } + void ByteWriter::WriteU8(uint8_t v) + { + strm->WriteByte(v); + } + void ByteWriter::WriteU16BE(uint16_t v) + { + uint8_t b[2]; + b[0] = (uint8_t)(v >> 8); + b[1] = (uint8_t)v; + strm->WriteBlock(b,2); + } + void ByteWriter::WriteU16LE(uint16_t v) + { + uint8_t b[2]; + b[0] = (uint8_t)v; + b[1] = (uint8_t)(v >> 8); + strm->WriteBlock(b,2); + } + void ByteWriter::WriteU32BE(uint32_t v) + { + uint8_t b[4]; + b[0] = (uint8_t)(v >> 24); + b[1] = (uint8_t)(v >> 16); + b[2] = (uint8_t)(v >> 8); + b[3] = (uint8_t)v; + strm->WriteBlock(b,4); + } + void ByteWriter::WriteU32LE(uint32_t v) + { + uint8_t b[4]; + b[0] = (uint8_t)v; + b[1] = (uint8_t)(v >> 8); + b[2] = (uint8_t)(v >> 16); + b[3] = (uint8_t)(v >> 24); + + strm->WriteBlock(b,4); + } + void ByteWriter::WriteU64BE(uint64_t v) + { + uint8_t b[8]; + b[0] = (uint8_t)(v >> 56); + b[1] = (uint8_t)(v >> 48); + b[2] = (uint8_t)(v >> 40); + b[3] = (uint8_t)(v >> 32); + b[4] = (uint8_t)(v >> 24); + b[5] = (uint8_t)(v >> 16); + b[6] = (uint8_t)(v >> 8); + b[7] = (uint8_t)v; + strm->WriteBlock(b,8); + } + void ByteWriter::WriteU64LE(uint64_t v) + { + uint8_t b[8]; + + b[0] = (uint8_t)v; + b[1] = (uint8_t)(v >> 8); + b[2] = (uint8_t)(v >> 16); + b[3] = (uint8_t)(v >> 24); + b[4] = (uint8_t)(v >> 32); + b[5] = (uint8_t)(v >> 40); + b[6] = (uint8_t)(v >> 48); + b[7] = (uint8_t)(v >> 56); + strm->WriteBlock(b,8); + } + void ByteWriter::WriteI8(int8_t v) + { + uint8_t data = *(uint8_t*)&v; + WriteU8(data); + } + void ByteWriter::WriteI16BE(int16_t v) + { + uint16_t data = *(uint16_t*)&v; + WriteU16BE(data); + } + void ByteWriter::WriteI16LE(int16_t v) + { + uint16_t data = *(uint16_t*)&v; + WriteU16LE(data); + } + void ByteWriter::WriteI32BE(int32_t v) + { + uint32_t data = *(uint32_t*)&v; + WriteU32BE(data); + } + void ByteWriter::WriteI32LE(int32_t v) + { + uint32_t data = *(uint32_t*)&v; + WriteU32LE(data); + } + void ByteWriter::WriteI64BE(int64_t v) + { + uint64_t data = *(uint64_t*)&v; + WriteU64BE(data); + } + void ByteWriter::WriteI64LE(int64_t v) + { + uint64_t data = *(uint64_t*)&v; + WriteU64LE(data); + } + void ByteWriter::WriteF32BE(float v) + { + uint32_t data = *(uint32_t*)&v; + WriteU32BE(data); + } + void ByteWriter::WriteF32LE(float v) + { + uint32_t data = *(uint32_t*)&v; + WriteU32LE(data); + } + void ByteWriter::WriteF64BE(double v) + { + uint64_t data = *(uint64_t*)&v; + WriteU64BE(data); + } + void ByteWriter::WriteF64LE(double v) + { + uint64_t data = *(uint64_t*)&v; + WriteU64LE(data); + } + ByteWriter::~ByteWriter() + { + if(this->owns) delete this->strm; + } +} \ No newline at end of file diff --git a/src/Streams/NetworkStream.cpp b/src/Streams/NetworkStream.cpp index 530f0d3..c5fec41 100644 --- a/src/Streams/NetworkStream.cpp +++ b/src/Streams/NetworkStream.cpp @@ -2,6 +2,9 @@ #include "TessesFramework/Http/HttpUtils.hpp" using HttpUtils = Tesses::Framework::Http::HttpUtils; +#if defined(TESSESFRAMEWORK_ENABLE_NETWORKING) + + #if defined(GEKKO) #define ss_family sin_family @@ -561,3 +564,110 @@ namespace Tesses::Framework::Streams { NETWORK_SETSOCKOPT(this->sock, SOL_SOCKET, TCP_NODELAY, (const char*)&noDelay2,(socklen_t)sizeof(noDelay2)); } } +#else +namespace Tesses::Framework::Streams { +class TcpServer { + int32_t sock; + bool owns; + bool valid; + public: + TcpServer(int32_t sock,bool owns); + TcpServer(uint16_t port, int32_t backlog); + TcpServer(std::string ip, uint16_t port, int32_t backlog); + NetworkStream* GetStream(std::string& ip, uint16_t& port); + ~TcpServer(); + void Close(); +}; +TcpServer::TcpServer(int32_t sock,bool owns) +{ + +} +TcpServer::TcpServer(uint16_t port, int32_t backlog) +{ + +} +TcpServer::TcpServer(std::string ip, uint16_t port, int32_t backlog) +{ + +} +NetworkStream* TcpServer::GetStream(std::string& ip, uint16_t& port) +{ + return nullptr; +} +TcpServer::~TcpServer() +{ + +} +void TcpServer::Close() +{ + +} +bool NetworkStream::EndOfStream() { + return true; +} +bool NetworkStream::CanRead() { + return false; +} +bool NetworkStream::CanWrite() { + return false; +} + +NetworkStream::NetworkStream(bool ipV6,bool datagram) +{ + +} +NetworkStream::NetworkStream(std::string ipOrFqdn, uint16_t port, bool datagram,bool broadcast,bool supportIPv6) +{ + +} +NetworkStream::NetworkStream(int32_t sock, bool owns) +{ + +} +void NetworkStream::Listen(int32_t backlog) +{ + +} +void NetworkStream::Bind(std::string ip, uint16_t port) +{ + +} +void NetworkStream::SetBroadcast(bool bC) +{ + +} +NetworkStream* NetworkStream::Accept(std::string& ip, uint16_t& port) +{ + return nullptr; +} +size_t NetworkStream::Read(uint8_t* buff, size_t sz) +{ + return 0; +} +size_t NetworkStream::Write(const uint8_t* buff, size_t sz) +{ + return 0; +} +size_t NetworkStream::ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port) +{ + return 0; +} +size_t NetworkStream::WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port) +{ + return 0; +} +std::vector> NetworkStream::GetIPs(bool ipV6) +{ + return {}; +} +NetworkStream::~NetworkStream() +{ + +} +void NetworkStream::SetNoDelay(bool noDelay) +{ + +} + +} +#endif \ No newline at end of file diff --git a/src/Threading/Mutex.cpp b/src/Threading/Mutex.cpp index 0127cf9..df0ca6b 100644 --- a/src/Threading/Mutex.cpp +++ b/src/Threading/Mutex.cpp @@ -1,62 +1,92 @@ #include "TessesFramework/Threading/Mutex.hpp" #include #include +#if defined(_WIN32) +#include +#elif defined(GEKKO) +#include +#else +#include +#endif namespace Tesses::Framework::Threading { + + + class MutexHiddenFieldData : public HiddenFieldData + { + public: + #if defined(_WIN32) + HANDLE mtx; + #elif defined(GEKKO) + mutex_t mtx; + #else + pthread_mutex_t mtx; + pthread_mutexattr_t attr; + #endif + ~MutexHiddenFieldData() + { + #if defined(_WIN32) + CloseHandle(mtx); + #elif defined(GEKKO) + LWP_MutexDestroy(mtx); + #else + pthread_mutex_destroy(&mtx); + pthread_mutexattr_destroy(&attr); + #endif + } + }; + Mutex::Mutex() { + auto md=this->data.AllocField(); #if defined(_WIN32) - this->mtx = CreateMutex(NULL,false,NULL); + md->mtx = CreateMutex(NULL,false,NULL); #elif defined(GEKKO) - mtx = LWP_MUTEX_NULL; - LWP_MutexInit(&mtx, true); + md->mtx = LWP_MUTEX_NULL; + LWP_MutexInit(&md->mtx, true); #else - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&mtx,&attr); + pthread_mutexattr_init(&md->attr); + pthread_mutexattr_settype(&md->attr,PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&md->mtx,&md->attr); #endif } void Mutex::Lock() { + auto md = this->data.GetField(); #if defined(_WIN32) - WaitForSingleObject(mtx, INFINITE); + WaitForSingleObject(md->mtx, INFINITE); #elif defined(GEKKO) - LWP_MutexLock(mtx); + LWP_MutexLock(md->mtx); #else - pthread_mutex_lock(&mtx); + pthread_mutex_lock(&md->mtx); #endif } void Mutex::Unlock() { + auto md = this->data.GetField(); #if defined(_WIN32) - ReleaseMutex(mtx); + ReleaseMutex(md->mtx); #elif defined(GEKKO) - LWP_MutexUnlock(mtx); + LWP_MutexUnlock(md->mtx); #else - pthread_mutex_unlock(&mtx); + pthread_mutex_unlock(&md->mtx); #endif } bool Mutex::TryLock() { + auto md = this->data.GetField(); #if defined(_WIN32) - return WaitForSingleObject(mtx, 100) == WAIT_OBJECT_0; + return WaitForSingleObject(md->mtx, 100) == WAIT_OBJECT_0; #elif defined(GEKKO) - return LWP_MutexTryLock(mtx) == 0; + return LWP_MutexTryLock(md->mtx) == 0; #else - return pthread_mutex_trylock(&mtx) == 0; + return pthread_mutex_trylock(&md->mtx) == 0; #endif } Mutex::~Mutex() { - #if defined(_WIN32) - CloseHandle(mtx); - #elif defined(GEKKO) - LWP_MutexDestroy(mtx); - #else - pthread_mutex_destroy(&mtx); - pthread_mutexattr_destroy(&attr); - #endif + } }; diff --git a/src/Threading/Thread.cpp b/src/Threading/Thread.cpp index e17eafa..3b1ef92 100644 --- a/src/Threading/Thread.cpp +++ b/src/Threading/Thread.cpp @@ -1,71 +1,95 @@ #include "TessesFramework/Threading/Thread.hpp" #include + namespace Tesses::Framework::Threading { + #if defined(TESSESFRAMEWORK_ENABLE_THREADING) + + class ThreadHiddenFieldData { + public: + #if defined(_WIN32) + + HANDLE thrd; + DWORD thrdId; + + public: + #elif defined(GEKKO) + lwp_t thrd; + + + #else + pthread_t thrd; + #endif + + + std::function fn; + + std::atomic hasInvoked; + }; + + #if defined(_WIN32) static DWORD __stdcall cb(LPVOID data) + #else + static void* cb(void* data) + #endif { - auto thrd = static_cast(data); + auto thrd = static_cast(data); auto fn = thrd->fn; thrd->hasInvoked=true; fn(); - #if defined(GEKKO) + #if !defined(_WIN32) return NULL; #else return 0; #endif } - #else - - - void* Thread::cb(void* data) - { - - auto thrd = static_cast(data); - - auto fn = thrd->fn; - thrd->hasInvoked=true; - fn(); - return NULL; - - } #endif + Thread::Thread(std::function fn) { - this->hasInvoked=false; - this->fn = fn; + #if defined(TESSESFRAMEWORK_ENABLE_THREADING) + auto data = this->data.AllocField(); + data->hasInvoked=false; + data->fn = fn; #if defined(_WIN32) - this->thrd = CreateThread(NULL,0,cb,static_cast(this), 0, &this->thrdId); + data->thrd = CreateThread(NULL,0,cb,static_cast(data), 0, &data->thrdId); #elif defined(GEKKO) - auto res = LWP_CreateThread(&this->thrd, cb, static_cast(this), nullptr,12000, 98); + auto res = LWP_CreateThread(&data->thrd, cb, static_cast(data), nullptr,12000, 98); #else - pthread_create(&thrd,NULL,cb,static_cast(this)); + pthread_create(&data->thrd,NULL,cb,static_cast(data)); //thrd_create(&thrd, cb, static_cast(this)); #endif - while(!this->hasInvoked); + while(!data->hasInvoked); + #endif } void Thread::Detach() { + #if defined(TESSESFRAMEWORK_ENABLE_THREADING) + auto data = this->data.AllocField(); #if !defined(GEKKO) #if defined(_WIN32) - CloseHandle(thrd); + CloseHandle(data->thrd); #else - pthread_detach(thrd); + pthread_detach(data->thrd); #endif #endif + #endif } void Thread::Join() { + #if defined(TESSESFRAMEWORK_ENABLE_THREADING) + auto data = this->data.AllocField(); #if defined(_WIN32) - WaitForSingleObject(this->thrd, INFINITE); + WaitForSingleObject(data->thrd, INFINITE); #elif defined(GEKKO) void* res; - LWP_JoinThread(thrd,&res); + LWP_JoinThread(data->thrd,&res); #else - pthread_join(thrd,NULL); + pthread_join(data->thrd,NULL); + #endif #endif - } } diff --git a/src/Threading/ThreadPool.cpp b/src/Threading/ThreadPool.cpp index 4d59453..4be7d29 100644 --- a/src/Threading/ThreadPool.cpp +++ b/src/Threading/ThreadPool.cpp @@ -8,12 +8,15 @@ namespace Tesses::Framework::Threading { #if defined(GEKKO) return 1; - #else + #elif defined(TESSESFRAMEWORK_ENABLE_THREADING) return (size_t)std::thread::hardware_concurrency(); + #else + return 1; #endif } ThreadPool::ThreadPool(size_t threads) { + #if defined(TESSESFRAMEWORK_ENABLE_THREADING) this->isRunning=true; for(size_t i = 0; i < threads; i++) { @@ -41,15 +44,19 @@ namespace Tesses::Framework::Threading } })); } + #endif } void ThreadPool::Schedule(std::function cb) { + #if defined(TESSESFRAMEWORK_ENABLE_THREADING) this->mtx.Lock(); this->callbacks.push(cb); this->mtx.Unlock(); + #endif } ThreadPool::~ThreadPool() { + #if defined(TESSESFRAMEWORK_ENABLE_THREADING) while(true) { this->mtx.Lock(); @@ -64,6 +71,6 @@ namespace Tesses::Framework::Threading item->Join(); delete item; } - + #endif } } \ No newline at end of file