Skip to content

Commit

Permalink
馃洜 Fix out-of-range and not-the-same array errors!
Browse files Browse the repository at this point in the history
  • Loading branch information
ThePhD committed Jun 25, 2021
1 parent 971b945 commit 0c56962
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 73 deletions.
26 changes: 8 additions & 18 deletions include/ztd/text/decode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,8 @@ namespace ztd { namespace text {
template <typename _Input, typename _Encoding, typename _Output, typename _ErrorHandler, typename _State>
constexpr auto basic_decode_into(_Input&& __input, _Encoding&& __encoding, _Output&& __output,
_ErrorHandler&& __error_handler, _State& __state) {
using _UInput = __txt_detail::__remove_cvref_t<_Input>;
using _InputValueType = __txt_detail::__range_value_type_t<_UInput>;
using _IntermediateInput
= __txt_detail::__range_reconstruct_t<::std::conditional_t<::std::is_array_v<_UInput>,
::std::conditional_t<__txt_detail::__is_character_v<_InputValueType>,
::std::basic_string_view<_InputValueType>, ::ztd::text::span<const _InputValueType>>,
_UInput>>;
= __txt_detail::__string_view_or_span_or_reconstruct_t<_Input>;
using _IntermediateOutput = __txt_detail::__range_reconstruct_t<_Output>;
using _Result = decltype(__encoding.decode_one(
::std::declval<_IntermediateInput>(), ::std::declval<_IntermediateOutput>(), __error_handler, __state));
Expand All @@ -113,8 +108,7 @@ namespace ztd { namespace text {
"or "
"decode_into(in, encoding, out, handler, ...) explicitly in order to bypass this.");

_WorkingInput __working_input(
__txt_detail::__reconstruct(::std::in_place_type<_WorkingInput>, ::std::forward<_Input>(__input)));
_WorkingInput __working_input = __txt_detail::__string_view_or_span_or_reconstruct(::std::forward<_Input>(__input));
_WorkingOutput __working_output(
__txt_detail::__reconstruct(::std::in_place_type<_WorkingOutput>, ::std::forward<_Output>(__output)));
::std::size_t __handled_errors = 0;
Expand Down Expand Up @@ -190,28 +184,24 @@ namespace ztd { namespace text {
= ZTD_TEXT_INTERMEDIATE_BUFFER_SIZE_I_ < max_code_points_v<_UEncoding>
? max_code_points_v<_UEncoding>
: ZTD_TEXT_INTERMEDIATE_BUFFER_SIZE_I_;
using _UInput = __txt_detail::__remove_cvref_t<_Input>;
using _InputValueType = __txt_detail::__range_value_type_t<_UInput>;
using _IntermediateValueType = code_point_t<_UEncoding>;
using _IntermediateInput
= __txt_detail::__range_reconstruct_t<::std::conditional_t<::std::is_array_v<_UInput>,
::std::conditional_t<__txt_detail::__is_character_v<_InputValueType>,
::std::basic_string_view<_InputValueType>, ::ztd::text::span<const _InputValueType>>,
_UInput>>;
using _Output = ::ztd::text::span<_IntermediateValueType, __intermediate_buffer_max>;
= __txt_detail::__string_view_or_span_or_reconstruct_t<_Input>;
using _OutputInitial = ::ztd::text::span<_IntermediateValueType, __intermediate_buffer_max>;
using _Output = ::ztd::text::span<_IntermediateValueType>;
using _Result = decltype(__encoding.decode_one(
::std::declval<_IntermediateInput>(), ::std::declval<_Output>(), __error_handler, __state));
using _WorkingInput = __txt_detail::__remove_cvref_t<decltype(::std::declval<_Result>().input)>;

_WorkingInput __working_input(
__txt_detail::__reconstruct(::std::in_place_type<_WorkingInput>, ::std::forward<_Input>(__input)));
__txt_detail::__string_view_or_span_or_reconstruct(::std::forward<_Input>(__input)));
_IntermediateValueType __intermediate_translation_buffer[__intermediate_buffer_max] {};
for (;;) {
// Ignore "out of output" errors and do our best to recover properly along the way...
_Output __intermediate_initial_output(__intermediate_translation_buffer);
_OutputInitial __intermediate_initial_output(__intermediate_translation_buffer);
auto __result = decode_into(::std::move(__working_input), ::std::forward<_Encoding>(__encoding),
__intermediate_initial_output, ::std::forward<_ErrorHandler>(__error_handler), __state);
::ztd::text::span<_IntermediateValueType> __intermediate_output(
_Output __intermediate_output(
__intermediate_initial_output.data(), __result.output.data());
using _SpanIterator = typename ::ztd::text::span<_IntermediateValueType>::iterator;
if constexpr (__txt_detail::__is_detected_v<__txt_detail::__detect_insert_bulk, _OutputContainer,
Expand Down
3 changes: 1 addition & 2 deletions include/ztd/text/detail/reconstruct.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ namespace ztd { namespace text {
_UInput> && ::std::is_const_v<::std::remove_extent_t<_VInput>> && ::std::is_lvalue_reference_v<_Input>) {
using _CharTy = ::std::remove_extent_t<_UInput>;
if constexpr (__is_char_traitable_v<_CharTy>) {
return __reconstruct(::std::in_place_type<::std::basic_string_view<_CharTy>>,
__adl::__adl_begin(__input), __adl::__adl_end(__input));
return ::std::basic_string_view<_CharTy>(::std::forward<_Input>(__input));
}
else {
using _Ty = ::std::remove_extent_t<_VInput>;
Expand Down
34 changes: 15 additions & 19 deletions include/ztd/text/detail/transcode_one.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,36 +520,32 @@ namespace ztd { namespace text {
__to_error_handler, __from_state, __to_state, __intermediate);
}

template <typename _Input, typename _Encoding, typename _CodePointContainer, typename _CodeUnitContainer,
typename _DecodeState, typename _EncodeState>
constexpr auto __basic_validate_decodable_as_one(_Input&& __input, _Encoding&& __encoding,
_CodeUnitContainer& __code_unit_output, _CodePointContainer& __code_point_output,
_DecodeState& __decode_state, _EncodeState& __encode_state) {
template <typename _Input, typename _Encoding, typename _Output, typename _DecodeState, typename _EncodeState,
typename _Intermediate>
constexpr auto __basic_validate_decodable_as_one(_Input&& __input, _Encoding&& __encoding, _Output& __output,
_DecodeState& __decode_state, _EncodeState& __encode_state, _Intermediate& __intermediate) {

using _UInput = __remove_cvref_t<_Input>;
using _UOutput = __remove_cvref_t<_CodeUnitContainer>;
using _UOutput = __remove_cvref_t<_Output>;
using _InSubRange = subrange<__range_iterator_t<_UInput>, __range_sentinel_t<_UInput>>;
using _OutSubRange = subrange<__range_iterator_t<_UOutput>, __range_sentinel_t<_UOutput>>;

auto __inital_input = __reconstruct(std::in_place_type<_UInput>, __input);
_OutSubRange __working_output(__code_unit_output);
_InSubRange __working_input(::std::forward<_Input>(__input));
_OutSubRange __working_output(__output);
__pass_through_handler __error_handler {};

using _TranscodeResult = decltype(__basic_transcode_one<__consume::__no>(::std::forward<_Input>(__input),
__encoding, __working_output, __encoding, __error_handler, __error_handler, __decode_state,
__encode_state, __code_point_output));
using _ValidateInput = decltype(::std::declval<_TranscodeResult>().input);
using _Result = validate_result<_ValidateInput, _DecodeState>;
using _Result = validate_result<__range_reconstruct_t<_InSubRange, _UInput>, _DecodeState>;

auto __transcode_result = __basic_transcode_one<__consume::__no>(::std::forward<_Input>(__input),
__encoding, __working_output, __encoding, __error_handler, __error_handler, __decode_state,
__encode_state, __code_point_output);
auto __transcode_result
= __basic_transcode_one<__consume::__no>(__working_input, __encoding, __working_output, __encoding,
__error_handler, __error_handler, __decode_state, __encode_state, __intermediate);
if (__transcode_result.error_code != encoding_error::ok) {
return _Result(__reconstruct(::std::in_place_type<_UInput>, ::std::move(__transcode_result.input)),
false, __decode_state);
}

const bool __is_equal_transcode
= __equal(__adl::__adl_begin(__inital_input), __adl::__adl_begin(__transcode_result.input),
= __equal(__adl::__adl_begin(__working_input), __adl::__adl_begin(__transcode_result.input),
__adl::__adl_begin(__working_output), __adl::__adl_begin(__transcode_result.output));
if (!__is_equal_transcode) {
return _Result(__reconstruct(::std::in_place_type<_UInput>, ::std::move(__transcode_result.input)),
Expand All @@ -571,7 +567,7 @@ namespace ztd { namespace text {
_CodeUnit __output_storage[max_code_units_v<_UEncoding>] {};
::ztd::text::span<_CodeUnit, max_code_units_v<_UEncoding>> __output(__output_storage);
return __basic_validate_decodable_as_one(::std::forward<_Input>(__input),
::std::forward<_Encoding>(__encoding), __output, __intermediate, __decode_state, __encode_state);
::std::forward<_Encoding>(__encoding), __output, __decode_state, __encode_state, __intermediate);
}

template <typename _Input, typename _Encoding, typename _CodePointContainer, typename _CodeUnitContainer,
Expand All @@ -582,9 +578,9 @@ namespace ztd { namespace text {

using _UInput = __remove_cvref_t<_Input>;
using _UOutput = __remove_cvref_t<_CodePointContainer>;
using _Result = validate_result<__reconstruct_t<_Input>, _EncodeState>;
using _InSubRange = subrange<__range_iterator_t<_UInput>, __range_sentinel_t<_UInput>>;
using _OutSubRange = subrange<__range_iterator_t<_UOutput>, __range_sentinel_t<_UOutput>>;
using _Result = validate_result<__range_reconstruct_t<_InSubRange, _UInput>, _EncodeState>;

__pass_through_handler __error_handler {};
_InSubRange __working_input(::std::forward<_Input>(__input));
Expand Down
36 changes: 11 additions & 25 deletions include/ztd/text/encode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,8 @@ namespace ztd { namespace text {
template <typename _Input, typename _Encoding, typename _Output, typename _ErrorHandler, typename _State>
constexpr auto basic_encode_into(_Input&& __input, _Encoding&& __encoding, _Output&& __output,
_ErrorHandler&& __error_handler, _State& __state) {
using _UInput = __txt_detail::__remove_cvref_t<_Input>;
using _InputValueType = __txt_detail::__range_value_type_t<_UInput>;
// using _OutputValueType = __txt_detail::__range_value_type_t<_UOutput>;
using _IntermediateInput
= __txt_detail::__range_reconstruct_t<::std::conditional_t<::std::is_array_v<_UInput>,
::std::conditional_t<__txt_detail::__is_character_v<_InputValueType>,
::std::basic_string_view<_InputValueType>, ::ztd::text::span<const _InputValueType>>,
_UInput>>;
using _IntermediateOutput = __txt_detail::__range_reconstruct_t<_Output>;
using _IntermediateInput = __txt_detail::__string_view_or_span_or_reconstruct_t<_Input>;
using _IntermediateOutput = __txt_detail::__reconstruct_t<_Output>;
using _Result = decltype(__encoding.encode_one(
::std::declval<_IntermediateInput>(), ::std::declval<_IntermediateOutput>(), __error_handler, __state));
using _WorkingInput = __txt_detail::__remove_cvref_t<decltype(::std::declval<_Result>().input)>;
Expand All @@ -112,10 +105,8 @@ namespace ztd { namespace text {
"to lose; specify a 'handler' error handler parameter to encode(in, encoding, handler, ...) or "
"encode_into(in, encoding, out, handler, ...) explicitly in order to bypass this.");

_WorkingInput __working_input(
__txt_detail::__reconstruct(::std::in_place_type<_WorkingInput>, ::std::forward<_Input>(__input)));
_WorkingOutput __working_output(
__txt_detail::__reconstruct(::std::in_place_type<_WorkingOutput>, ::std::forward<_Output>(__output)));
_WorkingInput __working_input = __txt_detail::__string_view_or_span_or_reconstruct(::std::forward<_Input>(__input));
_WorkingOutput __working_output =__txt_detail::__reconstruct(::std::in_place_type<_WorkingOutput>, ::std::forward<_Output>(__output));
::std::size_t __handled_errors = false;

for (;;) {
Expand Down Expand Up @@ -190,28 +181,23 @@ namespace ztd { namespace text {
= ZTD_TEXT_INTERMEDIATE_BUFFER_SIZE_I_ < max_code_units_v<_UEncoding>
? max_code_units_v<_UEncoding>
: ZTD_TEXT_INTERMEDIATE_BUFFER_SIZE_I_;
using _UInput = __txt_detail::__remove_cvref_t<_Input>;
using _InputValueType = __txt_detail::__range_value_type_t<_UInput>;
using _IntermediateValueType = code_unit_t<_UEncoding>;
using _IntermediateInput
= __txt_detail::__range_reconstruct_t<::std::conditional_t<::std::is_array_v<_UInput>,
::std::conditional_t<__txt_detail::__is_character_v<_InputValueType>,
::std::basic_string_view<_InputValueType>, ::ztd::text::span<const _InputValueType>>,
_UInput>>;
using _Output = ::ztd::text::span<_IntermediateValueType, __intermediate_buffer_max>;
using _Result = decltype(__encoding.encode_one(
= __txt_detail::__string_view_or_span_or_reconstruct_t<_Input>;
using _InitialOutput = ::ztd::text::span<_IntermediateValueType, __intermediate_buffer_max>;
using _Output = ::ztd::text::span<_IntermediateValueType>;
using _Result = decltype(__encoding.encode_one(
::std::declval<_IntermediateInput>(), ::std::declval<_Output>(), __error_handler, __state));
using _WorkingInput = __txt_detail::__remove_cvref_t<decltype(::std::declval<_Result>().input)>;

_WorkingInput __working_input(
__txt_detail::__reconstruct(::std::in_place_type<_WorkingInput>, ::std::forward<_Input>(__input)));
_WorkingInput __working_input = __txt_detail::__string_view_or_span_or_reconstruct(::std::forward<_Input>(__input));
_IntermediateValueType __intermediate_translation_buffer[__intermediate_buffer_max] {};
for (;;) {
// Ignore "out of output" errors and do our best to recover properly along the way...
_Output __intermediate_initial_output(__intermediate_translation_buffer);
_InitialOutput __intermediate_initial_output(__intermediate_translation_buffer);
auto __result = encode_into(::std::move(__working_input), ::std::forward<_Encoding>(__encoding),
__intermediate_initial_output, ::std::forward<_ErrorHandler>(__error_handler), __state);
::ztd::text::span<_IntermediateValueType> __intermediate_output(
_Output __intermediate_output(
__intermediate_initial_output.data(), __result.output.data());
using _SpanIterator = typename ::ztd::text::span<_IntermediateValueType>::iterator;
if constexpr (__txt_detail::__is_detected_v<__txt_detail::__detect_insert_bulk, _OutputContainer,
Expand Down
15 changes: 6 additions & 9 deletions include/ztd/text/validate_decodable_as.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,14 @@ namespace ztd { namespace text {
using _CodeUnit = code_unit_t<_UEncoding>;
using _CodePoint = code_point_t<_UEncoding>;

_CodePoint __code_point_intermediate_storage[max_code_points_v<_UEncoding>] {};
::ztd::text::span<_CodePoint, max_code_points_v<_UEncoding>> __code_point_intermediate(
__code_point_intermediate_storage);
_CodeUnit __code_unit_intermediate_storage[max_code_units_v<_UEncoding>] {};
::ztd::text::span<_CodeUnit, max_code_units_v<_UEncoding>> __code_unit_intermediate(
__code_unit_intermediate_storage);
_CodePoint __intermediate_storage[max_code_points_v<_UEncoding>] {};
::ztd::text::span<_CodePoint, max_code_points_v<_UEncoding>> __intermediate(__intermediate_storage);
_CodeUnit __output_storage[max_code_units_v<_UEncoding>] {};
::ztd::text::span<_CodeUnit, max_code_units_v<_UEncoding>> __output(__output_storage);

for (;;) {
auto __stateless_validate_result
= __txt_detail::__basic_validate_decodable_as_one(__working_input, __encoding,
__code_point_intermediate, __code_unit_intermediate, __decode_state, __encode_state);
auto __stateless_validate_result = __txt_detail::__basic_validate_decodable_as_one(
__working_input, __encoding, __output, __decode_state, __encode_state, __intermediate);
if (!__stateless_validate_result.valid) {
return _Result(__txt_detail::__reconstruct(
::std::in_place_type<_WorkingInput>, ::std::move(__working_input)),
Expand Down

0 comments on commit 0c56962

Please sign in to comment.