#pragma once #include "CoreMinimal.h" #include "lpx-basebuffer.hpp" #include "StringDecoder.generated.h" class FlxStreamBufferCore { private: bool err_eof_on_read_; bool err_string_too_long_; bool err_integer_truncated_; protected: void *basebuffer_malloc(size_t size) { return malloc(size); } void basebuffer_free(void *p) { free(p); } void clear_error_flags() { err_eof_on_read_ = err_string_too_long_ = err_integer_truncated_ = false; } void raise_eof_on_read() { err_eof_on_read_ = true; } void raise_string_too_long() { err_string_too_long_ = true; } void raise_integer_truncated() { err_integer_truncated_ = true; } public: bool get_err_eof_on_read() const { return err_eof_on_read_; } bool get_err_string_too_long() const { return err_string_too_long_; } bool get_err_integer_truncated() const { return err_integer_truncated_; } bool any_error() const { return err_eof_on_read_ || err_string_too_long_ || err_integer_truncated_; } }; class FlxStreamBuffer : public BaseBuffer { public: using BaseBuffer::BaseBuffer; using BaseBuffer::write_string; void write_string(const FString &str) { FTCHARToUTF8 utf8str(str); write_string(std::string_view(utf8str.Get(), utf8str.Length())); } void write_fname(const FName &name) { FTCHARToUTF8 utf8str(name.ToString()); write_string(std::string_view(utf8str.Get(), utf8str.Length())); } void write_string(const char *s) { write_string(std::string_view(s)); } void write_fvector(const FVector &xyz) { write_double(xyz.X); write_double(xyz.Y); write_double(xyz.Z); } FVector read_fvector() { double x = read_double(); double y = read_double(); double z = read_double(); return FVector(x, y, z); } FString read_fstring() { std::string_view s = read_string_view(); return FString(s.size(), (const UTF8CHAR *)s.data()); } FName read_fname() { std::string_view s = read_string_view(); return FName(s.size(), (const UTF8CHAR *)s.data(), FNAME_Add); } }; ///////////////////////////////////////////////////////////////// // // These are the types that can actually be packed into // a serialized buffer. // ///////////////////////////////////////////////////////////////// UENUM(BlueprintType) enum class ELxLuaValueType : uint8 { None, String, Name, Float, Boolean, Vector }; ///////////////////////////////////////////////////////////////// // // This class stores an array of values that were returned by Lua. // ///////////////////////////////////////////////////////////////// UCLASS(MinimalAPI) class UlxLuaValues : public UObject { GENERATED_BODY() private: // The raw serialized data returned by Lua. // std::string Serialized; // For each chunk, the type of the chunk. // TArray Types; // For each chunk, a pointer to the serialized data. // TArray Data; // The current cursor. // int Cursor; private: // Clear everything. // void Empty(); // Copies the data, and then preprocesses it to make sure // it's all valid. If it's not valid, returns false. // bool Initialize(std::string_view data); // Compare two types. If they aren't equal, log an error and return false. // static bool CheckType(ELxLuaValueType Type, ELxLuaValueType Desired); public: UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") int Length() const { return Types.Num(); } UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") int GetCursor() const { return Cursor; } UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") void SetCursor(int n) { Cursor = n; } private: // // Functions that get values from the array, random access. // UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") ELxLuaValueType GetType(int n) const; UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") bool IsType(int n, ELxLuaValueType Type) const { return GetType(n) == Type; } UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") FString GetString(int n) const; UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") FName GetName(int n) const; UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") double GetFloat(int n) const; UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") int GetInt(int n) const; UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") FVector GetVector(int n) const; UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") FVector2D GetVector2D(int n) const; UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") bool GetBoolean(int n) const; // // Functions that get values from the array using the cursor. // public: UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") ELxLuaValueType NextType() const { return GetType(Cursor); } UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") bool IsNextType(ELxLuaValueType Type) const { return IsType(Cursor, Type); } UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") FString ReadString() { return GetString(Cursor++); } UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") FName ReadName() { return GetName(Cursor++); } UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") double ReadFloat() { return GetFloat(Cursor++); } UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") int ReadInt() { return GetInt(Cursor++); } UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") FVector ReadVector() { return GetVector(Cursor++); } UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") FVector2D ReadVector2D() { return GetVector2D(Cursor++); } UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") bool ReadBoolean() { return GetBoolean(Cursor++); } };