This commit is contained in:
Joshua Ashton 2022-08-05 02:26:36 +00:00
parent 8a38007e35
commit aeed8530ad
6 changed files with 75 additions and 36 deletions

View File

@ -6,5 +6,6 @@
namespace orange::fs namespace orange::fs
{ {
Result<Buffer> OpenFileIntoBuffer(const char* path, bool text = false); Result<Buffer> OpenFileIntoBuffer(const char* path);
Result<TextBuffer> OpenFileIntoTextBuffer(const char* path);
} }

View File

@ -17,7 +17,7 @@ namespace orange::stream
if (result.ec == std::errc{}) if (result.ec == std::errc{})
{ {
first = result.ptr; first = result.ptr;
return Result<T>::Success(obj); return Result<T>::Success(obj);
} }
return Result<T>::Error(BasicErrorCode::NotFound); return Result<T>::Error(BasicErrorCode::NotFound);
@ -35,6 +35,11 @@ namespace orange::stream
return Parse<T>(first, first + strlen(first)); return Parse<T>(first, first + strlen(first));
} }
inline bool EndOfStream(const char* first, const char* end)
{
return first == end || *first == '\0';
}
inline bool CharMatches(char character, StringView delims) inline bool CharMatches(char character, StringView delims)
{ {
for (auto delim : delims) for (auto delim : delims)
@ -46,10 +51,10 @@ namespace orange::stream
return false; return false;
} }
inline size_t Consume(const char*& first, StringView delims) inline size_t Consume(const char*& first, const char* end, StringView delims)
{ {
size_t count = 0; size_t count = 0;
while (CharMatches(*first, delims)) while (!EndOfStream(first, end) && CharMatches(*first, delims))
{ {
first++; first++;
count++; count++;
@ -58,16 +63,16 @@ namespace orange::stream
return count; return count;
} }
inline size_t ConsumeSpace(const char*& first) inline size_t ConsumeSpace(const char*& first, const char* end)
{ {
return Consume(first, " \t"); return Consume(first, end, " \t");
} }
template <typename OutArray = SmallVector<char, 1>> template <typename OutArray = SmallVector<char, 1>>
size_t ReadOrAdvance(const char*& first, StringView delims, size_t advancement = 0, OutArray* array = nullptr) size_t ReadOrAdvance(const char*& first, const char* end, StringView delims, size_t advancement = 0, OutArray* array = nullptr)
{ {
size_t count = 0; size_t count = 0;
while (!CharMatches(*first, delims) && *first != '\0') while (!EndOfStream(first, end) && !CharMatches(*first, delims))
{ {
if (array) if (array)
array->PushBack(*first); array->PushBack(*first);
@ -75,7 +80,7 @@ namespace orange::stream
count++; count++;
} }
if (*first == '\0') if (EndOfStream(first, end))
return count; return count;
first += advancement; first += advancement;
@ -84,13 +89,13 @@ namespace orange::stream
} }
template <typename OutArray = SmallVector<char, 1>> template <typename OutArray = SmallVector<char, 1>>
size_t ReadString(const char*& first, StringView delims, OutArray& array) size_t ReadString(const char*& first, const char* end, StringView delims, OutArray& array)
{ {
return ReadOrAdvance(first, delims, 0, &array); return ReadOrAdvance(first, end, delims, 0, &array);
} }
inline size_t AdvancePast(const char*& first, StringView delims) inline size_t AdvancePast(const char*& first, const char* end, StringView delims)
{ {
return ReadOrAdvance(first, delims, 1); return ReadOrAdvance(first, end, delims, 1);
} }
} }

View File

@ -118,6 +118,11 @@ namespace orange
Ptr(--m_size)->~T(); Ptr(--m_size)->~T();
} }
bool Empty() const
{
return Size() == 0;
}
T& operator [] (size_t idx) { return *Ptr(idx); } T& operator [] (size_t idx) { return *Ptr(idx); }
const T& operator [] (size_t idx) const { return *Ptr(idx); } const T& operator [] (size_t idx) const { return *Ptr(idx); }
@ -171,4 +176,7 @@ namespace orange
}; };
template <typename T>
using Vector = SmallVector<T, sizeof(T) / sizeof(void*)>;
} }

View File

@ -58,8 +58,11 @@ namespace orange
}; };
using BufferView = Span<uint8_t>; using BufferView = Span<uint8_t>;
struct StringView : public Span<const char> struct StringView : public Span<const char>
{ {
using Span<const char>::Span;
StringView(const char* str) StringView(const char* str)
: Span<const char>{str, strlen(str)} {} : Span<const char>{str, strlen(str)} {}
}; };
@ -70,4 +73,11 @@ namespace orange
~Buffer() { delete[] data; } ~Buffer() { delete[] data; }
}; };
struct TextBuffer : public Span<char>
{
using Span<char>::Span;
~TextBuffer() { delete[] data; }
};
} }

View File

