Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
406 changes: 406 additions & 0 deletions .gitignore

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions include/cpp/encoding/Ascii.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

namespace cpp
{
namespace encoding
{
struct Ascii final
{
static bool isEncoded(const String& string);

/// <summary>
/// Encode the provided string to ASCII bytes and write them to the buffer.
/// If the provided string is UTF16 encoded an exception is raised and nothing is written to the buffer.
/// </summary>
/// <returns>Number of chars written to the buffer.</returns>
static int64_t encode(const String& string, cpp::marshal::View<uint8_t> buffer);

/// <summary>
/// Create a string from the provided ASCII bytes.
/// </summary>
static String decode(cpp::marshal::View<uint8_t> string);
};
}
}
24 changes: 24 additions & 0 deletions include/cpp/encoding/Utf16.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

namespace cpp
{
namespace encoding
{
struct Utf16 final
{
static bool isEncoded(const String& string);

static int getByteCount(const char32_t& codepoint);
static int64_t getByteCount(const String& string);

static int getCharCount(const char32_t& codepoint);
static int64_t getCharCount(const String& string);

static int encode(const char32_t& codepoint, cpp::marshal::View<uint8_t> buffer);
static int64_t encode(const String& string, cpp::marshal::View<uint8_t> buffer);

static char32_t codepoint(cpp::marshal::View<uint8_t> buffer);
static String decode(cpp::marshal::View<uint8_t> buffer);
};
}
}
22 changes: 22 additions & 0 deletions include/cpp/encoding/Utf8.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

namespace cpp
{
namespace encoding
{
struct Utf8 final
{
static int getByteCount(const char32_t& codepoint);
static int64_t getByteCount(const String& string);

static int getCharCount(const char32_t& codepoint);
static int64_t getCharCount(const String& string);

static int encode(const char32_t& codepoint, cpp::marshal::View<uint8_t> buffer);
static int64_t encode(const String& string, cpp::marshal::View<uint8_t> buffer);

static char32_t codepoint(cpp::marshal::View<uint8_t> buffer);
static String decode(cpp::marshal::View<uint8_t> buffer);
};
}
}
18 changes: 3 additions & 15 deletions include/cpp/marshal/Definitions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ namespace cpp
bool isEmpty();
View<T> slice(int64_t index);
View<T> slice(int64_t index, int64_t length);
void copyTo(const View<T>& destination);
bool tryCopyTo(const View<T>& destination);
template<class K> View<K> reinterpret();
int compare(const View<T>& inRHS);
Expand All @@ -210,10 +211,6 @@ namespace cpp
bool operator!=(const View<T>& inRHS) const;

T& operator[] (int64_t index);

operator void* ();
operator T* ();
operator Pointer<T>();
};

struct Marshal final
Expand All @@ -224,17 +221,8 @@ namespace cpp
static const bool isBigEndian = false;
#endif

static View<char> asView(const char* cstring);
static View<char16_t> asView(const char16_t* cstring);

static View<char> toCharView(const ::String& string);
static int toCharView(const ::String&, View<char> buffer);

static View<char16_t> toWideCharView(const ::String& string);
static int toWideCharView(const ::String& string, View<char16_t> buffer);

static ::String toString(View<char> buffer);
static ::String toString(View<char16_t> buffer);
static View<char> asCharView(const ::String& string);
static View<char16_t> asWideCharView(const ::String& string);

template<class T> static T read(View<uint8_t> view);
template<class T> static ::cpp::Pointer<T> readPointer(View<uint8_t> view);
Expand Down
70 changes: 18 additions & 52 deletions include/cpp/marshal/Marshal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,72 +18,38 @@ namespace
}
}

inline cpp::marshal::View<char> cpp::marshal::Marshal::asView(const char* cstring)
inline cpp::marshal::View<char> cpp::marshal::Marshal::asCharView(const ::String& string)
{
return cpp::marshal::View<char>(const_cast<char*>(cstring), static_cast<int>(std::char_traits<char>::length(cstring)));
}

inline cpp::marshal::View<char16_t> cpp::marshal::Marshal::asView(const char16_t* cstring)
{
return cpp::marshal::View<char16_t>(const_cast<char16_t*>(cstring), static_cast<int>(std::char_traits<char16_t>::length(cstring)));
}

inline cpp::marshal::View<char> cpp::marshal::Marshal::toCharView(const ::String& string)
{
auto length = 0;
auto ptr = string.utf8_str(nullptr, true, &length);

return View<char>(const_cast<char*>(ptr), length + 1);
}

