json: add escape

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2025-04-22 18:43:34 +02:00
parent 1b8053f95c
commit 4c499f2905

100
include/stdex/json.hpp Normal file
View File

@ -0,0 +1,100 @@
/*
SPDX-License-Identifier: MIT
Copyright © 2025 Amebis
*/
#pragma once
#include "assert.hpp"
#include "compat.hpp"
#include <string>
namespace stdex
{
namespace json
{
///
/// Appends escaped JSON string
///
/// \param[in,out] dst String to append to
/// \param[in] src Source string
/// \param[in] num_chars Code unit limit in string `src`
///
template<class TR = std::char_traits<char>, class AX = std::allocator<char>>
void escape(
_Inout_ std::basic_string<char, TR, AX>& dst,
_In_reads_or_z_opt_(num_chars) const char* src, _In_ size_t num_chars = SIZE_MAX)
{
stdex_assert(src || !num_chars);
for (size_t i = 0; i < num_chars && src[i]; ++i) {
switch (src[i]) {
case '\"': dst += "\\\""; break;
case '\\': dst += "\\\\"; break;
case '/' : dst += "\\/"; break;
case '\b': dst += "\\b"; break;
case '\f': dst += "\\f"; break;
case '\n': dst += "\\n"; break;
case '\r': dst += "\\r"; break;
case '\t': dst += "\\t"; break;
default: dst += src[i]; break;
}
}
}
///
/// Appends escaped JSON string
///
/// \param[in,out] dst String to append to
/// \param[in] src Source string
/// \param[in] num_chars Code unit limit in string `src`
///
template<class TR = std::char_traits<wchar_t>, class AX = std::allocator<wchar_t>>
void escape(
_Inout_ std::basic_string<wchar_t, TR, AX>& dst,
_In_reads_or_z_opt_(num_chars) const wchar_t* src, _In_ size_t num_chars = SIZE_MAX)
{
stdex_assert(src || !num_chars);
for (size_t i = 0; i < num_chars && src[i]; ++i) {
switch (src[i]) {
case L'\"': dst += L"\\\""; break;
case L'\\': dst += L"\\\\"; break;
case L'/' : dst += L"\\/"; break;
case L'\b': dst += L"\\b"; break;
case L'\f': dst += L"\\f"; break;
case L'\n': dst += L"\\n"; break;
case L'\r': dst += L"\\r"; break;
case L'\t': dst += L"\\t"; break;
default: dst += src[i]; break;
}
}
}
///
/// Appends escaped JSON string
///
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<class T, size_t N, class TR = std::char_traits<T>, class AX = std::allocator<T>>
void escape(
_Inout_ std::basic_string<T, TR, AX>& dst,
_In_ const T (&src)[N])
{
escape(dst, src, N);
}
///
/// Appends escaped JSON string
///
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<class T, class TR_dst = std::char_traits<T>, class AX_dst = std::allocator<T>, class TR_src = std::char_traits<T>, class AX_src = std::allocator<T>>
void escape(
_Inout_ std::basic_string<T, TR_dst, AX_dst>& dst,
_In_ const std::basic_string<T, TR_src, AX_src>& src)
{
escape(dst, src.data(), src.size());
}
}
}