1. 서문
UTF-8 인코딩은 유니코드(범용 문자 집합) 교환에 가장 적합한 인코딩입니다. 따라서, 새로운 프로토콜과 포맷뿐만 아니라, 새로운 맥락에서 사용되는 기존 포맷의 경우에도, 본 명세서는 UTF-8 인코딩을 요구(및 정의)합니다.
기타(레거시) 인코딩은 과거에 어느 정도 정의되어 있었습니다. 하지만, 사용자 에이전트마다 항상 동일하게 구현한 것은 아니었고, 동일한 레이블을 사용하지 않았으며, 인코딩의 미정의 영역이나 과거의 독자 영역 처리에서도 차이가 많았습니다. 본 명세서는 이러한 격차를 해결하여, 새로운 사용자 에이전트가 인코딩 구현을 리버스 엔지니어링할 필요가 없도록 하고, 기존 사용자 에이전트는 일치할 수 있도록 합니다.
특히, 본 명세서는 모든 인코딩, 바이트에서 스칼라 값으로(또는 그 반대) 변환하는 알고리즘, 그리고 표준 이름 및 식별 레이블을 정의합니다. 또한, 인코딩 알고리즘의 일부를 JavaScript에 노출하는 API도 정의합니다.
사용자 에이전트는 IANA 문자 집합 레지스트리에 명시된 레이블과도 많이 달라졌습니다. 레거시 인코딩이 더 이상 확산되지 않도록, 본 명세서는 위의 세부사항을 빠짐없이 기술하며, 따라서 별도의 레지스트리가 필요하지 않습니다. 특히, 본 명세서는 인코딩의 어떤 측면도 확장할 수 있는 메커니즘을 제공하지 않습니다.
2. 보안 배경
생산자와 소비자가 사용 중인 인코딩이나 특정 인코딩의 구현 방식에 합의하지 않을 때 인코딩 보안 문제가 발생할 수 있습니다. 예를 들어, 2011년에 보고된 공격에서는 Shift_JIS 선행 바이트 0x82가 JSON 리소스의 0x22 후행 바이트를 “마스킹”하는 데 사용되었습니다. 공격자가 일부 필드를 제어할 수 있었던 상황에서, 생산자는 이 조합이 불법 바이트 조합임에도 문제를 인식하지 못했습니다. 소비자는 이를 하나의 U+FFFD(�)로 디코딩했고, 이로 인해 전체 해석이 변경되었습니다. (U+0022(")는 중요한 구분자입니다.) 이제 여러 바이트로 스칼라 값을 표현하는 인코딩의 디코더는 불법 바이트 조합이 발생할 때, U+0000~U+007F 범위의 스칼라 값이 “마스킹”되지 않도록 해야 합니다. 위와 같은 시퀀스의 출력은 U+FFFD U+0022가 됩니다. (예외적으로, gb18030 디코더는 end-of-queue에서 최대 한 바이트까지 마스킹할 수 있습니다.)
선행 바이트 없이 ASCII 바이트를 ASCII 코드 포인트가 아닌 것으로 매핑하는 인코딩(“ASCII-비호환” 인코딩)은 이 문제가 더 심각합니다. ISO-2022-JP 및 UTF-16BE/LE는 배포된 콘텐츠로 인해 부득이하게 지원되지만, 그 외 인코딩은 지원하지 않습니다. (다른 인코딩의 더 많은 레이블을 대체(replacement) 인코딩으로 매핑할 수 있는지에 대한 조사가 진행 중입니다. 그렇지 않을 경우 미지정 인코딩 폴백이 사용됩니다.) 예를 들면, 악의적으로 제작된 콘텐츠를 리소스에 주입한 뒤 인코딩을 덮어쓰도록 유도하여 스크립트 실행이 일어날 수 있습니다.
HTML 및 HTML의 폼 기능에서 사용되는 URL의 인코더는 인코딩이 모든 스칼라 값을 표현할 수 없을 때 약간의 정보 손실을 초래할 수 있습니다. 예를 들어, windows-1252 인코딩을 사용하는 리소스에서는 서버가 “💩”과 “💩”을 구분할 수 없습니다.
여기서 설명한 문제는 UTF-8만을 사용할 경우 사라집니다. 이것이 모든 곳에서 UTF-8을 필수 인코딩으로 지정한 많은 이유 중 하나입니다.
자세한 내용은 브라우저 UI 장을 참고하세요.
3. 용어
이 명세서는 Infra Standard에 의존합니다. [INFRA]
16진수 숫자는 "0x"로 시작합니다.
수식에서는 모든 숫자가 정수이며, 덧셈은 "+", 뺄셈은 "−", 곱셈은 "×", 정수 나눗셈은 "/"(몫 반환), 나머지는 "%"(정수 나눗셈의 나머지 반환), 논리적 왼쪽 시프트는 "<<", 논리적 오른쪽 시프트는 ">>", 비트 AND는 "&", 비트 OR는 "|"로 나타냅니다.
논리적 오른쪽 시프트 연산의 피연산자는 최소 21비트 이상의 정밀도를 가져야 합니다.
I/O 큐는 특정 타입(바이트 또는 스칼라 값 등)의 항목으로 이루어진 리스트의 일종입니다. end-of-queue는 모든 타입의 I/O 큐에 존재할 수 있는 특수한 항목으로, 큐에 더 이상 항목이 없음을 나타냅니다.
I/O 큐를 사용하는 방법에는 두 가지가 있습니다: 즉시 모드에서는 메모리에 저장된 I/O 데이터를 나타내고, 스트리밍 모드에서는 네트워크에서 들어오는 데이터를 나타냅니다. 즉시 큐는 마지막 항목으로 end-of-queue를 가지지만, 스트리밍 큐는 그렇지 않을 수 있으므로 read 연산이 블록될 수 있습니다.
스트리밍 I/O 큐는 빈 상태에서 생성되고, 네트워크에서 데이터가 들어올 때마다 새로운 항목이 push됩니다. 네트워크 스트림이 닫히면, end-of-queue 항목이 큐에 push되어야 합니다.
스트리밍 I/O 큐에서 읽는 작업은 블록될 수 있으므로, 스트리밍 I/O 큐는 이벤트 루프에서 사용해서는 안 됩니다. 대신 병렬로 사용해야 합니다.
읽기란 항목을 I/O 큐 ioQueue에서 읽는 절차입니다:
-
ioQueue[0]이 end-of-queue라면, end-of-queue를 반환합니다.
-
제거 ioQueue[0]을(를) 제거하고 반환합니다.
읽기란 number개의 항목을 ioQueue에서 읽는 절차입니다:
-
readItems를 « »로 둡니다.
-
아래 단계를 number번 반복합니다:
-
제거 end-of-queue를 readItems에서 제거합니다.
-
readItems를 반환합니다.
peek이란 number개의 항목을 I/O 큐 ioQueue에서 미리 보는 절차입니다:
-
다음 두 조건 중 하나가 만족될 때까지 대기합니다: ioQueue의 크기가 number 이상이 되거나, ioQueue가 end-of-queue를 포함하는 경우.
-
prefix를 « »로 둡니다.
-
-
만약 ioQueue[n]이 end-of-queue라면, break합니다.
-
그 외에는 append로 ioQueue[n]을 prefix에 추가합니다.
-
-
prefix를 반환합니다.
push란 항목 item을 I/O 큐 ioQueue에 추가하는 절차입니다:
-
ioQueue의 마지막 항목이 end-of-queue라면:
-
item이 end-of-queue라면 아무것도 하지 않습니다.
-
-
그 외에는 append로 item을 ioQueue에 추가합니다.
restore란 항목을 end-of-queue가 아닌 경우 I/O 큐에 prepend하는 작업입니다. restore란 리스트의 항목들 중 end-of-queue가 아닌 항목을 주어진 순서대로 큐 맨 앞에 삽입하는 작업입니다.
바이트 « 0xF0, 0x9F »를 I/O 큐 « 0x92 0xA9, end-of-queue »에 삽입하면, 결과는 I/O 큐 « 0xF0, 0x9F, 0x92 0xA9, end-of-queue »가 됩니다. 다음에 읽을 항목은 0xF0입니다.
변환이란 리스트, 문자열 또는 바이트 시퀀스 input을 I/O 큐로 변환하는 절차입니다:
-
Assert: input이 리스트가 아니거나, 또는 end-of-queue를 포함하지 않아야 합니다.
-
I/O 큐를 반환하는데, input의 항목을 순서대로 포함하고, 마지막에 end-of-queue를 추가합니다.
Infra 표준에서는 타입 변환 관련 인프라를 정의할 예정입니다. whatwg/infra issue #319를 참고하세요. [INFRA]
I/O 큐는 리스트로 정의되며, 큐로 정의되지 않습니다. 이는 restore 연산 때문입니다. 하지만 이 restore 연산은 본 명세서의 알고리즘 내부 구현 세부사항일 뿐이며, 다른 표준에서 사용해서는 안 됩니다. 구현체는 구현 고려사항에 따라 이러한 알고리즘을 다른 방법으로 구현할 수도 있습니다.
대리쌍으로부터 스칼라 값 얻기는 선행 대리쌍 leading과 후행 대리쌍 trailing이 주어졌을 때, 0x10000 + ((leading − 0xD800) << 10) + (trailing − 0xDC00)을 반환합니다.
Uint8Array
객체 생성이란 I/O 큐
ioQueue와 realm realm이 주어졌을 때:
-
변환을 통해 ioQueue를 바이트 시퀀스로 변환한 결과를 bytes로 둡니다.
-
생성을 통해
Uint8Array
객체를 bytes와 realm으로부터 생성하여 반환합니다.
4. 인코딩
인코딩은 스칼라 값 시퀀스를 바이트 시퀀스로(그리고 그 반대로) 매핑하는 규칙을 정의합니다. 각 인코딩은 이름과 하나 이상의 레이블을 가집니다.
본 명세서는 유니코드 표준에서 정의된 인코딩 방식과 동일한 이름을 가진 세 가지 인코딩을 정의합니다: UTF-8, UTF-16LE, UTF-16BE. 인코딩은 인코딩 방식과 다르게 바이트 순서 표시(BOM) 처리가 인코딩 자체에 포함되지 않고, 본 명세서의 래퍼 알고리즘 일부로 처리됩니다. 반면 유니코드 표준의 인코딩 방식 정의에는 BOM 처리가 포함되어 있습니다. UTF-8과 UTF-8 디코드 알고리즘을 함께 사용할 경우, 동일 이름의 인코딩 방식과 일치합니다. 본 명세서는 UTF-16LE 및 UTF-16BE에 대해 인코딩 방식과 일치하는 래퍼 알고리즘을 제공하지 않습니다. [UNICODE]
4.1. 인코더와 디코더
각 인코딩에는 연관된 디코더가 있고, 대부분에는 연관된 인코더도 있습니다. 디코더 및 인코더의 인스턴스는 핸들러 알고리즘을 가지며 상태를 가질 수도 있습니다. 핸들러 알고리즘은 입력 I/O 큐와 항목을 받아, finished 또는 하나 이상의 항목, error(선택적으로 코드 포인트 포함), 또는 continue를 반환합니다.
대체(replacement)와 UTF-16BE/LE 인코딩에는 인코더가 없습니다.
오류 모드(error mode)는 아래에서
사용되며,
디코더의 경우 "replacement
" 또는
"fatal
",
인코더의 경우 "fatal
" 또는
"html
"입니다.
XML 프로세서는 오류
모드를 "fatal
"로 설정합니다.
[XML]
"html
"은 HTML 폼에서 종료되지 않는 레거시 인코더가 필요하기 때문에 오류 모드로 존재합니다. "html
" 오류 모드는 정상 입력과 구분할 수 없는 시퀀스를 출력하므로, 조용한 데이터 손실을 초래할 수
있습니다. 개발자들은 이러한 상황을 방지하기 위해 UTF-8 인코딩 사용을 강력히 권장합니다.
[HTML]
큐 처리란 인코딩의 디코더 또는 인코더 인스턴스 encoderDecoder, I/O 큐 input, I/O 큐 output, 오류 모드 mode가 주어졌을 때 다음과 같이 동작합니다:
항목 처리란 항목 item, 인코딩의 인코더 또는 디코더 인스턴스 encoderDecoder, I/O 큐 input, I/O 큐 output, 오류 모드 mode가 주어졌을 때 다음과 같이 동작합니다:
4.2. 이름과 레이블
아래 표에는 모든 인코딩과 사용자 에이전트가 반드시 지원해야 하는 레이블이 나와 있습니다. 사용자 에이전트는 이외의 인코딩이나 레이블을 지원해서는 안 됩니다.
각 인코딩에 대해, ASCII 소문자화한 이름이 해당 인코딩의 레이블 중 하나가 됩니다.
작성자는 반드시 UTF-8 인코딩을 사용해야 하며, 이를 식별할 때는 (ASCII
대소문자 구분하지 않음) "utf-8
" 레이블을 사용해야 합니다.
새 프로토콜과 포맷, 그리고 새로운 맥락에서 사용되는 기존 포맷은 반드시 UTF-8
인코딩만 사용해야 합니다. 이러한 프로토콜과 포맷이 인코딩의 이름이나 레이블을 노출해야 한다면, "utf-8
"로 노출해야 합니다.
문자열 label에서 인코딩 얻기 절차는 다음과 같습니다:
-
label에서 앞뒤의 ASCII 공백을 제거합니다.
-
label이 아래 표에 나열된 레이블 중 하나와 ASCII 대소문자 구분 없이 일치하면, 해당 인코딩을 반환합니다. 그렇지 않으면 실패를 반환합니다.
이 알고리즘은 인코딩에 대한 레이블 매핑을 Unicode 기술 표준 #22의 1.4절보다 더 기본적이고 제한적으로 정의합니다. 이는 배포된 콘텐츠와의 호환성 유지를 위해 필요합니다.
이름 | 레이블 |
---|---|
인코딩 | |
UTF-8 | "unicode-1-1-utf-8 "
|
"unicode11utf8 "
| |
"unicode20utf8 "
| |
"utf-8 "
| |
"utf8 "
| |
"x-unicode20utf8 "
| |
레거시 단일 바이트 인코딩 | |
IBM866 | "866 "
|
"cp866 "
| |
"csibm866 "
| |
"ibm866 "
| |
ISO-8859-2 | "csisolatin2 "
|
"iso-8859-2 "
| |
"iso-ir-101 "
| |
"iso8859-2 "
| |
"iso88592 "
| |
"iso_8859-2 "
| |
"iso_8859-2:1987 "
| |
"l2 "
| |
"latin2 "
| |
ISO-8859-3 | "csisolatin3 "
|
"iso-8859-3 "
| |
"iso-ir-109 "
| |
"iso8859-3 "
| |
"iso88593 "
| |
"iso_8859-3 "
| |
"iso_8859-3:1988 "
| |
"l3 "
| |
"latin3 "
| |
ISO-8859-4 | "csisolatin4 "
|
"iso-8859-4 "
| |
"iso-ir-110 "
| |
"iso8859-4 "
| |
"iso88594 "
| |
"iso_8859-4 "
| |
"iso_8859-4:1988 "
| |
"l4 "
| |
"latin4 "
| |
ISO-8859-5 | "csisolatincyrillic "
|
"cyrillic "
| |
"iso-8859-5 "
| |
"iso-ir-144 "
| |
"iso8859-5 "
| |
"iso88595 "
| |
"iso_8859-5 "
| |
"iso_8859-5:1988 "
| |
ISO-8859-6 | "arabic "
|
"asmo-708 "
| |
"csiso88596e "
| |
"csiso88596i "
| |
"csisolatinarabic "
| |
"ecma-114 "
| |
"iso-8859-6 "
| |
"iso-8859-6-e "
| |
"iso-8859-6-i "
| |
"iso-ir-127 "
| |
"iso8859-6 "
| |
"iso88596 "
| |
"iso_8859-6 "
| |
"iso_8859-6:1987 "
| |
ISO-8859-7 | "csisolatingreek "
|
"ecma-118 "
| |
"elot_928 "
| |
"greek "
| |
"greek8 "
| |
"iso-8859-7 "
| |
"iso-ir-126 "
| |
"iso8859-7 "
| |
"iso88597 "
| |
"iso_8859-7 "
| |
"iso_8859-7:1987 "
| |
"sun_eu_greek "
| |
ISO-8859-8 | "csiso88598e "
|
"csisolatinhebrew "
| |
"hebrew "
| |
"iso-8859-8 "
| |
"iso-8859-8-e "
| |
"iso-ir-138 "
| |
"iso8859-8 "
| |
"iso88598 "
| |
"iso_8859-8 "
| |
"iso_8859-8:1988 "
| |
"visual "
| |
ISO-8859-8-I | "csiso88598i "
|
"iso-8859-8-i "
| |
"logical "
| |
ISO-8859-10 | "csisolatin6 "
|
"iso-8859-10 "
| |
"iso-ir-157 "
| |
"iso8859-10 "
| |
"iso885910 "
| |
"l6 "
| |
"latin6 "
| |
ISO-8859-13 | "iso-8859-13 "
|
"iso8859-13 "
| |
"iso885913 "
| |
ISO-8859-14 | "iso-8859-14 "
|
"iso8859-14 "
| |
"iso885914 "
| |
ISO-8859-15 | "csisolatin9 "
|
"iso-8859-15 "
| |
"iso8859-15 "
| |
"iso885915 "
| |
"iso_8859-15 "
| |
"l9 "
| |
ISO-8859-16 | "iso-8859-16 "
|
KOI8-R | "cskoi8r "
|
"koi "
| |
"koi8 "
| |
"koi8-r "
| |
"koi8_r "
| |
KOI8-U | "koi8-ru "
|
"koi8-u "
| |
macintosh | "csmacintosh "
|
"mac "
| |
"macintosh "
| |
"x-mac-roman "
| |
windows-874 | "dos-874 "
|
"iso-8859-11 "
| |
"iso8859-11 "
| |
"iso885911 "
| |
"tis-620 "
| |
"windows-874 "
| |
windows-1250 | "cp1250 "
|
"windows-1250 "
| |
"x-cp1250 "
| |
windows-1251 | "cp1251 "
|
"windows-1251 "
| |
"x-cp1251 "
| |
windows-1252
아래 참고에서 역사적 "Latin1" 및 "ASCII" 개념과의 관계를 확인하세요. | "ansi_x3.4-1968 "
|
"ascii "
| |
"cp1252 "
| |
"cp819 "
| |
"csisolatin1 "
| |
"ibm819 "
| |
"iso-8859-1 "
| |
"iso-ir-100 "
| |
"iso8859-1 "
| |
"iso88591 "
| |
"iso_8859-1 "
| |
"iso_8859-1:1987 "
| |
"l1 "
| |
"latin1 "
| |
"us-ascii "
| |
"windows-1252 "
| |
"x-cp1252 "
| |
windows-1253 | "cp1253 "
|
"windows-1253 "
| |
"x-cp1253 "
| |
windows-1254 | "cp1254 "
|
"csisolatin5 "
| |
"iso-8859-9 "
| |
"iso-ir-148 "
| |
"iso8859-9 "
| |
"iso88599 "
| |
"iso_8859-9 "
| |
"iso_8859-9:1989 "
| |
"l5 "
| |
"latin5 "
| |
"windows-1254 "
| |
"x-cp1254 "
| |
windows-1255 | "cp1255 "
|
"windows-1255 "
| |
"x-cp1255 "
| |
windows-1256 | "cp1256 "
|
"windows-1256 "
| |
"x-cp1256 "
| |
windows-1257 | "cp1257 "
|
"windows-1257 "
| |
"x-cp1257 "
| |
windows-1258 | "cp1258 "
|
"windows-1258 "
| |
"x-cp1258 "
| |
x-mac-cyrillic | "x-mac-cyrillic "
|
"x-mac-ukrainian "
| |
레거시 다중 바이트 중국어(간체) 인코딩 | |
GBK | "chinese "
|
"csgb2312 "
| |
"csiso58gb231280 "
| |
"gb2312 "
| |
"gb_2312 "
| |
"gb_2312-80 "
| |
"gbk "
| |
"iso-ir-58 "
| |
"x-gbk "
| |
gb18030 | "gb18030 "
|
레거시 다중 바이트 중국어(번체) 인코딩 | |
Big5 | "big5 "
|
"big5-hkscs "
| |
"cn-big5 "
| |
"csbig5 "
| |
"x-x-big5 "
| |
레거시 다중 바이트 일본어 인코딩 | |
EUC-JP | "cseucpkdfmtjapanese "
|
"euc-jp "
| |
"x-euc-jp "
| |
ISO-2022-JP | "csiso2022jp "
|
"iso-2022-jp "
| |
Shift_JIS | "csshiftjis "
|
"ms932 "
| |
"ms_kanji "
| |
"shift-jis "
| |
"shift_jis "
| |
"sjis "
| |
"windows-31j "
| |
"x-sjis "
| |
레거시 다중 바이트 한국어 인코딩 | |
EUC-KR | "cseuckr "
|
"csksc56011987 "
| |
"euc-kr "
| |
"iso-ir-149 "
| |
"korean "
| |
"ks_c_5601-1987 "
| |
"ks_c_5601-1989 "
| |
"ksc5601 "
| |
"ksc_5601 "
| |
"windows-949 "
| |
레거시 기타 인코딩 | |
replacement | "csiso2022kr "
|
"hz-gb-2312 "
| |
"iso-2022-cn "
| |
"iso-2022-cn-ext "
| |
"iso-2022-kr "
| |
"replacement "
| |
UTF-16BE | "unicodefffe "
|
"utf-16be "
| |
UTF-16LE | "csunicode "
|
"iso-10646-ucs-2 "
| |
"ucs-2 "
| |
"unicode "
| |
"unicodefeff "
| |
"utf-16 "
| |
"utf-16le "
| |
x-user-defined | "x-user-defined "
|
모든 인코딩 및 레이블은 비권고 자료로 encodings.json 리소스에서도 제공됩니다.
지원되는 인코딩의 집합은, 이 표준 개발이 시작될 당시 주요 브라우저 엔진이 지원하던 집합의 교집합을 기반으로 하며, 합법적으로 거의 사용되지 않았으나 공격에 사용될 수 있는 인코딩은 제외되었습니다. 일부 인코딩의 포함은 기존 웹 콘텐츠에서의 사용 빈도에 대한 일화적 증거를 고려할 때 의문이 있지만, 브라우저에서 널리 지원되었으나 웹 콘텐츠에서 실제로 널리 사용되는지는 불분명합니다. 그러나 브라우저에서 널리 지원되었거나 ISO 8859 시리즈에 속하는 단일 바이트 인코딩을 적극적으로 제거하려는 시도는 이루어지지 않았습니다. 특히, IBM866, macintosh, x-mac-cyrillic, ISO-8859-3, ISO-8859-10, ISO-8859-14, 그리고 ISO-8859-16의 포함 필요성은 기존 콘텐츠 지원이라는 목적에서 의심스럽지만, 이들을 제거할 계획은 없습니다.
windows-1252 인코딩은
"latin1
", "iso-8859-1
", "ascii
" 등 다양한 레이블을 가집니다. 이들은 역사적으로 개발자들에게 혼란을 주었습니다. 웹, 그리고 이 표준을 구현하여 웹
호환성을 추구하는 모든 소프트웨어에서는, 이들은 동의어입니다: "latin1
" 과 "ascii
"는 windows-1252의 레이블일 뿐이며, 이 표준을 따르는 소프트웨어라면 예를 들어
"Latin1"이나 "ASCII"로 0x80 바이트를 디코딩할 때 U+20AC(€)로 변환합니다.
이 표준을 따르지 않는 소프트웨어는 항상 동일한 결과를 내지 않습니다. 그 원인은 Latin1을 정의한 최초 문서(ISO/IEC 8859-1)에서 0x00~0x1F, 0x7F~0x9F 바이트에 대한 매핑을 제공하지 않았고, ASCII를 정의한 최초 문서(ISO/IEC 646 등) 역시 0x80~0xFF 바이트에 대한 매핑을 제공하지 않았기 때문입니다. 이는 소프트웨어마다 Latin1 또는 ASCII 인코딩을 사용할 때 해당 바이트에 대해 서로 다른 코드 포인트 매핑을 선택하게 만듭니다. 웹 브라우저와 브라우저 호환 소프트웨어는 이 바이트들을 windows-1252에 따라 매핑하는데, 이는 두 가지 모두의 상위 집합이며, 이 선택은 본 표준에 명문화되었습니다. 다른 소프트웨어는 에러를 발생시키거나, 동형 디코딩이나 기타 매핑을 사용하기도 합니다. [ISO8859-1] [ISO646]
따라서 구현자와 개발자는 "Latin1" 또는 "ASCII" 관련 API를 제공하는 라이브러리를 사용할 때 주의해야 합니다. 이러한 라이브러리들이 원본 명세에서 정의하지 않은 바이트에 대해 다른 동작을 선택했다면, 이 표준과 일치하지 않는 결과를 반환할 수 있습니다.
4.3. 출력 인코딩
출력 인코딩 얻기란 인코딩 encoding이 주어졌을 때 다음 절차를 따릅니다:
-
encoding이 대체(replacement) 또는 UTF-16BE/LE라면, UTF-8을 반환합니다.
-
encoding을 반환합니다.
출력 인코딩 얻기 알고리즘은 URL 파싱과 HTML 폼 제출에 유용합니다. 이 둘 모두 정확히 이 동작이 필요합니다.
5. 인덱스
대부분의 레거시 인코딩은 인덱스를 사용합니다. 인덱스란, 각 항목이 포인터와 해당 코드 포인트로 이루어진 순서 있는 목록입니다. 하나의 인덱스 내에서 포인터는 고유하며, 코드 포인트는 중복될 수 있습니다.
효율적인 구현에서는 인덱스가 인코딩마다 두 개씩 존재할 수 있습니다. 하나는 디코더에 최적화되고, 다른 하나는 인코더에 최적화됩니다.
인덱스에서 포인터와 해당 코드 포인트를 찾으려면, lines를 리소스의 내용을 U+000A LF로 분할한 결과로 둡니다. 그리고 lines의 각 항목 중 빈 문자열이거나 U+0023(#)로 시작하는 항목은 제거합니다. 그런 다음 lines의 각 항목을 U+0009 TAB으로 분할해서 얻은 첫 번째 서브항목이 포인터(10진수), 두 번째가 해당 코드 포인트(16진수)입니다. 그 외의 서브항목은 무시합니다.
변경 사항을 표시하기 위해 인덱스에는 Identifier와 Date가 포함됩니다. Identifier가 변경되었다면, 인덱스도 변경된 것입니다.
index에서 pointer의 인덱스 코드 포인트는 index에서 pointer에 해당하는 코드 포인트이며, pointer가 index에 없으면 null입니다.
index에서 codePoint의 인덱스 포인터는 index에서 codePoint에 처음으로 매핑되는 포인터이며, codePoint가 없으면 null입니다.
인덱스마다(단, index gb18030 ranges와 index ISO-2022-JP katakana는 제외) 비권고 시각화 자료가 있습니다. index jis0208에는 Shift_JIS 시각화도 있습니다. 또한, index gb18030 ranges와 index ISO-2022-JP katakana를 제외한 각 인덱스에 대해 BMP(기본 다국어 평면) 커버리지 시각화도 존재합니다.
시각화 범례는 다음과 같습니다:
- 매핑되지 않음
- UTF-8에서 두 바이트
- UTF-8에서 두 바이트, 코드 포인트가 이전 포인터의 코드 포인트 바로 다음임
- UTF-8에서 세 바이트(비-PUA)
- UTF-8에서 세 바이트(비-PUA), 코드 포인트가 이전 포인터의 코드 포인트 바로 다음임
- 사적 사용 영역
- 사적 사용 영역, 코드 포인트가 이전 포인터의 코드 포인트 바로 다음임
- UTF-8에서 네 바이트
- UTF-8에서 네 바이트, 코드 포인트가 이전 포인터의 코드 포인트 바로 다음임
- 중복 코드 포인트(이전 인덱스에 이미 매핑됨)
- CJK 호환 한자
- CJK 통합 한자 확장 A
다음은 본 명세서에서 정의한 인덱스 목록입니다. index single-byte는 별도의 표를 가집니다:
인덱스 | 비고 | |||
---|---|---|---|---|
index Big5 | index-big5.txt | index Big5 시각화 | index Big5 BMP 커버리지 | 이는 Big5 표준과 홍콩 보조 문자 집합, 기타 일반 확장과 결합되어 일치합니다. |
index EUC-KR | index-euc-kr.txt | index EUC-KR 시각화 | index EUC-KR BMP 커버리지 | 이는 KS X 1001 표준과 Unified Hangul Code(Windows Codepage 949로 더 잘 알려짐)에 일치합니다. 유니코드의 한글 음절 블록 전체를 커버합니다. 시각화에서 좌상단이 포인터 9026인 한글 블록은 유니코드 순서로 되어 있습니다. 별도로 보면, 이 인덱스의 나머지 한글 음절도 유니코드 순서로 되어 있습니다. |
index gb18030 | index-gb18030.txt | index gb18030 시각화 | index gb18030 BMP 커버리지 | 이는 2바이트로 인코딩된 코드 포인트에 대해 GB18030-2022 표준에 일치합니다(단, 0xA3 0xA0은 배포된 콘텐츠와의 호환성을 위해 U+3000 IDEOGRAPHIC SPACE로 매핑됨). 이 인덱스는 유니코드의 CJK 통합 한자 블록 전체를 커버합니다. 시각화에서 (첫 번째) U+3000 위나 왼쪽에 있는 해당 블록의 항목들은 유니코드 순서입니다. |
index gb18030 ranges | index-gb18030-ranges.txt | 이 인덱스는 다른 모든 인덱스와 동작이 다릅니다. 모든 코드 포인트를 나열하면 100만 개가 넘지만, 207개 구간과 단순한 범위 체크로 표현할 수 있습니다. 따라서 4바이트로 인코딩된 코드 포인트에 대해 GB18030-2000 표준과는 표면적으로만 일치합니다. GB18030-2005 개정의 변경 사항은 아래의 index gb18030 ranges code point 및 index gb18030 ranges pointer 알고리즘에서 처리됩니다. GB18030-2022 개정에 대한 변경 사항은 사적 사용 영역 코드 포인트로 매핑되는 바이트 시퀀스 수를 더 늘리지 않기 위해 다르게 처리됩니다. 관련 사적 사용 영역 코드 포인트는 gb18030 인코더에서 별도의 테이블을 통해 직접 매핑되어 이전 매핑과의 호환성을 보장합니다. | ||
index jis0208 | index-jis0208.txt | index jis0208 시각화, Shift_JIS 시각화 | index jis0208 BMP 커버리지 | 이는 IBM과 NEC의 과거 독자 확장을 포함한 JIS X 0208 표준입니다. |
index jis0212 | index-jis0212.txt | index jis0212 시각화 | index jis0212 BMP 커버리지 | 이는 JIS X 0212 표준입니다. EUC-JP 디코더에서만 사용됩니다(다른 곳에서는 널리 지원되지 않음). |
index ISO-2022-JP katakana | index-iso-2022-jp-katakana.txt | 유니코드 정규화 형식 KC에 따라 반각 가타카나를 전각 가타카나로 매핑합니다. 단, U+FF9E(゙)와 U+FF9F(゚)는 U+3099(◌゙), U+309A(◌゚)가 아니라 U+309B(゛), U+309C(゜)로 매핑됩니다. ISO-2022-JP 인코더에서만 사용됩니다. [UNICODE] |
index gb18030 ranges code point는 pointer에 대해 다음 절차로 값을 반환합니다:
-
pointer가 39419보다 크고 189000보다 작거나, pointer가 1237575보다 크면 null을 반환합니다.
-
pointer가 7457이면 코드 포인트 U+E7C7을 반환합니다.
-
offset을 index gb18030 ranges에서 pointer 이하인 마지막 포인터로, codePointOffset을 해당 코드 포인트로 둡니다.
-
codePointOffset + pointer − offset 값의 코드 포인트를 반환합니다.
index gb18030 ranges pointer는 codePoint에 대해 다음 절차로 값을 반환합니다:
-
codePoint가 U+E7C7이면 포인터 7457을 반환합니다.
-
offset을 index gb18030 ranges에서 codePoint 이하인 마지막 코드 포인트로, pointerOffset을 해당 포인터로 둡니다.
-
pointerOffset + codePoint − offset 값의 포인터를 반환합니다.
index Shift_JIS pointer는 codePoint에 대해 다음 절차로 값을 반환합니다:
-
index를 index jis0208에서 포인터가 8272~8835(포함) 구간의 항목을 제외한 것으로 둡니다.
index jis0208에는 중복 코드 포인트가 있으므로 해당 항목을 제외하면 이후 코드 포인트가 사용됩니다.
-
index에서 codePoint의 인덱스 포인터를 반환합니다.
index Big5 pointer는 codePoint에 대해 다음 절차로 값을 반환합니다:
-
index를 index Big5에서 포인터가 (0xA1 - 0x81) × 157 미만인 항목을 제외한 것으로 둡니다.
홍콩 보조 문자 집합 확장 반환을 피하기 위함입니다.
-
codePoint가 U+2550(═), U+255E(╞), U+2561(╡), U+256A(╪), U+5341(十), U+5345(卅) 중 하나라면, index에서 codePoint에 해당하는 마지막 포인터를 반환합니다.
다른 중복 코드 포인트도 있으나, 이 경우는 첫 번째 포인터를 사용합니다.
-
index에서 codePoint의 인덱스 포인터를 반환합니다.
모든 인덱스는 비권고 indexes.json 리소스에서도 제공됩니다. (index gb18030 ranges는 범위 표현을 위해 형식이 약간 다릅니다.)
6. 표준을 위한 훅
아래에 정의된 알고리즘(UTF-8 디코드, BOM 없는 UTF-8 디코드, BOM 없는 UTF-8 디코드(실패 가능), UTF-8 인코드)는 다른 표준에서 사용하기 위해 만들어졌습니다.
디코딩에는 새로운 포맷에서 UTF-8 디코드를 사용해야 합니다. 포맷이나 프로토콜 내 식별자 또는 바이트 시퀀스에는 BOM 없는 UTF-8 디코드 또는 BOM 없는 UTF-8 디코드(실패 가능)를 사용하세요.
인코딩에는 UTF-8 인코드를 사용해야 합니다.
표준에서는 UTF-8 인코드(그리고 레거시 인코드)에 전달하는 입력 I/O 큐가 사실상 스칼라 값의 I/O 큐임을 보장해야 합니다. 즉, 대리쌍을 포함하지 않아야 합니다.
이러한 훅(디코드 및 인코드 포함)은 입력 I/O 큐가 완전히 소모될 때까지 블로킹됩니다. 스트림에 토큰이 push될 때마다 바로 출력을 사용하려면, 호출자는 빈 출력 I/O 큐로 훅을 실행하고 이를 병렬로 읽어야 합니다. BOM 없는 UTF-8 디코드(실패 가능) 사용 시에는 디코딩 중 오류가 발생하면 출력 I/O 큐에 end-of-queue 항목이 push되지 않음을 주의해야 합니다.
UTF-8 디코드란 바이트 I/O 큐 ioQueue와 선택적 스칼라 값 I/O 큐 output(기본값 « »)에 대해 다음을 수행합니다:
BOM 없는 UTF-8 디코드란 바이트 I/O 큐 ioQueue와 선택적 스칼라 값 I/O 큐 output(기본값 « »)에 대해 다음을 수행합니다:
BOM 없는 UTF-8 디코드(실패 가능)란 바이트 I/O 큐 ioQueue와 선택적 스칼라 값 I/O 큐 output(기본값 « »)에 대해 다음을 수행합니다:
UTF-8 인코드란 스칼라 값 I/O 큐 ioQueue와 선택적 바이트 I/O 큐 output(기본값 « »)에 대해, 인코딩 ioQueue를 인코딩 UTF-8과 output으로 실행한 결과를 반환합니다.
6.1. 레거시 표준 훅
표준에서는 디코드, BOM 감지, 인코드 사용을 호환성 외에는 강력히 권장하지 않습니다. 이러한 레거시 훅이 필요한 표준은 보통 인코딩 얻기(레이블을 인코딩으로 변환)와 출력 인코딩 얻기(인코딩을 인코드에 적합한 인코딩으로 변환)에 의존하게 됩니다.
URL 퍼센트 인코딩처럼 극히 드문 경우에는 커스텀 인코더 오류 처리가 필요합니다. 이럴 땐 인코더 얻기 및 인코딩 또는 실패 알고리즘을 사용해야 하며, 다른 알고리즘은 직접 사용하지 않아야 합니다.
디코드란 바이트 I/O 큐 ioQueue, 폴백 인코딩 encoding, 선택적 스칼라 값 I/O 큐 output(기본값 « »)에 대해 다음을 수행합니다:
-
BOMEncoding을 BOM 감지로 ioQueue에 대해 얻습니다.
-
BOMEncoding이 null이 아니라면:
-
encoding을 BOMEncoding으로 설정합니다.
-
BOMEncoding이 UTF-8이면 read로 ioQueue에서 3바이트, 그 외에는 read로 2바이트를 읽습니다. (해당 바이트는 아무 처리도 하지 않음)
배포된 콘텐츠와의 호환성을 위해 바이트 순서 표시는 그 어떤 것보다 우선합니다. HTTP가 사용되는 맥락에서는 이는 `
Content-Type
` 헤더 의미와 상충합니다. -
-
큐 처리를 encoding의 디코더 인스턴스, ioQueue, output, "
replacement
"로 실행합니다. -
output을 반환합니다.
BOM 감지란 바이트 I/O 큐 ioQueue에 대해 다음을 수행합니다:
-
BOM을 peek으로 ioQueue에서 3바이트를 가져와 바이트 시퀀스로 변환한 값으로 둡니다.
-
아래 표의 각 행에 대해 위에서 아래로 순서대로, BOM이 첫 번째 열의 바이트로 시작하면, 해당 행의 두 번째 열에 있는 인코딩을 반환합니다. 그렇지 않으면 null을 반환합니다.
바이트 순서 표시 인코딩 0xEF 0xBB 0xBF UTF-8 0xFE 0xFF UTF-16BE 0xFF 0xFE UTF-16LE
이 훅은 디코드가 바이트 순서 표시를 발견했음을 호출자에게 알릴 방법이 없다는 점을 보완하기 위한 것입니다. 이 훅은 디코드 전에 호출해야 하며, 발견된 바이트 순서 표시에 해당하는 인코딩을 반환하거나, 없으면 null을 반환합니다.
인코드란 스칼라 값 I/O 큐 ioQueue, 인코딩 encoding, 선택적 바이트 I/O 큐 output(기본값 « »)에 대해 다음을 수행합니다:
-
encoder를 인코더 얻기로 encoding에서 구한 값으로 둡니다.
-
큐 처리를 encoder, ioQueue, output, "
html
"로 실행합니다. -
output을 반환합니다.
이것은 HTML 폼을 위한 레거시 훅입니다. UTF-8 인코드를 위에 겹쳐 사용하는 것은 안전합니다. 에러가 발생하지 않기 때문입니다. [HTML]
인코더 얻기란 인코딩 encoding에서 다음을 수행합니다:
-
Assert: encoding이 대체(replacement)나 UTF-16BE/LE가 아님.
-
encoding의 인코더 인스턴스를 반환합니다.
인코딩 또는 실패란 스칼라 값 I/O 큐 ioQueue, 인코더 인스턴스 encoder, 바이트 I/O 큐 output에 대해 다음을 수행합니다:
-
potentialError를 큐 처리를 encoder, ioQueue, output, "
fatal
"로 실행한 결과로 둡니다. -
Push end-of-queue를 output에 추가합니다.
-
null을 반환합니다.
이것은 URL 퍼센트 인코딩을 위한 레거시 훅입니다. 호출자는 ISO-2022-JP 인코더가 에러를 반환할 때 두 가지 상태를 가질 수 있으므로 인코더 인스턴스를 유지해야 합니다. 또한, 에러를 인코딩할 때 바이트는 0x00~0x7F 범위(단, 0x0E, 0x0F, 0x1B, 0x5C, 0x7E 제외)이어야 합니다. [URL]
특히, 에러를 반환할 때 ISO-2022-JP 인코더가 Roman 상태라면 0x5C(\)를 출력할 수 없습니다. 이는 U+005C(\)로 디코드되지 않기 때문입니다. 따라서 인코딩 또는 실패를 의도와 다르게 사용하는 응용 프로그램은 대체 구문(예: JavaScript, CSS 등 U+005C(\)를 사용하는 대체 구문)을 사용하는 경우 ISO-2022-JP 인코더 사용을 방지하거나, 반드시 대체 구문을 인코더를 거치도록 해야 합니다(URL 퍼센트 인코딩과는 대조적임).
반환 값은 인코딩할 수 없었던 코드 포인트를 나타내는 숫자이거나, 에러가 없으면 null입니다. non-null이 반환되면 호출자는 동일한 인코더 인스턴스와 새로운 output I/O 큐로 다시 호출해야 합니다.
7. API
이 절에서는 Web IDL의 용어를 사용합니다. 브라우저 사용자 에이전트는 이 API를 지원해야 합니다. JavaScript 구현도 이 API를 지원하는 것이 좋습니다. 그 외의 사용자 에이전트나 프로그래밍 언어는 필요에 맞는 API를 사용하는 것이 권장되며, 반드시 이 API일 필요는 없습니다. [WEBIDL]
다음 예제는 TextEncoder
객체를 사용하여 문자열 배열을
ArrayBuffer
로
인코딩합니다.
결과는
Uint8Array
로, 문자열 개수(Uint32Array
),
첫 번째 문자열의 길이(Uint32Array
),
UTF-8로 인코딩된 문자열 데이터, 두 번째 문자열의 길이(Uint32Array
),
문자열 데이터, ... 순으로 포함합니다.
function encodeArrayOfStrings( strings) {
var encoder, encoded, len, bytes, view, offset;
encoder = new TextEncoder();
encoded = [];
len = Uint32Array. BYTES_PER_ELEMENT;
for ( var i = 0 ; i < strings. length; i++ ) {
len += Uint32Array. BYTES_PER_ELEMENT;
encoded[ i] = encoder. encode( strings[ i]);
len += encoded[ i]. byteLength;
}
bytes = new Uint8Array( len);
view = new DataView( bytes. buffer);
offset = 0 ;
view. setUint32( offset, strings. length);
offset += Uint32Array. BYTES_PER_ELEMENT;
for ( var i = 0 ; i < encoded. length; i += 1 ) {
len = encoded[ i]. byteLength;
view. setUint32( offset, len);
offset += Uint32Array. BYTES_PER_ELEMENT;
bytes. set( encoded[ i], offset);
offset += len;
}
return bytes. buffer;
}
다음 예제는 위의 예제에서와 같은 형식(또는 UTF-8 이외의 인코딩을 위한
동등 알고리즘)으로 인코딩된 데이터를 담은 ArrayBuffer
를
다시 문자열 배열로 디코딩합니다.
function decodeArrayOfStrings( buffer, encoding) {
var decoder, view, offset, num_strings, strings, len;
decoder = new TextDecoder( encoding);
view = new DataView( buffer);
offset = 0 ;
strings = [];
num_strings = view. getUint32( offset);
offset += Uint32Array. BYTES_PER_ELEMENT;
for ( var i = 0 ; i < num_strings; i++ ) {
len = view. getUint32( offset);
offset += Uint32Array. BYTES_PER_ELEMENT;
strings[ i] = decoder. decode(
new DataView( view. buffer, offset, len));
offset += len;
}
return strings;
}
7.1.
인터페이스 믹스인 TextDecoderCommon
interface mixin {
TextDecoderCommon readonly attribute DOMString encoding ;readonly attribute boolean fatal ;readonly attribute boolean ignoreBOM ; };
TextDecoderCommon
인터페이스 믹스인은 TextDecoder
와
TextDecoderStream
객체가 공유하는 공통 getter를 정의합니다. 이 객체들은 다음과 같은 연관 항목을 가집니다:
- encoding
- 인코딩.
- decoder
- 디코더 인스턴스.
- I/O queue
- 바이트 I/O 큐.
- ignore BOM
- 불리언, 초기값은 false.
- BOM seen
- 불리언, 초기값은 false.
- error mode
- 오류 모드, 초기값은
"
replacement
".
I/O 큐 직렬화
알고리즘은
TextDecoderCommon
decoder와 스칼라 값 I/O 큐 ioQueue가 주어졌을 때 다음을 수행합니다:
-
output을 빈 문자열로 둡니다.
-
다음이 참인 동안 반복합니다:
-
item을 읽기로 ioQueue에서 가져옵니다.
-
item이 end-of-queue이면 output을 반환합니다.
-
decoder의 encoding이 UTF-8 또는 UTF-16BE/LE이고, decoder의 ignore BOM 및 BOM seen이 false라면:
-
item을 output에 추가합니다.
-
이 알고리즘은 BOM 처리에 있어서 플랫폼의 디코드 알고리즘과 다르게 동작합니다. API 사용자가 더 많은 제어권을 가지도록 의도적으로 다르게 설계되었습니다.
fatal
getter의 동작은 this의 error mode가
"fatal
"이면 true, 아니면 false를 반환합니다.
ignoreBOM
getter의 동작은 this의 ignore BOM을 반환합니다.
7.2. 인터페이스 TextDecoder
dictionary {
TextDecoderOptions boolean =
fatal false ;boolean =
ignoreBOM false ; };dictionary {
TextDecodeOptions boolean =
stream false ; }; [Exposed=*]interface {
TextDecoder constructor (optional DOMString = "utf-8",
label optional TextDecoderOptions = {});
options USVString decode (optional AllowSharedBufferSource ,
input optional TextDecodeOptions = {}); };
options TextDecoder includes TextDecoderCommon ;
TextDecoder
객체는 다음과 연관된
do not flush 불리언 값을 가집니다. 초기값은 false입니다.
decoder = new TextDecoder([label = "utf-8" [, options]])
-
새
TextDecoder
객체를 반환합니다.label이 레이블이 아니거나 replacement의 레이블이라면 RangeError 예외를 발생시킵니다.
decoder . encoding
decoder . fatal
-
error mode가 "
fatal
"이면 true, 아니면 false를 반환합니다. decoder . ignoreBOM
-
ignore BOM 값을 반환합니다.
decoder . decode([input [, options]])
-
encoding의 디코더를 실행한 결과를 반환합니다. 이 메서드는 options의
stream
이 true로 여러 번 호출된 후, options의stream
이 없는(또는 false인) 한 번의 호출로 조각난 입력을 처리할 수 있습니다. options의stream
이 없는(또는 false인) 호출에 input이 없다면, 두 인자 모두 생략하는 것이 명확합니다.var string= "" , decoder= new TextDecoder( encoding), buffer; while ( buffer= next_chunk()) { string+= decoder. decode( buffer, { stream: true }); } string+= decoder. decode(); // end-of-queue error mode가 "
fatal
"이고 encoding의 디코더가 error를 반환하면, TypeError 예외를 발생시킵니다.
new TextDecoder(label, options)
생성자 동작은 다음과 같습니다:
-
encoding을 인코딩 얻기에서 label로 구합니다.
-
encoding이 실패이거나 replacement이면 RangeError 예외를 발생시킵니다.
-
options["
fatal
"] 이 true이면 this의 error mode를 "fatal
"로 설정합니다. -
this의 ignore BOM을 options["
ignoreBOM
"]로 설정합니다.
decode(input, options)
메서드 동작은 다음과 같습니다:
-
this의 do not flush가 false이면, this의 decoder를 encoding의 디코더의 새 인스턴스로, this의 I/O 큐를 바이트 I/O 큐 « end-of-queue »로, this의 BOM seen을 false로 설정합니다.
-
this의 do not flush를 options["
stream
"]로 설정합니다. -
input이 주어졌다면, push로 복사본 input을 this의 I/O 큐에 추가합니다.
구현에서는 이 복사를 피하는 전략을 권장합니다. 그렇게 할 경우 input 변경이 이후
decode()
호출에 영향을 주지 않도록 해야 합니다. -
output을 스칼라 값 I/O 큐 « end-of-queue »로 둡니다.
-
다음이 참인 동안 반복합니다:
-
item이 end-of-queue이고 this의 do not flush가 true이면, I/O 큐 직렬화를 this와 output에 실행한 결과를 반환합니다.
스트리밍 동작은 end-of-queue를 여기서 처리하지 않고, this의 do not flush를 false로 설정하지 않는 방식으로 동작합니다. 이렇게 하면 이후 호출에서 this의 decoder가 새로 설정되지 않아 상태가 보존됩니다.
-
그 외의 경우:
7.3.
인터페이스 믹스인 TextEncoderCommon
interface mixin {
TextEncoderCommon readonly attribute DOMString encoding ; };
TextEncoderCommon
인터페이스 믹스인은 TextEncoder
와
TextEncoderStream
객체가 공유하는 공통 getter를 정의합니다.
encoding
getter의 동작은 "utf-8
"을 반환하는 것입니다.
7.4. 인터페이스 TextEncoder
dictionary {
TextEncoderEncodeIntoResult unsigned long long ;
read unsigned long long ; }; [Exposed=*]
written interface {
TextEncoder constructor (); [NewObject ]Uint8Array encode (optional USVString = "");
input TextEncoderEncodeIntoResult encodeInto (USVString , [
source AllowShared ]Uint8Array ); };
destination TextEncoder includes TextEncoderCommon ;
TextEncoder
객체는 label 인자를 지원하지 않습니다. 오직 UTF-8만
지원하기 때문입니다. 또한 stream
옵션도 제공하지 않습니다. 어떤 인코더도 스칼라 값 버퍼링을 요구하지 않기 때문입니다.
encoder = new TextEncoder()
-
새
TextEncoder
객체를 반환합니다. encoder . encoding
-
"
utf-8
"을 반환합니다. encoder . encode([input = ""])
encoder . encodeInto(source, destination)
-
source에 대해 UTF-8 인코더를 실행하고, 그 결과를 destination에 저장하며, 변환 진행 상황을 객체로 반환합니다. 여기서
read
는 source에서 변환된 코드 유닛의 개수,written
은 destination에서 변환된 바이트 개수입니다.
new TextEncoder()
생성자는 아무 동작도 하지 않습니다.
encode(input)
메서드 동작은 다음과 같습니다:
-
output을 바이트 I/O 큐 « end-of-queue »로 둡니다.
-
다음이 참인 동안 반복합니다:
encodeInto(source, destination)
메서드 동작은 다음과 같습니다:
-
read를 0으로 둡니다.
-
written을 0으로 둡니다.
-
encoder를 UTF-8 인코더의 인스턴스로 둡니다.
-
unused를 스칼라 값 I/O 큐 « end-of-queue »로 둡니다.
아래에서 호출되는 handler 알고리즘은 이 인자를 필요로 하지만, UTF-8 인코더에서는 사용하지 않습니다.
-
다음이 참인 동안 반복합니다:
-
item을 읽기로 source에서 가져옵니다.
-
result를 encoder의 handler를 unused와 item에 실행한 결과로 둡니다.
-
그 외의 경우:
-
destination의 byte length − written이 result의 바이트 수 이상이면:
-
item이 U+FFFF보다 크면 read를 2 증가시킵니다.
-
그 외에는 read를 1 증가시킵니다.
-
result의 바이트를 destination에 startingOffset이 written인 상태로 씁니다.
위의 SharedArrayBuffer 경고 참고.
-
written을 result의 바이트 수만큼 증가시킵니다.
-
-
그 외에는 break합니다.
-
-
encodeInto() 메서드는 문자열을 기존 ArrayBuffer
객체로 인코딩할 때 사용할 수 있습니다. 아래 예시는 이 메서드를 활용하는 한 가지 방법을 보여줍니다(상세 구현은 생략):
function convertString( buffer, input, callback) {
let bufferSize = 256 ,
bufferStart = malloc( buffer, bufferSize),
writeOffset = 0 ,
readOffset = 0 ;
while ( true ) {
const view = new Uint8Array( buffer, bufferStart + writeOffset, bufferSize - writeOffset),
{ read, written} = cachedEncoder. encodeInto( input. substring( readOffset), view);
readOffset += read;
writeOffset += written;
if ( readOffset === input. length) {
callback( bufferStart, writeOffset);
free( buffer, bufferStart);
return ;
}
bufferSize *= 2 ;
bufferStart = realloc( buffer, bufferStart, bufferSize);
}
}
7.5.
인터페이스 TextDecoderStream
[Exposed=*]interface {
TextDecoderStream constructor (optional DOMString = "utf-8",
label optional TextDecoderOptions = {}); };
options TextDecoderStream includes TextDecoderCommon ;TextDecoderStream includes GenericTransformStream ;
decoder = new TextDecoderStream([label = "utf-8" [, options]])
-
새
TextDecoderStream
객체를 반환합니다.label이 레이블이 아니거나 replacement의 레이블이라면 RangeError 예외를 발생시킵니다.
decoder . encoding
decoder . fatal
-
error mode가 "
fatal
"이면 true, 아니면 false를 반환합니다. decoder . ignoreBOM
-
ignore BOM 값을 반환합니다.
decoder . readable
-
readable stream을 반환합니다. 이 스트림의 청크는 encoding의 디코더를
writable
에 기록된 청크에 대해 실행한 결과입니다. decoder . writable
-
writable stream을 반환합니다. 이 스트림은
AllowSharedBufferSource
청크를 받아 encoding의 디코더를 실행한 뒤,readable
에서 사용할 수 있도록 합니다.일반적으로
ReadableStream
소스의pipeThrough()
메서드로 사용합니다.var decoder= new TextDecoderStream( encoding); byteReadable. pipeThrough( decoder) . pipeTo( textWritable); error mode가 "
fatal
"이고 encoding의 디코더가 error를 반환하면,readable
과writable
모두TypeError
로 에러 처리됩니다.
new TextDecoderStream(label, options)
생성자 동작은 다음과 같습니다:
-
encoding을 인코딩 얻기에서 label로 구합니다.
-
encoding이 실패이거나 replacement라면 RangeError 예외를 발생시킵니다.
-
options["
fatal
"] 이 true이면 this의 error mode를 "fatal
"로 설정합니다. -
this의 ignore BOM을 options["
ignoreBOM
"]로 설정합니다. -
this의 decoder를 this의 encoding의 디코더의 새 인스턴스로, this의 I/O 큐를 새 I/O 큐로 설정합니다.
-
transformAlgorithm을 chunk 인자를 받아 청크 디코드 및 enqueue 알고리즘을 this와 chunk로 실행하는 알고리즘으로 둡니다.
-
flushAlgorithm을 인자 없이 flush and enqueue 알고리즘을 this로 실행하는 알고리즘으로 둡니다.
-
transformStream을 새
TransformStream
으로 둡니다. -
transformStream을 transformAlgorithm과 flushAlgorithm으로 설정합니다.
청크 디코드 및
enqueue 알고리즘은 TextDecoderStream
객체
decoder와 chunk가 주어졌을 때 다음을 수행합니다:
-
bufferSource를 chunk를 AllowSharedBufferSource로 변환한 값으로 둡니다.
-
Push로 bufferSource의 복사본을 decoder의 I/O 큐에 추가합니다.
위의 SharedArrayBuffer 경고 참고.
-
output을 스칼라 값 I/O 큐 « end-of-queue »로 둡니다.
-
다음이 참인 동안 반복합니다:
-
item이 end-of-queue라면:
-
result를 항목 처리를 item, decoder의 decoder, decoder의 I/O 큐, output, decoder의 error mode로 실행한 결과로 둡니다.
flush and enqueue
알고리즘은 입력 ReadableStream
객체의 데이터가 끝났을 때, TextDecoderStream
객체 decoder에 대해 다음을 수행합니다:
-
output을 스칼라 값 I/O 큐 « end-of-queue »로 둡니다.
-
다음이 참인 동안 반복합니다:
-
result를 항목 처리를 item, decoder의 decoder, decoder의 I/O 큐, output, decoder의 error mode로 실행한 결과로 둡니다.
-
result가 finished라면:
7.6.
인터페이스 TextEncoderStream
[Exposed=*]interface {
TextEncoderStream constructor (); };TextEncoderStream includes TextEncoderCommon ;TextEncoderStream includes GenericTransformStream ;
TextEncoderStream
객체는 다음과 연관된 값을 가집니다:
- encoder
- 인코더 인스턴스.
- 선행 서러게이트
- null 또는 선행 서러게이트, 초기값은 null.
TextEncoderStream
객체는 label 인자를 지원하지 않습니다. 오직 UTF-8만
지원합니다.
encoder = new TextEncoderStream()
-
새
TextEncoderStream
객체를 반환합니다. encoder . encoding
-
"
utf-8
"을 반환합니다. encoder . readable
-
readable stream을 반환합니다. 이 스트림의 청크는
Uint8Array
이며, UTF-8의 인코더를writable
에 기록된 청크에 대해 실행한 결과입니다. encoder . writable
-
writable stream을 반환합니다. 이 스트림은 문자열 청크를 받아 UTF-8의 인코더를 실행한 뒤,
readable
에서 사용할 수 있도록 합니다.일반적으로
ReadableStream
소스의pipeThrough()
메서드로 사용합니다.textReadable
. pipeThrough( new TextEncoderStream()) . pipeTo( byteWritable);
new TextEncoderStream()
생성자 동작은 다음과 같습니다:
-
transformAlgorithm을 chunk 인자를 받아 청크 인코딩 및 enqueue 알고리즘을 this와 chunk로 실행하는 알고리즘으로 둡니다.
-
transformStream을 새
TransformStream
으로 둡니다. -
transformStream을 transformAlgorithm과 flushAlgorithm으로 설정합니다.
청크 인코딩 및
enqueue 알고리즘은 TextEncoderStream
객체
encoder와 chunk가 주어졌을 때 다음을 수행합니다:
-
input을 chunk를 DOMString으로 변환한 값으로 둡니다.
-
input을 코드 유닛 I/O 큐로 변환합니다.
DOMString
과 코드 유닛 I/O 큐를 사용하는 이유는, 청크 사이에 분리된 서러게이트 쌍을 재조립할 수 있도록 하기 위함입니다. 동작 자체는USVString
과 동일합니다. 특히, 단독 서러게이트는 U+FFFD(�)로 대체됩니다. -
output을 바이트 I/O 큐 « end-of-queue »로 둡니다.
-
다음이 참인 동안 반복합니다:
-
item을 읽기로 input에서 가져옵니다.
-
item이 end-of-queue라면:
-
output을 바이트 시퀀스로 변환합니다.
-
output이 비어 있지 않으면:
-
chunk를 Uint8Array 객체 생성을 output과 encoder의 relevant realm으로 실행한 결과로 둡니다.
-
-
반환합니다.
-
-
result를 코드 유닛을 스칼라 값으로 변환 알고리즘을 encoder, item, input에 실행한 결과로 둡니다.
-
result가 continue가 아니면, 항목 처리를 result, encoder의 encoder, input, output, "
fatal
"로 실행합니다.
-
코드 유닛을
스칼라 값으로 변환 알고리즘은
TextEncoderStream
객체
encoder, 코드 유닛 item, 코드 유닛 I/O 큐
input이 주어졌을 때 다음을 수행합니다:
-
encoder의 선행 서러게이트가 null이 아니면:
-
leadingSurrogate를 encoder의 선행 서러게이트로 둡니다.
-
encoder의 선행 서러게이트를 null로 설정합니다.
-
item이 후행 서러게이트라면, 서러게이트로부터 스칼라 값을 leadingSurrogate, item으로 실행한 결과를 반환합니다.
-
item을 input에 복원합니다.
-
U+FFFD(�)를 반환합니다.
-
-
item이 선행 서러게이트라면 encoder의 선행 서러게이트를 item으로 설정하고 continue를 반환합니다.
-
item이 후행 서러게이트라면 U+FFFD(�)를 반환합니다.
-
item을 반환합니다.
이 알고리즘은 Infra 표준의 "문자열을 스칼라 값 문자열로 변환" 알고리즘과 동등하지만, 문자열 사이에 분리된 서러게이트 쌍도 허용합니다. [INFRA]
인코딩 및 플러시 알고리즘은
TextEncoderStream
객체
encoder가 주어졌을 때 다음을 수행합니다:
-
encoder의 선행 서러게이트가 null이 아니면:
-
chunk를 Uint8Array 객체 생성을 « 0xEF, 0xBF, 0xBD »와 encoder의 relevant realm으로 실행한 결과로 둡니다.
이는 UTF-8 바이트로 U+FFFD(�)입니다.
-
8. 인코딩
8.1. UTF-8
8.1.1. UTF-8 디코더
바이트 순서 표시는 실제 배포된 콘텐츠에서 레이블보다 더 신뢰성이 높으므로 우선시됩니다. 따라서 이는 UTF-8 디코더 알고리즘의 일부가 아니라, 디코드 및 UTF-8 디코드 알고리즘에서 처리됩니다.
- UTF-8 코드 포인트
- UTF-8 읽은 바이트 수
- UTF-8 필요한 바이트 수
- UTF-8 읽은 바이트 수
- 각각 숫자이며, 초기값은 0입니다.
- UTF-8 하한값
- 바이트, 초기값은 0x80입니다.
- UTF-8 상한값
- 바이트, 초기값은 0xBF입니다.
UTF-8의 디코더의 handler는 ioQueue와 byte가 주어졌을 때 다음을 수행합니다:
-
byte가 end-of-queue이고 UTF-8 필요한 바이트 수가 0이 아니라면, UTF-8 필요한 바이트 수를 0으로 설정하고 에러를 반환합니다.
-
byte가 end-of-queue라면, finished를 반환합니다.
-
UTF-8 필요한 바이트 수가 0이면, byte에 따라:
- 0x00 ~ 0x7F
-
byte 값을 가진 코드 포인트를 반환합니다.
- 0xC2 ~ 0xDF
-
-
UTF-8 필요한 바이트 수를 1로 설정합니다.
-
UTF-8 코드 포인트를 byte & 0x1F로 설정합니다.
byte의 하위 5비트입니다.
-
- 0xE0 ~ 0xEF
-
-
byte가 0xE0이면, UTF-8 하한값을 0xA0으로 설정합니다.
-
byte가 0xED이면, UTF-8 상한값을 0x9F로 설정합니다.
-
UTF-8 필요한 바이트 수를 2로 설정합니다.
-
UTF-8 코드 포인트를 byte & 0xF로 설정합니다.
byte의 하위 4비트입니다.
-
- 0xF0 ~ 0xF4
-
-
byte가 0xF0이면, UTF-8 하한값을 0x90으로 설정합니다.
-
byte가 0xF4이면, UTF-8 상한값을 0x8F로 설정합니다.
-
UTF-8 필요한 바이트 수를 3으로 설정합니다.
-
UTF-8 코드 포인트를 byte & 0x7로 설정합니다.
byte의 하위 3비트입니다.
-
- 그 외
-
에러 반환
continue를 반환합니다.
-
byte가 UTF-8 하한값부터 UTF-8 상한값 범위에 없으면:
-
UTF-8 코드 포인트, UTF-8 필요한 바이트 수, UTF-8 읽은 바이트 수를 0으로, UTF-8 하한값을 0x80으로, UTF-8 상한값을 0xBF로 설정합니다.
-
byte를 ioQueue에 복원합니다.
-
에러 반환
-
-
UTF-8 코드 포인트를 (UTF-8 코드 포인트 << 6) | (byte & 0x3F)로 설정합니다.
UTF-8 코드 포인트의 기존 비트들을 6비트 왼쪽으로 이동시키고, 새로 생긴 하위 6비트를 byte의 하위 6비트로 설정합니다.
-
UTF-8 읽은 바이트 수를 1 증가시킵니다.
-
UTF-8 읽은 바이트 수가 UTF-8 필요한 바이트 수와 같지 않다면 continue를 반환합니다.
-
codePoint를 UTF-8 코드 포인트로 둡니다.
-
UTF-8 코드 포인트, UTF-8 필요한 바이트 수, UTF-8 읽은 바이트 수를 0으로 설정합니다.
-
값이 codePoint인 코드 포인트를 반환합니다.
위 UTF-8 디코더의 제약사항은 Unicode 표준의 “Best Practices for Using U+FFFD”와 일치합니다. 현행 표준(Encoding Standard)에서는 이 외의 동작이 허용되지 않습니다(동일한 결과를 내는 다른 알고리즘은 허용, 오히려 장려됨). [UNICODE]
8.1.2. UTF-8 인코더
UTF-8의 인코더의 handler는 unused와 codePoint가 주어졌을 때 다음을 수행합니다:
-
codePoint가 end-of-queue라면, finished를 반환합니다.
-
codePoint가 ASCII 코드 포인트라면, 값이 codePoint인 바이트를 반환합니다.
-
codePoint가 속한 범위에 따라 count와 offset을 설정합니다:
- U+0080 ~ U+07FF (포함)
- 1 및 0xC0
- U+0800 ~ U+FFFF (포함)
- 2 및 0xE0
- U+10000 ~ U+10FFFF (포함)
- 3 및 0xF0
-
bytes를 바이트 시퀀스(첫 번째 바이트는 (codePoint >> (6 × count)) + offset)로 둡니다.
-
count가 0보다 큰 동안 반복합니다:
-
temp를 codePoint >> (6 × (count − 1))로 설정합니다.
-
bytes에 0x80 | (temp & 0x3F)를 추가합니다.
-
count를 1 감소시킵니다.
-
-
바이트 시퀀스 bytes를 순서대로 반환합니다.
이 알고리즘은 Unicode 표준에 기술된 것과 동일한 결과를 가집니다. 완전성을 위해 여기에 포함되어 있습니다. [UNICODE]
9. 레거시 단일 바이트 인코딩
각 바이트가 하나의 코드 포인트이거나 아무것도 아닌 인코딩을 단일 바이트 인코딩이라고 합니다. 단일 바이트 인코딩은 디코더와 인코더를 공유합니다. index single-byte는 단일 바이트 디코더와 단일 바이트 인코더에서 참조되며, 아래 표로 정의되고, 사용하는 단일 바이트 인코딩에 따라 다릅니다. 두 개를 제외한 모든 단일 바이트 인코딩은 고유한 index를 가집니다.
ISO-8859-8 과 ISO-8859-8-I는 별도의 인코딩 이름입니다. ISO-8859-8은 레이아웃 방향에 영향을 주기 때문입니다. 과거에는 ISO-8859-6과 "ISO-8859-6-I"도 그랬던 적이 있으나, 현행 표준에서는 더 이상 그렇지 않습니다.
9.1. 단일 바이트 디코더
단일 바이트 인코딩의 디코더의 handler는 unused와 byte가 주어졌을 때 다음을 수행합니다:
-
byte가 end-of-queue라면, finished를 반환합니다.
-
byte가 ASCII 바이트라면, 값이 byte인 코드 포인트를 반환합니다.
-
codePoint를 index code point 중 byte − 0x80에 해당하는 값을 index single-byte에서 찾은 값으로 둡니다.
-
codePoint가 null이면 에러를 반환합니다.
-
값이 codePoint인 코드 포인트를 반환합니다.
9.2. 단일 바이트 인코더
단일 바이트 인코딩의 인코더의 handler는 unused와 codePoint가 주어졌을 때 다음을 수행합니다:
-
codePoint가 end-of-queue라면, finished를 반환합니다.
-
codePoint가 ASCII 코드 포인트라면, 값이 codePoint인 바이트를 반환합니다.
-
pointer를 index pointer 중 codePoint에 해당하는 값을 index single-byte에서 찾은 값으로 둡니다.
-
pointer가 null이면 에러를 codePoint와 함께 반환합니다.
-
값이 pointer + 0x80인 바이트를 반환합니다.
10. 레거시 다중 바이트 중국어(간체) 인코딩
10.1. GBK
10.1.1. GBK 디코더
10.1.2. GBK 인코더
GBK의 인코더는 gb18030의 인코더이며, is GBK가 true로 설정되어 있습니다.
GBK를 gb18030와 완전히 동일하게 alias하지 않는 것은, 현행 서버 및 GBK 인코더로 생성된 콘텐츠를 사용하는 레거시 소비자에서의 호환성 문제를 줄이기 위한 보수적인 선택입니다.
10.2. gb18030
10.2.1. gb18030 디코더
gb18030의 디코더는 다음과 연관된 값을 가집니다:
- gb18030 first
- gb18030 second
- gb18030 third
- gb18030 second
- 각각 바이트이며, 초기값은 0x00입니다.
gb18030의 디코더의 handler는 ioQueue와 byte가 주어졌을 때 다음을 수행합니다:
-
byte가 end-of-queue이고 gb18030 first, gb18030 second, gb18030 third 모두 0x00이면 finished를 반환합니다.
-
byte가 end-of-queue이고, gb18030 first, gb18030 second, 또는 gb18030 third가 0x00이 아니라면 gb18030 first, gb18030 second, gb18030 third를 0x00으로 설정하고 에러를 반환합니다.
-
gb18030 third가 0x00이 아니라면:
-
byte가 0x30~0x39 범위가 아니라면:
-
복원 « gb18030 second, gb18030 third, byte »를 ioQueue에 복원합니다.
-
gb18030 first, gb18030 second, gb18030 third를 0x00으로 설정합니다.
-
에러 반환
-
-
codePoint를 index gb18030 ranges code point에서 ((gb18030 first − 0x81) × (10 × 126 × 10)) + ((gb18030 second − 0x30) × (10 × 126)) + ((gb18030 third − 0x81) × 10) + byte − 0x30의 값으로 둡니다.
-
gb18030 first, gb18030 second, gb18030 third를 0x00으로 설정합니다.
-
codePoint가 null이면 에러를 반환합니다.
-
값이 codePoint인 코드 포인트를 반환합니다.
-
-
gb18030 second가 0x00이 아니라면:
-
byte가 0x81~0xFE 범위라면, gb18030 third 에 byte를 설정하고 continue를 반환합니다.
-
복원 « gb18030 second, byte »를 ioQueue에 복원하고, gb18030 first 및 gb18030 second를 0x00으로 설정한 뒤, 에러를 반환합니다.
-
-
gb18030 first가 0x00이 아니라면:
-
byte가 0x30~0x39 범위라면 gb18030 second 에 byte를 설정하고 continue를 반환합니다.
-
leading을 gb18030 first로 둡니다.
-
gb18030 first를 0x00으로 설정합니다.
-
pointer를 null로 둡니다.
-
offset을 byte가 0x7F 미만이면 0x40, 그 외에는 0x41로 둡니다.
-
byte가 0x40~0x7E 또는 0x80~0xFE 범위라면 pointer를 (leading − 0x81) × 190 + (byte − offset)로 설정합니다.
-
codePoint를 pointer가 null이면 null, 아니면 index code point 중 pointer에 해당하는 index gb18030의 값으로 둡니다.
-
codePoint가 null이 아니라면 값이 codePoint인 코드 포인트를 반환합니다.
-
에러 반환
-
-
byte가 ASCII 바이트라면, 값이 byte인 코드 포인트를 반환합니다.
-
byte가 0x80이면, 코드 포인트 U+20AC(€)를 반환합니다.
-
byte가 0x81~0xFE 범위라면, gb18030 first에 byte를 설정하고 continue를 반환합니다.
-
에러 반환
10.2.2. gb18030 인코더
gb18030의 인코더는 is GBK라는 불리언 값을 가지며, 초기값은 false입니다.
gb18030의 인코더의 handler는 unused와 codePoint가 주어졌을 때 다음을 수행합니다:
-
codePoint가 end-of-queue라면, finished를 반환합니다.
-
codePoint가 ASCII 코드 포인트라면, 값이 codePoint인 바이트를 반환합니다.
-
codePoint가 U+E5E5라면, 에러를 codePoint와 함께 반환합니다.
index gb18030은 호환성 때문에 0xA3 0xA0을 U+E5E5가 아니라 U+3000 IDEOGRAPHIC SPACE로 매핑합니다. 따라서 역변환(roundtrip)이 불가능합니다.
-
is GBK가 true이고 codePoint가 U+20AC(€)라면, 바이트 0x80을 반환합니다.
-
아래 표의 첫 번째 열이 codePoint인 행이 있다면, 해당 행의 두 번째 열에 있는 두 바이트를 반환합니다:
코드 포인트 바이트 U+E78D 0xA6 0xD9 U+E78E 0xA6 0xDA U+E78F 0xA6 0xDB U+E790 0xA6 0xDC U+E791 0xA6 0xDD U+E792 0xA6 0xDE U+E793 0xA6 0xDF U+E794 0xA6 0xEC U+E795 0xA6 0xED U+E796 0xA6 0xF3 U+E81E 0xFE 0x59 U+E826 0xFE 0x61 U+E82B 0xFE 0x66 U+E82C 0xFE 0x67 U+E832 0xFE 0x6D U+E843 0xFE 0x7E U+E854 0xFE 0x90 U+E864 0xFE 0xA0 이 비대칭 인코더 테이블은 GB18030-2005 표준과의 호환성 유지를 위해 존재합니다. 자세한 설명은 index gb18030 ranges 참고.
-
pointer를 index pointer에서 codePoint에 해당하는 값으로 index gb18030에서 찾습니다.
-
pointer가 null이 아니라면:
-
leading을 pointer / 190 + 0x81로 둡니다.
-
trailing을 pointer % 190로 둡니다.
-
offset을 trailing이 0x3F 미만이면 0x40, 그 외에는 0x41로 둡니다.
-
leading과 trailing + offset 값을 가지는 두 바이트를 반환합니다.
-
-
pointer를 index gb18030 ranges pointer에서 codePoint에 해당하는 값으로 둡니다.
-
byte1을 pointer / (10 × 126 × 10)로 둡니다.
-
pointer를 pointer % (10 × 126 × 10)으로 설정합니다.
-
byte2를 pointer / (10 × 126)로 둡니다.
-
pointer를 pointer % (10 × 126)으로 설정합니다.
-
byte3를 pointer / 10으로 둡니다.
-
byte4를 pointer % 10으로 둡니다.
-
값이 byte1 + 0x81, byte2 + 0x30, byte3 + 0x81, byte4 + 0x30인 네 바이트를 반환합니다.
11. 레거시 다중 바이트 중국어(번체) 인코딩
11.1. Big5
11.1.1. Big5 디코더
Big5의 디코더는 Big5 lead라는 바이트 값을 가지며, 초기값은 0x00입니다.
Big5의 디코더의 handler는 ioQueue와 byte가 주어졌을 때 다음을 수행합니다:
-
byte가 end-of-queue이고 Big5 lead가 0x00이 아니면, Big5 lead를 0x00으로 설정하고 에러를 반환합니다.
-
byte가 end-of-queue이고 Big5 lead가 0x00이면, finished를 반환합니다.
-
Big5 lead가 0x00이 아니면:
-
leading을 Big5 lead로 둡니다.
-
Big5 lead를 0x00으로 설정합니다.
-
pointer를 null로 둡니다.
-
offset을 byte가 0x7F 미만이면 0x40, 그 외에는 0x62로 둡니다.
-
byte가 0x40~0x7E 또는 0xA1~0xFE 범위라면 pointer를 (leading − 0x81) × 157 + (byte − offset)로 설정합니다.
-
아래 표의 첫 번째 열이 pointer인 행이 있다면, 두 번째 열에 있는 두 개 코드 포인트를 반환합니다(세 번째 열은 무시):
포인터 코드 포인트 비고 1133 U+00CA U+0304 Ê̄ (라틴 대문자 E 위에 곡절표 및 장음표) 1135 U+00CA U+030C Ê̌ (라틴 대문자 E 위에 곡절표 및 캐런 부호) 1164 U+00EA U+0304 ê̄ (라틴 소문자 e 위에 곡절표 및 장음표) 1166 U+00EA U+030C ê̌ (라틴 소문자 e 위에 곡절표 및 캐런 부호) 인덱스는 하나의 코드 포인트만 허용하므로, 이 표는 이러한 포인터에 사용됩니다.
-
codePoint를 pointer가 null이면 null, 아니면 index code point 중 pointer에 해당하는 index Big5의 값으로 둡니다.
-
codePoint가 null이 아니면, 값이 codePoint인 코드 포인트를 반환합니다.
-
에러 반환
-
-
byte가 ASCII 바이트라면, 값이 byte인 코드 포인트를 반환합니다.
-
byte가 0x81~0xFE 범위라면, Big5 lead에 byte를 설정하고 continue를 반환합니다.
-
에러 반환
11.1.2. Big5 인코더
Big5의 인코더의 handler는 unused와 codePoint가 주어졌을 때 다음을 수행합니다:
-
codePoint가 end-of-queue라면, finished를 반환합니다.
-
codePoint가 ASCII 코드 포인트라면, 값이 codePoint인 바이트를 반환합니다.
-
pointer를 index Big5 pointer에서 codePoint에 해당하는 값으로 둡니다.
-
pointer가 null이면 에러를 codePoint와 함께 반환합니다.
-
leading을 pointer / 157 + 0x81로 둡니다.
-
trailing을 pointer % 157로 둡니다.
-
offset을 trailing이 0x3F 미만이면 0x40, 그 외에는 0x62로 둡니다.
-
값이 leading과 trailing + offset인 두 바이트를 반환합니다.
12. 레거시 다중 바이트 일본어 인코딩
12.1. EUC-JP
12.1.1. EUC-JP 디코더
- EUC-JP jis0212
- 불리언, 초기값은 false.
- EUC-JP lead
- 바이트, 초기값은 0x00.
EUC-JP의 디코더의 handler는 ioQueue와 byte가 주어졌을 때 다음을 수행합니다:
-
byte가 end-of-queue이고 EUC-JP lead가 0x00이 아니면, EUC-JP lead를 0x00으로 설정하고 에러를 반환합니다.
-
byte가 end-of-queue이고 EUC-JP lead가 0x00이면, finished를 반환합니다.
-
EUC-JP lead가 0x8E이고 byte가 0xA1~0xDF 범위라면, EUC-JP lead를 0x00으로 설정하고 값이 0xFF61 − 0xA1 + byte인 코드 포인트를 반환합니다.
-
EUC-JP lead가 0x8F이고 byte가 0xA1~0xFE 범위라면, EUC-JP jis0212를 true로, EUC-JP lead를 byte로 설정하고 continue를 반환합니다.
-
EUC-JP lead가 0x00이 아니면:
-
leading을 EUC-JP lead로 둡니다.
-
EUC-JP lead를 0x00으로 설정합니다.
-
codePoint를 null로 둡니다.
-
leading과 byte가 모두 0xA1~0xFE 범위라면, EUC-JP jis0212가 false일 때는 index code point 중 (leading − 0xA1) × 94 + byte − 0xA1에 해당하는 값을 index jis0208에서, true일 때는 index jis0212에서 codePoint로 설정합니다.
-
EUC-JP jis0212를 false로 설정합니다.
-
codePoint가 null이 아니면, 값이 codePoint인 코드 포인트를 반환합니다.
-
에러 반환
-
-
byte가 ASCII 바이트라면, 값이 byte인 코드 포인트를 반환합니다.
-
byte가 0x8E, 0x8F 또는 0xA1~0xFE 범위라면 EUC-JP lead에 byte를 설정하고 continue를 반환합니다.
-
에러 반환
12.1.2. EUC-JP 인코더
EUC-JP의 인코더의 handler는 unused와 codePoint가 주어졌을 때 다음을 수행합니다:
-
codePoint가 end-of-queue라면, finished를 반환합니다.
-
codePoint가 ASCII 코드 포인트라면, 값이 codePoint인 바이트를 반환합니다.
-
codePoint가 U+00A5(¥)라면, 바이트 0x5C을 반환합니다.
-
codePoint가 U+203E(‾)라면, 바이트 0x7E을 반환합니다.
-
codePoint가 U+FF61(。) ~ U+FF9F(゚) 범위라면, 값이 0x8E와 codePoint − 0xFF61 + 0xA1인 두 바이트를 반환합니다.
-
codePoint가 U+2212(−)라면, U+FF0D(-)로 설정합니다.
-
pointer를 index pointer에서 codePoint에 해당하는 값으로 index jis0208에서 찾습니다.
pointer가 null이 아니면 index jis0208의 특성상 8836 미만입니다.
-
pointer가 null이면 에러를 codePoint와 함께 반환합니다.
-
leading을 pointer / 94 + 0xA1로 둡니다.
-
trailing을 pointer % 94 + 0xA1로 둡니다.
-
값이 leading과 trailing인 두 바이트를 반환합니다.
12.2. ISO-2022-JP
12.2.1. ISO-2022-JP 디코더
ISO-2022-JP의 디코더는 다음과 연관된 값을 가집니다:
- ISO-2022-JP 디코더 상태
- 상태, 초기값은 ASCII.
- ISO-2022-JP 디코더 출력 상태
- 상태, 초기값은 ASCII.
- ISO-2022-JP lead
- 바이트, 초기값은 0x00.
- ISO-2022-JP output
- 불리언, 초기값은 false.
ISO-2022-JP의 디코더의 handler는 ioQueue와 byte가 주어졌을 때, ISO-2022-JP 디코더 상태를 기준으로 동작합니다:
- ASCII
-
byte에 따라:
- 0x1B
-
ISO-2022-JP 디코더 상태를 escape start로 설정하고 continue를 반환합니다.
- 0x00 ~ 0x7F (0x0E, 0x0F, 0x1B 제외)
-
ISO-2022-JP output을 false로 설정하고, 값이 byte인 코드 포인트를 반환합니다.
- end-of-queue
-
finished를 반환합니다.
- 그 외
-
ISO-2022-JP output을 false로 설정하고 에러를 반환합니다.
- Roman
-
byte에 따라:
- 0x1B
-
ISO-2022-JP 디코더 상태를 escape start로 설정하고 continue를 반환합니다.
- 0x5C
-
ISO-2022-JP output을 false로 설정하고 코드 포인트 U+00A5(¥) 반환.
- 0x7E
-
ISO-2022-JP output을 false로 설정하고 코드 포인트 U+203E(‾) 반환.
- 0x00 ~ 0x7F (0x0E, 0x0F, 0x1B, 0x5C, 0x7E 제외)
-
ISO-2022-JP output을 false로 설정하고, 값이 byte인 코드 포인트를 반환합니다.
- end-of-queue
-
finished를 반환합니다.
- 그 외
-
ISO-2022-JP output을 false로 설정하고 에러를 반환합니다.
- katakana
-
byte에 따라:
- 0x1B
-
ISO-2022-JP 디코더 상태를 escape start로 설정하고 continue를 반환합니다.
- 0x21 ~ 0x5F
-
ISO-2022-JP output을 false로 설정하고 값이 0xFF61 − 0x21 + byte인 코드 포인트를 반환합니다.
- end-of-queue
-
finished를 반환합니다.
- 그 외
-
ISO-2022-JP output을 false로 설정하고 에러를 반환합니다.
- Leading byte
-
byte에 따라:
- 0x1B
-
ISO-2022-JP 디코더 상태를 escape start로 설정하고 continue를 반환합니다.
- 0x21 ~ 0x7E
-
ISO-2022-JP output을 false로, ISO-2022-JP lead를 byte로, ISO-2022-JP 디코더 상태를 trailing byte로 설정하고 continue를 반환합니다.
- end-of-queue
-
finished를 반환합니다.
- 그 외
-
ISO-2022-JP output을 false로 설정하고 에러를 반환합니다.
- Trailing byte
-
byte에 따라:
- 0x1B
-
ISO-2022-JP 디코더 상태를 escape start로 설정하고 에러를 반환합니다.
- 0x21 ~ 0x7E
-
-
ISO-2022-JP 디코더 상태를 leading byte로 설정합니다.
-
pointer를 (ISO-2022-JP lead − 0x21) × 94 + byte − 0x21로 둡니다.
-
codePoint를 index code point 중 pointer에 해당하는 index jis0208의 값으로 둡니다.
-
codePoint가 null이면 에러를 반환합니다.
-
값이 codePoint인 코드 포인트를 반환합니다.
-
- end-of-queue
-
ISO-2022-JP 디코더 상태를 leading byte로 설정하고 에러를 반환합니다.
- 그 외
-
ISO-2022-JP 디코더 상태를 leading byte로 설정하고 에러를 반환합니다.
- Escape start
-
-
byte가 0x24 또는 0x28이면 ISO-2022-JP lead를 byte로, ISO-2022-JP 디코더 상태를 escape로 설정하고 continue를 반환합니다.
-
byte가 end-of-queue가 아니면, byte를 ioQueue에 복원합니다.
-
ISO-2022-JP output을 false로, ISO-2022-JP 디코더 상태를 ISO-2022-JP 디코더 출력 상태로 설정하고 에러를 반환합니다.
-
- Escape
-
-
leading을 ISO-2022-JP lead로 두고, ISO-2022-JP lead를 0x00으로 설정합니다.
-
state를 null로 둡니다.
-
leading이 0x28이고 byte가 0x42이면 state를 ASCII로 설정합니다.
-
leading이 0x28이고 byte가 0x4A이면 state를 Roman으로 설정합니다.
-
leading이 0x28이고 byte가 0x49이면 state를 katakana로 설정합니다.
-
leading이 0x24이고 byte가 0x40 또는 0x42이면, state를 leading byte로 설정합니다.
-
state가 null이 아니면:
-
ISO-2022-JP 디코더 상태와 ISO-2022-JP 디코더 출력 상태를 state로 설정합니다.
-
output을 ISO-2022-JP output의 값으로 둡니다.
-
ISO-2022-JP output을 true로 설정합니다.
-
-
byte가 end-of-queue이면 leading을 ioQueue에 복원하고, 아니면 « leading, byte »를 ioQueue에 복원합니다.
-
ISO-2022-JP output을 false로, ISO-2022-JP 디코더 상태를 ISO-2022-JP 디코더 출력 상태로 설정하고 에러 반환.
-
12.2.2. ISO-2022-JP 인코더
ISO-2022-JP 인코더는 여러 번 출력 결과를 이어붙였을 때 해당 디코더에서 에러가 발생할 수 있는 유일한 인코더입니다.
U+00A5(¥)를 인코딩하면 0x1B 0x28 0x4A 0x5C 0x1B 0x28 0x42가 됩니다. 두 번 인코딩해서 결과를 이어붙이고 디코딩하면 U+00A5 U+FFFD U+00A5가 나옵니다.
ISO-2022-JP의 인코더는 ISO-2022-JP 인코더 상태를 가지며, ASCII, Roman, jis0208 중 하나이며, 초기값은 ASCII입니다.
ISO-2022-JP의 인코더의 handler는 ioQueue와 codePoint가 주어졌을 때 다음을 수행합니다:
-
codePoint가 end-of-queue이고 ISO-2022-JP 인코더 상태가 ASCII가 아니라면, ISO-2022-JP 인코더 상태를 ASCII로 설정하고, 세 바이트 0x1B 0x28 0x42를 반환합니다.
-
codePoint가 end-of-queue이고 ISO-2022-JP 인코더 상태가 ASCII라면, finished를 반환합니다.
-
ISO-2022-JP 인코더 상태가 ASCII 또는 Roman이고, codePoint가 U+000E, U+000F, U+001B 중 하나라면, U+FFFD(�)와 함께 에러를 반환합니다.
공격 방지를 위해 해당 codePoint 대신 U+FFFD(�)를 반환합니다.
-
ISO-2022-JP 인코더 상태가 ASCII이고, codePoint가 ASCII 코드 포인트라면, 값이 codePoint인 바이트를 반환합니다.
-
ISO-2022-JP 인코더 상태가 Roman이고, codePoint가 ASCII 코드 포인트(U+005C(\), U+007E(~) 제외)이거나 U+00A5(¥), U+203E(‾)라면:
-
codePoint가 ASCII 코드 포인트라면, 값이 codePoint인 바이트를 반환합니다.
-
codePoint가 U+00A5(¥)라면, 바이트 0x5C을 반환합니다.
-
codePoint가 U+203E(‾)라면, 바이트 0x7E을 반환합니다.
-
-
codePoint가 ASCII 코드 포인트이고 ISO-2022-JP 인코더 상태가 ASCII가 아니라면, codePoint를 ioQueue에 복원하고, ISO-2022-JP 인코더 상태를 ASCII로 설정한 뒤, 세 바이트 0x1B 0x28 0x42를 반환합니다.
-
codePoint가 U+00A5(¥), U+203E(‾)이고, ISO-2022-JP 인코더 상태가 Roman이 아니라면, codePoint를 ioQueue에 복원하고, ISO-2022-JP 인코더 상태를 Roman으로 설정한 뒤, 세 바이트 0x1B 0x28 0x4A를 반환합니다.
-
codePoint가 U+2212(−)라면, U+FF0D(-)로 설정합니다.
-
codePoint가 U+FF61(。)~U+FF9F(゚) 범위라면, codePoint − 0xFF61에 해당하는 index code point를 index ISO-2022-JP katakana에서 찾아서 codePoint로 설정합니다.
-
pointer를 index pointer에서 codePoint에 해당하는 값으로 index jis0208에서 찾습니다.
pointer가 null이 아니면 index jis0208의 특성상 8836 미만입니다.
-
pointer가 null이면:
-
ISO-2022-JP 인코더 상태가 jis0208이면, codePoint를 ioQueue에 복원하고, ISO-2022-JP 인코더 상태를 ASCII로 설정한 뒤, 세 바이트 0x1B 0x28 0x42를 반환합니다.
-
에러를 codePoint와 함께 반환합니다.
-
-
ISO-2022-JP 인코더 상태가 jis0208이 아니라면, codePoint를 ioQueue에 복원하고, ISO-2022-JP 인코더 상태를 jis0208으로 설정한 뒤, 세 바이트 0x1B 0x24 0x42를 반환합니다.
-
leading을 pointer / 94 + 0x21로 둡니다.
-
trailing을 pointer % 94 + 0x21로 둡니다.
-
값이 leading과 trailing인 두 바이트를 반환합니다.
12.3. Shift_JIS
12.3.1. Shift_JIS 디코더
Shift_JIS의 디코더는 Shift_JIS lead라는 바이트 값을 가지며, 초기값은 0x00입니다.
Shift_JIS의 디코더의 handler는 ioQueue와 byte가 주어졌을 때 다음을 수행합니다:
-
byte가 end-of-queue이고 Shift_JIS lead가 0x00이 아니면, Shift_JIS lead를 0x00으로 설정하고 에러를 반환합니다.
-
byte가 end-of-queue이고 Shift_JIS lead가 0x00이면, finished를 반환합니다.
-
Shift_JIS lead가 0x00이 아니면:
-
leading을 Shift_JIS lead로 둡니다.
-
Shift_JIS lead를 0x00으로 설정합니다.
-
pointer를 null로 둡니다.
-
offset을 byte가 0x7F 미만이면 0x40, 그 외에는 0x41로 둡니다.
-
leadingOffset을 leading이 0xA0 미만이면 0x81, 그렇지 않으면 0xC1로 둡니다.
-
byte가 0x40~0x7E 또는 0x80~0xFC 범위라면, pointer를 (leading − leadingOffset) × 188 + byte − offset으로 설정합니다.
-
pointer가 8836~10715 범위라면, 값이 0xE000 − 8836 + pointer인 코드 포인트를 반환합니다.
이 값은 Windows의 EUDC와 연동되는 레거시 값입니다.
-
codePoint를 pointer가 null이면 null, 아니면 index code point 중 pointer에 해당하는 index jis0208의 값으로 둡니다.
-
codePoint가 null이 아니면, 값이 codePoint인 코드 포인트를 반환합니다.
-
에러 반환
-
-
byte가 ASCII 바이트이거나 0x80이면, 값이 byte인 코드 포인트를 반환합니다.
-
byte가 0xA1~0xDF 범위라면, 값이 0xFF61 − 0xA1 + byte인 코드 포인트를 반환합니다.
-
byte가 0x81~0x9F 또는 0xE0~0xFC 범위라면, Shift_JIS lead에 byte를 설정하고 continue를 반환합니다.
-
에러 반환
12.3.2. Shift_JIS 인코더
Shift_JIS의 인코더의 handler는 unused와 codePoint가 주어졌을 때 다음을 수행합니다:
-
codePoint가 end-of-queue라면, finished를 반환합니다.
-
codePoint가 ASCII 코드 포인트이거나 U+0080이면, 값이 codePoint인 바이트를 반환합니다.
-
codePoint가 U+00A5(¥)라면, 바이트 0x5C을 반환합니다.
-
codePoint가 U+203E(‾)라면, 바이트 0x7E을 반환합니다.
-
codePoint가 U+FF61(。)~U+FF9F(゚) 범위라면, 값이 codePoint − 0xFF61 + 0xA1인 바이트를 반환합니다.
-
codePoint가 U+2212(−)라면, U+FF0D(-)로 설정합니다.
-
pointer를 index Shift_JIS pointer에서 codePoint에 해당하는 값으로 둡니다.
-
pointer가 null이면, 에러를 codePoint와 함께 반환합니다.
-
leading을 pointer / 188로 둡니다.
-
leadingOffset을 leading이 0x1F 미만이면 0x81, 그렇지 않으면 0xC1로 둡니다.
-
trailing을 pointer % 188로 둡니다.
-
offset을 trailing이 0x3F 미만이면 0x40, 그 외에는 0x41로 둡니다.
-
값이 leading + leadingOffset과 trailing + offset인 두 바이트를 반환합니다.
13. 레거시 다중 바이트 한글 인코딩
13.1. EUC-KR
13.1.1. EUC-KR 디코더
EUC-KR의 디코더는 EUC-KR lead라는 바이트 값을 가지며, 초기값은 0x00입니다.
EUC-KR의 디코더의 handler는 ioQueue와 byte가 주어졌을 때 다음을 수행합니다:
-
byte가 end-of-queue이고 EUC-KR lead가 0x00이 아니면, EUC-KR lead를 0x00으로 설정하고 에러를 반환합니다.
-
byte가 end-of-queue이고 EUC-KR lead가 0x00이면, finished를 반환합니다.
-
EUC-KR lead가 0x00이 아니면:
-
leading을 EUC-KR lead로 둡니다.
-
EUC-KR lead를 0x00으로 설정합니다.
-
pointer를 null로 둡니다.
-
byte가 0x41~0xFE 범위라면 pointer를 (leading − 0x81) × 190 + (byte − 0x41)로 설정합니다.
-
codePoint를 pointer가 null이면 null, 아니면 index code point 중 pointer에 해당하는 index EUC-KR의 값으로 둡니다.
-
codePoint가 null이 아니면, 값이 codePoint인 코드 포인트를 반환합니다.
-
에러 반환
-
-
byte가 ASCII 바이트라면, 값이 byte인 코드 포인트를 반환합니다.
-
byte가 0x81~0xFE 범위라면, EUC-KR lead에 byte를 설정하고 continue를 반환합니다.
-
에러 반환
13.1.2. EUC-KR 인코더
EUC-KR의 인코더의 handler는 unused와 codePoint가 주어졌을 때 다음을 수행합니다:
-
codePoint가 end-of-queue라면, finished를 반환합니다.
-
codePoint가 ASCII 코드 포인트라면, 값이 codePoint인 바이트를 반환합니다.
-
pointer를 index pointer에서 codePoint에 해당하는 값으로 index EUC-KR에서 찾습니다.
-
pointer가 null이면, 에러를 codePoint와 함께 반환합니다.
-
leading을 pointer / 190 + 0x81로 둡니다.
-
trailing을 pointer % 190 + 0x41로 둡니다.
-
값이 leading과 trailing인 두 바이트를 반환합니다.
14. 레거시 기타 인코딩
14.1. replacement
replacement 인코딩은 서버와 클라이언트에서 지원되는 인코딩이 불일치할 때 발생하는 특정 공격을 방지하기 위해 존재합니다.
14.1.1. replacement 디코더
replacement의 디코더는 replacement error returned라는 불리언 값을 가지며, 초기값은 false입니다.
replacement의 디코더의 handler는 unused와 byte가 주어졌을 때 다음을 수행합니다:
-
byte가 end-of-queue라면, finished를 반환합니다.
-
replacement error returned가 false라면, replacement error returned를 true로 설정하고 에러를 반환합니다.
-
finished를 반환합니다.
14.2. UTF-16BE/LE 공통 구조
UTF-16BE/LE는 UTF-16BE 또는 UTF-16LE입니다.
14.2.1. 공용 UTF-16 디코더
바이트 오더 마크는 레이블보다 우선하며, 실제 배포된 콘텐츠에서 더 정확한 것으로 나타났습니다. 따라서 공용 UTF-16 디코더 알고리즘의 일부가 아니라 decode 알고리즘의 일부입니다.
공용 UTF-16 디코더는 다음과 연관된 값을 가집니다:
- UTF-16 lead 바이트
- null 또는 바이트, 초기값은 null.
- UTF-16 lead 서러게이트
- null 또는 leading surrogate, 초기값은 null.
- is UTF-16BE 디코더
- 불리언, 초기값은 false.
공용 UTF-16 디코더의 handler는 ioQueue와 byte가 주어졌을 때 다음을 수행합니다:
-
byte가 end-of-queue이고 UTF-16 lead 바이트 또는 UTF-16 lead 서러게이트가 null이 아니면, UTF-16 lead 바이트와 UTF-16 lead 서러게이트를 null로 설정하고 에러를 반환합니다.
-
byte가 end-of-queue이고 UTF-16 lead 바이트와 UTF-16 lead 서러게이트가 모두 null이면, finished를 반환합니다.
-
UTF-16 lead 바이트가 null이면, UTF-16 lead 바이트를 byte로 설정하고 continue를 반환합니다.
-
codeUnit을 다음과 같이 둡니다:
- is UTF-16BE 디코더가 true
-
(UTF-16 lead 바이트 << 8) + byte.
- is UTF-16BE 디코더가 false
-
(byte << 8) + UTF-16 lead 바이트.
-
UTF-16 lead 바이트를 null로 설정합니다.
-
UTF-16 lead 서러게이트가 null이 아니면:
-
leadingSurrogate를 UTF-16 lead 서러게이트로 둡니다.
-
UTF-16 lead 서러게이트를 null로 설정합니다.
-
codeUnit이 trailing surrogate라면, scalar value from surrogates를 leadingSurrogate와 codeUnit을 인수로 하여 반환합니다.
-
byte1을 codeUnit >> 8로 둡니다.
-
byte2를 codeUnit & 0x00FF로 둡니다.
-
bytes를 리스트로, is UTF-16BE 디코더가 true면 byte1, byte2, 아니면 byte2, byte1 두 개의 바이트로 둡니다.
-
-
codeUnit이 leading surrogate라면, UTF-16 lead 서러게이트를 codeUnit으로 설정하고 continue를 반환합니다.
-
codeUnit이 trailing surrogate라면, 에러를 반환합니다.
-
코드 포인트 codeUnit을 반환합니다.
14.3. UTF-16BE
14.3.1. UTF-16BE 디코더
UTF-16BE의 디코더는 공용 UTF-16 디코더이며, is UTF-16BE 디코더가 true로 설정됩니다.
14.4. UTF-16LE
"utf-16
"은 배포된 콘텐츠 호환성을 위해 UTF-16LE의 label입니다.
14.4.1. UTF-16LE 디코더
UTF-16LE의 디코더는 공용 UTF-16 디코더입니다.
14.5. x-user-defined
기술적으로는 단일 바이트 인코딩이지만, 알고리즘적으로 구현이 가능하므로 별도로 정의됩니다.
14.5.1. x-user-defined 디코더
x-user-defined의 디코더의 handler는 unused와 byte가 주어졌을 때 다음을 수행합니다:
-
byte가 end-of-queue라면, finished를 반환합니다.
-
byte가 ASCII 바이트라면, 값이 byte인 코드 포인트를 반환합니다.
-
값이 0xF780 + byte − 0x80인 코드 포인트를 반환합니다.
14.5.2. x-user-defined 인코더
x-user-defined의 인코더의 handler는 unused와 codePoint가 주어졌을 때 다음을 수행합니다:
-
codePoint가 end-of-queue라면, finished를 반환합니다.
-
codePoint가 ASCII 코드 포인트라면, 값이 codePoint인 바이트를 반환합니다.
-
codePoint가 U+F780~U+F7FF 범위에 있다면, 값이 codePoint − 0xF780 + 0x80인 바이트를 반환합니다.
-
에러를 codePoint와 함께 반환합니다.
15. 브라우저 UI
브라우저는 리소스의 인코딩을 재정의하는 기능을 활성화하지 않도록 권장됩니다. 만약 이러한 기능이 존재한다면, 위에서 언급한 보안상의 이유로 UTF-16BE/LE을 옵션으로 제공하지 않아야 합니다. 또한 리소스가 UTF-16BE/LE로 디코딩된 경우에는 이 기능을 비활성화해야 합니다.
구현 관련 고려사항
이 표준의 인코딩에 대한 디코더는 임의의 I/O 큐와 복원 기능을 지원하는 대신 다음과 같이 구현할 수 있습니다:
-
현재 바이트를 읽지 않은 상태로 되돌리는 기능.
-
gb18030(ASCII 바이트)와 ISO-2022-JP(0x24 또는 0x28)를 위한 단일 바이트 버퍼.
gb18030에서 gb18030 third가 0x00이 아닐 때 잘못된 바이트를 만난 경우, gb18030 second를 단일 바이트 버퍼로 옮겨 다음에 반환하고, gb18030 third가 새 gb18030 first가 되며, 단일 바이트 버퍼가 반환되어 비워진 후 0x00이 아님을 체크할 수 있습니다. gb18030에서 첫 번째와 세 번째 바이트의 범위가 동일하기 때문에 가능합니다.
ISO-2022-JP 인코더는 추가 상태로 ISO-2022-JP 인코더 상태가 필요하지만, 이 표준의 나머지 인코더들은 별도의 추가 상태나 버퍼가 필요하지 않습니다.
감사의 글
수년에 걸쳐 인코딩의 상호운용성을 향상시키고 이 표준의 목표 달성에 기여해주신 많은 분들이 계셨습니다. 또한, 이 표준을 오늘날의 모습으로 만드는데 도움을 주신 많은 분들께도 감사드립니다.
감사의 마음을 전합니다. Adam Rice, Alan Chaney, Alexander Shtuchkin, Allen Wirfs-Brock, Andreu Botella, Aneesh Agrawal, Arkadiusz Michalski, Asmus Freytag, Ben Noordhuis, Bnaya Peretz, Boris Zbarsky, Bruno Haible, Cameron McCormack, Charles McCathieNeville, Christopher Foo, CodifierNL, David Carlisle, Domenic Denicola, Dominique Hazaël-Massieux, Doug Ewell, Erik van der Poel, 譚永鋒 (Frank Yung-Fong Tang), Glenn Maynard, Gordon P. Hemsley, Henri Sivonen, Ian Hickson, J. King, James Graham, Jeffrey Yasskin, John Tamplin, Joshua Bell, 村井純 (Jun Murai), 신정식 (Jungshik Shin), Jxck, 강 성훈 (Kang Seonghoon), 川幡太一 (Kawabata Taichi), Ken Lunde, Ken Whistler, Kenneth Russell, 田村健人 (Kent Tamura), Leif Halvard Silli, Luke Wagner, Maciej Hirsz, Makoto Kato, Mark Callow, Mark Crispin, Mark Davis, Martin Dürst, Masatoshi Kimura, Mattias Buelens, Ms2ger, Nigel Megitt, Nigel Tao, Norbert Lindenberg, Øistein E. Andersen, Peter Krefting, Philip Jägenstedt, Philip Taylor, Richard Ishida, Robbert Broersma, Robert Mustacchi, Ryan Dahl, Sam Sneddon, Shawn Steele, Simon Montagu, Simon Pieters, Simon Sapin, Stephen Checkoway, 寺田健 (Takeshi Terada), Vyacheslav Matva, Wolf Lammen, 그리고 成瀬ゆい (Yui Naruse) 여러분의 훌륭한 기여에 깊이 감사드립니다.
이 표준은 Anne van Kesteren (Apple, annevk@annevk.nl)가 집필하였습니다. API 장은 Joshua Bell (Google)이 초안을 작성하였습니다.
지적 재산권
Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). 이 저작물은 Creative Commons Attribution 4.0 International License에 따라 라이선스가 부여됩니다. 일부가 소스 코드에 통합되는 경우, 해당 부분은 BSD 3-Clause License가 적용됩니다.
이 문서는 현행 표준입니다. 특허 검토 버전을 원하는 경우 현행 표준 검토 초안을 참고하세요.