@ -10,23 +10,25 @@
using namespace orange; using namespace orange;
Result<VoidResult> ParseOBJ(BufferView buffer) Result<VoidResult> ParseOBJ(StringView buffer)
{ {
const char* obj = (const char *)buffer.data; const char* obj = buffer.data;
do const char* end = buffer.data + buffer.size;
while (obj != end)
{ {
SmallVector<char, 8> element; SmallVector<char, 8> element;
stream::ReadString(obj, " #\n", element); stream::ReadString(obj, end, " #\n", element);
if (element == "v" || element == "vn" || element == "vt") if (element == "v" || element == "vn" || element == "vt")
{ {
float vtx[3]{}; float vtx[3]{};
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
stream::ConsumeSpace(obj); stream::ConsumeSpace(obj, end);
auto r_float = stream::Parse<float>(obj); if (auto r_float = stream::Parse<float>(obj, end))
if (!r_float) return Result<VoidResult>::Error(); vtx[i] = *r_float;
vtx[i] = *r_float; else
return Result<VoidResult>::Error();
} }
element.PushBack('\0'); element.PushBack('\0');
@ -34,9 +36,9 @@ Result<VoidResult> ParseOBJ(BufferView buffer)
} }
else if (element == "g" || element == "o") else if (element == "g" || element == "o")
{ {
stream::ConsumeSpace(obj); stream::ConsumeSpace(obj, end);
SmallVector<char, 32> name; SmallVector<char, 32> name;
stream::ReadString(obj, " #\n", name); stream::ReadString(obj, end, " #\n", name);
name.PushBack('\0'); name.PushBack('\0');
if (element == "g") if (element == "g")
@ -49,18 +51,16 @@ Result<VoidResult> ParseOBJ(BufferView buffer)
int32_t indices[3][3]{}; int32_t indices[3][3]{};
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
stream::ConsumeSpace(obj); stream::ConsumeSpace(obj, end);
for (int j = 0; j < 3; j++) for (int j = 0; j < 3; j++)
{ {
indices[i][j] = -1; indices[i][j] = -1;
if (j == 0 || stream::Consume(obj, "/")) if (j == 0 || stream::Consume(obj, end, "/"))
{ {
auto r_int = stream::Parse<uint32_t>(obj); if (auto r_int = stream::Parse<uint32_t>(obj, end))
if (!r_int) continue; indices[i][j] = *r_int;
indices[i][j] = *r_int;
} }
} }
} }
@ -69,14 +69,14 @@ Result<VoidResult> ParseOBJ(BufferView buffer)
indices[1][0], indices[1][1], indices[1][2], indices[1][0], indices[1][1], indices[1][2],
indices[2][0], indices[2][1], indices[2][2]); indices[2][0], indices[2][1], indices[2][2]);
} }
else if (element.Size()) else if (!element.Empty())
{ {
element.PushBack('\0'); element.PushBack('\0');
log::info("Unknown element: %s", element.Data()); log::info("Unknown element: %s", element.Data());
} }
stream::AdvancePast(obj, "\n"); stream::AdvancePast(obj, end, "\n");
} while (*obj != '\0'); };
return Result<VoidResult>::Success(); return Result<VoidResult>::Success();
} }
@ -101,7 +101,7 @@ int main(int argc, char** argv)
if (!r_swapchain) if (!r_swapchain)
return 1; return 1;
auto r_objData = fs::OpenFileIntoBuffer("/home/joshua/chair.obj", true); auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/chair.obj");
if (!r_objData) if (!r_objData)
return 1; return 1;

View File

@ -4,9 +4,9 @@
namespace orange::fs namespace orange::fs
{ {
Result<Buffer> OpenFileIntoBuffer(const char* path, bool text) Result<Buffer> OpenFileIntoBuffer(const char* path)
{ {
FILE* file = fopen(path, text ? "r" : "rb"); FILE* file = fopen(path, "rb");
if (!file) if (!file)
Result<Buffer>::Error(BasicErrorCode::NotFound); Result<Buffer>::Error(BasicErrorCode::NotFound);
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
@ -16,8 +16,23 @@ namespace orange::fs
uint8_t* data = new uint8_t[size]; uint8_t* data = new uint8_t[size];
fread(data, size, 1, file); fread(data, size, 1, file);
fclose(file); fclose(file);
if (text) data[size++] = '\0';
return Result<Buffer>::Success(data, size); return Result<Buffer>::Success(data, size);
} }
Result<TextBuffer> OpenFileIntoTextBuffer(const char* path)
{
FILE* file = fopen(path, "rb");
if (!file)
Result<TextBuffer>::Error(BasicErrorCode::NotFound);
fseek(file, 0, SEEK_END);
size_t size = size_t(ftell(file));
fseek(file, 0, SEEK_SET);
char* data = new char[size];
fread(data, size, 1, file);
fclose(file);
return Result<TextBuffer>::Success(data, size);
}
} }