/
redgpu
/
ezEngine
Обзор
Документация
Войти
/
redgpu
/
ezEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
Code/Engine/Foundation/IO/Implementation/StandardJSONWriter.cpp
614 строк
16 KB
Ingrater
Clang-format fixes and update to 18.1.1 (#1234)
10 мар 2024, 15:51
Не верифицирован
10 мар 2024, 15:51
2f16acf
Код
Авторство
О чём код?
#include <Foundation/FoundationPCH.h> #include <Foundation/IO/JSONWriter.h> ezStandardJSONWriter::JSONState::JSONState() { m_State = Invalid; m_bRequireComma = false; m_bValueWasWritten = false; } ezStandardJSONWriter::CommaWriter::CommaWriter(ezStandardJSONWriter* pWriter) { const ezStandardJSONWriter::State state = pWriter->m_StateStack.PeekBack().m_State; EZ_IGNORE_UNUSED(state); EZ_ASSERT_DEV(state == ezStandardJSONWriter::Array || state == ezStandardJSONWriter::NamedArray || state == ezStandardJSONWriter::Variable, "Values can only be written inside BeginVariable() / EndVariable() and BeginArray() / EndArray()."); m_pWriter = pWriter; if (m_pWriter->m_StateStack.PeekBack().m_bRequireComma) { // we are writing the comma now, so it is not required anymore m_pWriter->m_StateStack.PeekBack().m_bRequireComma = false; if (m_pWriter->m_StateStack.PeekBack().m_State == ezStandardJSONWriter::Array || m_pWriter->m_StateStack.PeekBack().m_State == ezStandardJSONWriter::NamedArray) { if (pWriter->m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::NewlinesOnly) { if (pWriter->m_ArrayMode == ezJSONWriter::ArrayMode::InOneLine) m_pWriter->OutputString(","); else m_pWriter->OutputString(",\n"); } else { if (pWriter->m_ArrayMode == ezJSONWriter::ArrayMode::InOneLine) m_pWriter->OutputString(", "); else { m_pWriter->OutputString(",\n"); m_pWriter->OutputIndentation(); } } } else { if (pWriter->m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::None) m_pWriter->OutputString(","); else m_pWriter->OutputString(",\n"); m_pWriter->OutputIndentation(); } } } ezStandardJSONWriter::CommaWriter::~CommaWriter() { m_pWriter->m_StateStack.PeekBack().m_bRequireComma = true; m_pWriter->m_StateStack.PeekBack().m_bValueWasWritten = true; } ezStandardJSONWriter::ezStandardJSONWriter() { m_iIndentation = 0; m_pOutput = nullptr; JSONState s; s.m_State = ezStandardJSONWriter::Empty; m_StateStack.PushBack(s); } ezStandardJSONWriter::~ezStandardJSONWriter() { if (!HadWriteError()) { EZ_ASSERT_DEV(m_StateStack.PeekBack().m_State == ezStandardJSONWriter::Empty, "The JSON stream must be closed properly."); } } void ezStandardJSONWriter::SetOutputStream(ezStreamWriter* pOutput) { m_pOutput = pOutput; } void ezStandardJSONWriter::OutputString(ezStringView s) { EZ_ASSERT_DEBUG(m_pOutput != nullptr, "No output stream has been set yet."); if (m_pOutput->WriteBytes(s.GetStartPointer(), s.GetElementCount()).Failed()) { SetWriteErrorState(); } } void ezStandardJSONWriter::OutputEscapedString(ezStringView s) { ezStringBuilder sEscaped = s; sEscaped.ReplaceAll("\\", "\\\\"); // sEscaped.ReplaceAll("/", "\\/"); // this is not necessary to escape sEscaped.ReplaceAll("\"", "\\\""); sEscaped.ReplaceAll("\b", "\\b"); sEscaped.ReplaceAll("\r", "\\r"); sEscaped.ReplaceAll("\f", "\\f"); sEscaped.ReplaceAll("\n", "\\n"); sEscaped.ReplaceAll("\t", "\\t"); OutputString("\""); OutputString(sEscaped); OutputString("\""); } void ezStandardJSONWriter::OutputIndentation() { if (m_WhitespaceMode >= WhitespaceMode::NoIndentation) return; ezInt32 iIndentation = m_iIndentation * 2; if (m_WhitespaceMode == WhitespaceMode::LessIndentation) iIndentation = m_iIndentation; ezStringBuilder s; s.SetPrintf("%*s", iIndentation, ""); OutputString(s.GetData()); } void ezStandardJSONWriter::WriteBool(bool value) { CommaWriter cw(this); if (value) OutputString("true"); else OutputString("false"); } void ezStandardJSONWriter::WriteInt32(ezInt32 value) { CommaWriter cw(this); ezStringBuilder s; s.SetFormat("{0}", value); OutputString(s.GetData()); } void ezStandardJSONWriter::WriteUInt32(ezUInt32 value) { CommaWriter cw(this); ezStringBuilder s; s.SetFormat("{0}", value); OutputString(s.GetData()); } void ezStandardJSONWriter::WriteInt64(ezInt64 value) { CommaWriter cw(this); ezStringBuilder s; s.SetFormat("{0}", value); OutputString(s.GetData()); } void ezStandardJSONWriter::WriteUInt64(ezUInt64 value) { CommaWriter cw(this); ezStringBuilder s; s.SetFormat("{0}", value); OutputString(s.GetData()); } void ezStandardJSONWriter::WriteFloat(float value) { CommaWriter cw(this); ezStringBuilder s; s.SetFormat("{0}", value); OutputString(s.GetData()); } void ezStandardJSONWriter::WriteDouble(double value) { CommaWriter cw(this); ezStringBuilder s; s.SetFormat("{0}", value); OutputString(s.GetData()); } void ezStandardJSONWriter::WriteString(ezStringView value) { CommaWriter cw(this); OutputEscapedString(value); } void ezStandardJSONWriter::WriteNULL() { CommaWriter cw(this); OutputString("null"); } void ezStandardJSONWriter::WriteTime(ezTime value) { WriteDouble(value.GetSeconds()); } void ezStandardJSONWriter::WriteColor(const ezColor& value) { ezVec4 temp(value.r, value.g, value.b, value.a); ezEndianHelper::NativeToLittleEndian((ezUInt32*)&temp, sizeof(temp) / sizeof(float)); ezStringBuilder s; if (m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::NewlinesOnly) s.SetFormat("({0},{1},{2},{3})", ezArgF(value.r, 4), ezArgF(value.g, 4), ezArgF(value.b, 4), ezArgF(value.a, 4)); else s.SetFormat("({0}, {1}, {2}, {3})", ezArgF(value.r, 4), ezArgF(value.g, 4), ezArgF(value.b, 4), ezArgF(value.a, 4)); WriteBinaryData("color", &temp, sizeof(temp), s.GetData()); } void ezStandardJSONWriter::WriteColorGamma(const ezColorGammaUB& value) { ezStringBuilder s; if (m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::NewlinesOnly) s.SetFormat("({0},{1},{2},{3})", value.r, value.g, value.b, value.a); else s.SetFormat("({0}, {1}, {2}, {3})", value.r, value.g, value.b, value.a); WriteBinaryData("gamma", value.GetData(), sizeof(ezColorGammaUB), s.GetData()); } void ezStandardJSONWriter::WriteVec2(const ezVec2& value) { ezVec2 temp = value; ezEndianHelper::NativeToLittleEndian((ezUInt32*)&temp, sizeof(temp) / sizeof(float)); ezStringBuilder s; if (m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::NewlinesOnly) s.SetFormat("({0},{1})", ezArgF(value.x, 4), ezArgF(value.y, 4)); else s.SetFormat("({0}, {1})", ezArgF(value.x, 4), ezArgF(value.y, 4)); WriteBinaryData("vec2", &temp, sizeof(temp), s.GetData()); } void ezStandardJSONWriter::WriteVec3(const ezVec3& value) { ezVec3 temp = value; ezEndianHelper::NativeToLittleEndian((ezUInt32*)&temp, sizeof(temp) / sizeof(float)); ezStringBuilder s; if (m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::NewlinesOnly) s.SetFormat("({0},{1},{2})", ezArgF(value.x, 4), ezArgF(value.y, 4), ezArgF(value.z, 4)); else s.SetFormat("({0}, {1}, {2})", ezArgF(value.x, 4), ezArgF(value.y, 4), ezArgF(value.z, 4)); WriteBinaryData("vec3", &temp, sizeof(temp), s.GetData()); } void ezStandardJSONWriter::WriteVec4(const ezVec4& value) { ezVec4 temp = value; ezEndianHelper::NativeToLittleEndian((ezUInt32*)&temp, sizeof(temp) / sizeof(float)); ezStringBuilder s; if (m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::NewlinesOnly) s.SetFormat("({0},{1},{2},{3})", ezArgF(value.x, 4), ezArgF(value.y, 4), ezArgF(value.z, 4), ezArgF(value.w, 4)); else s.SetFormat("({0}, {1}, {2}, {3})", ezArgF(value.x, 4), ezArgF(value.y, 4), ezArgF(value.z, 4), ezArgF(value.w, 4)); WriteBinaryData("vec4", &temp, sizeof(temp), s.GetData()); } void ezStandardJSONWriter::WriteVec2I32(const ezVec2I32& value) { CommaWriter cw(this); ezVec2I32 temp = value; ezEndianHelper::NativeToLittleEndian((ezUInt32*)&temp, sizeof(temp) / sizeof(ezInt32)); ezStringBuilder s; if (m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::NewlinesOnly) s.SetFormat("({0},{1})", value.x, value.y); else s.SetFormat("({0}, {1})", value.x, value.y); WriteBinaryData("vec2i", &temp, sizeof(temp), s.GetData()); } void ezStandardJSONWriter::WriteVec3I32(const ezVec3I32& value) { CommaWriter cw(this); ezVec3I32 temp = value; ezEndianHelper::NativeToLittleEndian((ezUInt32*)&temp, sizeof(temp) / sizeof(ezInt32)); ezStringBuilder s; if (m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::NewlinesOnly) s.SetFormat("({0},{1},{2})", value.x, value.y, value.z); else s.SetFormat("({0}, {1}, {2})", value.x, value.y, value.z); WriteBinaryData("vec3i", &temp, sizeof(temp), s.GetData()); } void ezStandardJSONWriter::WriteVec4I32(const ezVec4I32& value) { CommaWriter cw(this); ezVec4I32 temp = value; ezEndianHelper::NativeToLittleEndian((ezUInt32*)&temp, sizeof(temp) / sizeof(ezInt32)); ezStringBuilder s; if (m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::NewlinesOnly) s.SetFormat("({0},{1},{2},{3})", value.x, value.y, value.z, value.w); else s.SetFormat("({0}, {1}, {2}, {3})", value.x, value.y, value.z, value.w); WriteBinaryData("vec4i", &temp, sizeof(temp), s.GetData()); } void ezStandardJSONWriter::WriteQuat(const ezQuat& value) { ezQuat temp = value; ezEndianHelper::NativeToLittleEndian((ezUInt32*)&temp, sizeof(temp) / sizeof(float)); WriteBinaryData("quat", &temp, sizeof(temp)); } void ezStandardJSONWriter::WriteMat3(const ezMat3& value) { ezMat3 temp = value; ezEndianHelper::NativeToLittleEndian((ezUInt32*)&temp, sizeof(temp) / sizeof(float)); WriteBinaryData("mat3", &temp, sizeof(temp)); } void ezStandardJSONWriter::WriteMat4(const ezMat4& value) { ezMat4 temp = value; ezEndianHelper::NativeToLittleEndian((ezUInt32*)&temp, sizeof(temp) / sizeof(float)); WriteBinaryData("mat4", &temp, sizeof(temp)); } void ezStandardJSONWriter::WriteUuid(const ezUuid& value) { CommaWriter cw(this); ezUuid temp = value; ezEndianHelper::NativeToLittleEndian((ezUInt64*)&temp, sizeof(temp) / sizeof(ezUInt64)); WriteBinaryData("uuid", &temp, sizeof(temp)); } void ezStandardJSONWriter::WriteAngle(ezAngle value) { WriteFloat(value.GetDegree()); } void ezStandardJSONWriter::WriteDataBuffer(const ezDataBuffer& value) { WriteBinaryData("data", value.GetData(), value.GetCount()); } void ezStandardJSONWriter::BeginVariable(ezStringView sName) { const ezStandardJSONWriter::State state = m_StateStack.PeekBack().m_State; EZ_IGNORE_UNUSED(state); EZ_ASSERT_DEV(state == ezStandardJSONWriter::Empty || state == ezStandardJSONWriter::Object || state == ezStandardJSONWriter::NamedObject, "Variables can only be written inside objects."); if (m_StateStack.PeekBack().m_bRequireComma) { if (m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::None) OutputString(","); else OutputString(",\n"); OutputIndentation(); } OutputEscapedString(sName); if (m_WhitespaceMode >= WhitespaceMode::NewlinesOnly) OutputString(":"); else OutputString(" : "); JSONState s; s.m_State = ezStandardJSONWriter::Variable; m_StateStack.PushBack(s); } void ezStandardJSONWriter::EndVariable() { EZ_ASSERT_DEV(m_StateStack.PeekBack().m_State == ezStandardJSONWriter::Variable, "EndVariable() must be called in sync with BeginVariable()."); EZ_ASSERT_DEV(m_StateStack.PeekBack().m_bValueWasWritten, "EndVariable() cannot be called without writing any value in between."); End(); } void ezStandardJSONWriter::BeginArray(ezStringView sName) { const ezStandardJSONWriter::State state = m_StateStack.PeekBack().m_State; EZ_IGNORE_UNUSED(state); EZ_ASSERT_DEV((state == ezStandardJSONWriter::Empty) || ((state == ezStandardJSONWriter::Object || state == ezStandardJSONWriter::NamedObject) && !sName.IsEmpty()) || ((state == ezStandardJSONWriter::Array || state == ezStandardJSONWriter::NamedArray) && sName.IsEmpty()) || (state == ezStandardJSONWriter::Variable && sName == nullptr), "Inside objects you can only begin arrays when also giving them a (non-empty) name.\n" "Inside arrays you can only nest anonymous arrays, so names are forbidden.\n" "Inside variables you cannot specify a name again."); if (sName != nullptr) BeginVariable(sName); m_StateStack.PeekBack().m_bValueWasWritten = true; if (m_StateStack.PeekBack().m_bRequireComma) { if (m_WhitespaceMode >= WhitespaceMode::NewlinesOnly) OutputString(","); else OutputString(", "); } if (m_WhitespaceMode >= WhitespaceMode::NewlinesOnly) OutputString("["); else OutputString("[ "); JSONState s; s.m_State = (sName == nullptr) ? ezStandardJSONWriter::Array : ezStandardJSONWriter::NamedArray; m_StateStack.PushBack(s); ++m_iIndentation; } void ezStandardJSONWriter::EndArray() { const ezStandardJSONWriter::State state = m_StateStack.PeekBack().m_State; EZ_IGNORE_UNUSED(state); EZ_ASSERT_DEV( state == ezStandardJSONWriter::Array || state == ezStandardJSONWriter::NamedArray, "EndArray() must be called in sync with BeginArray()."); const State CurState = m_StateStack.PeekBack().m_State; End(); if (CurState == ezStandardJSONWriter::NamedArray) EndVariable(); } void ezStandardJSONWriter::BeginObject(ezStringView sName) { const ezStandardJSONWriter::State state = m_StateStack.PeekBack().m_State; EZ_IGNORE_UNUSED(state); EZ_ASSERT_DEV((state == ezStandardJSONWriter::Empty) || ((state == ezStandardJSONWriter::Object || state == ezStandardJSONWriter::NamedObject) && !sName.IsEmpty()) || ((state == ezStandardJSONWriter::Array || state == ezStandardJSONWriter::NamedArray) && sName.IsEmpty()) || (state == ezStandardJSONWriter::Variable && sName == nullptr), "Inside objects you can only begin objects when also giving them a (non-empty) name.\n" "Inside arrays you can only nest anonymous objects, so names are forbidden.\n" "Inside variables you cannot specify a name again."); if (sName != nullptr) BeginVariable(sName); m_StateStack.PeekBack().m_bValueWasWritten = true; if (m_StateStack.PeekBack().m_bRequireComma) { if (m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::None) OutputString(","); else OutputString(",\n"); OutputIndentation(); } if (m_WhitespaceMode >= ezJSONWriter::WhitespaceMode::None) OutputString("{"); else OutputString("{\n"); JSONState s; s.m_State = (sName == nullptr) ? ezStandardJSONWriter::Object : ezStandardJSONWriter::NamedObject; m_StateStack.PushBack(s); ++m_iIndentation; OutputIndentation(); } void ezStandardJSONWriter::EndObject() { const ezStandardJSONWriter::State state = m_StateStack.PeekBack().m_State; EZ_IGNORE_UNUSED(state); EZ_ASSERT_DEV( state == ezStandardJSONWriter::Object || state == ezStandardJSONWriter::NamedObject, "EndObject() must be called in sync with BeginObject()."); const State CurState = m_StateStack.PeekBack().m_State; End(); if (CurState == ezStandardJSONWriter::NamedObject) EndVariable(); } void ezStandardJSONWriter::End() { const ezStandardJSONWriter::State state = m_StateStack.PeekBack().m_State; if (m_StateStack.PeekBack().m_State == ezStandardJSONWriter::Array || m_StateStack.PeekBack().m_State == ezStandardJSONWriter::NamedArray) { --m_iIndentation; if (m_WhitespaceMode >= WhitespaceMode::NewlinesOnly) OutputString("]"); else OutputString(" ]"); } m_StateStack.PopBack(); m_StateStack.PeekBack().m_bRequireComma = true; if (state == ezStandardJSONWriter::Object || state == ezStandardJSONWriter::NamedObject) { --m_iIndentation; if (m_WhitespaceMode < ezJSONWriter::WhitespaceMode::None) OutputString("\n"); OutputIndentation(); OutputString("}"); } } void ezStandardJSONWriter::WriteBinaryData(ezStringView sDataType, const void* pData, ezUInt32 uiBytes, ezStringView sValueString) { CommaWriter cw(this); if (m_WhitespaceMode >= WhitespaceMode::NewlinesOnly) OutputString("{\"$t\":\""); else OutputString("{ \"$t\" : \""); OutputString(sDataType); if (!sValueString.IsEmpty()) { if (m_WhitespaceMode >= WhitespaceMode::NewlinesOnly) OutputString("\",\"$v\":\""); else OutputString("\", \"$v\" : \""); OutputString(sValueString); } if (m_WhitespaceMode >= WhitespaceMode::NewlinesOnly) OutputString("\",\"$b\":\"0x"); else OutputString("\", \"$b\" : \"0x"); ezStringBuilder s; ezUInt8* pBytes = (ezUInt8*)pData; for (ezUInt32 i = 0; i < uiBytes; ++i) { s.SetFormat("{0}", ezArgU((ezUInt32)*pBytes, 2, true, 16, true)); ++pBytes; OutputString(s.GetData()); } if (m_WhitespaceMode >= WhitespaceMode::NewlinesOnly) OutputString("\"}"); else OutputString("\" }"); }