바이트 문자열

바이트 문자열 (Byte Strings)

Racket Guide의 Bytes and Byte Strings 문서가 바이트 문자열을 소개하고 있어요. 바이트 문자열은 바이트들의 고정 길이 배열이고, 바이트는 0 이상 255 이하의 정확한 정수(exact integer)예요.

출처: Racket Reference

본문

4.5 바이트 문자열

바이트 문자열은 가변(mutable)일 수도 있고 불변(immutable)일 수도 있어요. 불변 바이트 문자열을 bytes-set! 같은 프로시저에 주면 exn:fail:contract 예외가 발생해요. 기본 리더(Reading Strings 참고)가 생성하는 바이트 문자열 상수는 불변이고, read-syntax 모드에서는 intern돼요. 바이트 문자열이 불변인지 확인하려면 immutable?를 쓰세요.

두 바이트 문자열이 같은 길이를 갖고 같은 바이트 시퀀스를 담고 있으면 equal?예요.

바이트 문자열은 단일 값 시퀀스로 쓸 수 있어요(Sequences 참고). 문자열의 바이트들이 시퀀스의 원소가 돼요. in-bytes도 함께 보세요.

바이트 문자열 읽기에 대해서는 Reading Strings, 출력에 대해서는 Printing Strings를 참고하세요. immutable?도 함께 보세요.

4.5.1 바이트 문자열 생성자, 선택자, 뮤테이터

(bytes? v) → boolean?
  v : any/c

v가 바이트 문자열이면 #t, 그렇지 않으면 #f를 반환해요. immutable-bytes?mutable-bytes?도 함께 보세요.

