Files
integration/Source/Integration/StringDecoder.h

211 lines
6.1 KiB
C++

#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<FlxStreamBufferCore, std::string> {
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<ElxLuaValueType> Types;
// For each chunk, a pointer to the serialized data.
//
TArray<std::string_view> Data;
// The current cursor.
//
int Cursor;
private:
// Clear everything.
//
void Empty();
// Compare two types. If they aren't equal, log an error and return false.
//
static bool CheckType(ElxLuaValueType Type, ElxLuaValueType Desired);
public:
UlxLuaValues() { Cursor = 0; }
// 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);
UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array")
FString DebugString() const;
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++); }
};