2020-05-03 17:41:34 -03:00
|
|
|
/*
|
2024-10-04 08:19:50 -03:00
|
|
|
* Copyright (c) 2020-2021, Andreas Kling <andreas@ladybird.org>
|
2024-11-01 08:14:53 -03:00
|
|
|
* Copyright (c) 2022, Jelle Raaijmakers <jelle@ladybird.org>
|
2023-02-17 14:45:08 -03:00
|
|
|
* Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org>
|
2020-05-03 17:41:34 -03:00
|
|
|
*
|
2021-04-22 05:24:48 -03:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-05-03 17:41:34 -03:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <AK/Forward.h>
|
2021-08-29 08:44:28 -03:00
|
|
|
#include <AK/Function.h>
|
2026-06-19 19:51:56 -03:00
|
|
|
#include <AK/Noncopyable.h>
|
2023-02-17 14:45:08 -03:00
|
|
|
#include <AK/Optional.h>
|
2023-02-17 17:15:10 -03:00
|
|
|
#include <AK/String.h>
|
Libraries: Clean up UTF-16 source text paths
Store parser errors, source range filenames, source code filenames,
module source, and Rust parser errors as UTF-16 where they flow back
into JavaScript-visible strings. Keep byte-oriented source buffers
byte-backed.
Remove temporary PrimitiveString, ByteString, and UTF-8 detours from
JSON, RegExp, module debug logging, print formatting, and tests.
2026-06-21 14:03:19 -03:00
|
|
|
#include <AK/Utf16String.h>
|
2026-01-16 11:14:26 -03:00
|
|
|
#include <LibTextCodec/Export.h>
|
2025-06-28 16:57:28 -03:00
|
|
|
#include <LibTextCodec/Forward.h>
|
2020-05-03 17:41:34 -03:00
|
|
|
|
|
|
|
|
namespace TextCodec {
|
|
|
|
|
|
2026-06-22 17:07:40 -03:00
|
|
|
enum class IgnoreBOM {
|
|
|
|
|
Yes,
|
|
|
|
|
No,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// https://encoding.spec.whatwg.org/#concept-encoding-error-mode
|
|
|
|
|
enum class ErrorMode {
|
|
|
|
|
Replacement,
|
|
|
|
|
Fatal,
|
|
|
|
|
};
|
|
|
|
|
|
2025-06-28 16:57:28 -03:00
|
|
|
class TEXTCODEC_API Decoder {
|
2020-05-03 17:41:34 -03:00
|
|
|
public:
|
2026-06-22 17:07:40 -03:00
|
|
|
virtual ErrorOr<String> to_utf8(StringView, IgnoreBOM, ErrorMode);
|
Libraries: Clean up UTF-16 source text paths
Store parser errors, source range filenames, source code filenames,
module source, and Rust parser errors as UTF-16 where they flow back
into JavaScript-visible strings. Keep byte-oriented source buffers
byte-backed.
Remove temporary PrimitiveString, ByteString, and UTF-8 detours from
JSON, RegExp, module debug logging, print formatting, and tests.
2026-06-21 14:03:19 -03:00
|
|
|
virtual ErrorOr<Utf16String> to_utf16(StringView);
|
2026-06-03 06:03:51 -03:00
|
|
|
virtual ErrorOr<size_t> length_in_utf16_code_units(StringView);
|
2026-05-17 14:05:53 -03:00
|
|
|
ErrorOr<void> process_code_points(StringView, Function<ErrorOr<void>(u32)>);
|
2021-04-15 14:43:29 -03:00
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
virtual ~Decoder() = default;
|
2025-04-15 12:49:09 -03:00
|
|
|
virtual ErrorOr<void> process(StringView, Function<ErrorOr<void>(u32)> on_code_point) = 0;
|
2020-05-03 17:41:34 -03:00
|
|
|
};
|
|
|
|
|
|
LibTextCodec: Add streaming decoder
Introduce a StreamingDecoder wrapper that lets callers feed bytes to a
Decoder one chunk at a time. It buffers any incomplete trailing byte
sequence at the end of a chunk and prepends it to the next chunk, so a
multi-byte code point split across a chunk boundary is decoded correctly
once the next chunk arrives.
To support that, add an incomplete_tail_length() virtual on Decoder
returning the number of trailing bytes that form an incomplete sequence
per the Encoding Standard's decoder handler byte ranges, with overrides
for UTF-8, UTF-16BE, UTF-16LE, GB18030, Big5, EUC-JP, ISO-2022-JP,
Shift_JIS, and EUC-KR. The default implementation returns 0, which keeps
single-byte legacy decoders correct.
This is the foundation for the upcoming incremental HTML parser, which
needs to decode network response bodies as they arrive.
2026-04-27 15:00:25 -03:00
|
|
|
class TEXTCODEC_API StreamingDecoder final {
|
2026-06-19 19:51:56 -03:00
|
|
|
AK_MAKE_NONCOPYABLE(StreamingDecoder);
|
|
|
|
|
|
LibTextCodec: Add streaming decoder
Introduce a StreamingDecoder wrapper that lets callers feed bytes to a
Decoder one chunk at a time. It buffers any incomplete trailing byte
sequence at the end of a chunk and prepends it to the next chunk, so a
multi-byte code point split across a chunk boundary is decoded correctly
once the next chunk arrives.
To support that, add an incomplete_tail_length() virtual on Decoder
returning the number of trailing bytes that form an incomplete sequence
per the Encoding Standard's decoder handler byte ranges, with overrides
for UTF-8, UTF-16BE, UTF-16LE, GB18030, Big5, EUC-JP, ISO-2022-JP,
Shift_JIS, and EUC-KR. The default implementation returns 0, which keeps
single-byte legacy decoders correct.
This is the foundation for the upcoming incremental HTML parser, which
needs to decode network response bodies as they arrive.
2026-04-27 15:00:25 -03:00
|
|
|
public:
|
2026-06-22 17:07:40 -03:00
|
|
|
StreamingDecoder(StringView encoding, IgnoreBOM, ErrorMode);
|
2026-06-19 19:51:56 -03:00
|
|
|
~StreamingDecoder();
|
LibTextCodec: Add streaming decoder
Introduce a StreamingDecoder wrapper that lets callers feed bytes to a
Decoder one chunk at a time. It buffers any incomplete trailing byte
sequence at the end of a chunk and prepends it to the next chunk, so a
multi-byte code point split across a chunk boundary is decoded correctly
once the next chunk arrives.
To support that, add an incomplete_tail_length() virtual on Decoder
returning the number of trailing bytes that form an incomplete sequence
per the Encoding Standard's decoder handler byte ranges, with overrides
for UTF-8, UTF-16BE, UTF-16LE, GB18030, Big5, EUC-JP, ISO-2022-JP,
Shift_JIS, and EUC-KR. The default implementation returns 0, which keeps
single-byte legacy decoders correct.
This is the foundation for the upcoming incremental HTML parser, which
needs to decode network response bodies as they arrive.
2026-04-27 15:00:25 -03:00
|
|
|
|
|
|
|
|
ErrorOr<String> to_utf8(ReadonlyBytes);
|
|
|
|
|
ErrorOr<String> finish();
|
|
|
|
|
|
|
|
|
|
private:
|
2026-06-22 17:07:40 -03:00
|
|
|
ErrorMode m_error_mode { ErrorMode::Replacement };
|
2026-06-19 19:51:56 -03:00
|
|
|
void* m_decoder { nullptr };
|
LibTextCodec: Add streaming decoder
Introduce a StreamingDecoder wrapper that lets callers feed bytes to a
Decoder one chunk at a time. It buffers any incomplete trailing byte
sequence at the end of a chunk and prepends it to the next chunk, so a
multi-byte code point split across a chunk boundary is decoded correctly
once the next chunk arrives.
To support that, add an incomplete_tail_length() virtual on Decoder
returning the number of trailing bytes that form an incomplete sequence
per the Encoding Standard's decoder handler byte ranges, with overrides
for UTF-8, UTF-16BE, UTF-16LE, GB18030, Big5, EUC-JP, ISO-2022-JP,
Shift_JIS, and EUC-KR. The default implementation returns 0, which keeps
single-byte legacy decoders correct.
This is the foundation for the upcoming incremental HTML parser, which
needs to decode network response bodies as they arrive.
2026-04-27 15:00:25 -03:00
|
|
|
};
|
|
|
|
|
|
2024-06-02 10:56:36 -03:00
|
|
|
// This will return a decoder for the exact name specified, skipping get_standardized_encoding.
|
|
|
|
|
// Use this when you want ISO-8859-1 instead of windows-1252.
|
2025-06-28 16:57:28 -03:00
|
|
|
TEXTCODEC_API Optional<Decoder&> decoder_for_exact_name(StringView encoding);
|
2024-06-02 10:56:36 -03:00
|
|
|
|
2025-06-28 16:57:28 -03:00
|
|
|
TEXTCODEC_API Optional<Decoder&> decoder_for(StringView encoding);
|
|
|
|
|
TEXTCODEC_API Optional<StringView> get_standardized_encoding(StringView encoding);
|
2020-05-03 17:41:34 -03:00
|
|
|
|
2023-02-17 16:53:51 -03:00
|
|
|
// This returns the appropriate Unicode decoder for the sniffed BOM or nothing if there is no appropriate decoder.
|
2025-06-28 16:57:28 -03:00
|
|
|
TEXTCODEC_API Optional<Decoder&> bom_sniff_to_decoder(StringView);
|
2022-02-11 17:58:06 -03:00
|
|
|
|
2022-02-11 18:02:29 -03:00
|
|
|
// NOTE: This has an obnoxious name to discourage usage. Only use this if you absolutely must! For example, XHR in LibWeb uses this.
|
|
|
|
|
// This will use the given decoder unless there is a byte order mark in the input, in which we will instead use the appropriate Unicode decoder.
|
2025-06-28 16:57:28 -03:00
|
|
|
TEXTCODEC_API ErrorOr<String> convert_input_to_utf8_using_given_decoder_unless_there_is_a_byte_order_mark(Decoder&, StringView);
|
Libraries: Clean up UTF-16 source text paths
Store parser errors, source range filenames, source code filenames,
module source, and Rust parser errors as UTF-16 where they flow back
into JavaScript-visible strings. Keep byte-oriented source buffers
byte-backed.
Remove temporary PrimitiveString, ByteString, and UTF-8 detours from
JSON, RegExp, module debug logging, print formatting, and tests.
2026-06-21 14:03:19 -03:00
|
|
|
TEXTCODEC_API ErrorOr<Utf16String> convert_input_to_utf16_using_given_decoder_unless_there_is_a_byte_order_mark(Decoder&, StringView);
|
2026-06-03 06:03:51 -03:00
|
|
|
TEXTCODEC_API ErrorOr<size_t> convert_input_to_utf16_length_using_given_decoder_unless_there_is_a_byte_order_mark(Decoder&, StringView);
|
2022-02-11 18:02:29 -03:00
|
|
|
|
2025-06-28 16:57:28 -03:00
|
|
|
TEXTCODEC_API StringView get_output_encoding(StringView encoding);
|
2023-06-18 12:25:33 -03:00
|
|
|
|
2025-11-24 14:20:51 -03:00
|
|
|
TEXTCODEC_API String isomorphic_decode(StringView);
|
|
|
|
|
|
2020-05-03 17:41:34 -03:00
|
|
|
}
|