> (bytes? #"Apple")
#t
> (bytes? "Apple")
#f
(make-bytes k [b]) → bytes?
  k : exact-nonnegative-integer?
  b : byte? = 0

길이 k의 새 가변 바이트 문자열을 반환하는데, 각 위치가 바이트 b로 초기화돼요.

> (make-bytes 5 65)
#"AAAAA"
(bytes b ...) → bytes?
  b : byte?

길이가 제공된 b들의 개수이고, 위치들이 주어진 b로 초기화된 새 가변 바이트 문자열을 반환해요.

> (bytes 65 112 112 108 101)
#"Apple"
(bytes->immutable-bytes bstr) → (and/c bytes? immutable?)
  bstr : bytes?

bstr과 같은 내용의 불변 바이트 문자열을 반환해요. bstr이 이미 불변이면 bstr 자체를 반환해요.

> (bytes->immutable-bytes (bytes 65 65 65))
#"AAA"
> (define b (bytes->immutable-bytes (make-bytes 5 65)))
> (bytes->immutable-bytes b)
#"AAAAA"
> (eq? (bytes->immutable-bytes b) b)
#t
(byte? v) → boolean?
  v : any/c

v가 바이트(즉 0 이상 255 이하의 정확한 정수)이면 #t, 그렇지 않으면 #f를 반환해요.

> (byte? 65)
#t
> (byte? 0)
#t
> (byte? 256)
#f
> (byte? -1)
#f
(bytes-length bstr) → exact-nonnegative-integer?
  bstr : bytes?

bstr의 길이를 반환해요.

> (bytes-length #"Apple")
5
(bytes-ref bstr k) → byte?
  bstr : bytes?
  k : exact-nonnegative-integer?

bstr의 위치 k에 있는 바이트를 반환해요. 바이트 문자열의 첫 위치가 0에 해당하므로 k는 바이트 문자열의 길이보다 작아야 하고, 그렇지 않으면 exn:fail:contract 예외가 발생해요.

> (bytes-ref #"Apple" 0)
65
(bytes-set! bstr k b) → void?
  bstr : (and/c bytes? (not/c immutable?))
  k : exact-nonnegative-integer?
  b : byte?

bstr의 위치 k에 있는 바이트를 b로 바꿔요. 첫 위치가 0에 해당하므로 k는 바이트 문자열의 길이보다 작아야 하고, 그렇지 않으면 exn:fail:contract 예외가 발생해요.

> (define s (bytes 65 112 112 108 101))
> (bytes-set! s 4 121)
> s
#"Apply"
(subbytes bstr start [end]) → bytes?
  bstr : bytes?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer? = (bytes-length str)

(- end start) 바이트 길이이고 bstrstart(포함)부터 end(미포함)까지와 같은 바이트를 담는 새 가변 바이트 문자열을 반환해요. startend 인자는 bstr의 길이보다 작거나 같아야 하고, endstart보다 크거나 같아야 하며, 그렇지 않으면 exn:fail:contract 예외가 발생해요.

> (subbytes #"Apple" 1 3)
#"pp"
> (subbytes #"Apple" 1)
#"pple"
(bytes-copy bstr) → bytes?
  bstr : bytes?

(subbytes bstr 0)을 반환해요.

(bytes-copy! dest dest-start src [src-start src-end]) → void?
  dest : (and/c bytes? (not/c immutable?))
  dest-start : exact-nonnegative-integer?
  src : bytes?
  src-start : exact-nonnegative-integer? = 0
  src-end : exact-nonnegative-integer? = (bytes-length src)

destdest-start 위치부터 시작하는 바이트들을 srcsrc-start(포함)부터 src-end(미포함)까지의 바이트와 일치하도록 바꿔요. destsrc는 같은 바이트 문자열일 수 있고, 그 경우 목적지 영역이 소스 영역과 겹칠 수 있어요. 복사 후의 목적지 바이트들은 복사 전의 소스 바이트들과 일치해요. dest-start, src-start, src-end 중 어느 하나라도 범위를 벗어나면(바이트 문자열의 크기와 소스·목적지 영역을 고려해서), exn:fail:contract 예외가 발생해요.

> (define s (bytes 65 112 112 108 101))
> (bytes-copy! s 4 #"y")
> (bytes-copy! s 0 s 3 4)
> s
#"lpply"
(bytes-fill! dest b) → void?
  dest : (and/c bytes? (not/c immutable?))
  b : byte?

dest의 모든 위치를 b로 채워요.

> (define s (bytes 65 112 112 108 101))
> (bytes-fill! s 113)
> s
#"qqqqq"
(bytes-append bstr ...) → bytes?
  bstr : bytes?

주어진 bstr들의 길이 합만큼 길고, 주어진 bstr들의 바이트를 이어 붙인 새 가변 바이트 문자열을 반환해요. bstr이 주어지지 않으면 결과는 길이 0인 바이트 문자열이에요.

> (bytes-append #"Apple" #"Banana")
#"AppleBanana"
(bytes->list bstr) → (listof byte?)
  bstr : bytes?

bstr의 내용에 해당하는 바이트들의 새 리스트를 반환해요. 즉 리스트의 길이는 (bytes-length bstr)이고, bstr의 바이트 시퀀스가 결과 리스트의 시퀀스와 같아요.

> (bytes->list #"Apple")
'(65 112 112 108 101)
(list->bytes lst) → bytes?
  lst : (listof byte?)

lst의 바이트 리스트를 내용으로 하는 새 가변 바이트 문자열을 반환해요. 즉 바이트 문자열의 길이는 (length lst)이고, lst의 바이트 시퀀스가 결과 바이트 문자열의 시퀀스와 같아요.

> (list->bytes (list 65 112 112 108 101))
#"Apple"
(make-shared-bytes k [b]) → bytes?
  k : exact-nonnegative-integer?
  b : byte? = 0

길이 k의 새 가변 바이트 문자열을 반환하는데, 각 위치가 바이트 b로 초기화돼요. place들 사이의 통신을 위해 새 바이트 문자열이 공유 메모리 공간에 할당돼요.

> (make-shared-bytes 5 65)
#"AAAAA"
(shared-bytes b ...) → bytes?
  b : byte?

길이가 제공된 b들의 개수이고, 위치들이 주어진 b로 초기화된 새 가변 바이트 문자열을 반환해요. place들 사이의 통신을 위해 새 바이트 문자열이 공유 메모리 공간에 할당돼요.

> (shared-bytes 65 112 112 108 101)
#"Apple"

4.5.2 바이트 문자열 비교

(bytes=? bstr1 bstr2 ...) → boolean?
  bstr1 : bytes?
  bstr2 : bytes?

모든 인자가 eqv?이면 #t를 반환해요.

> (bytes=? #"Apple" #"apple")
#f
> (bytes=? #"a" #"as" #"a")
#f

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

(bytes<? bstr1 bstr2 ...) → boolean?
  bstr1 : bytes?
  bstr2 : bytes?

인자들이 사전식(lexicographic)으로 증가 순으로 정렬되어 있으면 #t를 반환해요. 개별 바이트들은 <로 정렬돼요. 그렇지 않으면 #f.

> (bytes<? #"Apple" #"apple")
#t
> (bytes<? #"apple" #"Apple")
#f
> (bytes<? #"a" #"b" #"c")
#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

(bytes>? bstr1 bstr2 ...) → boolean?
  bstr1 : bytes?
  bstr2 : bytes?

bytes<?와 같지만, 인자들이 감소 순인지 검사해요.

> (bytes>? #"Apple" #"apple")
#f
> (bytes>? #"apple" #"Apple")
#t
> (bytes>? #"c" #"b" #"a")
#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

4.5.3 문자와의 상호 변환, 디코딩과 인코딩

(bytes->string/utf-8 bstr [err-char start end]) → string?
  bstr : bytes?
  err-char : (or/c #f char?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)

bstrstart부터 end까지 부분 문자열을 Unicode 코드 포인트의 UTF-8 인코딩으로 디코딩해 문자열을 만들어요. err-char#f가 아니면, 유효한 인코딩 시퀀스의 일부가 아닌 128255 범위의 바이트에 사용돼요(이 규칙은 포트에서 문자를 읽는 것과 일치해요. 상세는 Encodings and Locales 참고). err-char#f이고 bstrstartend 부분 문자열이 전체적으로 유효한 UTF-8 인코딩이 아니면 exn:fail:contract 예외가 발생해요.

> (bytes->string/utf-8 (bytes 195 167 195 176 195 182 194 163))
"çðö£"
(bytes->string/locale bstr [err-char start end]) → string?
  bstr : bytes?
  err-char : (or/c #f char?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)

bstrstart부터 end까지 부분 문자열을 현재 로케일의 인코딩(Encodings and Locales 함께 보기)으로 디코딩해 문자열을 만들어요. err-char#f가 아니면 유효한 인코딩의 일부가 아닌 각 바이트에 사용돼요. err-char#f이고 bstrstart~end 부분 문자열이 전체적으로 유효한 인코딩이 아니면 exn:fail:contract 예외가 발생해요.

(bytes->string/latin-1 bstr [err-char start end]) → string?
  bstr : bytes?
  err-char : (or/c #f char?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)

bstrstart부터 end까지 부분 문자열을 Unicode 코드 포인트의 Latin-1 인코딩으로 디코딩해 문자열을 만들어요. 즉 각 바이트가 integer->char로 직접 문자로 변환되므로 디코딩은 항상 성공해요. err-char 인자는 무시되지만 다른 연산들과 일관성을 위해 존재해요.

> (bytes->string/latin-1 (bytes 254 211 209 165))
"þÓÑ¥"
(string->bytes/utf-8 str [err-byte start end]) → bytes?
  str : string?
  err-byte : (or/c #f byte?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)

strstart부터 end까지 부분 문자열을 UTF-8로 인코딩해(항상 성공) 바이트 문자열을 만들어요. err-byte 인자는 무시되지만 다른 연산들과의 일관성을 위해 포함돼요.

> (define b
    (bytes->string/utf-8
     (bytes 195 167 195 176 195 182 194 163)))
> (string->bytes/utf-8 b)
#"\303\247\303\260\303\266\302\243"
> (bytes->string/utf-8 (string->bytes/utf-8 b))
"çðö£"
(string->bytes/locale str [err-byte start end]) → bytes?
  str : string?
  err-byte : (or/c #f byte?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)

strstart부터 end까지 부분 문자열을 현재 로케일의 인코딩(Encodings and Locales 함께 보기)으로 인코딩해 문자열을 만들어요. err-byte#f가 아니면 현재 로케일로 인코딩할 수 없는 각 문자에 사용돼요. err-byte#f이고 strstart~end 부분 문자열을 인코딩할 수 없으면 exn:fail:contract 예외가 발생해요.

(string->bytes/latin-1 str [err-byte start end]) → bytes?
  str : string?
  err-byte : (or/c #f byte?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)

strstart부터 end까지 부분 문자열을 Latin-1로 인코딩해 문자열을 만들어요. 즉 각 문자는 char->integer로 직접 바이트로 변환돼요. err-byte#f가 아니면 값이 255보다 큰 str의 각 문자에 사용돼요. err-byte#f이고 strstart~end 부분 문자열에 값이 255보다 큰 문자가 있으면 exn:fail:contract 예외가 발생해요.

> (define b
    (bytes->string/latin-1 (bytes 254 211 209 165)))
> (string->bytes/latin-1 b)
#"\376\323\321\245"
> (bytes->string/latin-1 (string->bytes/latin-1 b))
"þÓÑ¥"
(string-utf-8-length str [start end]) → exact-nonnegative-integer?
  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)

strstart부터 end까지 부분 문자열의 UTF-8 인코딩 길이를 바이트 단위로 반환하되, 실제로 인코딩된 바이트를 생성하지는 않아요.

> (string-utf-8-length
    (bytes->string/utf-8 (bytes 195 167 195 176 195 182 194 163)))
8
> (string-utf-8-length "hello")
5
(bytes-utf-8-length bstr [err-char start end])
 → (or/c exact-nonnegative-integer? #f)
  bstr : bytes?
  err-char : (or/c #f char?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)

bstrstart부터 end까지 부분 문자열의 UTF-8 디코딩 길이를 문자 단위로 반환하되, 실제로 디코딩된 문자를 생성하지는 않아요. err-char#f이고 부분 문자열이 전체적으로 UTF-8 인코딩이 아니면 결과는 #f예요. 그 외에는 err-charbytes->string/utf-8에서처럼 디코딩 오류를 해결하는 데 쓰여요.

> (bytes-utf-8-length (bytes 195 167 195 176 195 182 194 163))
4
> (bytes-utf-8-length (make-bytes 5 65))
5
(bytes-utf-8-ref bstr skip [err-char start end]) → (or/c char? #f)
  bstr : bytes?
  skip : exact-nonnegative-integer?
  err-char : (or/c #f char?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)

bstrstart부터 end까지 부분 문자열의 UTF-8 디코딩에서 skip번째 문자를 반환하되, 다른 디코딩된 문자를 생성하지는 않아요. 부분 문자열이 skip번째 문자까지 UTF-8 인코딩이 아니거나(err-char#f일 때), 부분 문자열 디코딩이 skip보다 적은 문자를 만들면 결과는 #f예요. err-char#f가 아니면 bytes->string/utf-8에서처럼 디코딩 오류를 해결하는 데 쓰여요.

> (bytes-utf-8-ref (bytes 195 167 195 176 195 182 194 163) 0)
#\ç
> (bytes-utf-8-ref (bytes 195 167 195 176 195 182 194 163) 1)
#\ð
> (bytes-utf-8-ref (bytes 195 167 195 176 195 182 194 163) 2)
#\ö
> (bytes-utf-8-ref (bytes 65 66 67 68) 0)
#\A
> (bytes-utf-8-ref (bytes 65 66 67 68) 1)
#\B
> (bytes-utf-8-ref (bytes 65 66 67 68) 2)
#\C
(bytes-utf-8-index bstr skip [err-char start end])
 → (or/c exact-nonnegative-integer? #f)
  bstr : bytes?
  skip : exact-nonnegative-integer?
  err-char : (or/c #f char?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)

bstrstart부터 end까지 부분 문자열의 UTF-8 디코딩에서 skip번째 문자의 인코딩이 시작되는 bstr 안의 바이트 오프셋을 반환해요(다른 디코딩된 문자는 생성하지 않음). 결과는 start가 아니라 bstr의 시작을 기준으로 해요. 부분 문자열이 skip번째 문자까지 UTF-8 인코딩이 아니거나(err-char#f일 때), 부분 문자열 디코딩이 skip보다 적은 문자를 만들면 결과는 #f예요. err-char#f가 아니면 bytes->string/utf-8에서처럼 디코딩 오류를 해결하는 데 쓰여요.

> (bytes-utf-8-index (bytes 195 167 195 176 195 182 194 163) 0)
0
> (bytes-utf-8-index (bytes 195 167 195 176 195 182 194 163) 1)
2
> (bytes-utf-8-index (bytes 195 167 195 176 195 182 194 163) 2)
4
> (bytes-utf-8-index (bytes 65 66 67 68) 0)
0
> (bytes-utf-8-index (bytes 65 66 67 68) 1)
1
> (bytes-utf-8-index (bytes 65 66 67 68) 2)
2

4.5.4 바이트 대 바이트 인코딩 변환

(bytes-open-converter from-name to-name)
 → (or/c bytes-converter? #f)
  from-name : string?
  to-name : string?

from-name이 이름 붙인 인코딩에서 to-name이 이름 붙인 인코딩으로 가는 바이트 변환기를 만들어요. 요청한 변환 쌍을 쓸 수 없으면 변환기 대신 #f를 반환해요.

다음 인코딩 조합은 항상 이용 가능해요:

  • (bytes-open-converter "UTF-8" "UTF-8") — 항등 변환이되, 입력의 인코딩 오류는 디코딩 실패로 이어져요.
  • (bytes-open-converter "UTF-8-permissive" "UTF-8") — 항등 변환이되, 유효한 인코딩 시퀀스의 일부가 아닌 입력 바이트는 #\uFFFD의 UTF-8 인코딩 시퀀스로 사실상 대체돼요. (이런 무효 시퀀스 처리는 포트 바이트 스트림을 문자로 해석하는 것과 일치해요. Ports 참고.)
  • (bytes-open-converter "" "UTF-8") — 현재 로케일의 기본 인코딩(Encodings and Locales 참고)에서 UTF-8로 변환해요.
  • (bytes-open-converter "UTF-8" "") — UTF-8에서 현재 로케일의 기본 인코딩(Encodings and Locales 참고)으로 변환해요.
  • (bytes-open-converter "platform-UTF-8" "platform-UTF-16") — Unix와 Mac OS에서 UTF-8을 UTF-16으로 변환하는데, 각 UTF-16 코드 유닛은 현재 플랫폼의 엔디언(endianness)으로 정렬되는 두 바이트의 시퀀스예요. Windows에서는 짝 없는 서로게이트 코드 유닛을 지원하기 위해 (bytes-open-converter "WTF-8" "WTF-16")과 동일해요.
  • (bytes-open-converter "platform-UTF-8-permissive" "platform-UTF-16")(bytes-open-converter "platform-UTF-8" "platform-UTF-16")과 같지만, 유효한 UTF-8 인코딩 시퀀스(또는 Windows에서 짝 없는 서로게이트 확장에 유효한)의 일부가 아닌 입력 바이트가 #\uFFFD로 사실상 대체돼요.
  • (bytes-open-converter "platform-UTF-16" "platform-UTF-8") — Unix와 Mac OS에서 UTF-16(현재 플랫폼의 엔디언으로 정렬된 바이트)을 UTF-8로 변환해요. Windows에서는 짝 없는 서로게이트를 지원하기 위해 (bytes-open-converter "WTF-16" "WTF-8")과 동일해요. Unix와 Mac OS에서 서로게이트는 짝을 이루는 것으로 가정돼요. #xD800 비트를 가진 바이트 쌍이 서로게이트 쌍을 시작하고, 그 쌍과 다음 쌍에서 #x03FF 비트가 사용돼요(#xDC00 비트의 값과 무관). 모든 플랫폼에서 입력 바이트 문자열의 홀수 오프셋에서 디코딩하면 성능이 나빠질 수 있어요.
  • (bytes-open-converter "WTF-8" "WTF-16") — UTF-8의 WTF-8 [Sapin18] 상위집합을 짝 없는 서로게이트 코드 유닛을 지원하는 UTF-16의 상위집합으로 변환하는데, 각 UTF-16 코드 유닛은 현재 플랫폼의 엔디언으로 정렬되는 두 바이트의 시퀀스예요.
  • (bytes-open-converter "WTF-8-permissive" "WTF-16")(bytes-open-converter "WTF-8" "WTF-16")과 같지만, 유효한 WTF-8 인코딩 시퀀스의 일부가 아닌 입력 바이트가 #\uFFFD로 사실상 대체돼요.
  • (bytes-open-converter "WTF-16" "WTF-8") — UTF-16의 WTF-16 [Sapin18] 상위집합을 UTF-8의 WTF-8 상위집합으로 변환해요. 입력은 짝 없는 서로게이트인 UTF-16 코드 유닛을 포함할 수 있고, 대응하는 출력은 UTF-8의 자연스러운 확장으로 각 서로게이트의 인코딩을 포함해요.

새로 열린 바이트 변환기는 현재 custodian(Custodians 참고)에 등록되어, custodian이 종료될 때 변환기가 닫혀요. 변환기가 ""을 포함하지 않는 보장된 조합 중 하나(Unix)이거나, Windows와 Mac OS에서 보장된 조합( "" 포함) 중 하나라면 custodian에 등록되지 않아요(그리고 닫을 필요도 없어요).

Windows용 Racket 소프트웨어 배포판에서 적절한 "iconv.dll""libmzschVERS.dll"과 함께 포함돼요. 이용 가능한 인코딩과 조합의 집합은 설치된 iconv 라이브러리에 따라 플랫폼마다 달라져요. from-nameto-name 인자는 iconv_open으로 전달돼요. Windows에서 "iconv.dll" 또는 "libiconv.dll"은 실행 시 "libmzschVERS.dll"(VERS는 버전 번호)과 같은 디렉터리, 사용자 경로, 시스템 디렉터리, 또는 현재 실행 파일의 디렉터리에 있어야 하고, DLL은 _errno를 제공하거나 _errno를 위해 "msvcrt.dll"에 링크해야 해요. 그렇지 않으면 보장된 조합만 이용 가능해요. 바이트 문자열을 변환하려면 결과와 함께 bytes-convert를 쓰세요.

Changed in version 7.9.0.17 of package base: Added built-in converters for "WTF-8", "WTF-8-permissive", and "WTF-16".

(bytes-close-converter converter) → void
  converter : bytes-converter?

주어진 변환기를 닫아서, 더 이상 bytes-convertbytes-convert-end와 함께 쓸 수 없게 해요.

(bytes-convert converter src-bstr [src-start-pos src-end-pos
                                  dest-bstr dest-start-pos dest-end-pos])
 → (or/c bytes? exact-nonnegative-integer?)
    exact-nonnegative-integer?
    (or/c 'complete 'continues 'aborts 'error)
  converter : bytes-converter?
  src-bstr : bytes?
  src-start-pos : exact-nonnegative-integer? = 0
  src-end-pos : exact-nonnegative-integer? = (bytes-length src-bstr)
  dest-bstr : (or/c bytes? #f) = #f
  dest-start-pos : exact-nonnegative-integer? = 0
  dest-end-pos : (or/c exact-nonnegative-integer? #f) = (and dest-bstr (bytes-length dest-bstr))

src-bstrsrc-start-pos부터 src-end-pos까지 바이트를 변환해요. dest-bstr#f가 아니면 변환된 바이트는 dest-bstrdest-start-pos부터 dest-end-pos까지에 기록돼요. dest-bstr#f면 새로 할당된 바이트 문자열이 변환 결과를 담는데, dest-end-pos#f가 아니면 결과 바이트 문자열의 크기는 (- dest-end-pos dest-start-pos)를 넘지 않아요.

bytes-convert의 결과는 세 값이에요:

  • result-bstr 또는 dest-wrote-amtdest-bstr#f이거나 제공되지 않으면 바이트 문자열, 그렇지 않으면 dest-bstr에 기록된 바이트 수예요.
  • src-read-amtsrc-bstr에서 성공적으로 변환된 바이트 수예요.
  • 'complete, 'continues, 'aborts, 'error — 변환이 어떻게 끝났는지 나타내요:
    • 'complete: 입력 전체가 처리됐고, src-read-amt(- src-end-pos src-start-pos)와 같아요.
    • 'continues: 결과 크기 제한이나 dest-bstr의 공간 때문에 변환이 멈췄어요. 이 경우 src-bstr의 다음 완전한 인코딩 시퀀스를 처리하는 데 더 많은 공간이 필요하면 (- dest-end-pos dest-start-pos)보다 적은 바이트가 반환될 수 있어요.
    • 'aborts: 입력이 인코딩 시퀀스 중간에 멈췄고, 계속하려면 더 많은 입력 바이트가 필요해요. 예를 들어 "UTF-8-permissive" 디코딩에서 입력의 마지막 바이트가 195이면 결과는 'aborts예요. 195 바이트를 어떻게 쓰는지 결정하려면 다른 바이트가 필요하기 때문이죠.
    • 'error: src-bstr(+ src-start-pos src-read-amt) 바이트에서 시작하는 바이트들이 유효한 인코딩 시퀀스를 이루지 못해요. 이 결과는 일부 인코딩에서는(모든 바이트 시퀀스가 유효한 인코딩인 곳) 절대 만들어지지 않아요. 예를 들어 "UTF-8-permissive"는 문자를 버리거나 "?"를 만들어 무효한 UTF-8 시퀀스를 처리하므로, 사실상 모든 바이트 시퀀스가 유효해요.

변환기를 적용하면 스트림 안의 모드를 바꾸는 "시프트 시퀀스"를 포함하는 변환에서만, 변환기에 상태가 축적돼요(bytes-convert의 세 번째 결과가 'complete일 때도). 이 상태는 입력의 추가 처리와 출력의 추가 생성 모두에 영향을 줄 수 있어요. 입력 시퀀스를 종료하고 변환기를 재설정하려면 bytes-convert-end를 쓰세요.

> (define convert (bytes-open-converter "UTF-8" "UTF-16"))
> (bytes-convert convert (bytes 65 66 67 68))
#"\376\377\0A\0B\0C\0D"
4
'complete
> (bytes 195 167 195 176 195 182 194 163)
#"\303\247\303\260\303\266\302\243"
> (bytes-convert convert (bytes 195 167 195 176 195 182 194 163))
#"\0\347\0\360\0\366\0\243"
8
'complete
> (bytes-close-converter convert)
(bytes-convert-end converter [dest-bstr dest-start-pos dest-end-pos])
 → (or/c bytes? exact-nonnegative-integer?)
    (or/c 'complete 'continues)
  converter : bytes-converter?
  dest-bstr : (or/c bytes? #f) = #f
  dest-start-pos : exact-nonnegative-integer? = 0
  dest-end-pos : (or/c exact-nonnegative-integer? #f) = (and dest-bstr (bytes-length dest-bstr))

bytes-convert와 같지만, 바이트를 변환하는 대신 이 프로시저는 (있다면) 변환의 종료 시퀀스(때로 "시프트 시퀀스"라 불림)를 생성해요. 시프트 시퀀스를 쓰는 인코딩은 드물어서, 대부분의 인코딩에서 이 함수는 출력 없이 성공해요. 어쨌든 (어쩌면 빈) 시프트 시퀀스의 성공적인 출력은 변환기를 초기 상태로 재설정해요.

bytes-convert-end의 결과는 두 값이에요:

  • result-bstr 또는 dest-wrote-amtdest-bstr#f이거나 제공되지 않으면 바이트 문자열, 그렇지 않으면 dest-bstr에 기록된 바이트 수예요.
  • 'complete 또는 'continues — 변환이 완료됐는지 나타내요. 'complete이면 완전한 종료 시퀀스가 생성됐어요. 'continues이면 결과 크기 제한이나 dest-bstr의 공간 때문에 변환이 완료될 수 없었고, 첫 결과는 빈 바이트 문자열이거나 0이에요.
(bytes-converter? v) → boolean?
  v : any/c

vbytes-open-converter가 만든 바이트 변환기이면 #t, 그렇지 않으면 #f를 반환해요.

> (bytes-converter? (bytes-open-converter "UTF-8" "UTF-16"))
#t
> (bytes-converter? (bytes-open-converter "whacky" "not likely"))
#f
> (define b (bytes-open-converter "UTF-8" "UTF-16"))
> (bytes-close-converter b)
> (bytes-converter? b)
#t
(locale-string-encoding) → any

현재 로케일의 인코딩(즉 보통 ""로 식별되는 인코딩)에 대한 문자열을 반환해요. system-language+country도 함께 보세요.

4.5.5 추가 바이트 문자열 함수

이 섹션의 바인딩들은 racket/bytes(package: base)와 racket 라이브러리에서 제공되지만 racket/base에서는 제공되지 않아요.

(bytes-append* str ... strs) → bytes?
  str : bytes?
  strs : (listof bytes?)

bytes-append와 같지만, 마지막 인자를 bytes-append의 인자 리스트로 사용하므로, (bytes-append* str ... strs)(apply bytes-append str ... strs)와 같아요. 즉 bytes-appendbytes-append*의 관계는 listlist*의 관계와 비슷해요.

> (bytes-append* #"a" #"b" '(#"c" #"d"))
#"abcd"
> (bytes-append* (cdr (append* (map (lambda (x) (list #", " x))
                                     '(#"Alpha" #"Beta" #"Gamma")))))
#"Alpha, Beta, Gamma"
(bytes-join strs sep) → bytes?
  strs : (listof bytes?)
  sep : bytes?

strs의 바이트 문자열들을 이어 붙이고, 각 바이트 쌍 사이에 sep을 끼워 넣어요. 새 가변 바이트 문자열이 반환돼요.

> (bytes-join '(#"one" #"two" #"three" #"four") #" potato ")
#"one potato two potato three potato four"

더 알아보기