11#include "sgml_unicode.hpp"
18#pragma GCC diagnostic push
19#pragma GCC diagnostic ignored "-Wexit-time-destructors"
26 const utf32_t* sgml2uni(_In_reads_or_z_(count)
const T* entity, _In_
size_t count, utf32_t buf[2])
28 stdex_assert(entity && count);
30 if (count < 2 || entity[0] !=
'#') {
31 for (
size_t i = 0, j = _countof(sgml_unicode); i < j; ) {
32 size_t m = (i + j) / 2;
33 if (sgml_unicode[m].sgml[0] < entity[0])
35 else if (sgml_unicode[m].sgml[0] > entity[0])
38 auto r = strncmp<char, T>(sgml_unicode[m].sgml + 1, _countof(sgml_unicode[0].sgml) - 1, entity + 1, count - 1);
44 for (; i < m && strncmp<char, T>(sgml_unicode[m - 1].sgml, _countof(sgml_unicode[0].sgml), entity, count) == 0; m--);
45 return sgml_unicode[m].unicode;
52 buf[0] = entity[1] ==
'x' || entity[1] ==
'X' ?
53 static_cast<utf32_t
>(strtou32(&entity[2], count - 2,
nullptr, 16)) :
54 static_cast<utf32_t>(strtou32(&entity[1], count - 1, nullptr, 10));
59 inline const utf16_t* utf32_to_wstr(_In_opt_z_
const utf32_t* str, utf16_t* buf)
63 for (
size_t i = 0, j = 0;; ++i) {
69 buf[j++] =
static_cast<utf16_t
>(str[i]);
71 ucs4_to_surrogate_pair(&buf[j], str[i]);
77 inline const utf32_t* utf32_to_wstr(_In_opt_z_
const utf32_t* str, utf32_t* buf)
85 _In_reads_or_z_opt_(count)
const T* str, _In_
size_t count)
87 stdex_assert(str || !count);
88 for (
size_t i = 0; i < count; i++) {
91 if (!str[i] || str[i] ==
'&' || isspace(str[i]))
98 constexpr int sgml_full = 0x40000000;
99 constexpr int sgml_quot = 0x00000001;
100 constexpr int sgml_apos = 0x00000002;
101 constexpr int sgml_quot_apos = sgml_quot | sgml_apos;
102 constexpr int sgml_amp = 0x00000004;
103 constexpr int sgml_lt_gt = 0x00000008;
104 constexpr int sgml_bsol = 0x00000010;
105 constexpr int sgml_dollar = 0x00000020;
106 constexpr int sgml_percnt = 0x00000040;
107 constexpr int sgml_commat = 0x00000080;
108 constexpr int sgml_num = 0x00000100;
109 constexpr int sgml_lpar_rpar = 0x00000200;
110 constexpr int sgml_lcub_rcub = 0x00000400;
111 constexpr int sgml_lsqb_rsqb = 0x00000800;
112 constexpr int sgml_sgml = sgml_amp | sgml_lt_gt;
113 constexpr int sgml_ml_attrib = sgml_amp | sgml_quot_apos;
114 constexpr int sgml_c = sgml_amp | sgml_bsol | sgml_quot_apos;
126 template <
class T_from>
128 _In_reads_or_z_opt_(count_src)
const T_from* src, _In_
size_t count_src,
131 stdex_assert(src || !count_src);
134 do_ascii = (what & sgml_full) == 0;
136 for (
size_t i = 0; i < count_src && src[i];) {
138 auto end = sgmlend(&src[i + 1], count_src - i - 1);
141 size_t n = end - src - i - 1;
142 auto entity_w = sgml2uni(&src[i + 1], n, chr);
156 if (do_ascii && !is7bit(src[i])) {
174 template <
class T_from,
class TR_from = std::
char_traits<T_from>,
class AX_from = std::allocator<T_from>>
176 _In_
const std::basic_string<T_from, TR_from, AX_from>& src,
179 return sgmlerr(src.data(), src.size(), what);
192 template <
class T_to,
class T_from,
class TR_to = std::
char_traits<T_to>,
class AX_to = std::allocator<T_to>>
194 _Inout_ std::basic_string<T_to, TR_to, AX_to>& dst,
195 _In_reads_or_z_opt_(count_src)
const T_from* src, _In_
size_t count_src,
197 _In_
const mapping<size_t>& offset = mapping<size_t>(0, 0),
198 _Inout_opt_ mapping_vector<size_t>* map =
nullptr)
200 stdex_assert(src || !count_src);
203 skip_quot = (skip & sgml_quot) == 0,
204 skip_apos = (skip & sgml_apos) == 0,
205 skip_amp = (skip & sgml_amp) == 0,
206 skip_lt_gt = (skip & sgml_lt_gt) == 0,
207 skip_bsol = (skip & sgml_bsol) == 0,
208 skip_dollar = (skip & sgml_dollar) == 0,
209 skip_percnt = (skip & sgml_percnt) == 0,
210 skip_commat = (skip & sgml_commat) == 0,
211 skip_num = (skip & sgml_num) == 0,
212 skip_lpar_rpar = (skip & sgml_lpar_rpar) == 0,
213 skip_lcub_rcub = (skip & sgml_lcub_rcub) == 0,
214 skip_lsqb_rsqb = (skip & sgml_lsqb_rsqb) == 0;
216 count_src = strnlen(src, count_src);
217 dst.reserve(dst.size() + count_src);
218 for (
size_t i = 0; i < count_src;) {
220 auto end = sgmlend(&src[i + 1], count_src - i - 1);
223 stdex_assert(&src[i + 1] <= end);
224 size_t n =
static_cast<size_t>(end - src) - i - 1;
226 auto entity_w = utf32_to_wstr(sgml2uni(&src[i + 1], n, chr32), chr);
228 (skip_quot || (entity_w[0] !=
'"')) &&
229 (skip_apos || (entity_w[0] !=
'\'')) &&
230 (skip_amp || (entity_w[0] !=
'&')) &&
231 (skip_lt_gt || (entity_w[0] !=
'<' && entity_w[0] !=
'>')) &&
232 (skip_bsol || (entity_w[0] !=
'\\')) &&
233 (skip_dollar || (entity_w[0] !=
'$')) &&
234 (skip_percnt || (entity_w[0] !=
'%')) &&
235 (skip_commat || (entity_w[0] !=
'@')) &&
236 (skip_num || (entity_w[0] !=
'#')) &&
237 (skip_lpar_rpar || (entity_w[0] !=
'(' && entity_w[0] !=
')')) &&
238 (skip_lcub_rcub || (entity_w[0] !=
'{' && entity_w[0] !=
'}')) &&
239 (skip_lsqb_rsqb || (entity_w[0] !=
'[' && entity_w[0] !=
']')))
241 if (map) map->push_back(mapping<size_t>(offset.from + i, offset.to + dst.size()));
242 dst.append(entity_w);
243 stdex_assert(src <= end);
244 i =
static_cast<size_t>(end - src) + 1;
245 if (map) map->push_back(mapping<size_t>(offset.from + i, offset.to + dst.size()));
250 dst.append(1, src[i++]);
263 template <
class T_to,
class T_from,
class TR_to = std::
char_traits<T_to>,
class AX_to = std::allocator<T_to>,
class TR_from = std::
char_traits<T_from>,
class AX_from = std::allocator<T_from>>
265 _Inout_ std::basic_string<T_to, TR_to, AX_to>& dst,
266 _In_
const std::basic_string<T_from, TR_from, AX_from>& src,
268 _In_
const mapping<size_t>& offset = mapping<size_t>(0, 0),
269 _Inout_opt_ mapping_vector<size_t>* map =
nullptr)
271 sgml2strcat(dst, src.data(), src.size(), skip, offset, map);
287 template <
class T_to,
class T_from>
289 _Inout_cap_(count_dst) T_to* dst, _In_
size_t count_dst,
290 _In_reads_or_z_opt_(count_src)
const T_from* src, _In_
size_t count_src,
292 _In_
const mapping<size_t>& offset = mapping<size_t>(0, 0),
293 _Inout_opt_ mapping_vector<size_t>* map =
nullptr)
295 stdex_assert(dst || !count_dst);
296 stdex_assert(src || !count_src);
298 static const std::invalid_argument buffer_overrun(
"buffer overrun");
300 skip_quot = (skip & sgml_quot) == 0,
301 skip_apos = (skip & sgml_apos) == 0,
302 skip_amp = (skip & sgml_amp) == 0,
303 skip_lt_gt = (skip & sgml_lt_gt) == 0,
304 skip_bsol = (skip & sgml_bsol) == 0,
305 skip_dollar = (skip & sgml_dollar) == 0,
306 skip_percnt = (skip & sgml_percnt) == 0,
307 skip_commat = (skip & sgml_commat) == 0,
308 skip_num = (skip & sgml_num) == 0,
309 skip_lpar_rpar = (skip & sgml_lpar_rpar) == 0,
310 skip_lcub_rcub = (skip & sgml_lcub_rcub) == 0,
311 skip_lsqb_rsqb = (skip & sgml_lsqb_rsqb) == 0;
313 size_t j = strnlen(dst, count_dst);
314 count_src = strnlen(src, count_src);
315 for (
size_t i = 0; i < count_src;) {
317 auto end = sgmlend(&src[i + 1], count_src - i - 1);
321 size_t n = end - src - i - 1;
322 auto entity_w = utf32_to_wstr(sgml2uni(&src[i + 1], n, chr32), chr);
324 (skip_quot || (entity_w[0] !=
'"')) &&
325 (skip_apos || (entity_w[0] !=
'\'')) &&
326 (skip_amp || (entity_w[0] !=
'&')) &&
327 (skip_lt_gt || (entity_w[0] !=
'<' && entity_w[0] !=
'>')) &&
328 (skip_bsol || (entity_w[0] !=
'\\')) &&
329 (skip_dollar || (entity_w[0] !=
'$')) &&
330 (skip_percnt || (entity_w[0] !=
'%')) &&
331 (skip_commat || (entity_w[0] !=
'@')) &&
332 (skip_num || (entity_w[0] !=
'#')) &&
333 (skip_lpar_rpar || (entity_w[0] !=
'(' && entity_w[0] !=
')')) &&
334 (skip_lcub_rcub || (entity_w[0] !=
'{' && entity_w[0] !=
'}')) &&
335 (skip_lsqb_rsqb || (entity_w[0] !=
'[' && entity_w[0] !=
']')))
337 if (map) map->push_back(mapping<size_t>(offset.from + i, offset.to + j));
338 size_t m = strlen(entity_w);
339 if (j + m >= count_dst)
340 throw buffer_overrun;
341 memcpy(dst + j, entity_w, m *
sizeof(*entity_w)); j += m;
343 if (map) map->push_back(mapping<size_t>(offset.from + i, offset.to + j));
348 if (j + 1 >= count_dst)
349 throw buffer_overrun;
353 throw buffer_overrun;
368 template <
class T_to,
class T_from,
class TR_to = std::
char_traits<T_to>,
class AX_to = std::allocator<T_to>>
370 _Inout_ std::basic_string<T_to, TR_to, AX_to>& dst,
371 _In_reads_or_z_opt_(count_src)
const T_from* src, _In_
size_t count_src,
373 _In_
const mapping<size_t>& offset = mapping<size_t>(0, 0),
374 _Inout_opt_ mapping_vector<size_t>* map =
nullptr)
379 sgml2strcat(dst, src, count_src, skip, offset, map);
391 template<
class T_to,
class T_from,
class TR_to = std::
char_traits<T_to>,
class AX_to = std::allocator<T_to>,
class TR_from = std::
char_traits<T_from>,
class AX_from = std::allocator<T_from>>
393 _Inout_ std::basic_string<T_to, TR_to, AX_to>& dst,
394 _In_
const std::basic_string<T_from, TR_from, AX_from>& src,
396 _In_
const mapping<size_t>& offset = mapping<size_t>(0, 0),
397 _Inout_opt_ mapping_vector<size_t>* map =
nullptr)
399 sgml2strcpy(dst, src.data(), src.size(), skip, offset, map);
415 template <
class T_to,
class T_from>
417 _Inout_cap_(count_dst) T_to* dst, _In_
size_t count_dst,
418 _In_reads_or_z_opt_(count_src)
const T_from* src, _In_
size_t count_src,
420 _In_
const mapping<size_t>& offset = mapping<size_t>(0, 0),
421 _Inout_opt_ mapping_vector<size_t>* map =
nullptr)
423 stdex_assert(dst || !count_dst);
428 return sgml2strcat(dst, count_dst, src, count_src, skip, offset, map);
442 template <
class T_to =
wchar_t,
class T_from,
class TR_to = std::
char_traits<T_to>,
class AX_to = std::allocator<T_to>>
443 std::basic_string<T_to, TR_to, AX_to> sgml2str(
444 _In_reads_or_z_opt_(count_src)
const T_from* src, _In_
size_t count_src,
446 _In_
const mapping<size_t>& offset = mapping<size_t>(0, 0),
447 _Inout_opt_ mapping_vector<size_t>* map =
nullptr)
449 std::basic_string<T_to, TR_to, AX_to> dst;
450 sgml2strcat(dst, src, count_src, skip, offset, map);
464 template <
class T_to =
wchar_t,
class T_from,
class TR_to = std::
char_traits<T_to>,
class AX_to = std::allocator<T_to>,
class TR_from = std::
char_traits<T_from>,
class AX_from = std::allocator<T_from>>
465 std::basic_string<T_to, TR_to, AX_to> sgml2str(
466 _In_
const std::basic_string<T_from, TR_from, AX_from>& src,
468 _In_
const mapping<size_t>& offset = mapping<size_t>(0, 0),
469 _Inout_opt_ mapping_vector<size_t>* map =
nullptr)
471 return sgml2str<T_to, T_from, TR_to, AX_to>(src.data(), src.size(), skip, offset, map);
475 inline const char* chr2sgml(_In_reads_or_z_(count)
const utf16_t* entity, _In_
size_t count)
477 stdex_assert(entity && count);
481 if (count < 2 || !is_surrogate_pair(entity)) {
482 e2 =
static_cast<utf32_t
>(entity[0]);
486 e2 = surrogate_pair_to_ucs4(entity);
489 for (
size_t i = 0, j = _countof(unicode_sgml); i < j; ) {
490 size_t m = (i + j) / 2;
491 auto e1 = sgml_unicode[unicode_sgml[m]].unicode[0];
497 auto r = strncmp(sgml_unicode[unicode_sgml[m]].unicode + 1, _countof(sgml_unicode[0].unicode) - 1, entity + offset, count - offset);
503 for (; i < m && sgml_unicode[unicode_sgml[m - 1]].unicode[0] == e2 && strncmp(sgml_unicode[unicode_sgml[m - 1]].unicode + 1, _countof(sgml_unicode[0].unicode) - 1, entity + offset, count - offset) == 0; m--);
504 return sgml_unicode[unicode_sgml[m]].sgml;
511 inline const char* chr2sgml(_In_reads_or_z_(count)
const utf32_t* entity, _In_
size_t count)
513 stdex_assert(entity && count);
515 utf32_t e2 = entity[0];
516 for (
size_t i = 0, j = _countof(unicode_sgml); i < j; ) {
517 size_t m = (i + j) / 2;
518 auto e1 = sgml_unicode[unicode_sgml[m]].unicode[0];
524 auto r = strncmp(sgml_unicode[unicode_sgml[m]].unicode + 1, _countof(sgml_unicode[0].unicode) - 1, entity + 1, count - 1);
530 for (; i < m && sgml_unicode[unicode_sgml[m - 1]].unicode[0] == e2 && strncmp(sgml_unicode[unicode_sgml[m - 1]].unicode + 1, _countof(sgml_unicode[0].unicode) - 1, entity + 1, count - 1) == 0; m--);
531 return sgml_unicode[unicode_sgml[m]].sgml;
538 inline utf32_t wstr_to_utf32(_In_reads_(end)
const utf16_t* src, _Inout_
size_t& i, _In_
size_t end)
540 stdex_assert(i < end);
541 if (i + 1 >= end || !is_surrogate_pair(src + i))
544 utf32_t unicode = surrogate_pair_to_ucs4(src + i);
549 inline utf32_t wstr_to_utf32(_In_reads_(end)
const utf32_t* src, _Inout_
size_t& i, _In_
size_t end)
552 stdex_assert(i < end);
565 template <
class T_from,
class TR_to = std::
char_traits<
char>,
class AX_to = std::allocator<
char>>
567 _Inout_ std::basic_string<char, TR_to, AX_to>& dst,
568 _In_reads_or_z_opt_(count_src)
const T_from* src, _In_
size_t count_src,
571 stdex_assert(src || !count_src);
574 do_ascii = (what & sgml_full) == 0,
575 do_quot = (what & sgml_quot) == 0,
576 do_apos = (what & sgml_apos) == 0,
577 do_lt_gt = (what & sgml_lt_gt) == 0,
578 do_bsol = (what & sgml_bsol) == 0,
579 do_dollar = (what & sgml_dollar) == 0,
580 do_percnt = (what & sgml_percnt) == 0,
581 do_commat = (what & sgml_commat) == 0,
582 do_num = (what & sgml_num) == 0,
583 do_lpar_rpar = (what & sgml_lpar_rpar) == 0,
584 do_lcub_rcub = (what & sgml_lcub_rcub) == 0,
585 do_lsqb_rsqb = (what & sgml_lsqb_rsqb) == 0;
587 count_src = strnlen(src, count_src);
588 dst.reserve(dst.size() + count_src);
589 for (
size_t i = 0; i < count_src;) {
590 size_t n = glyphlen(src + i, count_src - i);
592 do_ascii && is7bit(src[i]) &&
594 (do_quot || (src[i] !=
'"')) &&
595 (do_apos || (src[i] !=
'\'')) &&
596 (do_lt_gt || (src[i] !=
'<' && src[i] !=
'>')) &&
597 (do_bsol || (src[i] !=
'\\')) &&
598 (do_dollar || (src[i] !=
'$')) &&
599 (do_percnt || (src[i] !=
'%')) &&
600 (do_commat || (src[i] !=
'@')) &&
601 (do_num || (src[i] !=
'#')) &&
602 (do_lpar_rpar || (src[i] !=
'(' && src[i] !=
')')) &&
603 (do_lcub_rcub || (src[i] !=
'{' && src[i] !=
'}')) &&
604 (do_lsqb_rsqb || (src[i] !=
'[' && src[i] !=
']')))
607 dst.append(1,
static_cast<char>(src[i++]));
610 const char* entity = chr2sgml(src + i, n);
620 dst.append(1,
static_cast<char>(src[i++]));
622 char tmp[3 + 8 + 1 + 1];
623 snprintf(tmp, _countof(tmp),
"&#x%x;",
static_cast<unsigned int>(src[i++]));
629 const size_t end = i + n;
631 if ((entity = chr2sgml(src + i, 1)) !=
nullptr) {
637 else if (is7bit(src[i]))
638 dst.append(1,
static_cast<char>(src[i++]));
640 char tmp[3 + 8 + 1 + 1];
641 snprintf(tmp, _countof(tmp),
"&#x%x;",
static_cast<unsigned int>(wstr_to_utf32(src, i, end)));
657 template <
class T_from,
class TR_to = std::
char_traits<
char>,
class AX_to = std::allocator<
char>,
class TR_from = std::
char_traits<T_from>,
class AX_from = std::allocator<T_from>>
659 _Inout_ std::basic_string<char, TR_to, AX_to>& dst,
660 _In_
const std::basic_string<T_from, TR_from, AX_from>& src,
663 str2sgmlcat(dst, src.data(), src.size(), what);
677 template <
class T_from>
679 _Inout_cap_(count_dst)
char* dst, _In_
size_t count_dst,
680 _In_reads_or_z_opt_(count_src)
const T_from* src, _In_
size_t count_src,
683 stdex_assert(dst || !count_dst);
684 stdex_assert(src || !count_src);
686 static const std::invalid_argument buffer_overrun(
"buffer overrun");
688 do_ascii = (what & sgml_full) == 0,
689 do_quot = (what & sgml_quot) == 0,
690 do_apos = (what & sgml_apos) == 0,
691 do_lt_gt = (what & sgml_lt_gt) == 0,
692 do_bsol = (what & sgml_bsol) == 0,
693 do_dollar = (what & sgml_dollar) == 0,
694 do_percnt = (what & sgml_percnt) == 0,
695 do_commat = (what & sgml_commat) == 0,
696 do_num = (what & sgml_num) == 0,
697 do_lpar_rpar = (what & sgml_lpar_rpar) == 0,
698 do_lcub_rcub = (what & sgml_lcub_rcub) == 0,
699 do_lsqb_rsqb = (what & sgml_lsqb_rsqb) == 0;
701 size_t j = strnlen(dst, count_dst);
702 count_src = strnlen(src, count_src);
703 for (
size_t i = 0; i < count_src;) {
704 size_t n = glyphlen(src + i, count_src - i);
706 do_ascii && is7bit(src[i]) &&
708 (do_quot || (src[i] !=
'"')) &&
709 (do_apos || (src[i] !=
'\'')) &&
710 (do_lt_gt || (src[i] !=
'<' && src[i] !=
'>')) &&
711 (do_bsol || (src[i] !=
'\\')) &&
712 (do_dollar || (src[i] !=
'$')) &&
713 (do_percnt || (src[i] !=
'%')) &&
714 (do_commat || (src[i] !=
'@')) &&
715 (do_num || (src[i] !=
'#')) &&
716 (do_lpar_rpar || (src[i] !=
'(' && src[i] !=
')')) &&
717 (do_lcub_rcub || (src[i] !=
'{' && src[i] !=
'}')) &&
718 (do_lsqb_rsqb || (src[i] !=
'[' && src[i] !=
']')))
721 if (j + 1 >= count_dst)
722 throw buffer_overrun;
723 dst[j++] =
static_cast<char>(src[i++]);
726 const char* entity = chr2sgml(src + i, n);
728 size_t m = strlen(entity);
729 if (j + m + 2 >= count_dst)
730 throw buffer_overrun;
732 memcpy(dst + j, entity, m *
sizeof(
char)); j += m;
738 if (is7bit(src[i])) {
739 if (j + 1 >= count_dst)
740 throw buffer_overrun;
741 dst[j++] =
static_cast<char>(src[i++]);
744 char tmp[3 + 8 + 1 + 1];
745 int m = snprintf(tmp, _countof(tmp),
"&#x%x;",
static_cast<unsigned int>(src[i++]));
746 stdex_assert(m >= 0);
747 if (
static_cast<size_t>(m) >= count_dst)
748 throw buffer_overrun;
749 memcpy(dst + j, tmp,
static_cast<size_t>(m) *
sizeof(
char));
750 j +=
static_cast<size_t>(m);
755 const size_t end = i + n;
757 if ((entity = chr2sgml(src + i, 1)) !=
nullptr) {
758 size_t m = strlen(entity);
759 if (j + m + 2 >= count_dst)
760 throw buffer_overrun;
762 memcpy(dst + j, entity, m *
sizeof(
char)); j += m;
766 else if (is7bit(src[i])) {
767 if (j + 1 >= count_dst)
768 throw buffer_overrun;
769 dst[j++] =
static_cast<char>(src[i++]);
772 char tmp[3 + 8 + 1 + 1];
773 int m = snprintf(tmp, _countof(tmp),
"&#x%x;",
static_cast<unsigned int>(wstr_to_utf32(src, i, end)));
774 stdex_assert(m >= 0);
775 if (
static_cast<size_t>(m) >= count_dst)
776 throw buffer_overrun;
777 memcpy(dst + j, tmp,
static_cast<size_t>(m) *
sizeof(
char));
778 j +=
static_cast<size_t>(m);
785 throw buffer_overrun;
798 template <
class T_from,
class TR_to = std::
char_traits<
char>,
class AX_to = std::allocator<
char>>
800 _Inout_ std::basic_string<char, TR_to, AX_to>& dst,
801 _In_reads_or_z_opt_(count_src)
const T_from* src, _In_
size_t count_src,
805 str2sgmlcat(dst, src, count_src, what);
815 template <
class T_from,
class TR_to = std::
char_traits<
char>,
class AX_to = std::allocator<
char>,
class TR_from = std::
char_traits<T_from>,
class AX_from = std::allocator<T_from>>
817 _Inout_ std::basic_string<char, TR_to, AX_to>& dst,
818 _In_
const std::basic_string<T_from, TR_from, AX_from>& src,
821 str2sgmlcpy(dst, src.data(), src.size(), what);
835 template <
class T_from>
837 _Inout_cap_(count_dst)
char* dst, _In_
size_t count_dst,
838 _In_reads_or_z_opt_(count_src)
const T_from* src, _In_
size_t count_src,
841 stdex_assert(dst || !count_dst);
844 return str2sgmlcat(dst, count_dst, src, count_src, what);
856 template <
class T_from>
857 std::string str2sgml(
858 _In_reads_or_z_opt_(count_src)
const T_from* src, _In_
size_t count_src,
862 str2sgmlcat(dst, src, count_src, what);
874 template <
class T_from,
class TR_from = std::
char_traits<T_from>,
class AX_from = std::allocator<T_from>>
875 std::string str2sgml(
876 _In_
const std::basic_string<T_from, TR_from, AX_from>& src,
879 return str2sgml(src.data(), src.size(), what);
884#pragma GCC diagnostic pop