Skip to content

Commit

Permalink
OrcLib: add missing StructuredOutput overloads
Browse files Browse the repository at this point in the history
  • Loading branch information
jgautier-anssi authored and fabienfl-orc committed Nov 9, 2020
1 parent aec3c11 commit 769d7b2
Show file tree
Hide file tree
Showing 11 changed files with 654 additions and 117 deletions.
59 changes: 48 additions & 11 deletions src/OrcLib/Buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,6 @@ class Buffer
if (!m_Ptr)
throw Orc::Exception(Severity::Fatal, E_OUTOFMEMORY);
}
HeapStore(_T* Ptr, ULONG Elts)
: m_Ptr(Ptr)
, m_EltsAlloc(Elts)
{
if (!m_Ptr)
throw Orc::Exception(Severity::Fatal, E_POINTER);
};
HeapStore(HeapStore&& other) noexcept
{
std::swap(m_Ptr, other.m_Ptr);
Expand Down Expand Up @@ -321,7 +314,7 @@ class Buffer
}
explicit Buffer(const Buffer& other) { assign(other); }

Buffer(_In_reads_(Elts) _T* Ptr, _In_ ULONG Elts, _In_ bool Owned, _In_ ULONG Used) { set(Ptr, Elts, Owned, Used); }
Buffer(_In_reads_(Elts) const _T* Ptr, _In_ ULONG Elts, _In_ ULONG Used) { set(Ptr, Elts, Used); }