inline int cpp::marshal::Marshal::toCharView(const ::String& string, View<char> buffer)
{
auto length = 0;

if (string.utf8_str(buffer, &length))
if (null() == string)
{
return length;
hx::NullReference("string", false);
}
else
{
hx::Throw(HX_CSTRING("Not enough space in the view to write the string"));

return 0;
if (false == string.isAsciiEncoded())
{
hx::Throw(HX_CSTRING("String is not ASCII encoded"));
}
}

inline cpp::marshal::View<char16_t> cpp::marshal::Marshal::toWideCharView(const ::String& string)
{
auto length = 0;
auto ptr = string.wc_str(nullptr, &length);

return View<char16_t>(const_cast<char16_t*>(ptr), length + 1);
return View<char>(const_cast<char*>(string.raw_ptr()), string.length);
}

inline int cpp::marshal::Marshal::toWideCharView(const ::String& string, View<char16_t> buffer)
inline cpp::marshal::View<char16_t> cpp::marshal::Marshal::asWideCharView(const ::String& string)
{
auto length = 0;

if (string.wc_str(buffer, &length))
#if defined(HX_SMART_STRINGS)
if (null() == string)
{
return length;
hx::NullReference("string", false);
}
else
{
hx::Throw(HX_CSTRING("Not enough space in the view to write the string"));

return 0;
if (false == string.isUTF16Encoded())
{
hx::Throw(HX_CSTRING("String is not ASCII encoded"));
}
}

inline ::String cpp::marshal::Marshal::toString(View<char> buffer)
{
return ::String::create(buffer);
}

inline ::String cpp::marshal::Marshal::toString(View<char16_t> buffer)
{
return ::String::create(buffer);
return View<char16_t>(const_cast<char16_t*>(string.raw_wptr()), string.length);
#else
return hx::Throw(HX_CSTRING("HX_SMART_STRINGS not defined"));
#endif
}

template<class T>
Expand Down
29 changes: 10 additions & 19 deletions include/cpp/marshal/View.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ inline bool cpp::marshal::View<T>::tryCopyTo(const View<T>& destination)
return true;
}

template<class T>
inline void cpp::marshal::View<T>::copyTo(const View<T>& destination)
{
if (tryCopyTo(destination) == false)
{
hx::Throw(HX_CSTRING("View OOB"));
}
}

template<class T>
inline void cpp::marshal::View<T>::clear()
{
Expand Down Expand Up @@ -67,7 +76,7 @@ template<class T>
template<class K>
inline cpp::marshal::View<K> cpp::marshal::View<T>::reinterpret()
{
auto newPtr = ::cpp::Pointer<K>{ ptr.reinterpret() };
auto newPtr = ::cpp::Pointer<K>(reinterpret_cast<K*>(ptr.ptr));
auto fromSize = sizeof(T);
auto toSize = sizeof(K);

Expand Down Expand Up @@ -121,22 +130,4 @@ inline T& cpp::marshal::View<T>::operator[](int64_t index)
}

return ptr[index];
}

template<class T>
inline cpp::marshal::View<T>::operator void* ()
{
return ptr.ptr;
}

template<class T>
inline cpp::marshal::View<T>::operator T* ()
{
return ptr.ptr;
}

template<class T>
inline cpp::marshal::View<T>::operator cpp::Pointer<T> ()
{
return ptr;
}
3 changes: 3 additions & 0 deletions include/hxcpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,9 @@ typedef PropertyAccessMode PropertyAccess;
#include <cpp/marshal/PointerReference.hpp>
#include <cpp/marshal/View.hpp>
#include <cpp/marshal/Marshal.hpp>
#include <cpp/encoding/Ascii.hpp>
#include <cpp/encoding/Utf8.hpp>
#include <cpp/encoding/Utf16.hpp>
#include <hx/Native.h>
#include <hx/Operators.h>
#include <hx/Functions.h>
Expand Down
66 changes: 66 additions & 0 deletions src/cpp/encoding/Ascii.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <hxcpp.h>

using namespace cpp::marshal;

bool cpp::encoding::Ascii::isEncoded(const String& string)
{
if (null() == string)
{
hx::NullReference("String", false);
}

return string.isAsciiEncoded();
}

int64_t cpp::encoding::Ascii::encode(const String& string, View<uint8_t> buffer)
{
if (null() == string)
{
hx::NullReference("String", false);
}

if (string.isUTF16Encoded())
{
hx::Throw(HX_CSTRING("String cannot be encoded to ASCII"));
}

auto src = cpp::marshal::View<char>(string.raw_ptr(), string.length).reinterpret<uint8_t>();

if (src.tryCopyTo(buffer))
{
return src.length;
}
else
{
return hx::Throw(HX_CSTRING("Buffer too small"));
}
}

String cpp::encoding::Ascii::decode(View<uint8_t> view)
{
if (view.isEmpty())
{
return hx::Throw(HX_CSTRING("View is empty"));
}

auto bytes = int64_t{ 0 };
auto i = int64_t{ 0 };
auto chars = view.reinterpret<char>();

while (i < chars.length && 0 != chars.ptr[i])
{
bytes += sizeof(char);
i++;
}

if (0 == bytes)
{
return String::emptyString;
}

auto backing = hx::NewGCPrivate(0, bytes + sizeof(char));

std::memcpy(backing, view.ptr.ptr, bytes);

return String(static_cast<const char*>(backing), bytes / sizeof(char));
}
Loading
Loading