3
3
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
4
5
5
use std:: borrow:: ToOwned ;
6
- use std:: cell:: { Cell , RefCell } ;
6
+ use std:: cell:: Cell ;
7
7
8
8
use dom_struct:: dom_struct;
9
- use encoding_rs:: { Decoder , DecoderResult , Encoding } ;
9
+ use encoding_rs:: Encoding ;
10
10
use js:: rust:: HandleObject ;
11
11
12
12
use crate :: dom:: bindings:: codegen:: Bindings :: TextDecoderBinding ;
@@ -19,37 +19,29 @@ use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto};
19
19
use crate :: dom:: bindings:: root:: DomRoot ;
20
20
use crate :: dom:: bindings:: str:: { DOMString , USVString } ;
21
21
use crate :: dom:: globalscope:: GlobalScope ;
22
+ use crate :: dom:: textdecodercommon:: TextDecoderCommon ;
22
23
use crate :: script_runtime:: CanGc ;
23
24
25
+ /// <https://encoding.spec.whatwg.org/#textdecoder>
24
26
#[ dom_struct]
25
27
#[ allow( non_snake_case) ]
26
28
pub ( crate ) struct TextDecoder {
27
29
reflector_ : Reflector ,
28
- #[ no_trace]
29
- encoding : & ' static Encoding ,
30
- fatal : bool ,
31
- ignoreBOM : bool ,
32
- #[ ignore_malloc_size_of = "defined in encoding_rs" ]
33
- #[ no_trace]
34
- decoder : RefCell < Decoder > ,
35
- in_stream : RefCell < Vec < u8 > > ,
30
+
31
+ /// <https://encoding.spec.whatwg.org/#textdecodercommon>
32
+ decoder : TextDecoderCommon ,
33
+
34
+ /// <https://encoding.spec.whatwg.org/#textdecoder-do-not-flush-flag>
36
35
do_not_flush : Cell < bool > ,
37
36
}
38
37
39
38
#[ allow( non_snake_case) ]
40
39
impl TextDecoder {
41
40
fn new_inherited ( encoding : & ' static Encoding , fatal : bool , ignoreBOM : bool ) -> TextDecoder {
41
+ let decoder = TextDecoderCommon :: new_inherited ( encoding, fatal, ignoreBOM) ;
42
42
TextDecoder {
43
43
reflector_ : Reflector :: new ( ) ,
44
- encoding,
45
- fatal,
46
- ignoreBOM,
47
- decoder : RefCell :: new ( if ignoreBOM {
48
- encoding. new_decoder ( )
49
- } else {
50
- encoding. new_decoder_without_bom_handling ( )
51
- } ) ,
52
- in_stream : RefCell :: new ( Vec :: new ( ) ) ,
44
+ decoder,
53
45
do_not_flush : Cell :: new ( false ) ,
54
46
}
55
47
}
@@ -77,6 +69,7 @@ impl TextDecoder {
77
69
}
78
70
}
79
71
72
+ #[ allow( non_snake_case) ]
80
73
impl TextDecoderMethods < crate :: DomTypeHolder > for TextDecoder {
81
74
/// <https://encoding.spec.whatwg.org/#dom-textdecoder>
82
75
fn Constructor (
@@ -100,85 +93,59 @@ impl TextDecoderMethods<crate::DomTypeHolder> for TextDecoder {
100
93
) )
101
94
}
102
95
103
- // https://encoding.spec.whatwg.org/#dom-textdecoder-encoding
96
+ /// < https://encoding.spec.whatwg.org/#dom-textdecoder-encoding>
104
97
fn Encoding ( & self ) -> DOMString {
105
- DOMString :: from ( self . encoding . name ( ) . to_ascii_lowercase ( ) )
98
+ DOMString :: from ( self . decoder . encoding ( ) . name ( ) . to_ascii_lowercase ( ) )
106
99
}
107
100
108
- // https://encoding.spec.whatwg.org/#dom-textdecoder-fatal
101
+ /// < https://encoding.spec.whatwg.org/#dom-textdecoder-fatal>
109
102
fn Fatal ( & self ) -> bool {
110
- self . fatal
103
+ self . decoder . fatal ( )
111
104
}
112
105
113
- // https://encoding.spec.whatwg.org/#dom-textdecoder-ignorebom
106
+ /// < https://encoding.spec.whatwg.org/#dom-textdecoder-ignorebom>
114
107
fn IgnoreBOM ( & self ) -> bool {
115
- self . ignoreBOM
108
+ self . decoder . ignore_bom ( )
116
109
}
117
110
118
- // https://encoding.spec.whatwg.org/#dom-textdecoder-decode
111
+ /// < https://encoding.spec.whatwg.org/#dom-textdecoder-decode>
119
112
fn Decode (
120
113
& self ,
121
114
input : Option < ArrayBufferViewOrArrayBuffer > ,
122
115
options : & TextDecodeOptions ,
123
116
) -> Fallible < USVString > {
124
- // Step 1.
117
+ // Step 1. If this’s do not flush is false, then set this’s decoder to a new
118
+ // instance of this’s encoding’s decoder, this’s I/O queue to the I/O queue
119
+ // of bytes « end-of-queue », and this’s BOM seen to false.
125
120
if !self . do_not_flush . get ( ) {
126
- if self . ignoreBOM {
121
+ if self . decoder . ignore_bom ( ) {
127
122
self . decoder
128
- . replace ( self . encoding . new_decoder_without_bom_handling ( ) ) ;
123
+ . decoder ( )
124
+ . replace ( self . decoder . encoding ( ) . new_decoder_without_bom_handling ( ) ) ;
129
125
} else {
130
- self . decoder . replace ( self . encoding . new_decoder ( ) ) ;
126
+ self . decoder
127
+ . decoder ( )
128
+ . replace ( self . decoder . encoding ( ) . new_decoder_with_bom_removal ( ) ) ;
131
129
}
132
- self . in_stream . replace ( Vec :: new ( ) ) ;
130
+ self . decoder . io_queue ( ) . replace ( Vec :: new ( ) ) ;
133
131
}
134
132
135
- // Step 2.
133
+ // Step 2. Set this’s do not flush to options["stream"].
136
134
self . do_not_flush . set ( options. stream ) ;
137
135
138
- // Step 3.
139
- match input {
140
- Some ( ArrayBufferViewOrArrayBuffer :: ArrayBufferView ( ref a) ) => {
141
- self . in_stream . borrow_mut ( ) . extend_from_slice ( & a. to_vec ( ) ) ;
142
- } ,
143
- Some ( ArrayBufferViewOrArrayBuffer :: ArrayBuffer ( ref a) ) => {
144
- self . in_stream . borrow_mut ( ) . extend_from_slice ( & a. to_vec ( ) ) ;
145
- } ,
146
- None => { } ,
147
- } ;
148
-
149
- let mut decoder = self . decoder . borrow_mut ( ) ;
150
- let ( remaining, s) = {
151
- let mut in_stream = self . in_stream . borrow_mut ( ) ;
152
-
153
- let ( remaining, s) = if self . fatal {
154
- // Step 4.
155
- let mut out_stream = String :: with_capacity (
156
- decoder
157
- . max_utf8_buffer_length_without_replacement ( in_stream. len ( ) )
158
- . unwrap ( ) ,
159
- ) ;
160
- // Step 5: Implemented by encoding_rs::Decoder.
161
- match decoder. decode_to_string_without_replacement (
162
- & in_stream,
163
- & mut out_stream,
164
- !options. stream ,
165
- ) {
166
- ( DecoderResult :: InputEmpty , read) => ( in_stream. split_off ( read) , out_stream) ,
167
- // Step 5.3.3.
168
- _ => return Err ( Error :: Type ( "Decoding failed" . to_owned ( ) ) ) ,
169
- }
170
- } else {
171
- // Step 4.
172
- let mut out_stream =
173
- String :: with_capacity ( decoder. max_utf8_buffer_length ( in_stream. len ( ) ) . unwrap ( ) ) ;
174
- // Step 5: Implemented by encoding_rs::Decoder.
175
- let ( _result, read, _replaced) =
176
- decoder. decode_to_string ( & in_stream, & mut out_stream, !options. stream ) ;
177
- ( in_stream. split_off ( read) , out_stream)
178
- } ;
179
- ( remaining, s)
180
- } ;
181
- self . in_stream . replace ( remaining) ;
182
- Ok ( USVString ( s) )
136
+ // Step 3. If input is given, then push a copy of input to this’s I/O queue.
137
+ // Step 4. Let output be the I/O queue of scalar values « end-of-queue ».
138
+ // Step 5. While true:
139
+ // Step 5.1 Let item be the result of reading from this’s I/O queue.
140
+ // Step 5.2 If item is end-of-queue and this’s do not flush is true,
141
+ // then return the result of running serialize I/O queue with this and output.
142
+ // Step 5.3 Otherwise:
143
+ // Step 5.3.1 Let result be the result of processing an item with item, this’s decoder,
144
+ // this’s I/O queue, output, and this’s error mode.
145
+ // Step 5.3.2 If result is finished, then return the result of running serialize I/O
146
+ // queue with this and output.
147
+ self . decoder
148
+ . decode ( input. as_ref ( ) , !options. stream )
149
+ . map ( USVString )
183
150
}
184
151
}
0 commit comments