Buffer(const std::initializer_list<_T>& list)
{
Expand All @@ -339,16 +332,20 @@ class Buffer
bool full() const { return capacity() == size(); }

bool empty() const { return std::holds_alternative<EmptyStore>(m_store); }
void set(_In_reads_(Elts) _T* Ptr, _In_ ULONG Elts, _In_ ULONG Used)
void set(_In_reads_(Elts) const _T* Ptr, _In_ ULONG Elts, _In_ ULONG Used)
{
if (Elts == 0)
m_store = EmptyStore();
else if (Elts <= _DeclElts)
{
m_store = InnerStore(Ptr, Ptr + Elts);
m_store = InnerStore(Ptr, Ptr + Used);
}
else
m_store = HeapStore(Ptr, Elts);
{
HeapStore heap(Elts);
heap.assign(Ptr, Used);
m_store = std::move(heap);
}

if (Used <= Elts)
m_EltsUsed = Used;
Expand Down Expand Up @@ -416,6 +413,46 @@ class Buffer
view_of(Other.m_Ptr, Other.m_Elts, InUse);
}

void append(const _T& Src)
{
auto capacity_ = capacity();
auto size_ = size();
auto new_size = size_ + 1;

if (new_size > capacity_)
{
auto new_capacity = std::max(new_size, capacity_ + capacity_ / 2);
if (new_capacity < _DeclElts)
new_capacity = _DeclElts;
reserve(new_capacity);
capacity_ = new_capacity;
}

if (is_view() && (capacity_ < new_size)) // current store is a view, and is too small to contains the new
// elts -> we need to "mutate" to a owning one.
{
if (new_size <= _DeclElts)
{
auto new_store = InnerStore();

std::visit([&new_store](const auto& arg) { new_store.assign(arg.get(), arg.capacity()); }, m_store);
m_store = std::move(new_store);
capacity_ = _DeclElts;
}
else
{
auto new_capacity = std::max(new_size, capacity_ + capacity_ / 2);
auto new_store = HeapStore(new_capacity);
std::visit([&new_store](const auto& arg) { new_store.assign(arg.get(), arg.capacity()); }, m_store);
m_store = std::move(new_store);
capacity_ = new_capacity;
}
}

std::copy(&Src, &Src + 1, stdext::checked_array_iterator(get() + size_, capacity_ - size_));
m_EltsUsed = new_size;
}

void append(_In_reads_(Elts) const _T* Src, _In_ ULONG Elts = 1)
{
if (!Src)
Expand Down
106 changes: 78 additions & 28 deletions src/OrcLib/JSONOutputWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,48 +112,53 @@ HRESULT Orc::StructuredOutput::JSON::Writer<_RapidWriter, _Ch>::EndCollection(LP
}

template <class _RapidWriter, typename _Ch>
HRESULT Orc::StructuredOutput::JSON::Writer<_RapidWriter, _Ch>::WriteFormated(const WCHAR* szFormat, ...)
HRESULT Orc::StructuredOutput::JSON::Writer<_RapidWriter, _Ch>::WriteFormated_(
const std::wstring_view& szFormat,
wformat_args args)
{
va_list argList;
va_start(argList, szFormat);
Buffer<WCHAR, MAX_PATH> buffer;
auto result = fmt::vformat_to(std::back_inserter(buffer), szFormat, args);

const DWORD dwMaxChar = 1024;
WCHAR szBuffer[dwMaxChar];
HRESULT hr = StringCchVPrintfW(szBuffer, dwMaxChar, szFormat, argList);
rapidWriter.String(buffer.get(), buffer.size());
return S_OK;
}

va_end(argList);
template <class _RapidWriter, typename _Ch>
HRESULT Orc::StructuredOutput::JSON::Writer<_RapidWriter, _Ch>::WriteFormated_(
const std::string_view& szFormat,
format_args args)
{
Buffer<CHAR, MAX_PATH> buffer;
auto result = fmt::vformat_to(std::back_inserter(buffer), szFormat, args);

std::string_view result_string = buffer.size() > 0 ? std::string_view(buffer.get(), buffer.size()) : ""sv;
auto [hr, wstr] = Orc::AnsiToWide(result_string);
if (FAILED(hr))
{
Log::Error(L"Failed to write formated string (code: {:#x})", hr);
return hr;
}

rapidWriter.String(szBuffer);
rapidWriter.String(wstr.data(), wstr.size());
return S_OK;
}

template <class _RapidWriter, typename _Ch>
HRESULT
Orc::StructuredOutput::JSON::Writer<_RapidWriter, _Ch>::WriteNamedFormated(LPCWSTR szName, const WCHAR* szFormat, ...)
HRESULT Orc::StructuredOutput::JSON::Writer<_RapidWriter, _Ch>::WriteNamedFormated_(
LPCWSTR szName,
const std::wstring_view& szFormat,
wformat_args args)
{
va_list argList;
va_start(argList, szFormat);

const DWORD dwMaxChar = 1024;
WCHAR szBuffer[dwMaxChar];
HRESULT hr = StringCchVPrintfW(szBuffer, dwMaxChar, szFormat, argList);

va_end(argList);

if (FAILED(hr))
{
Log::Error(L"Failed to write formated string (code: {:#x})", hr);
return hr;
}
rapidWriter.Key(szName);
WriteFormated_(szFormat, args);
return S_OK;
}

template <class _RapidWriter, typename _Ch>
HRESULT Orc::StructuredOutput::JSON::Writer<_RapidWriter, _Ch>::WriteNamedFormated_(
LPCWSTR szName,
const std::string_view& szFormat,
format_args args)
{
rapidWriter.Key(szName);
rapidWriter.String(szBuffer);
WriteFormated_(szFormat, args);
return S_OK;
}

Expand All @@ -170,6 +175,51 @@ HRESULT Orc::StructuredOutput::JSON::Writer<_RapidWriter, _Ch>::WriteNamed(LPCWS
return WriteNamed_(szName, szValue);
}

template <class _RapidWriter, typename _Ch>
HRESULT Writer<_RapidWriter, _Ch>::Write(const std::wstring_view str)
{
rapidWriter.String(str.data(), str.length());
return S_OK;
}

template <class _RapidWriter, typename _Ch>
HRESULT Writer<_RapidWriter, _Ch>::WriteNamed(LPCWSTR szName, const std::wstring_view str)
{
return WriteNamed_(szName, str);
}

template <class _RapidWriter, typename _Ch>
HRESULT Writer<_RapidWriter, _Ch>::Write(const std::wstring& str)
{
rapidWriter.String(str.data(), str.length());
return S_OK;
}

template <class _RapidWriter, typename _Ch>
HRESULT Writer<_RapidWriter, _Ch>::WriteNamed(LPCWSTR szName, const std::wstring& str)
{
return WriteNamed_(szName, str);
}

template <class _RapidWriter, typename _Ch>
HRESULT Writer<_RapidWriter, _Ch>::Write(const std::string_view str)
{
if (auto [hr, wstr] = Orc::AnsiToWide(str); FAILED(hr))
return hr;
else
rapidWriter.String(wstr.data(), wstr.length());
return S_OK;
}

template <class _RapidWriter, typename _Ch>
HRESULT Writer<_RapidWriter, _Ch>::WriteNamed(LPCWSTR szName, const std::string_view str)
{
if (auto [hr, wstr] = Orc::AnsiToWide(str); FAILED(hr))
return hr;
else
return WriteNamed(szName, wstr);
}

template <class _RapidWriter, typename _Ch>
HRESULT Orc::StructuredOutput::JSON::Writer<_RapidWriter, _Ch>::Write(uint32_t dwValue, bool bInHex)
{
Expand Down
20 changes: 17 additions & 3 deletions src/OrcLib/JSONOutputWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,18 @@ class Writer : public StructuredOutput::Writer
virtual HRESULT BeginCollection(LPCWSTR szCollection) override final;
virtual HRESULT EndCollection(LPCWSTR szCollection) override final;

virtual HRESULT WriteFormated(const WCHAR* szFormat, ...) override final;
virtual HRESULT WriteNamedFormated(LPCWSTR szName, const WCHAR* szFormat, ...) override final;

virtual HRESULT Write(LPCWSTR szString) override final;
virtual HRESULT WriteNamed(LPCWSTR szName, const WCHAR* szValue) override final;

virtual HRESULT Write(const std::wstring_view str) override final;
virtual HRESULT WriteNamed(LPCWSTR szName, const std::wstring_view str) override final;

virtual HRESULT Write(const std::wstring& str) override final;
virtual HRESULT WriteNamed(LPCWSTR szName, const std::wstring& str) override final;

virtual HRESULT Write(const std::string_view str) override final;
virtual HRESULT WriteNamed(LPCWSTR szName, const std::string_view str) override final;

virtual HRESULT Write(bool bBoolean) override final;
virtual HRESULT WriteNamed(LPCWSTR szName, bool bBoolean) override final;

Expand Down Expand Up @@ -160,6 +166,14 @@ class Writer : public StructuredOutput::Writer
private:
template <typename... Args>
HRESULT WriteNamed_(LPCWSTR szName, Args&&... args);

protected:
virtual HRESULT WriteFormated_(const std::wstring_view& szFormat, wformat_args args) override final;
virtual HRESULT WriteFormated_(const std::string_view& szFormat, format_args args) override final;
virtual HRESULT
WriteNamedFormated_(LPCWSTR szName, const std::wstring_view& szFormat, wformat_args args) override final;
virtual HRESULT
WriteNamedFormated_(LPCWSTR szName, const std::string_view& szFormat, format_args args) override final;
};

std::shared_ptr<StructuredOutput::IWriter>
Expand Down
10 changes: 5 additions & 5 deletions src/OrcLib/RegFind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,15 @@ HRESULT RegFind::Match::Write(IStructuredOutput& pWriter)

pWriter.BeginElement(L"regfind_match");

pWriter.WriteNamedFormated(L"description", L"%S", strMatchDescr.c_str());
pWriter.WriteNamedFormated(L"description", "{}", strMatchDescr);

pWriter.BeginCollection(L"value");
for (const auto& aValueNameMatch : MatchingValues)
{
pWriter.BeginElement(nullptr);
{
pWriter.WriteNamedFormated(L"key", L"%S", aValueNameMatch.KeyName.c_str());
pWriter.WriteNamedFormated(L"value", L"%S", aValueNameMatch.ValueName.c_str());
pWriter.WriteNamed(L"key", aValueNameMatch.KeyName);
pWriter.WriteNamed(L"value", aValueNameMatch.ValueName);

for (UINT idx = 0; g_ValueTypeDefinitions[idx].Type != RegMaxType; idx++)
{
Expand All @@ -172,7 +172,7 @@ HRESULT RegFind::Match::Write(IStructuredOutput& pWriter)

pWriter.WriteNamed(L"lastmodified_key", aValueNameMatch.LastModificationTime);

pWriter.WriteNamedFormated(L"data_size", L"%Iu", aValueNameMatch.DatasLength);
pWriter.WriteNamed(L"data_size", aValueNameMatch.DatasLength);
}
pWriter.EndElement(nullptr);
}
Expand All @@ -183,7 +183,7 @@ HRESULT RegFind::Match::Write(IStructuredOutput& pWriter)
{
pWriter.BeginElement(nullptr);
{
pWriter.WriteNamedFormated(L"key", L"%S", aKeyNameMatch.KeyName.c_str());
pWriter.WriteNamedFormated(L"key", aKeyNameMatch.KeyName);
pWriter.WriteNamed(L"subkeys_count", (UINT32)aKeyNameMatch.SubKeysCount);
pWriter.WriteNamed(L"values_count", (UINT32)aKeyNameMatch.ValuesCount);
pWriter.WriteNamed(L"lastmodified_key", aKeyNameMatch.LastModificationTime);
Expand Down
Loading

0 comments on commit 769d7b2

Please sign in to comment.