/
944.txt
270 lines (225 loc) · 15.6 KB
/
944.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
[47] [DFN[符号化]]は、[[文字列]]を[[バイト列]]に変換する操作です。
[DFN[復号]]は、[[バイト列]]を[[文字列]]に変換する操作です。
* 仕様書
[REFS[
- [15] [CITE@en-US[Encoding Standard]] ([TIME[2016-07-29 16:12:31 +09:00]]) <https://encoding.spec.whatwg.org/#encodings>
- [1] [CITE@en-US[Encoding Standard]] ([TIME[2016-07-29 16:12:31 +09:00]]) <https://encoding.spec.whatwg.org/#specification-hooks>
- [56] [CITE@en-US[Encoding Standard]] ([TIME[2016-07-29 16:12:31 +09:00]]) <https://encoding.spec.whatwg.org/#textdecoder>
]REFS]
* 符号化
[45] [[符号化][符号化 (動詞)]]は、[[文字列]]を何らかの[[バイト列]]に変換する操作です。
[40] [DFN[[RUBYB[符号化]@en[encode]]]]は、
[[符号位置]]の[[ストリーム]][VAR[ストリーム]]と[[文字符号化]][VAR[符号化]]について、
次のようにします [SRC[>>1]]。
[FIG(steps)[
= [41] [VAR[出力]]を、[[バイトストリーム]]に設定します。
= [42] [VAR[符号化]]の[F[符号化器クラス]]を[[走らせ][走らせる]]ます。
[VAR[入力]]を[VAR[ストリーム]]、[VAR[出力]]を[VAR[出力]]とし、
[VAR[[[誤りモード]]]]は [CODE[html]] とします。
= [43] [VAR[出力]]を返します。
]FIG]
;; [44] [[replacement]]、[[UTF-16BE]]、[[UTF-16LE]] を[VAR[符号化]]とすることはできません
[SRC[>>1]]。
[53] 次の場面で用いられます。
[FIG(list short)[
- [[UTF-8符号化]]
- [[URL構文解析器]]の [[query][URL query]]
- [CODE(MIME)@en[application/x-www-form-urlencoded]] の[[符号化]]
]FIG]
[31] [CODE(DOMi)@en[TextEncoder]] の [CODE(DOMm)@en[encode][TextEncoder]]
[[メソッド]]は、[[UTF-8符号化]]を使っていませんが、実質的に等価です。
[46] この操作は、 [[Encoding Standard]] の任意の[[文字符号化]]への[[符号化][符号化 (動詞)]]に対応しています。
これは[[後方互換性]]のため必要な場面でのみ使われることになっています。
新しい文脈では [[UTF-8符号化]]などを用いるのが望ましいと考えられています [SRC[>>1]]。
* 復号
[33] [[復号][復号 (符号化)]]は、何らかの[[バイト列]]を[[文字列]]に変換する操作です。
[37] この操作は、引数として[[文字符号化]]を引き渡すことができます。
しかし入力に [[BOM]] が含まれていれば、そちらが優先されます。
;; [38] [[HTTP]] 仕様上は [CODE(MIME)@en[charset]] [[引数]]の[[文字符号化]]の指定が
[[BOM]] より優先されることになっていますが、現実にはそれでは[[相互運用性]]に問題があります。
これは[[意図的違反]]です [SRC[>>1]]。
[3] [DFN[[RUBYB[復号]@en[decode]]][復号 (符号化)]]は、
[[バイトストリーム]][VAR[ストリーム]]とフォールバック符号化[VAR[符号化]]について、
次のようにします [SRC[>>1]]。
[FIG(steps)[
= [4] [VAR[バッファー]]を、空の[[バイト列]]に設定します。
= [6] 繰り返し、[VAR[ストリーム]]を[[読み][読む (ストリーム)]]、
[VAR[バッファー]]の末尾に追加します。[VAR[バッファー]]が3[[バイト]]となるか、
[[end-of-stream]] が得られた時点でやめます。
= [7] [VAR[バッファー]]の最初の3バイトが [CODE[0xEF 0xBB 0xBF]] なら、
== [8] [VAR[符号化]]を、 [[UTF-8]] に設定します。
= [10] それ以外で、[VAR[バッファー]]の最初の2バイトが [CODE[0xFE 0xFF]] なら、
== [11] [VAR[符号化]]を、 [[UTF-16BE]] に設定します。
== [5] [VAR[バッファー]]が3バイトなら、
=== [9] [VAR[バッファー]]の最後の[[バイト]]を、[VAR[ストリーム]]に[[prepend][prepend (ストリーム)]]します。
= [13] それ以外で、[VAR[バッファー]]の最初の2バイトが [CODE[0xFF 0xFE]] なら、
== [14] [VAR[符号化]]を、 [[UTF-16LE]] に設定します。
== [35] [VAR[バッファー]]が3バイトなら、
=== [36] [VAR[バッファー]]の最後の[[バイト]]を、[VAR[ストリーム]]に[[prepend][prepend (ストリーム)]]します。
= [34] それ以外なら、
== [32] [VAR[バッファー]]を、[VAR[ストリーム]]に[[prepend][prepend (ストリーム)]]します。
= [12] [VAR[出力]]を、[[符号位置]]の[[ストリーム]]に設定します。
= [16] [VAR[符号化]]の[F[復号器クラス]]を[[走らせ][走らせる (符号化)]]ます。
[VAR[入力]]は[VAR[ストリーム]]、[VAR[出力]]は[VAR[出力]]とします。
= [17] [VAR[出力]]を返します。
]FIG]
[39] この操作は、 [[Encoding Standard]] の任意の[[文字符号化]]からの[[復号][復号 (符号化)]]に対応しています。
これは[[後方互換性]]のため必要な場面でのみ使われることになっています。
新しい文脈では [[UTF-8復号]]を用いるのが望ましいと考えられています [SRC[>>1]]。
[72] 次の場面で使われています。
[FIG(list short)[
- [[XHR]] [[テキスト応答]]
- [[古典スクリプトのfetch]]
- [[HTML構文解析器]]
- [[CSS構文解析器]]
- [[Web Transport Processing]]
[HISTORY[
- [CODE(MIME)@en[application/x-www-form-urlencoded]] の[[復号]]
]HISTORY]
]FIG]
;; [73] [[HTML Standard]] は[[復号][復号 (符号化)]]を使っていますが、
厳密には、これでは受信したデータを順次処理していくことができません。
>>57 に近い処理を繰り返す必要があります。
[57] [CODE(DOMi)@en[TextDecoder]] [[インターフェイス]]の
[CODE(DOMa)@en[decode][TextDecoder]] [[メソッド]] [SRC[>>56]]
は、その[[復号][復号 (符号化)]]の処理の部分について、引数として
[FIG(list members)[
: [VAR[復号器オブジェクト]] : [[復号器オブジェクト]]
: [VAR[ストリーム]] : [[ストリーム]]
: [VAR[誤りモード]] : [[誤りモード]] ([CODE[replacement][replacement (符号化)]] または [CODE[fatal][fatal (符号化)]])
: [VAR[do not flush flag]] : [[フラグ]]
: [VAR[BOM無視フラグ]] : [[フラグ]]
]FIG]
... を受け取り、次のようにします。
[FIG(steps)[
= [58] [VAR[出力]]を、新しい[[ストリーム]]に設定します。
= [59] 繰り返し、
== [60] [VAR[字句]]を、[VAR[ストリーム]]を[[読ん][読む]]だ結果に設定します。
== [61] [VAR[字句]]が [[end-of-stream]] で、 [VAR[do not flush flag]] が[[真]]なら、
=== [63] 繰り返しをここで脱出します。
== [62] それ以外なら、
=== [64] [VAR[結果]]を、[VAR[復号器オブジェクト]]の[[処理][処理 (符号化)]]の結果に設定します。
[VAR[入力]]は[VAR[ストリーム]]、[VAR[出力]]を[VAR[出力]]、
[VAR[誤りモード]]を[VAR[誤りモード]]とします。
=== [65] [VAR[結果]]により、
[FIG(switch)[
: [[終了済み][終了済み (符号化)]] : 繰り返しをここで脱出します。
: [[誤り][誤り (符号化)]] : [CODE(DOMe)@en[TypeError]] を[[投げ]]、ここで停止します。
]FIG]
= [67] [DFN[[RUBYB[ストリームの直列化]@en[serialize stream]]]]、すなわち、
== [66] [VAR[ストリーム]]を、 [[end-of-stream]] が得られるまで[[読み][読む]]続けます。
[VAR[結果]]を、得られた[[符号位置]]を順に連結したものに設定します。
== [68] [VAR[復号器オブジェクト]]の[F[クラス]]の[F[BOMを持つ]]が[[真]]で、
[VAR[BOM無視フラグ]]が[[偽]]なら、
=== [69] [VAR[結果]]の先頭が [CODE(char)[U+FEFF]] なら、これを除去します。
== [70] [VAR[結果]]を返します。
]FIG]
[71] この操作は、[[文字列]]の境界以外で分割されているかもしれない複数の[[バイト列]]を連続する1つの[[文字列]]として処理することや、
[[BOM]] の扱いを[[著者]]が指示することを想定し、他での処理よりも複雑となっています。
* 符号化器と復号器
[49] [[Encoding Standard]] は、[[符号化器]]と[[復号器]]を、
[[文字符号化]]ごとに定義される[[クラス]]的なものと、
その[[実現値]]たる個別の[[オブジェクト]]的なものの両方の意味で使っています。
[52] [[符号化器クラス]]や[[復号器クラス]]には、
[[走らせる][走らせる (符号化)]]処理と[F[取扱器][取扱器 (符号化)]]が定義されています。
また[[復号器クラス]]の[F[BOMを持つ]]は、当該[[復号器]]の[[文字符号化]]が
[[UTF-8]]、[[UTF-16BE]]、[[UTF-16LE]] のいずれかなら[[真]]で、それ以外なら[[偽]]です。
[2] [[符号化器オブジェクト]]や[[復号器オブジェクト]]は、
いくつかの[[文字符号化]]依存の状態を持ちます。
また、[[処理][処理 (符号化)]]演算が定義されています。
[50] 更に、 [[Web IDLインターフェイス]]として [CODE(DOMi)@en[TextEncoder]]
と [CODE(DOMi)@en[TextDecoder]] があり、それぞれ (通常の [[Web IDL]]
の[[インターフェイス]]同様に) [[インターフェイスオブジェクト]] (≒ [[クラス]])
と[[オブジェクト]]が存在しています。
[51] [CODE(DOMi)@en[TextEncoder]] や [CODE(DOMi)@en[TextDecoder]] の[[オブジェクト]]は、
いくつかの状態を持ちます。それには[[符号化器オブジェクト]]や[[復号器オブジェクト]]も含まれます。
同時には1つの[[オブジェクト]]だけを持ちますが、時に新しい[[オブジェクト]]に差し替えられることがあります。
[21] [[符号化][文字符号化]]の[F[符号化器クラス]]または[F[復号器クラス]][VAR[器]]を、
[[ストリーム]][VAR[入力]]、[[ストリーム]][VAR[出力]]、
[[誤りモード]][VAR[モード]]について[DFN[[RUBYB[走らせる]@en[run]]]]には、
次のようにします [SRC[>>15]]。
[FIG(steps)[
= [22] [VAR[オブジェクト]]を、[VAR[器]]の新しい[[実現値]]オブジェクトに設定します。
= [23] 繰り返し、
== [24] [VAR[結果]]を、[[処理][処理 (符号化)]]の結果に設定します。
[FIG(list members middle)[
: [VAR[オブジェクト]] : [VAR[オブジェクト]]
: [VAR[字句]] : [VAR[入力]]を[[読んだ][読む (ストリーム)]]結果
: [VAR[入力]] : [VAR[入力]]
: [VAR[出力]] : [VAR[出力]]
: [VAR[モード]] : [VAR[モード]]
]FIG]
== [25] [VAR[結果]]が[[継続][継続 (符号化)]]以外なら、
=== [26] [VAR[結果]]を返し、ここで停止します。
]FIG]
;; [55] [[走らせる][走らせる (符号化)]]は、[[符号化][符号化 (動詞)]]、
[[復号][復号 (符号化)]]の他に、
[[UTF-8復号]]、[[BOMなしUTF-8復号]]、[[BOMなしUTF-8復号または失敗]]から呼び出されます。
[27] [[符号化器オブジェクト]]または[[復号器オブジェクト]][VAR[オブジェクト]]を、
[[字句][字句 (文字コード)]][VAR[字句]]、
[[ストリーム]][VAR[入力]]、[[ストリーム]][VAR[出力]]、
[[誤りモード]][VAR[モード]]について[DFN[[RUBYB[処理]@en[process]]]]するには、
次のようにします [SRC[>>15]]。
[FIG(steps)[
= [28] [VAR[結果]]を、[VAR[入力]]と[VAR[字句]]について[VAR[オブジェクト]]の[F[クラス]]の[F[取扱器][取扱器 (符号化)]]を実行した結果に設定します。
= [29] [VAR[結果]]により、
[FIG(switch)[
: [[継続][継続 (符号化)]]、[[終了済み][終了済み (符号化)]] : [VAR[結果]]を返し、ここで停止します。
: 1つ[[以上]]の[[字句]] : [VAR[結果]]を[VAR[出力]]に[[push][push (ストリーム)]]します。
: [[誤り][誤り (符号化)]] : [VAR[モード]]により、
[FIG(switch)[
: [CODE[replacement][replacement (符号化)]] : [CODE[U+FFFD]] を[VAR[出力]]に[[push][push (ストリーム)]]します。
: [CODE[html][html (符号化)]] :
[CODE[&#]]、[VAR[結果]]の[F[符号位置]]を[[十進数]]で[[ASCII数字]]で最短で表現したもの、
[CODE[;]] を連結したものを''[VAR[入力]]''に[[prepend][prepend (ストリーム)]]します。
: [CODE[fatal][fatal (符号化)]] : [[誤り][誤り (符号化)]]を返し、ここで停止します。
]FIG]
]FIG]
= [30] [[継続][継続 (符号化)]]を返します。
]FIG]
;; [54] [[処理][処理 (符号化)]]は、[[走らせる][走らせる (符号化)]]の他に、
[CODE(DOMi)@en[TextEncoder]] の [CODE(DOMm)@en[encode][TextEncoder]]
[[メソッド]]でも呼びだされます。しかし[[UTF-8符号化]]
(間接的に[[走らせる][走らせる (符号化)]]を呼び出します。) と実質的に等価です。
[19] [[符号化器]]や[[復号器]]の[DFN[[F[[RUBYB[[[取扱器][取扱器 (符号化)]]]@en[handler]]]]]]は、
[[ストリーム]]と[[字句]]を入力とします。
次のいずれかを返します。 [SRC[>>15]]
[FIG(list middle)[
- [DFN[[RUBYB[[[終了済み][終了済み (符号化)]]]@en[finished]]]]
- 1つ[[以上]]の[[字句][字句 (文字コード)]]
- [DFN[[RUBYB[[[誤り][誤り (符号化)]]]@en[error]]]]と省略可能な[[符号位置]]
- [DFN[[RUBYB[[[継続][継続 (符号化)]]]@en[continue]]]]
]FIG]
[48] 具体的な[[アルゴリズム]]は、[[文字符号化]]ごとに規定されています。
;; 各[[文字符号化]]の項を参照。
* 文脈
[18] [[符号化]]は、[DFN[[F[[RUBYB[[[符号化器]]]@en[encoder]]クラス]]]]と[DFN[[F[[RUBYB[[[復号器]]]@en[decoder]]クラス]]]]を持ちます
[SRC[>>15]]。
;; ただし[[置換]]、[[UTF-16BE]]、[[UTF-16LE]]は[F[[[符号化器]]クラス]]を持ちません [SRC[>>15]]。
* 誤りモード
[20] [DFN[[RUBYB[誤りモード]@en[error mode]]]]は、次のいずれかです [SRC[>>15]]。
[FIG(list)[
: [DFN[[CODE[replacement][replacement (符号化)]]]] ([[復号器]]、[[既定値]]) :
不正な入力を [CODE(char)[U+FFFD]] に置換することを指定するものです。
: [DFN[[CODE[fatal][fatal (符号化)]]]] ([[復号器]] / [[符号化器]]、[[既定値]]) :
不正な入力の時[[エラー]]を報告して停止するべきことを指定するものです。
: [DFN[[CODE[html][html (符号化)]]]] ([[符号化器]]) :
出力の[[文字符号化]]で表現できない時 [[HTML]] の[[十進文字参照]]に置換することを指定するものです。
]FIG]
[75] [CODE[fatal][fatal (符号化)]] は、 [[XML構文解析器]] [SRC[>>15]]、
[[BOMなしUTF-8復号または失敗]]、 [CODE(DOMi)@en[TextDecoder]] [CODE(DOMa)@en[fatal][fatal (符号化)]]
で使われます。
[78] [CODE[replacement]] はその他の[[復号]]が必要な場面で使われます。
例えば[[HTML構文解析器]]が該当します。
[74] [[符号化器]]では実際には [CODE[html][html (符号化)]] しか使われません。
かつては [CODE(DOMi)@en[TextEncoder]] で [[UTF-8]] 以外かつ [CODE(DOMa)@en[fatal][fatal (符号化)]]
が指定される可能性があったようですが、現在では [[UTF-8]] しか指定できません。
また [[UTF-8]] はすべての[[Unicodeスカラー値]]を[[誤り][誤り (符号化)]]なく[[符号化][符号化 (動詞)]]できます。
;; [[サロゲート]]は [[Web IDL]] [CODE(IDL)@en[USVString]] への変換の時点で置換されます。
* 歴史
[76] [CITE@en[Define 'continue' and 'break' statements]]
([[mikewest]]著, [TIME[2016-11-22 03:27:37 +09:00]])
<https://github.com/whatwg/infra/commit/8fbf990dcdb5f7ee80a85b569cba61a056fe1cc5>
[77] [CITE@en[Parse application/x-www-form-urlencoded using UTF-8 only]]
([[annevk]]著, [TIME[2017-01-17 19:11:02 +09:00]])
<https://github.com/whatwg/url/commit/3fe969679f78c92c353047661b0c4b6797f099f6>