Pack200: 팩 된 클래스 어카이브(archive)의 스펙 - xrath.com 에서 번역됨

## Pack200: Javatm 어플리케이션용의 팩 된 클래스 배치 형식

### JSR-200 공개 드래프트 스펙

## 목차

- 1. 처음에
- 2. 어카이브(archive)의 입력
- 3. archive파일 구조의 개요
- 4. 정수 encode의 개요

- 4.1. 정수 encode schema

- 5. 밴드의 정의

- 5.1. 어카이브(archive)의 분할
- 5.2. 어카이브(archive) 헤더

- 5.2. 1. 어카이브(archive) 옵션과 파일 프로퍼티
- 5.2. 2. 어카이브(archive)의 엔티티수와 클래스 형식

- 5.3. 정수 풀

- 5.3. 1. 스칼라 정수
- 5.3. 2. Utf8 정수
- 5.3. 3. 형태의 시그니챠
- 5.3. 4. 타풀 정수

- 5.4. 파일의 속성
- 5.5. 플래그와 속성

- 5.5. 1. 속성에의 flag bit의 할당
- 5.5. 2. 속성 레이아웃의 정의
- 5.5. 3. 재귀적인 레이아웃
- 5.5. 4. 디폴트의 속성 레이아웃
- 5.5. 5. 스택 맵의 레이아웃
- 5.5. 6. 메타데이타의 레이아웃
- 5.5. 7. 예외적인 레이아웃의 사용 방법

- 5.6. 원시 파일의 생략 표기
- 5.7. 상자의 클래스
- 5.8. 클래스 schema
- 5.9. 속성 밴드

- 5.9. 1. 메타데이타의 전송

- 5.10. 바이트 코드 명령

- 6. 밴드 코딩의 스펙

- 6.1. 주어진수의 encode

- 6.1. 1. 복수 코딩의 방식
- 6.1. 2. 바이트 순서의 encode의 정의
- 6.1. 3. 복호화 한 자연수치의 정의

- 6.2. 부호 첨부 정수의 encode

- 6.2. 1. 부호 변환의 상세

- 6.3. 코딩의 속성
- 6.4. 상관관계가 있는 순서의 encode
- 6.5. 상관관계가 없는 값의 encode

- 6.5. 1. 우선 순위의 비싼 값의 겉(표)
- 6.5. 2. 토큰의 순서
- 6.5. 3. 비우선치의 순서

- 6.6. 적응형의 encode
- 6.7. 메타 encode

- 6.7. 1. 코딩 지정자의 구조
- 6.7. 2. 코딩 지정자의 시멘틱스
- 6.7. 3. 코딩 지정자의 메타 encode
- 6.7. 4. 정규의 BHSD 코딩

- 7. 압축 해제 프로그램의 출력의 안정성

- 7.1. 속성 리스트의 순서
- 7.2. 정수 풀의 순서

- 8. 부록

- 8.1. 부록: 밴드의 리스트
- 8.2. 부록: 의사 코드의 예

- 8.2. 1. `cp_Utf8` 정수 풀의 표현
- 8.2. 2. `cp_Signature` 정수 풀의 표현
- 8.2. 3. 바이트 오프셋(offset)의 표현
- 8.2. 4. 예측 가능한 상자의 클래스명의 표현

- 8.3. 부록: 설계에 관한 FAQ

- 8.3. 1. 일반적인 질문

## 1. 처음에

이 문서에서는, Pack200 로 불리는 어카이브(archive) 형식의 스펙을 기술합니다. 이 어카이브(archive) 형식은, Javatm 프로그램 언어로 작성된 어플리케이션에 맞추어 최적화되고 있습니다. 일반적으로, 이러한 어플리케이션은 클래스 컬렉션으로서 배포되어 관련하는 resource file가 부속되어 있는 경우도 있습니다.

이 형식을 사용하면(자), 1 으로부터 수십만까지의 임의의 수의 Java 클래스를 압축 프로그램으로 encode 하는 것, 단일의 바이트 블록으로 컴팩트하게 전송 하는 것, 및 압축 해제 프로그램으로 복호화 해 동등의 Java 클래스 파일로 변환할 수가 있습니다. 또, 클래스의 resource file나 다른 부차적 파일을 나타낼 수도 있으므로, 일부의 배치 작업, 특히 Java 어플리케이션의 다운로드에서는, JAR 어카이브(archive) 대신에 사용할 수 있습니다.

Pack200 형식에서는, 압축되어 있지 않은 ( 「포함되었다」) 클래스 파일을 포함하고 있는 동등의 JAR 파일과 비교해, Java 어플리케이션의 사이즈를 7 배에서 9 배 축소할 수 있습니다. 이것에 대해, JAR 어카이브(archive)나 ZIP 어카이브(archive)에 짜넣어지고 있는 zip DEFLATE 알고리즘을 사용하면(자), 얻을 수 있는 압축율은 2 배가 됩니다. SDK 다운로드의 배치에 이전 사용되고 있던 문서화되어 있지 않은 「crunch」기구에서는, 똑같이 5 에서 6 배의 압축율을 얻을 수 있습니다. 다만, 이러한 값은 모두, DEFLATE 나 유사한 기제 압축 알고리즘에 의한 포스트패스를 상정해, 그 효과를 고려하고 있습니다. DEFLATE 에 대해서는,여기를 참조해 주세요.

이 형식의 주된 목적은, Java 어플리케이션의 패키지화, 전송, 및 배포에 필요한 디스크 조건과 대역폭 조건을 경감하는 것입니다. 이전의 버젼은, Java 2 Standard Edition 릴리스 1.4. 1 및 1.4. 2 (코드명 「Hopper」 및 「Mantis」)의 다운로드를 패키지화하기 위해서 사용되고 있었습니다.

이 형식은, 가상 머신에 고속으로 읽어들이는 것을 목적으로 한 것은 아니고, Java 어플리케이션의 실행시에 기동 속도나 메모리 사이즈를 개선하는 일도 없습니다. 직접 읽어들여 가능한 파일 형식에 관한 기술 요건이 어려우면 최적인 압축은 불가능하게 되겠지요. 강하게 압축된 파일의 압축 해제 프로그램은 복잡한 처리를 실행할 필요가 있어, 그 처리를 위해서(때문에) 메모리와 CPU 시간을 사용할 수 있는 것이 필요합니다. Pack200 어카이브(archive)는, Java SE 및 J2EE 어플리케이션을 실행하는 동종의 머신에 전개되는 것을 상정하고 있습니다.

이것은 배치 지향의 형식에서, Java 클래스의 패키지화와 전송을 위해서(때문에) 최적화되고 있습니다. 개별적으로 포함된 클래스에의 랜덤 억세스는 지원하고 있습니다. 이 어카이브(archive) 형식의 연속적인 성질을 강조하기 위해서, 압축 프로그램으로 생성되고 압축 해제 프로그램으로 받아들여지는 데이터를 포맷 하는 것을 나타내는데, 「포함한다」는 아니고 「전송 한다」라고 하는 동사를 사용합니다.

이 형식에서는, DEFLATE 등의 바이트 지향의 압축 알고리즘으로 실행되는 처리는 반복해지지 않습니다. 일반적으로, Pack200 를 사용하는 툴은, 어카이브(archive)를 ZIP 파일에 포함하거나 다른 압축 기술을 사용하거나 해, 어카이브(archive)를 한층 더 압축합니다. Pack200 의 설계에서는, 이러한 포스트패스 압축 프로그램이 존재하는 것을 상정하고 있습니다.

이 스펙은 복잡해, 일부의 독자에게는 필요이상으로 복잡하게 보일지도 모릅니다. 여기에 반영되고 있는 설계상의 결정 사항은, 실제의 제품에 사용되고 있는 실제의 Java 클래스 파일로 행한 광범위한 테스트와 실험에 근거하고 있습니다. 이 스펙으로부터 복잡함을 없애려고 하면(자), 압축의 효율도 꽤 저하하게 되겠지요.

## 2. 어카이브(archive)의 입력

Pack200 어카이브(archive)는, JAR 파일과 같게, 클래스 파일 및 다른 ( 「자원」) 파일의 이미지를 계층형 디렉토리 구조로 보관 유지하고 있습니다.

클래스 파일 이외의 파일에 대해서는, 경우에 의해 파일 타이프별이 늘어놓고 바꾸고를 하는 것 외에는, 특별한 압축이나 변환은 행해지지 않습니다. 클래스 파일 이외의 이미지를 보관 유지하고 있는 어카이브(archive)의 경우, 이러한 파일은 포스트패스 압축 프로그램으로 적절히 압축되는 것을 상정하고 있습니다.

클래스는, 개개의 정수 풀 대신에, 어카이브(archive) 전체에 사용되는 큰 정수 풀을 사용한 형식에서 나타내집니다. 따라서, 클래스 파일을 Pack200 어카이브(archive)로부터 추출하면(자), 그 파일용의 새로운 정수 풀이 작성되어 정수 풀의 참조가 모두 조정됩니다. 이것에 의해 클래스의 시멘틱스가 변경될 것은 없습니다만, 일반적으로은 파일의 비트 단위의 이미지가 변경됩니다. 또, 사용되어 있지 않은 정수 풀 엔트리가 삭제되기 (위해)때문에, 그 사이즈도 바뀌는 일이 있습니다.

각 클래스 파일은, 정수 풀의 인덱스를 모두 검출해 (나중에) 번호를 재설정할 수 있도록(듯이), 압축 프로그램으로 완전하게 해석될 필요가 있습니다. 이 요건은, 정수를 참조하는 임의의 클래스 속성, 필드 속성, 메소드 속성, 및 코드 속성에 들어맞읍니다. Pack200 형식에서는, 적당한 범위의 속성이 지원되고 있습니다. 몇개의 종류의 새로운 속성레이아웃을 압축 프로그램에 대해서 선언할 수 있어 그러한 레이아웃을 압축 해제 프로그램으로 사용할 수 있도록(듯이) Pack200 형식을 개입시켜 전송 할 수 있습니다.

## 3. archive파일 구조의 개요

archive파일은, 짧은 「어카이브(archive) 헤더」라고, 거기에 계속되는 「밴드」라고 불리는, 몇개의 독립한 파일 섹션으로 구성됩니다. 그 수는 약 100 으로, 경우에 따라서 다릅니다. 각 밴드는, 밴드의 「요소」라고 불리는 주어진수의 배열을 전송 합니다. 어카이브(archive)는, 어카이브(archive) 헤더의 뒤는 밴드만으로 구성되어 있습니다.

논리적이게는, 밴드는 암묵에 사이즈 지정되는 32 비트의 부호 (플러스마이너스 기호)가 없는 정수의 배열입니다. 다만, 요소의 encode는 실제의 밴드치를 보다 컴팩트하게 전송 하기 위해서 선택되므로, 대부분의 경우, 물리적으로 필요한 것은 밴드의 요소 근처 1 바이트나 2 바이트입니다.

밴드에는 고정의 헤더는 없고, 그 사이즈를 나타내는 것도 없습니다. 밴드의 요소수는, 압축 해제 프로그램에 의해 이전의 밴드의 내용으로부터, 혹은 (최종적으로) 어카이브(archive) 헤더로부터 추정됩니다.

어느 특정의 밴드의 요소에는, 공통의 의미와 역할이 있습니다. 예를 들어, 전송 되는 모든 클래스의 이름은 1 개의 밴드에 보관 유지되어 클래스의 필드수는 모두 다른 밴드에 보관 유지됩니다. 각 밴드는, 어카이브(archive)내에서 연속한 바이트 세그먼트(segment)로서 전송 됩니다. Pack200 어카이브(archive)가 최초부터 컴팩트하고면서 zip 등의 유틸리티에 의한 압축성도 높은 주된 이유는, 이 연속성에 있습니다.

일부의 밴드에서는, 각 요소가 1 개의 객체를 기술합니다. 예를 들어, 각 클래스에는 필드수를 관련지을 수 있어 이것은 어카이브(archive)의 `class_field_count` 밴드내의 대응하는 값으로 지정됩니다. 다른 밴드에서는, 밴드내에서 연속한 0 개 이상의 요소에 의해 1 개의 객체가 기술되는 경우도 있습니다. 예를 들어, 클래스에서 구현되고 있는 인터페이스는, 어카이브(archive)의 `class_interface` 밴드내에서, 대응하는 연속한 0 개 이상의 값에 의해 지정됩니다. 이러한 값은 각각, 1 개의 클래스를 참조하는 인덱스입니다.

매우 소수의 밴드 (10 미만)에는, resource file의 이미지등의, 균일하지 않은 바이트가 보관 유지됩니다. 이것들은 「byte 밴드」라고 불립니다. 밴드가 많게는, 정수 풀에의 참조가 보관 유지됩니다. 액세스 수식자 플래그와 관련 비트를 보관 유지하는 밴드도 있습니다. 「char 밴드」라고 하는 밴드에는, CHAR3 로 불리는 (UTF8 를 닮아 있지만 동일하지 않다) 특별히 선택된 encode로, 캐릭터 라인의 문자가 보관 유지됩니다. 나머지의 밴드는, 다양한 다른 해석과 함께 정수를 전송 합니다.

정수형 밴드의 1 개 (cp_Utf8_big_chars)에는, 특수 처리를 위해서(때문에) 선택된 1 개의 CONSTANT_Utf8 캐릭터 라인의 문자가 보관 유지됩니다. 다른 밴드와는 달라, 이 밴드는, 이 특수 처리를 위해서(때문에) 선택된 캐릭터 라인의 수에 응해 0 회 이상 반복해집니다. 특별히 전송 되는 이러한 「큰 캐릭터 라인」에 대해서는,이 문서로 후술 합니다.

밴드의 대부분은, 클래스내의 메소드수, 필드의 이름, getfield 바이트 코드 명령의 오퍼랜드등을 전송 한다고 하는, 알기 쉬운 기능을 가지고 있습니다.

byte 밴드의 특수 케이스를 제외해, 밴드는 사이즈 지정된 일련의 바이트로 보여질 것은 없고, encode 된 정수인 요소가 지정의 수만큼 연속한 것이라고 보여집니다. 일반적으로, 정수 encode는 (바이트 순서라고 보았을 경우) 가변 사이즈이므로, 밴드의 요소수로부터 밴드의 바이트 사이즈를 요구하기 위한 확고한 규칙은 없습니다. 실제, 밴드의 말미를 검출하려면 , 밴드를 1 바이트씩 해석할 필요가 있습니다.

## 4. 정수 encode의 개요

각 밴드는, 1 개(살) 이상의 encode 방식을 사용해, 요소를 바이트 순서로서 encode 합니다. 포스트패스 압축 프로그램에 의해 이러한 바이트가 비트 순서에 변환되는 것이 상정되고 있습니다만, 그 처리에 대해서는 이 문서로 지정되고 있지 않습니다. Pack200 압축 프로그램에서는, 밴드로 사용하는 encode 방식을 자유롭게 선택해 변경할 수가 있습니다. 어느 밴드로 사용하는 encode 방식은, 다른 밴드로 사용하는 것과는 독립하고 있습니다. 지원되고 있는 encode 방식에 관한 부분은, Pack200 스펙의 중요한 부분입니다. 이 마디에서는, 이러한 encode의 개요에 대해 설명합니다. 상세한 것에 대하여는,이 문서로 후술 합니다.

resource file 이미지등의 바이트 단위의 데이터를 encode 하는 byte 밴드에서는, 정수는 부호 없음 8 비트 바이트로서 encode 됩니다. 이 스펙에서는, 이 encode는 BYTE1 로 불립니다. 클래스 파일 정의의 타입 u1 와 비교해 주세요.

다른 밴드는, 훨씬 넓은 다이나믹 레인지의 값을 가져, 부의 수가 포함되는 경우나, 32 비트 부호 없음 최대치까지의 값이 포함되는 경우가 있습니다. 표현에 많은 바이트를 필요로 하는 큰 요소도 있습니다만, 일반적인 밴드 요소의 절대치는 비교적 작은 일을 상정해, 이러한 encode의 대부분은 가변 길이이 되어 있습니다. 밴드의 요소 순서에 강한 상관관계가 나타난다고 예측되는 경우, 이러한 밴드는, 절대 수치로서가 아니고, 연속하는 차분으로서 encode (델타 encode) 됩니다.

각 밴드에는, 압축 프로그램과 압축 해제 프로그램으로 그 밴드의 요소를 전송 할 때에 사용되는 「primary encode」를 관련지을 수 있습니다. byte 밴드의 경우를 제외해, primary encode 대신에 사용하는 「세칸다리 encode」를 압축 프로그램으로 지정할 수도 있습니다. 요컨데, 세칸다리 encode가 명시적으로 선언되어 있지 않은 한, 밴드의 encode에는 primary encode가 디폴트로 사용됩니다. 이것에 의해, Pack200 형식을 밴드 요소의 실제의 통계 데이터에 한층 더 적응시킬 수가 있습니다.

예를 들어, 개수나 사이즈를 보관 유지하는 밴드 등, 대부분의 밴드로 UNSIGNED5 라고 하는 primary encode가 사용됩니다. 이것은, 범위 [0..191] 의 값을 1 바이트로서 표현하는 부호 (플러스마이너스 기호)가 없는 encode이며, 일반적인 것입니다. 최대 사이즈 5 바이트까지 확장해 약 50,000,000 을 넘는 수치를 나타낼 수가 있습니다. 다만, 밴드에 범위 [0,255] 의 수치만이 포함되어 있는 경우는, BYTE1 encode가 컴팩트해서, 대신에 이것을 사용하도록(듯이) 압축 프로그램으로부터 압축 해제 프로그램에 지시할 수가 있습니다.

압축 프로그램으로 세칸다리 encode를 지정하는 경우는, 임의 지정의 「밴드 코딩 지시자」를 발행할 필요가 있습니다. 이것에 대해서는,다른 마디로 설명합니다. 커스터마이즈 된 encode 방식을 사용하면(자), 밴드의 요소치의 실제의 다이나믹 레인지와 보다 정확하게 일치하는 경우는, 많은 바이트를 절약할 수 있는 일이 자주 있습니다.

#### 4.1. 정수 encode schema

Pack200 형식은, 4 개의 수치 (B, H, S, D)로 파라미터화 된, 정수 encode 방식의 schema에 근거하고 있습니다. 이 편성은 무한하게 있습니다만, 그 중 약 10 세트가 밴드의 primary encode로서 사용되어 약 100 세트 이상이 임의 지정의 encode로서 사용됩니다. (B, H, S, D) encode 방식의 상세한 것에 대하여는,나머지의 마디로 설명합니다. 여기에서는, 필요한 개략만 설명합니다.

파라미터 B (1<=B<=5)는, 1 개의 정수의 encode의 최대 길이을 바이트수로 가리킵니다. 항상 하위 비트로부터 먼저 바이트에 encode 됩니다.

파라미터 H (1<=H<=256)는, encode의 기수이며, encode의 바이트 순서가 종료하는 조건도 결정합니다. 파생 파라미터 L (0<=L<=255)는, (256-H)라고 정의됩니다. encode 된 바이트 순서 로 유지할 수 있는 것은, L 보다 작은 값을 가지는 1 바이트만으로, 그 바이트는 순서의 말미가 아니면 안됩니다. 따라서, 값 H 가 큰 만큼, encode장의 평균은 길어집니다. H 가 256 으로 L 가 0 의 경우는, 모든 encode장이 정확히 B 바이트가 되기 (위해)때문에, 그 encode 방식은 고정장이 됩니다.

파라미터 S (0<=S<=2)는, encode가 부호 첨부 수치를 나타낼지 어떨지, 또 어떻게 나타낼까를 결정합니다. 보다 정확하게는, 일반적으로 밴드 요소는 32 비트 부호 없음 정수로 보여지기 (위해)때문에, S 가 결정되는 것은, 31 비트 부호 없음 정수의 최대치 2147483647 보다 큰 밴드 요소의 encode입니다. 다만, 구별해도 의미는 없기 때문에, 그러한 수치는 계속해 부의 수치라고 부르기로 하겠습니다. S 는, 부호 비트로서 기능하는 최하정도 비트의 수를 나타냅니다. S 가 0 의 경우, 수치는 부호 없음 수치입니다. S 가 1 의 경우는, 부호 없음 수치의 LSB 와 오른쪽 쉬프트 된 남은 부분과의 배타적 논리합에 의해, 대응하는 부호 첨부 수치가 생성됩니다. S 가 1 보다 큰 경우, 생성된 부호 첨부 수치는, S 의 최하정도 비트가 모두 설정되어 있는 경우만 부가 됩니다. 그 이외의 경우, 이러한 하위 비트는, 그 정수의 정의 절대치에 기여합니다. 이 표현은, 바이트 코드의 분기 오프셋(offset) 등, 대부분 정의 수치를 가지는 밴드에 사용하면(자) 효과적입니다. 부호 비트의 해석의 상세한 것에 대하여는,다른 마디로 설명합니다.

파라미터 D (0<=D<=1)는, 밴드가 그 데이터를 연속하는 차분으로서 전송 (델타 encode) 할지 어떨지를 결정합니다. 이러한 encode를 기술하는 경우, S 와 D 는 양쪽 모두 0 의 경우에 생략 할 수 있어 D 는 0 의 경우에 생략 할 수 있습니다.

따라서, encode (1,256,0,0)는 (1,256)과 기술할 수도 있어 이것은 부호 없음 바이트로 수치를 표현합니다. encode (4,256)는, little endian 32 비트 부호 없음 정수로 수치를 표현합니다. encode (1,256,1)는, 1 바이트를 범위 [-128, 127] 의 수치에 매핑 합니다. encode (1,256,1,1)는, 연속하는 차분 ( 및 최초의 수치)이 범위 [-128, 127] 에 있는 수치 순서를 표현합니다.

무엇보다 일반적인 encode인 UNSIGNED5 는, 32 비트 부호 없음 정수의 전범위를 표현할 수 있습니다. 이 encode의 바이트 순서는, 192 보다 작은 바이트 4 개(살)에 임의의 1 바이트가 계속된 것인가, 192 보다 작은 바이트 0 ? 3 개(살)에 192 이상의 1 바이트가 계속된 것입니다. 부호 없음의 값은, 연속하는 각 바이트를 기수 64 말하고 나무승으로 슬캘링 해, 슬캘링 된 바이트치를 모두 가산하는 것에 의해 생성됩니다.

값 | 바이트 0 | 바이트 1 | 바이트 2 | 바이트 3 | 바이트 4
1 | 1
191 | 191
192 | 192 | 0
193 | 193 | 0
255 | 255 | 0
256 | 192 | 1
512 | 192 | 5
1024 | 192 | 13
2048 | 192 | 29
12479 | 255 | 191
12480 | 192 | 192 | 0
798911 | 255 | 255 | 191
798912 | 192 | 192 | 192 | 0
51130559 | 255 | 255 | 255 | 191
51130560 | 192 | 192 | 192 | 192 | 0
0xFFFFFFFF | 255 | 252 | 252 | 252 | 252

1 개(살) 이상의 밴드로 사용되고 있는 primary encode의 일람을 다음에 나타냅니다.

형태 | 이름 | 목적
(1,256) | BYTE1 | bytes
(3,128) | CHAR3 | Java 문자
(5,4) | BCI5 | 바이트 코드의 위치
(5,4,2) | BRANCH5 | 바이트 코드의 분기 오프셋(offset)
(5,64) | UNSIGNED5 | 일반적인 부호 없음 정수
(5,64,1) | SIGNED5 | 일반적인 부호 첨부 정수
(5,64,0,1) | UDELTA5 | 단조로운 순서
(5,64,1,1) | DELTA5 | 자기 상관이 있는 순서
(5,64,2,1) | MDELTA5 | 거의 단조로운 순서

## 5. 밴드의 정의

파일 전체는, 4 개의 주요 그룹에 속하는 약 200 의 밴드로 구성됩니다. 헤더의 뒤, 정수 풀의 내용, 클래스 schema의 대부분, 및 모든 속성 정보 (클래스, 필드, 메소드, 코드, 및 어카이브(archive) 전체)의 통합이 계속되어, 모든 메소드의 바이트 코드로 끝납니다.

각 밴드를 길게 한 순서로 기술하는 대신에, 재귀적이지 않은 단순한 문법을 사용해 계통적으로 표현합니다. 이 문법은 클래스 파일의 문법과 거의 같습니다.

      pack200_segment:
            segment_header
            *band_headers :BYTE1
            cp_bands
            attr_definition_bands
            ic_bands
            class_bands
            bc_bands
            file_bands

이 문법의 끝어는 스칼라와 밴드입니다. 끝어를 인식하기 쉽게 하기 위해서, 스칼라명은 샤프 기호 (#), 밴드명은 asterisk (*)로 시작합니다. 스칼라는 encode 된 정수 (또는 그 작은 고정치)로, archive파일의 헤더에 출현합니다. 문법으로 스칼라를 기술할 때는, 그 후에 구두점, 스칼라치의 encode, 및 꺽쇄묶음으로 둘러싸인 스칼라치의 개수를 부가합니다. 밴드를 기술할 때는, 그 후에 구두점, 밴드의 primary encode, 및 꺽쇄묶음으로 둘러싸인 밴드의 길이를 나타내는 코멘트를 부가합니다. 정수 풀등의 다른 데이터 구조에의 참조를 encode 하는 경우는, 그 구조를 환괄호내에 코멘트로서 기술합니다. 참조가 null 에서도 상관없는 경우는, 그것도 기술합니다.

다음에 예를 나타냅니다.

      example_non_terminal:
            other_non_terminal
            #single_scalar_integer :UNSIGNED5[1]
            #four_byte_scalar :BYTE1[4]
            *band_of_integers :UNSIGNED5 [#integer_count]
            *band_of_method_references :UNSIGNED5 [SUM(*ref_counts)] (cp_Method)
            *band_of_strings_and_nulls :UNSIGNED5 [...] (null or cp_String)

많은 경우, 밴드의 길이는, 단순하게 전술의 스칼라를 참조한 것인가 (`[#class_count]` 등), 개수를 전송 하는 전술의 밴드의 합계 (`[SUM(*class_method_count)]` 등)가 됩니다. 밴드의 길이는 스펙의 문장으로 정의되기 (위해)때문에, 꺽쇄묶음내의 길이는 문법에서는 코멘트라고 볼 필요가 있습니다. 밴드의 개수는, 생략 기호를 포함한 부분적인 식에서 지정되는 경우도 있기 (위해)때문에, 간단하게 요약할 수 없습니다.

다른 문법상의 표기법을 사용하는 일도 있습니다. 일반적으로의 정규 표현 연산자 `(X | Y)` 는, X 또는 Y 의 어느쪽이든과의 일치를 의미합니다. `(X)*` (은)는, 임의의 수의 X 와의 일치를 의미합니다. `(X)+` (은)는, 1 개(살) 이상의 X 와의 일치를 의미합니다. `(X)?` (은)는, 0 또는 1 개의 X 와의 일치를 의미합니다. 1 개의 케이스에서는, 밴드가 복수의 인스턴스를 가지는 경우가 있어, 식 (band1)`**` length(band2) 는,band1 의 인스턴스가 band2 의 요소수와 같은 수만큼 존재하는 것을 의미합니다. 같이 3 개의 케이스에서는, 식 (band1)`**` #scalar 는, 불형의 스칼라치 (0 또는 1)에 응해,band1 의 인스턴스가 각각 0 또는 1 개(살) 존재하는 것을 나타냅니다.

#### 5.1. 어카이브(archive)의 분할

압축 해제 프로그램에의 전송으로, Pack200 어카이브(archive) 형식 전체가 1 회 이상 반복해지는 경우가 있습니다. 이 경우, 전송 되는 밴드의 각 세트는, 전송 전체의 「세그먼트(segment)」라고 보여집니다. 압축 해제 프로그램은 복수의 세그먼트(segment)를 받아들여 각 세그먼트(segment)를 차례로 독립해 처리할 필요가 있습니다. 각 세그먼트(segment)로부터의 출력 파일은, 차례로 축적됩니다. 압축 해제 프로그램으로 JAR 파일을 생성하는 경우는, 복수의 세그먼트(segment)를 1 개의 출력 JAR 파일에 축적할 필요가 있습니다. 그 요소는, 각 세그먼트(segment)로 전송 된 대응하는 요소로 구성되어 순서도 같습니다.

      pack200_archive:
            (pack200_segment)+

각 세그먼트(segment)는, Pack200 magic number-와 버젼 번호로 시작됩니다.

(Pack200 어카이브(archive)는, 어카이브(archive)를 결합한다고 하는 의미로 서로 연결되는 경우가 있습니다. 후술대로, 각 세그먼트(segment)의 헤더에 `#archive_size` 필드가 존재하지 않는 경우는, 그것을 삽입하고 나서 다른 세그먼트(segment)를 추가할 필요가 있습니다. 이것에 의해, 압축 해제 프로그램으로 각 세그먼트(segment)의 말미를 검출할 수가 있습니다. 세그먼트(segment) 헤더의 형식은, 이 조정을 간단하게 실행할 수 있게 되어 있습니다.

분할을 스트리밍 트랜스폴트층과 조합하면(자), 압축 프로그램의 효율은 저하합니다만, 압축 프로그램으로 대기 시간을 줄이거나 압축 해제 프로그램의 메모리 요건을 경감하거나 할 수가 있습니다.

분할은, 매우 큰 어카이브(archive) (수십 메가바이트)의 슬캘링에 관련하는 문제의 해결에도 도움이 됩니다. 이러한 어카이브(archive)에서는, 결합된 글로벌인 정수 풀의 인덱스의 폭이 너무 커져 정수를 글로벌하게 공유하는 이점이 없어집니다. 새로운 세그먼트(segment)를 개시하는 것으로, 압축 프로그램은 압축 해제 프로그램의 정수 풀을 리셋 해, 불필요한 정수를 삭제합니다. 다만, 계속 사용되는 정수는 다시 인용할 필요가 있습니다. 이 균형은, 가비지 컬렉터를 카피하는 설계와 닮은 곳(점)이 있습니다.

#### 5.2. 어카이브(archive) 헤더

헤더는 magic number-와 버젼 정보로 구성되어 그 형식은 Java 클래스 파일 형식과 완전히 같습니다. 다만, Pack200 형식에는, magic number-외에 빅 endian의 정수는 없습니다. 밴드의 정수 encode에서는, 항상 산술상의 하위 비트가 먼저 출현합니다.

어카이브(archive)의 magic number- (세그먼트(segment) 헤더의 최초의 4 바이트)만이 고정 사이즈입니다. 어카이브(archive)외의 구조체는 모두 가변 사이즈이므로, 순서에 해석할 필요가 있습니다. 일반적으로, 압축 해제 프로그램은, 어카이브(archive)의 각 세그먼트(segment)를 2 회 해석할 필요가 있습니다. 1 번째는 밴드의 사이즈를 요구해 해석해, 2 번째는 밴드로부터 정보를 차례로 추출해 각 JAR 요소에 출력합니다.

      segment_header:
            archive_magic archive_header

      archive_magic:
            #archive_magic_word :BYTE1[4]

      archive_header:
            #archive_minver :UNSIGNED5[1]
            #archive_majver :UNSIGNED5[1]
            #archive_options :UNSIGNED5[1]
            (archive_file_counts) ** (#have_file_headers)
            (archive_special_counts) ** (#have_special_formats)
            cp_counts
            class_counts

      archive_file_counts:
            #archive_size_hi :UNSIGNED5[1]
            #archive_size_lo :UNSIGNED5[1]
            #archive_next_count :UNSIGNED5[1]
            #archive_modtime :UNSIGNED5[1]
            #file_count :UNSIGNED5[1]

`archive_magic_word` 는, 0 xCA, 0 xFE, 0 xD0, 0x0D 의 4 바이트로 구성됩니다. `#archive_minver` 는 수치 1,`#archive_majver` 는 수치 160 이 아니면 안됩니다. 이것들 2 개의 값은, 장래 이 파일 형식의 소규모의 개정을 반영해 증분 되는 경우가 있습니다. 이 규격의 이전의 버젼에서는, 마이너 버젼 번호는 7, 메이저 버젼 번호는 150 이었습니다.

헤더에는, 정수 풀 엔트리 및 다른 「톱 레벨」엔티티의, 초기의 개수도 포함됩니다. 이러한 개수는, 모두 UNSIGNED5 형식에서 지정됩니다. 이러한 개수의 일부는,`#archive_options` 워드의 비트로 제어되는 조건에 응해 존재합니다. 결핍 하고 있는 헤더치 ( 및 특별히 다른 기재가 없는 경우는, 결핍 하고 있는 값일반)에 관한 규칙으로서 압축 해제 프로그램은 명시적으로 값 0 을 받았을 경우와 같게 동작할 필요가 있습니다.

##### 5.2. 1. 어카이브(archive) 옵션과 파일 프로퍼티

`#archive_options` 워드는 비트 단위로 해석됩니다. 일부의 비트에는 다음과 같은 기호명이 주어지고 있습니다. LSB 는 비트 0 입니다.

비트 | 이름 | `#archive_options` 로 설정되어 있는 경우의 의미
0 | `have_special_formats` | `archive_special_counts` 에 개수가 보관 유지되고 있습니다
1 | `have_cp_numbers` | `cp_number_counts` 에 개수가 보관 유지되고 있습니다
2 | `have_all_code_flags` | `code_flags_lo` 에 각 코드의 요소가 보관 유지되고 있습니다
3 |  | (미사용, 0 이 아니면 안된다)
4 | `have_file_headers` | `archive_file_counts` 에 개수가 보관 유지되고 있습니다
5 | `deflate_hint` | 모든 요소에 대해 압축된 JAR 파일을 요구합니다
6 | `have_file_modtime` | `file_modtime` 에 갱신 시각이 보관 유지되고 있습니다
7 | `have_file_options` | `file_options` 에 옵션 비트가 보관 유지되고 있습니다
8 | `have_file_size_hi` | `file_size_hi` 에 상위의 사이즈 워드가 보관 유지되고 있습니다
9 | `have_class_flags_hi` | `class_flags_hi` 에 추가의 속성 플래그가 보관 유지되고 있습니다
10 | `have_field_flags_hi` | `field_flags_hi` 에 추가의 속성 플래그가 보관 유지되고 있습니다
11 | `have_method_flags_hi` | `method_flags_hi` 에 추가의 속성 플래그가 보관 유지되고 있습니다
12 | `have_code_flags_hi` | `code_flags_hi` 에 추가의 속성 플래그가 보관 유지되고 있습니다
13 |  | (미사용, 0 이 아니면 안된다)
... |  | (미사용, 0 이 아니면 안된다)
31 |  | (미사용, 0 이 아니면 안된다)

`have_special_formats` (LSB)가 설정되어 있는 경우, 밴드 `archive_special_counts` 에는, 문법에 따라 2 개의 요소가 보관 유지됩니다. 그 이외의 경우, 이 밴드에 요소는 없습니다. 같이`have_cp_numbers` 가 설정되어 있는 경우, 밴드 `cp_number_counts` 에는, 문법에 따라 4 개의 요소가 보관 유지됩니다. 그 이외의 경우, 이 밴드에 요소는 없습니다. `have_all_code_flags` 가 설정되어 있는 경우, 밴드 `code_flags` 에는, 모든 `Code` 속성에 대해서 각각 1 개의 요소가 보관 유지될 필요가 있습니다. 그 이외의 경우, 이 밴드의 요소는 보다 적게 됩니다. 이 옵션은,`Code` 속성에 많은 서브 속성이 포함되어 있는 경우에 도움이 됩니다. 이러한 경우는, JAR 에 대량의 디버그 정보가 포함되어 있다고 생각되기 (위해)때문에입니다. `have_file_headers` 가 설정되어 있는 경우, 밴드 `archive_file_counts` 에는, 문법에 따라 5 개의 요소가 보관 유지됩니다. 그 이외의 경우, 이 밴드에 요소는 없습니다. `deflate_hint` 가 설정되어 있는 경우, 압축 해제 프로그램은 그 출력의 사이즈를 작게 하도록(듯이) 요구됩니다 (다만 필수는 아니다). 예를 들어, 압축 해제 프로그램으로 JAR 파일을 생성하는 경우는, JAR 요소를 압축하면 좋을 것입니다. 옵션 `have_file_modtime`,`have_file_options`,`have_file_size_hi`,`have_class_flags_hi`,`have_field_flags_hi`,`have_method_flags_hi`,`have_code_flags_hi` 가 설정되어 있는 경우는, 아래와 같이, 각각 대응하는 밴드 `file_modtime`,`file_options`,`file_size_hi`,`class_flags_hi`,`field_flags_hi`,`method_flags_hi`,`code_flags_hi` 가 빈 상태(empty)이 아니게 되는 일이 있습니다. 그 이외의 경우, 그 밴드에 요소는 없습니다. 어카이브(archive) 옵션외의 비트는, 장래 사용하기 위해서 예약되고 있어 0 이 아니면 안됩니다.

`#archive_options` 워드의 직후에 32 비트 수치의 페어가 있어, 양쪽 모두로 64 bit length가 됩니다. 압축 해제 프로그램은 이것을 이용해, 어카이브(archive) 세그먼트(segment)의 말미까지, 세그먼트(segment)를 넘어 읽어들이는 일 없이, 입력 데이터를 간단하게 버퍼링 할 수 있습니다. 값 `#archive_size` 는, 64 비트의 부호 없음의 값으로, 32 비트 부호 없음 워드 `#archive_size_lo` 와 `#archive_size_hi` 로 구성됩니다. 전자는 하위의 32 비트 워드, 후자는 상위의 32 비트 워드입니다. 값 `#archive_size` 는 0 인가, 어카이브(archive) 세그먼트(segment)내의 바이트수를 선언합니다. 개시 위치는 `#archive_size_lo` 의 직후 또한 `#archive_next_count` 의 직전으로, 종료 위치는 마지막 밴드 `*file_bits` 밴드입니다. 즉, 사이즈가 0 이외의 경우는,`#archive_next_count` 와 `*file_bits`, 및 그 사이에 있는 모든 데이터의 사이즈를 나타냅니다. 이 값은 장황합니다만, 0 이외의 경우는 올바른 값을 압축 프로그램으로 지정할 필요가 있습니다. 어카이브(archive) 세그먼트(segment)가 스트림의 일부로서 전송 되는 경우로, 추가 세그먼트(segment)등의 다른 데이터가 어카이브(archive)에 이어 전송 될 때는,`#archive_size` 의 값은 0 으로 할 수 없습니다. 이 값은, 압축 해제 프로그램으로 완전하게 무시되는 경우도 있습니다만, 입력 데이터를 보다 효율 좋게 버퍼링 하기 위해서 일부의 압축 해제 프로그램으로 이용되는 경우도 있습니다.

`#archive_size` 의 직후에 있는 값 `#archive_next_count` 는, 현재의 어카이브(archive) 세그먼트(segment)의 직후부터 계속되는 어카이브(archive) 세그먼트(segment)의 수의 견적입니다. 이 수치는 정확한 필요는 없고, 항상 0 에서도 괜찮습니다. 나머지의 압축 해제 처리의 분량에 대해 압축 해제 프로그램에 힌트를 제공하기 위한 치입니다. 일반적으로, 이러한 힌트는 진척 바에 표시됩니다.

`#archive_modtime` 의 값이 0 이외의 경우, 압축 해제 프로그램은 시스템 고유의 갱신 시각을 출력용으로 조정하도록(듯이) 요구됩니다 (다만 필수는 아니다). 예를 들어, 압축 해제 프로그램으로 JAR 파일을 생성하는 경우는, 각 JAR 요소 또는 JAR 파일 자체의 갱신 일자를 그 일자로 설정합니다. 다만,`file_modtime` 의 값이 0 이외의 경우 등, 보다 상세한 지시가 있는 경우를 제외합니다. `#archive_modtime` 의 값은,`System.currentTimeMillis` 로 사용되는 기준일시 (1970 년 1 월 1 일 00:00:00 GMT)부터의 초수라고 해석됩니다. 다만, 0 은 특수한 값으로 해서 예약되고 있어 어카이브(archive) 전체적으로의 갱신 시각이 존재하지 않는 것을 나타냅니다. 어카이브(archive)의 갱신 시각이 존재하지 않는 경우, 압축 해제 프로그램은 대신에 임의의 값을 지정할 수가 있습니다. 이 처리를 하는 경우,`file_modtime` 의 값이 존재할 때는, 이러한 값은, 압축 프로그램에 의해 지정되는 갱신 시각 `#archive_modtime` 를 기준으로 하고 있다고 해석됩니다.

`#file_count` 는, 어카이브(archive)에 의해 상세하게 기술되고 있는 파일의 수를 나타냅니다. 클래스 파일은 단순해 (아래와 같이를 참조), 클래스 자체를 전송 하면 충분해서, 파일로서 기술할 필요는 없습니다. 따라서, 전송 되는 클래스의 수보다 `#file_count` 가 작아질 수도 있습니다. 전송 되는 클래스의 수는 `#class_count` 로 불립니다. 한편, 전송 되는 파일이 클래스를 포함하고 있다고는 할 수 없기 때문에,`#file_count` 는 클래스의 수부터 커질 수도 있습니다.

##### 5.2. 2. 어카이브(archive)의 엔티티수와 클래스 형식

archive파일에서는, 「정수 풀」이라고 불리는 정수 세트가 12 지정됩니다. 이러한 구조체는, 클래스 파일내에서 유사한 이름을 가지는 구조체를 닮아 있습니다만, 동일하지는 않습니다. 이러한 정수 풀의 상세한 것에 대하여는, 다음의 마디로 설명합니다.

각 정수 풀의 카디나리티는, 어카이브(archive) 헤더의 `cp_counts` 구조체로 UNSIGNED5 형식에서 지정됩니다.

      cp_counts:
            #cp_Utf8_count :UNSIGNED5[1]
            (cp_number_counts) ** (#have_cp_numbers)
            #cp_String_count :UNSIGNED5[1]
            #cp_Class_count :UNSIGNED5[1]
            #cp_Signature_count :UNSIGNED5[1]
            #cp_Descr_count :UNSIGNED5[1]
            #cp_Field_count :UNSIGNED5[1]
            #cp_Method_count :UNSIGNED5[1]
            #cp_Imethod_count :UNSIGNED5[1]

      cp_number_counts:
            #cp_Int_count :UNSIGNED5[1]
            #cp_Float_count :UNSIGNED5[1]
            #cp_Long_count :UNSIGNED5[1]
            #cp_Double_count :UNSIGNED5[1]

      archive_special_counts:
            #band_headers_size :UNSIGNED5[1]
            #attr_definition_count :UNSIGNED5[1]

      class_counts:
            #ic_count :UNSIGNED5[1]
            #default_class_minver :UNSIGNED5[1]
            #default_class_majver :UNSIGNED5[1]
            #class_count :UNSIGNED5[1]

이러한 수가 발생하는 순서는, 정수 풀 자체가 어카이브(archive)로 전송 되는 순서와 같습니다. 이 순서는, 정수 풀의 「정의 순서」라고 불립니다.

4 개의 수치 정수 풀의 사이즈는 `cp_number_counts` 로 지정됩니다. 이것들이 지정하는 수치는,`ldc` 바이트 코드로 사용되는 일이 있습니다. 이러한 바이트 코드를 실제로 사용하는 클래스는 몇 안 되는의로, 이러한 사이즈는 생략 가능하고,`#have_cp_numbers` 에 의해 제어됩니다.

각 클래스 파일의 헤더에는, magic number-, 마이너 버젼 번호, 및 메이저 버젼 번호가 포함되어 있습니다. magic number- (0xCAFEBABE)는 고정의 정수로, Pack200 어카이브(archive)에서는 전송 되지 않습니다. 다만, 버젼 번호는 변경되는 경우가 있기 (위해)때문에, 기록할 필요가 있습니다.

특정의 버젼 번호가 주로 사용되는 것을 상정해, 어카이브(archive) 헤더에서는 디폴트의 메이저 버젼 번호와 마이너 버젼 번호가 전송 됩니다. 이러한 번호는, 어느쪽이나 UNSIGNED5 형식에서 지정됩니다.

어카이브(archive)내의 개개의 클래스에서는 (아래와 같이를 참조), 독자적인 버젼 번호를 의사 속성으로 지정할 수도 있습니다. 이것은, 어카이브(archive) 헤더로 지정되고 있는 `#default_class_minver` 와 `#default_class_majver` 보다 우선됩니다.

`#band_headers_size` 는,`band_headers` 의 사이즈를 바이트수로 지정합니다. 이러한 바이트는, 세칸다리 encode의 밴드 코딩 지시자의 정의에 도움이 됩니다. 그 형식의 상세한 것에 대하여는,메타 encode에 관한 마디로 설명합니다.

어카이브(archive) 헤더에서는, 속성의 형태의 수 (`#attr_definition_count`), 클래스 정의의 수 (`#class_count`), 및 상자의 클래스 선언의 수 (`#ic_count`)도 지정됩니다. 이러한 수는, 다른 각종의 밴드의 정의에 따라, 이러한 밴드의 사이즈를 요구하기 위해서(때문에) 사용됩니다.

12 의 정수 풀의 카운트를 모두 산술적으로 합계한 값은,`536870912` (`2^29`)보다 작지 않으면 안됩니다. 합계가 이 제한치 이상이 되는 것 같은 어카이브(archive)를 압축 프로그램으로 전송 하는 것은 금지됩니다. 이 제약의 목적은, 압축 해제의 실행중에 특정의 정수 (분해 해제된 내부 클래스명이나 암묵적인 `SourceFile` 명등)를 정수 풀에 추가할 필요가 있는 경우에 대해도, 압축 해제 프로그램이 내부에서 통일된 정수의 번호부를 사용할 수 있도록(듯이) 하는 것입니다.

구현 에 해당하는 주의: `cp_counts` 에서는 12 개까지의 수치가 전송 되기 (위해)때문에, 어카이브(archive) 헤더에서는 26 개까지의 32 비트 정수가 전송 됩니다. 세그먼트(segment) 헤더에는, 생략 가능한 서브 밴드가 3 개 있어, 각각 2 개(살), 5 개(살), 및 4 개의 값이 포함됩니다. 따라서,`segment_header` 의 최소 사이즈는 19 바이트, 가정상의 최대 사이즈는 134 바이트입니다. 게다가 압축 해제 프로그램에서는, 잘못한 예측을 피하기 위해서(때문에),`#archive_size` 필드가 확실히 포함되어 있는 최초의 19 바이트의 블록을 읽어들여 버퍼링 할 수도 있습니다. 이것은 버젼 번호가 실제와 같게 작은 일을 전제로 하고 있습니다. 그 직후에, 어카이브(archive)의 나머지를 주사 하기 위해서 추가로 필요한 버퍼 기억 영역의 바이트수를 판정하기 위해서, (적어도 resource file 이미지까지) 필요한 정보를 해석합니다. `*file_bits` 내의 resource file 이미지를 해석할 때까지는, 압축 해제 프로그램은 `*file_size` 밴드의 read를 완료하고 있어, 최초의 `#archive_size` 에 존재하고 있던 불확실성을 모두 없앨 수가 있습니다. `#archive_size` 필드가 0 의 경우는, 압축 해제 프로그램으로 어카이브(archive)를 해석하려면 , 입력 채널의 모든 데이터를 마지막까지 읽어들일 필요가 생기는 일도 있습니다.

#### 5.3. 정수 풀

12 의 독립한 정수 풀이 있어, 그 중 11 은, Java 클래스 파일 형식의 11 의 정수형에 직접 대응하고 있습니다. Pack200 어카이브(archive) 형식에서는, 이러한 정수 풀은 「정의 순서」라고 불리는 고정의 논리적인 순서로 편성됩니다. 이 순서에 의해, 어카이브(archive)의 밴드 구조에 정수 풀이 어떻게 출현할지가 정해져, 일부의 정수의 번호부의 구축 방법도 정해집니다.

정수 풀에는, 모든 입력 클래스 파일의 정수 풀에 있는 정보가 통합됩니다. 각 정수 풀에는, 1 개의 형태의 정수치가 포함됩니다. 클래스 파일로 사용되는 11 의 형태의 정수 풀은, 각각 독자적인 정수 풀에 넣어집니다. 12 번째의 풀에는 「시그니챠」가 보관 유지됩니다. 시그니챠는, 클래스 파일에서는 메소드나 필드의 형태를 나타내는 UTF8 캐릭터 라인입니다만, Pack200 어카이브(archive)에서는 개별적으로 압축된 데이터형입니다.

다음의 겉(표)에, 12 의 정수 풀을 그 정의 순서에 따라 가리킵니다. Java 클래스 파일 형식에서 사용되는 정수형과의 대응도 정의합니다.

이름 | 클래스 파일의 요소 | 클래스 파일의 태그 | 목적
cp_Utf8 | ConstantPool.cpUtf8 | CONSTANT_Utf8 | 기본적인 캐릭터 라인 데이터
cp_Int | ConstantPool.cpInteger | CONSTANT_Integer | int 형의 정수
cp_Float | ConstantPool.cpFloat | CONSTANT_Float | float 형의 정수
cp_Long | ConstantPool.cpLong | CONSTANT_Long | long 형의 정수
cp_Double | ConstantPool.cpDouble | CONSTANT_Double | double 형의 정수
cp_String | ConstantPool.cpString | CONSTANT_String | String 형의 정수
cp_Class | ConstantPool.cpClass | CONSTANT_Class | 클래스의 참조
cp_Signature | (이하를 참조) | (없음) | 메소드, 필드, 또는 변수의 형태
cp_Descr | ConstantPool.cpNameAndType | CONSTANT_NameAndType | 이름과 형태의 페어
cp_Field | ConstantPool.cpFieldref | CONSTANT_Fieldref | 필드의 참조
cp_Method | ConstantPool.cpMethodref | CONSTANT_Methodref | 메소드 호출
cp_Imethod | ConstantPool.cpInterfaceMethodref | CONSTANT_InterfaceMethodref | 인터페이스 호출
(없음) |  | CONSTANT_Unicode | 미사용의 형태

논리적이게는, 각 정수 풀은, 모두 같은 1 개의 형태를 가지는 기호치 또는 수치세트입니다. Pack200 어카이브(archive)에서는, 정수 풀은 이러한 값의 순서로서 구성되어 각 치에 순서내에서 일의의 인덱스를 붙일 수 있고 있습니다. 어카이브(archive)로 정수를 기술할 필요가 있을 때는, 해당하는 정수 풀내 (또는 풀의 부분집합내)의 인덱스가 지정됩니다. 풀의 부분집합은, 풀에의 참조를 포함하고 있는 밴드와 함께 건네받을 때 기술됩니다.

클래스 파일 형식과는 달라, Pack200 어카이브(archive) 형식에서는 정수 풀의 인덱스는 0 으로부터 시작됩니다. null 참조가 상정되는 보기 드문 케이스에서는, 그 가능성이 기재되어 null 참조 자체는 0 의 인덱스로 encode 됩니다. 다른 모든 인덱스치는 1 증가합니다. null 참조가 상정되어 있지 않은 케이스에서도, null 참조는 32 비트의 인덱스치 -1 로 encode 되는 경우가 있습니다.

또, 클래스 파일과는 달라, long 치나 double 치에 관련해 미사용의 인덱스 (갭)가 발생할 것은 없습니다. 정수 풀의 요소를 정식으로 참조하기 위해서, 배열의 표기법을 사용하는 일도 있습니다. 예를 들어,`cp_Int` 정수 풀의 최초의 3 개의 정수는 `cp_Int[0]`,`cp_Int[1]`,`cp_Int[2]` 로, 마지막 정수는 `cp_Int[cp_Int_count-1]` 입니다. 이 스펙에서는, 밴드와 정수 풀은 어느쪽이나 0 으로부터 시작되는 배열로서 다루어집니다.

압축 프로그램으로 같은 정수를 2 회전송 하는 것은 부정합니다. 즉, 정수 풀의 엔트리는 모두 일의가 아니면 안됩니다.

클래스 파일에서는, 소수의 예외를 제외해, 정수 풀의 참조는 강하고 형지를 무늬를 박아서 염색한 것 됩니다. 즉, 어느 참조도, 참조의 문맥에 관련지을 수 있었던 고정 태그의 정수 풀 엔트리를 참조하는지, null 가 됩니다. 예외는,`ConstantValue` 속성과`ldc`,`ldc_w`, 및 `ldc2_w` 명령의 오퍼랜드 필드입니다.

다만, Pack200 어카이브(archive)의 정수 풀에는 개별적으로 인덱스가 설정되므로, 어느 특정의 인덱스가 적용되는 정수 풀 (또는 풀의 부분집합)은 1 개만으로 되도록(듯이), 정수의 참조는 모두 강하게 형지를 무늬를 박아서 염색한 것 할 필요가 있습니다. 그 때문에(위해)는, 문맥으로부터 정수의 형태를 추정하는지 (`ConstantValue` 속성의 경우), 참조의 문맥에 다른 정보를 추가합니다. 바이트 코드 스트림내에서,`ldc` 는 정수형에 의해 `aldc`,`ildc` 등의 개별의 명령에 분할됩니다.

어카이브(archive)내의 정수 풀 밴드의 레이아웃은, 정수 풀 자체의 정의 순서에 따릅니다. 정수 풀도 또, 각각 1 개(살) 이상의 밴드의 순서로 표현됩니다. 정수 풀 밴드의 순서는 다음과 같은 구조가 됩니다.

      cp_bands:
            cp_Utf8
            *cp_Int :UDELTA5 [#cp_Int_count]
            *cp_Float :UDELTA5 [#cp_Float_count]
            cp_Long
            cp_Double
            *cp_String :UDELTA5 [#cp_String_count] (cp_Utf8)
            *cp_Class :UDELTA5 [#cp_Class_count] (cp_Utf8)
            cp_Signature
            cp_Descr
            cp_Field
            cp_Method
            cp_Imethod

여기에 나타나고 있도록(듯이), 1 개의 32 비트 정수 또는 1 개의 참조로부터 엔트리를 파생할 수 있는 정수 풀은, 각각 1 개의 밴드로 나타내집니다. 그 외의 정수 풀은, 밴드의 모임에서 나타내집니다. 각 정수 풀의 대응하는 문법 요소에는, 풀의 이름을 붙일 수 있습니다. 이 예의 `cp_bands` 에서는, 이름 원이 되고 있는 정수 풀의 정수를 전송 하는 각 밴드 또는 밴드 그룹의 순서가 선언되고 있습니다.

몇개의 밴드로 UDELTA5 가 primary encode로서 사용되고 있는 것에 유의해 주세요. Pack200 파일 형식에서는, 정수 풀의 값을 특정의 순서에 늘어놓을 필요는 없습니다만, 밴드내에서 UDELTA5 로 encode 된 값이 단조롭게 증가하도록(듯이) 늘어놓으면(자), 일반적으로은 유리하게 됩니다. 부의 차분을 UDELTA5 로 encode 하는 것은 가능합니다만, 부하가 높아집니다. 또, UDELTA5 대신에, 부호 첨부의 세칸다리 encode를 압축 프로그램으로 선택할 수도 있습니다. 출력 순서의 선택사항이 주어졌을 경우에, 고품질의 압축 프로그램은 밴드의 primary encode를 사용해 좋은 결과를 얻을 수 있도록(듯이) 선택하면(자) 상정해, 이 스펙에서는 primary encode를 선택하고 있습니다.

##### 5.3. 1. 스칼라 정수

`cp_Utf8` 정수 풀의 encode에 대해서는 간략하게 설명합니다. 우선, 수치, 캐릭터 라인, 및 클래스의 정수 풀의 encode에 대해 설명합니다.

`cp_Int` 정수 풀의 값은, 그 밴드내의 encode 된 값으로 직접 나타내집니다. `cp_Float` 정수 풀의 값은, 그 밴드내의 encode 된 32 비트치에 `java.lang.Float.intBitsToFloat` 를 적용했을 경우와 같게 취득됩니다.

`cp_Long` 밴드의 64 비트치는, 2 개의 밴드 `cp_Long_hi` 및 `cp_Long_lo` 의 대응하는 32 비트치를 상위 워드 및 하위 워드로서 연결하는 것에 의해 취득됩니다. 이러한 밴드에는, 각각 상위 워드와 하위 워드가 포함되어 있습니다. 같이`cp_Double` 밴드의 값은, 우선 다른 2 개의 밴드로부터 상위 워드 및 하위 워드를 연결해,`java.lang.Double.longBitsToDouble` 를 적용했을 경우와 같게, 얻을 수 있던 64 비트 정수의 형태를 다시 지정하는 것 에 의해 취득됩니다. 상위 워드와 하위 워드는, 각각 `cp_Double_hi` 밴드와 `cp_Double_lo` 밴드에 포함되어 있습니다.

      cp_Long:
            *cp_Long_hi :UDELTA5 [#cp_Long_count]
            *cp_Long_lo :DELTA5 [#cp_Long_count]

      cp_Double:
            *cp_Double_hi :UDELTA5 [#cp_Double_count]
            *cp_Double_lo :DELTA5 [#cp_Double_count]

최종적으로 부동 소수점치를 클래스 파일에 기입할 때는,`java.lang.Float.floatToRawIntBits` 또는 `java.lang.Double.doubleToRawLongBits` 로 처리했을 경우와 같게, 그 비트를 정확하게 포함할 필요가 있습니다. 이와 같이 하면(자), NaN 치가 정규화되는 일 없이, 충실히 전송 됩니다.

덧붙여 Pack200 의 밴드 코딩 기술을 확장해 64 비트치를 직접 encode 할 수도 있습니다만, 이 파일 형식에서는, 64 비트치는 항상 32 비트치의 페어로서 밴드의 페어로 전송 됩니다. 이것에 의해 구현이 단순하게 되어, 32 비트의 데이터 패스로 밴드 데이터를 처리하는 것이 가능하게 됩니다.

`cp_String` 정수 풀의 각 캐릭터 라인은, 그 밴드내에서,`cp_Utf8` 정수로서의 캐릭터 라인의 스펠에의 참조에 의해 나타내집니다.

같이`cp_Class` 정수 풀의 각 클래스는, 그 밴드내에서,`cp_Utf8` 정수로서의 클래스의 스펠에의 참조에 의해 나타내집니다. 클래스 파일이나 VM 의 경우와 같게, 스펠에서는 패키지의 접두사 요소를 단락짓기 위해서(때문에) slash 캐릭터 라인이 사용됩니다.

##### 5.3. 2. Utf8 정수

`cp_Utf8` 정수 풀의 각 치는, 0 개 이상의 16 비트 Java 문자로부터 완성되는 배열입니다. 「Utf8」라고 하는 이름은 구식에서, Java 클래스 파일의 기본적인 캐릭터 라인형을 가리키고 있는에 지나지 않습니다. Pack200 형식의 어느 부분에서도 UTF 인코딩은 사용됩니다만, 클래스 파일과의 관련을 강조하기 위해서 「Utf8」라고 하는 이름이 남아 있습니다. 클래스 파일 형식의 경우와 같게, 모든 캐릭터 라인 데이터는 이 1 종류의 정수 풀 엔트리로 전송 됩니다. 문맥이 명확한 경우는, 이러한 배열을 단지 「캐릭터 라인」이라고 부릅니다만, cp_String 정수 풀내의 Java 정수와는 다른 것입니다.

`cp_Utf8` 가 빈 상태(empty)이 아닌 경우, 그 최초의 값은 항상 빈 상태(empty)의 캐릭터 라인입니다. 따라서, 그 빈 상태(empty)의 캐릭터 라인에는 항상 인덱스 0 이 주어집니다. 이 빈 상태(empty)의 캐릭터 라인을 나타내기 위한 밴드치는 전송 되지 않습니다. 밴드 `cp_Utf8_prefix` 및 `cp_Utf8_suffix` 의 값은,`cp_Utf8` 의 빈 상태(empty)의 캐릭터 라인의 뒤의 캐릭터 라인에 관련합니다. 정수의 중복은 허가되어 있지 않기 때문에,`cp_Utf8` 외의 모든 요소에는 적어도 1 문자가 보관 유지됩니다.

`cp_Utf8` 정수 풀의 각 캐릭터 라인은, archive파일에서는 접두사 및 접미사(suffix)의 2 개의 부분에서 나타내집니다. 접미사(suffix)은, 개수와 문자 코드 순서의 양쪽 모두로 나타내집니다. 접두사는 개수만으로 나타내집니다. 접두사의 문자는, 전의 캐릭터 라인의 반복입니다. 이 수법에 의해, 압축 프로그램에서는, 연속하는 차분을 사용해 캐릭터 라인을 나타낼 수도 있습니다. 접미사(suffix)의 최초의 값과 접두사의 최초의 2 개의 값은, 전송 되는 어카이브(archive)에서는 생략 됩니다. 전송 된다고 하면(자), 이러한 값은 항상 0 이 됩니다. `cp_Utf8` 의 최초의 캐릭터 라인은 항상 빈 상태(empty)에서, 2 번째의 캐릭터 라인은 빈 상태(empty)이 아닌 접두사를 최초의 캐릭터 라인과 공유할 수 없기 때문입니다.

각 접미사(suffix)은, 「소접미사(suffix)」또는 「대접미사(suffix)」의 어느 쪽일까하고 해 전송 됩니다. 소접미사(suffix)은 1 개의 큰 밴드로 연속해 전송 됩니다. 대접미사(suffix)은 보기 드뭅니다만, 예외적인 통계 데이터를 가지는 캐릭터 라인을 컴팩트하게 전송 하기 위해서 사용됩니다. 예를 들어, 실제로는 수치 데이터의 테이블인 캐릭터 라인 등에 사용됩니다. 대접미사(suffix)은, 각각 독자적인 밴드로 전송 됩니다. 이것에 의해, 예외적인 큰 캐릭터 라인 마다, 포함되어 있는 문자에 응해 효율적으로 커스터마이즈 된, 세칸다리 encode를 압축 프로그램으로 선택할 수가 있습니다.

      cp_Utf8:
            *cp_Utf8_prefix :DELTA5      [MAX(0, #cp_Utf8_count-2)]
            *cp_Utf8_suffix :UNSIGNED5   [MAX(0, #cp_Utf8_count-1)]
            *cp_Utf8_chars :CHAR3        [SUM( *cp_Utf8_suffix )]
            *cp_Utf8_big_suffix :DELTA5  [COUNT(0, *cp_Utf8_suffix )]
            (*cp_Utf8_big_chars :DELTA5)
              ** length(cp_Utf8_big_suffix)  [SUM( *cp_Utf8_big_suffix )]

덧붙여 이 스펙에서는 필수가 아닙니다만, 캐릭터 라인을 사전식 순서로 늘어놓아 인접하는 캐릭터 라인 끼리로 최대한의 공통 접두사가 발견되도록(듯이) 하면(자) 도움이 됩니다. 접두사의 공유 기능을 무시해 모든 접두사를 0 으로 선언할 수도 있습니다.

밴드 `cp_Utf8_suffix` 에는,`#cp_Utf8_count` - 1 개의 요소가 포함됩니다. 이 밴드에서는, 정수 풀의 각 캐릭터 라인의 소접미사(suffix)의 길이가 차례로 지정됩니다 (최초의 암묵적인 빈 상태(empty)의 캐릭터 라인은 제외하다). 밴드 `cp_Utf8_prefix` 에는,`#cp_Utf8_count` - 2 개의 요소가 포함됩니다. 이 밴드에서는, 정수 풀의 각 캐릭터 라인의 접두사의 길이가 차례로 지정됩니다 (접두사의 길이가 항상 0 이 되는 최초의 2 개의 캐릭터 라인은 제외하다). 접두사의 길이는,`cp_Utf8[i-1]` 와 `cp_Utf8[i]` 의 양쪽 모두로 공유되는 접두사 서브 캐릭터 라인의 길이를 encode 한 것입니다. `cp_Utf8` 내의 캐릭터 라인이 3 개보다 적은 경우,`cp_Utf8_prefix` 는 비웁니다. 접두사의 길이는, 전체의 길이의 대부분을 차지하는 것이 일반적으로으로, 반을 차지하는 경우도 있습니다.

밴드 `cp_Utf8_chars` 의 각 치는, Java 문자를 나타내는 16 비트의 수치입니다. 이 밴드에는, 모든 소접미사(suffix)의 문자가 차례로 포함되어 있습니다. 연속하는 각 캐릭터 라인에 대해, 그 소접미사(suffix)의 문자를 encode 하는 추가적인 일련의 값이 있는 경우, 그러한 값은 `cp_Utf8_chars` 에 보관 유지됩니다. 따라서, 이 밴드 전체의 길이는,`cp_Utf8_suffix` 밴드내의 모든 값을 합계한 것입니다.

정수 풀의 엔트리의 소접미사(suffix)의 길이가 0 인 경우, 그 캐릭터 라인은 소접미사(suffix)은 아니고 대접미사(suffix)을 가지고 있습니다. 각 대접미사(suffix)의 길이는,`cp_Utf8_big_suffix` 밴드의 1 요소로 지정됩니다. 따라서, 이 밴드의 길이는,`cp_Utf8_suffix` 밴드내의 0 치의 개수와 정확하게 일치합니다. 각 대접미사(suffix)은, 16 비트의 문자치로부터 완성되는 개별의 밴드로서 전송 되어 밴드의 1 요소가 1 문자를 나타냅니다. 각 대접미사(suffix)에, 이러한 밴드가 1 개 존재합니다. 이러한 밴드는 `cp_Utf8_big_suffix` 밴드의 직후에 있어, 정리해 `cp_Utf8_big_chars` 밴드로 불립니다. 일반적으로, 같은 형태의 데이터는 1 개의 밴드에 정리합니다만, 이러한 캐릭터 라인은 독립해 encode 할 수 있도록, 개별의 밴드에 넣어집니다. 이러한 캐릭터 라인은 일반적으로, 실제의 Java 문자는 아니고 바이너리 데이터의 배열을 encode 합니다.

대접미사(suffix)의 길이가 0 이 될 수도 있습니다. 이것은, 그 정수 풀 엔트리가 전의 캐릭터 라인의 빈 상태(empty)이 아닌 접두사인 것을 의미합니다. 그러한 경우, 대응하는 접미사(suffix)밴드는 archive파일내에서 영역을 점유 하지 않습니다. 길이 0 의 밴드는 영역을 전혀 점유 하지 않기 때문입니다.

이 개념에 대해서는, 부록의 마디로의사 코드에 관한 설명을 참조해 주세요.

##### 5.3. 3. 형태의 시그니챠

`cp_Signature` 정수 풀의 각 엔트리는, 형태의 캐릭터 라인을 나타냅니다. 클래스 파일 형식에서 필드나 메소드의 형태가 선언되는 것 멈춘 구 와 같습니다. 클래스 파일 형식에서는, 이러한 캐릭터 라인에는 단순한 `Utf8` 정수 풀 엔트리가 사용됩니다만, Pack200 파일 형식에서는, 일반적인 캐릭터 라인의 것보다 컴팩트한 표현을 사용할 수 있도록, 이러한 캐릭터 라인에 개별의 정수 풀을 할당할 수 있습니다.

시그니챠 정수는,`cp_Class` 정수에의 묻어 참조를 보관 유지할 수 있다고 하는 점으로써 특수합니다. 파묻히고 있는 클래스 참조가 스펠에 전개된 뒤는, 시그니챠 정수는 Utf8 정수와 등가입니다. 시그니챠 정수는, 유연성이 높게 임의의 캐릭터 라인을 나타낼 수가 있습니다만, 대문자의 `'L'` 에 계속되는 클래스명을 보관 유지하는 것이 많은 캐릭터 라인에 사용됩니다. 이러한 캐릭터 라인에는, 필드, 메소드, 및 로컬 변수의 형태, 총칭 `Signature` 속성등이 있습니다.

각 시그니챠 캐릭터 라인은, 1 개(살)의 「폼」이라고, 0 개 이상의 클래스 참조의 순서에 분해됩니다. 클래스 참조를 취득하기 위해서, 원의 시그니챠 캐릭터 라인으로 `L`classname`` 라고 하는 패턴에 일치하는 모든 순서가 검색되어classname 부분이 삭제됩니다. 이것이 `cp_Class` 정수 풀에의 참조로서 다루어집니다. 폼은, 원의 캐릭터 라인으로부터 클래스명이 삭제된 뒤의 나머지로서 정의됩니다.

폼에는, 삭제된 클래스명을 마크 하는 것 이외로, 문자 '`L`'를 포함할 수 없습니다.

따라서, 폼에는, 원의 형태 캐릭터 라인으로 클래스가 참조되고 있는 여러분치에, 문자 '`L`'가 포함되게 됩니다. 압축 해제 프로그램에서는, 폼내의 이러한 문자를 세는 것으로, 원의 형태 캐릭터 라인으로 참조되고 있는 클래스의 수를 추정할 수가 있습니다. 이 수는, 폼의 「클래스장」이라고 불립니다.

`cp_Class` 의 정수는, 기존의 클래스를 참조할 필요는 없고, 유효한 클래스명의 스펠을 보관 유지할 필요조차 없습니다. 따라서, 압축 프로그램에서는, 시그니챠 캐릭터 라인으로부터 추출하는 클래스명이 있는 경우, 그 선택의 자유도가 꽤 높아집니다. 극단적인 경우, 각 폼을 그 대응하는 시그니챠 캐릭터 라인과 동일하게 해, 빈 상태(empty)의 이름을 가지는 가공의 클래스에의 참조를 발행해 클래스장을 만족시킬 수도 있습니다. 이 클래스장에는, 클래스명 자체에 포함되는 `'L'` 의 발생수도 모두 포함할 필요가 있습니다.

또,`Signature` 속성의 총칭형의 인스턴스의 경우, 클래스명의 후에는 일반적으로은 세미콜론이나 왼쪽산괄호가 계속됩니다만, 이러한 encode 규칙으로 필수의 문자가 지정되고 있는 것은 아닙니다.

규칙에서는, 각 `'L'` 문자의 후에 문자가 있는 경우에 그 몇개(살)을 클래스명의 일부로서 전송 할지도, 압축 프로그램으로 임의로 결정할 수 있게 되어 있습니다. 따라서, 1 개의 시그니챠 캐릭터 라인이 몇개의 폼으로 나타내지는 경우도 있어, 압축 해제 프로그램은 그것들 모든 것을 처리할 수 있도록(듯이) 준비할 필요가 있습니다.

다음에 몇개의 예를 나타냅니다.

형태의 시그니챠 캐릭터 라인 | Form | 클래스 장 | 클래스
`F` | `F` | 0
`[Z` | `[Z` | 0
`[[[LLL;` | `[[[L;` | 1 | `LL`
`[[[LLL;` | `[[[LLL;` | 3 | `(빈 상태(empty)), (빈 상태(empty)), (빈 상태(empty))`
`([Ljava/lang/String;) V` | `([L;) V` | 1 | `java/lang/String`
`Ljava/util/List<Lpkg/Item;>;` | `L<L;>;` | 2 | `java/util/List, pkg/Item`
`(Ljava/lang/String;II) Lpkg/Item;` | `(L;II) L;` | 2 | `java/lang/String, pkg/Item`
`Ljava/util/List<Ljava/lang/Byte;>;` | `L<L;>;` | 2 | `java/util/List, java/lang/Byte`
`<ELEM:>(Ljava/util/List<TELEM;>;) TELEM;` | `<EL:>(L<TEL;>;) TEL;` | 1 | `EM, java/util/List, EM, EM`
`ALLOWABLE` | `ALLOWABLE` | 3 | `(빈 상태(empty)), (빈 상태(empty)), (빈 상태(empty))`
`ALLOWABLE` | `AL` | 1 | `LOWABLE`
`ALLOWABLE` | `ALABL` | 2 | `LOW, E`

`cp_Signature` 정수 풀내의 모든 캐릭터 라인의 폼은,`cp_Signature_form` 밴드내에서 차례로 지정되어 각 시그니챠 캐릭터 라인 마다 1 개의 `cp_Utf8` 참조로 나타내집니다. 각 폼에 대해, 시그니챠 캐릭터 라인을 복구성 하기 위해서 필요한 클래스의 순서가, 클래스장과 같은 길이만,`cp_Signature_classes` 밴드내가 연속한 `cp_Class` 참조로서 전송 됩니다. 이러한 정의의 결과로서,`cp_Signature_classes` 밴드의 길이는,`cp_Signature_form` 에 기술되고 있는 폼의 스펠 순서에 발생하는 `'L'` 문자의 합계수가 됩니다.

      cp_Signature:
            *cp_Signature_form :DELTA5 [#cp_Signature_count](cp_Utf8)
            *cp_Signature_classes :UDELTA5 [COUNT('L',...)] (cp_Class)

이 개념에 대해서는, 부록의 마디로의사 코드에 관한 설명을 참조해 주세요.

##### 5.3. 4. 타풀 정수

나머지의 정수 풀에는, 각종의 값 (형태, 이름, 문자, 클래스등)의 페어가 차례로 보관 유지됩니다. `cp_Descr` 의 각 정수는, 이름과 형태의 페어를 차례로 늘어놓은 것입니다. 이름은 `cp_Utf8` 참조, 형태는 `cp_Signature` 참조로 나타내집니다. 이러한 참조는,`cp_Descr_name` 밴드와 `cp_Descr_type` 밴드의 대응하는 요소로 전송 됩니다.

같이`cp_Field`,`cp_Method`, 및 `cp_Imethod` 의 각 정수는, 클래스와 이름·형태 기술자의 페어를 차례로 늘어놓은 것입니다. 클래스는 `cp_Class` 참조, 이름·형태 기술자는 `cp_Descr` 참조로 나타내집니다. 이러한 참조도, 관련지을 수 있고 있는 밴드의 대응하는 요소로 전송 됩니다.

      cp_Descr:
            *cp_Descr_name :DELTA5 [#cp_Descr_count] (cp_Utf8)
            *cp_Descr_type :UDELTA5 [#cp_Descr_count] (cp_Signature)
      cp_Field:
            *cp_Field_class :DELTA5 [#cp_Field_count] (cp_Class)
            *cp_Field_desc :UDELTA5 [#cp_Field_count] (cp_Descr)
      cp_Method:
            *cp_Method_class :DELTA5 [#cp_Method_count] (cp_Class)
            *cp_Method_desc :UDELTA5 [#cp_Method_count] (cp_Descr)
      cp_Imethod:
            *cp_Imethod_class :DELTA5 [#cp_Imethod_count] (cp_Class)
            *cp_Imethod_desc :UDELTA5 [#cp_Imethod_count] (cp_Descr)

#### 5.4. 파일의 속성

JAR 어카이브(archive)는 일련의 파일로 구성되어 각 파일이 내용 물어 구두인가의 속성을 가지고 있습니다. 따라서, Pack200 어카이브(archive)에서는, 속성을 가지는 파일의 순서를 나타낼 수도 있습니다. 당연, 클래스 파일의 내용은 특별히 전송 됩니다만, 파일 (즉 JAR 어카이브(archive)의 요소)에 클래스가 포함되어 있을까 다른 자원이 포함되어 있을까에 관계없이, Pack200 어카이브(archive)는 다음의 속성을 전송 할 수가 있습니다.

- 파일의 이름 (클래스의 경우는 생략 가능)
- 파일의 내용 (클래스의 경우는 생략 가능)
- 파일의 갱신 시각 (생략 가능)
- 파일의 디플레이션 힌트 (생략 가능)
- 어카이브(archive)내의 파일의 차례 (클래스의 경우는 생략 가능)

클래스 파일의 내용이 Pack200 로 압축되는 경우, 그 클래스 파일은 특별한 옵션 비트로 「Stub」로서 마크 됩니다. 클래스 Stub 파일은, 길이 0 을 가지도록(듯이) 선언될 필요가 있습니다. 이름으로서 빈 상태(empty)의 캐릭터 라인을 가지도록(듯이) 선언되는 경우도 있습니다. 전송 되는 클래스 Stub 파일의 수가, 전송 되는 클래스의 수에 못 미친 경우, 압축 해제 프로그램은, 압축 프로그램으로부터 일련의 무의미한 Stub, 예를 들어 이름이나 내용, 어카이브(archive) 헤더로부터 카피되는 갱신 시각이나 디플레이션 힌트를 가지지 않는 Stub가, 추가로 전송 되었을 경우와 같게 동작할 필요가 있습니다.

Pack200 어카이브(archive)에서는, 각 resource file는 단순한 바이트 단위의 이미지로서 상대 경로명으로 전송 됩니다. 상대 경로명의 디렉토리의 단락 문자에는, slash (/)가 사용됩니다. 이 경로명의 규칙은, ZIP 어카이브(archive)로 사용되는 것 것과 같습니다. resource file와 클래스 파일의 어느 쪽의 경우도, 각 파일에 디플레이션 힌트나 갱신 일자를 임의로 지정할 수 있습니다.

      file_bands:
            *file_name :UNSIGNED5 [#file_count] (cp_Utf8)
            *file_size_hi :UNSIGNED5 [#file_count*(#have_file_size_hi)]
            *file_size_lo :UNSIGNED5 [#file_count]
            *file_modtime :DELTA5 [#file_count*(#have_file_modtime)]
            *file_options :UNSIGNED5 [#file_count*(#have_file_options)]
            *file_bits :BYTE1 [SUM(*file_size)]

코멘트, 여분의 속성, CRC 치등의 추가적인 파일 속성은 없습니다. 어플리케이션으로 일부의 파일에 그러한 속성을 사용할 필요가 있는 경우는, 파일을 적절한 archive파일 형식 (ZIP 등)에 encode 해, 그러한 어카이브(archive)를 Pack200 어카이브(archive)로 resource file로서 전송 할 수가 있습니다.

각 파일의 이름은 `file_name` 밴드의 요소로서 전송 되어 길이 (바이트수)는 `file_size_lo` 밴드와 `file_size_hi` 밴드 (존재하는 경우)의 대응하는 요소로 전송 됩니다. 이것들 3 개의 밴드의 길이는 모두 `#file_count` 입니다. 다만,`#archive_options` 의 `have_file_size_hi` 비트가 설정되어 있지 않은 경우,`file_size_hi` 의 요소수는 0 이 됩니다.

각 파일의 길이는 바이트수로 나타내져`file_size_hi` 밴드가 빈 상태(empty)의 경우는,`file_size_lo` 밴드로부터 취득되는 대응하는 32 비트 부호 없음치와 일치합니다. 그 이외의 경우, 파일의 길이는 64 비트의 부호 없음의 값으로,`file_size_lo` 밴드와 `file_size_hi` 밴드의 대응하는 32 비트 부호 없음 요소로 구성됩니다. 전자의 값은 하위의 32 비트 워드, 후자의 값은 상위의 32 비트 워드입니다.

클래스 파일 이외의 파일 (즉 resource file)의 바이트는,`file_bits` 밴드내에서 직후에 계속됩니다. 각 파일은, 대응하는 연속한 바이트치로서 지정됩니다.

임의 지정의 밴드 `file_modtime` 는, 빈 상태(empty)이 아닌 경우, 각 resource file의 갱신 시각을 지정합니다 (클래스 파일 Stub가 존재하는 경우는 클래스 파일의 갱신 시각을 지정하는 경우도 있습니다). 각 정수치는,`#archive_modtime` 의 값과의 차이를 초수로 가리킵니다. 따라서,`#archive_modtime` 의 값이 0 의 경우는, 개개의 파일 시각을 절대치로서 해석할 필요가 있습니다. `file_modtime` 의 전송 순서는,`file_name` 의 전송 순서와 일치합니다. `#archive_options` 의 `have_file_modtime` 비트가 설정되어 있지 않은 경우, 이 밴드는 비웁니다.

임의 지정의 밴드 `file_options` 는, 빈 상태(empty)이 아닌 경우, 각 resource file의 flag bit를 지정합니다 (클래스 파일 Stub가 존재하는 경우는 클래스 파일의 flag bit를 지정하는 경우도 있습니다). `#archive_options` 의 `have_file_options` 비트가 설정되어 있지 않은 경우, 이 밴드는 비웁니다. `file_options` 의 각 워드는 비트 단위로 해석됩니다. 일부의 비트에는 다음과 같은 기호명이 주어지고 있습니다. LSB 는 비트 0 입니다.

비트 | 이름 | 목적
0 | deflate_hint | 압축된 JAR 파일 요소를 요구합니다
1 | is_class_stub | 이 파일에는 클래스의 바이트 코드가 보관 유지되고 있습니다

`deflate_hint` (LSB)가 설정되어 있는 경우, 압축 해제 프로그램은 그 출력의 사이즈를 작게 하도록(듯이) 요구됩니다 (다만 필수는 아니다). 예를 들어, 압축 해제 프로그램으로 JAR 파일을 생성하는 경우는, JAR 요소를 압축하면 좋을 것입니다. `#archive_options` 워드의 `deflate_hint` 비트도 같은 효과를 가지고 있기 (위해)때문에, 실제로는, 각 파일에 대해 이것들 2 개의 비트의 논리합이 놓칩니다. `is_class_stub` (최하정도로부터 2 번째의 비트)이 설정되어 있는 경우, resource file의 설명은 실제로는 「Stub」가 되어, 파일의 내용은 Pack200 어카이브(archive)로 정의되는 몇개의 클래스의 바이트 코드로서 정의됩니다. 파일 옵션외의 비트는, 장래 사용하기 위해서 예약되고 있어 0 이 아니면 안됩니다.

전송 되는 파일이 클래스 Stub로서 마크 되고 있는 경우, 그 내용의 전송은, 파일이 빈 상태(empty)의 경우와 같게 행해질 필요가 있습니다. 즉,`file_size_hi` 와 `file_size_lo` 는 어느쪽이나 0 이 아니면 안되어, 대응하는 바이트가 `file_bits` 에 포함되어 있어서는 안됩니다. 압축 해제 프로그램은,`class_this` 등으로 전송 되는 클래스에 도착해, 클래스 파일의 내용을 복구성 하는 것에 의해 resource file의 내용을 제공할 필요가 있습니다. 다른 resource file와 같게, 클래스 Stub는 이름, 갱신 시각, 및 `deflate_hint` 를 가질 수가 있습니다.

클래스 Stub와 클래스의 순서는 일치합니다. 파생 파라미터 `#class_stub_count` 는, 클래스 Stub로서 마크 된 파일의 수로 정의됩니다. 이것은 `file_options` 로 설정되어 있는 `is_class_stub` 비트의 수이기도 합니다. 따라서,`#class_stub_count` 는 `#class_count` 이하가 아니면 안됩니다. 최초의 클래스 Stub는, 최초의 클래스의 바이트 코드를 받는 파일을 정의해, 이하와 같이 계속됩니다. 클래스 Stub에는 이름이 있어,`file_name` 로 전송 됩니다만, 이 이름은 빈 상태(empty)의 캐릭터 라인의 경우도 있습니다. 이 경우, 압축 해제 프로그램에서는, 클래스 파일의 표준명을 사용할 필요가 있습니다. 이것은, 클래스의 바이트 코드명에 캐릭터 라인 「. class」를 부가하는 것에 의해 작성됩니다 (패키지의 단락 문자에는 slash (/)를 사용). 따라서, 클래스 파일에 표준명 이외의 임의의 이름을 붙일 수도 있습니다만, 일반적으로의 방법으로 클래스로부터 작성한 이름을 붙이면(자), 최적인 압축 처리가 됩니다.

`#class_count` 가 `#class_stub_count` 보다 큰 경우, 압축 해제 프로그램은, 마지막 명시적 파일의 후에 충분한 수의 무의미한 클래스 Stub가 추가로 전송 되었을 경우와 같게 동작할 필요가 있습니다. 이러한 무의미한 Stub의 이름은 빈 상태(empty)의 캐릭터 라인으로,`deflate_hint` 이나 `file_modtime` 는 0 입니다.

따라서, (`have_file_options` 가 0 인 등의 이유로써) 클래스 Stub가 전혀 없는 단순한 경우에는, 압축 해제 프로그램은 파일을 그 전송 순서에 따라 생성해, 다음에 클래스의 전송 순서에 따라 생성할 필요가 있습니다. 각 클래스 파일에는, 표준명, 갱신 시각, 및 디플레이션 힌트가 필요합니다. 이것들은,`#archive_modtime` 및 `#archive_options` 의 `deflate_hint` 비트로부터 상속됩니다. 여분의 전송 사이즈가 필요하게 됩니다만, 압축 프로그램으로부터 압축 해제 프로그램에 지시해, resource file나 클래스 파일을 임의의 고정 순서로 출력하거나 각 출력 파일에 임의의 이름, 갱신 시각, 및 디플레이션 힌트를 지정하거나 할 수도 있습니다. 압축 해제 프로그램은, 순서가 중요해지는 형식 (JAR 어카이브(archive)등)에서 출력하는 경우, 이 순서를 존중할 필요가 있습니다.

압축 프로그램에서는, 특별히 다른 지시가 없는 경우, 파일의 순서를 임의에 선택할 수 있습니다. 유사한 통계 데이터를 가지는 파일이 서로 인접하도록(듯이) 늘어놓으면(자), 포스트패스 압축 프로그램이 존재하는 경우는 파일의 내용을 정리해 (DEFLATE 알고리즘의 경우는 같은 윈도우로) 처리할 수 있게 되어, 유리하게 되는 일이 자주 있습니다. 전송 효율이 향상하도록(듯이) 입력 파일을 다시 늘어놓을 수 있는 압축 프로그램이면, 입력 파일의 원의 순서를 유지하도록(듯이) 강제하는 커멘드 옵션을 갖추고 있겠지요. 모두가 아닙니다만, 일부의 배치 어플리케이션에서는 이 순서가 중요하게 되기 (위해)때문에입니다.

압축 프로그램에서는, 클래스 파일을 resource file와 같게 취급해 전송 할 수도 있습니다. 비트 단위로 정확하게 유지할 필요가 있는 클래스 파일이나, 압축 프로그램으로는 충분한 정밀도로 압축해 전송 할 수 없는 클래스 파일도, 이 방법을 사용해 전송 할 수가 있습니다. 압축 해제 프로그램은, resource file로서 비트 단위로 전송 되는 클래스 파일을 받아들일 필요가 있습니다.

주:압축 해제 프로그램으로 실행되는 마지막 처리는 출력 파일의 조립이므로, 압축 해제 프로그램의 구현을 다소 용이하게 하기 위해서, 파일과 그 속성을 제어하는 밴드는 어카이브(archive)의 마지막에 전송 됩니다. 특히, resource file의 사이즈는 임의이므로, 그 비트를 어카이브(archive)의 말미에 배치하는 것으로, 압축 해제 프로그램으로 resource file용의 일시적인 기억 영역을 할당할 필요가 없어집니다.

#### 5.5. 플래그와 속성

Pack200 파일 형식에서는, 클래스 파일 형식에서 정의 떠날 수 있어 모든 출력 플래그 필드에서 최대 16 의 수식자 비트를 직접 지원하고 있습니다. 또,`Code`,`InnerClasses`,`ConstantValue` 라고 하는 일부의 정의가 끝난 속성도 직접 지원하고 있습니다. 압축 프로그램으로 추가의 속성을 정의해, 압축 해제 프로그램에 충분한 정보를 건네주어, 그 데이터를 밴드로부터 올바르게 추출해 클래스 파일에 복구성 할 수 있도록(듯이) 할 수도 있습니다. 속성의 유무는, 모두 플래그 밴드의 특정의 비트의 설정에 의해 제어됩니다.

5 세트의 「플래그 밴드」에서는, 수식자 비트나 속성 제어 비트가 전송 됩니다. `ic_flags` 밴드에서는, 상자의 클래스의 수식자 비트가 전송 됩니다. 또,`class_flags_lo`,`field_flags_lo`,`method_flags_lo`, 및 `code_flags_lo` 와 각각 대응하는 생략 가능한 상위 워드 밴드 `class_flags_hi`,`field_flags_hi`,`method_flags_hi`, 및 `code_flags_hi` 에서도, 수식자 비트와 속성 제어 비트가 전송 됩니다. `ic_flags` 에는 상위 워드는 없습니다. 이러한 밴드내의 각 치는, 32 비트 부호 없음 바이너리 수치로서 해석됩니다. 이러한 밴드내의 각 비트는, Java 액세스 수식자 (`ACC_PRIVATE` 등)의 유무, 클래스 속성, 필드 속성, 메소드 속성, 코드 속성 (`Deprecated` 이나 `SourceFile` 등)의 유무, 또는 필요한 다른 제어 정보 (클래스 파일에 디폴트 이외의 버젼 번호가 설정되어 있는지 어떤지 등)의 유무를, 각각 독립해 지정합니다.

클래스, 필드, 메소드, 및 `Code` 의 각 속성에 대해, 최대 63 비트의 플래그치가 각각 `class_flags_lo`,`field_flags_lo`,`method_flags_lo`,`code_flags_lo` 로 전송 되어 경우에 따라서는 `class_flags_hi`,`field_flags_hi`,`method_flags_hi`,`code_flags_hi` 에서도 전송 됩니다. 이러한 플래그치는, 각각 `class_flags`,`field_flags`,`method_flags`,`code_flags` 로 불리는 64 비트 수치에 조립할 수 있습니다. `Code` 속성을 제외해, flag bit의 하위 16 비트는 액세스 플래그의 전송에 사용할 수 있습니다. 상위 16 비트 (생략 가능한 상위 워드도 전송 되는 경우는 47 비트)는, 정의가 끝난 속성 또는 압축 프로그램으로 정의된 속성이 존재할지 어떨지를 나타내기 위해서(때문에) 사용됩니다. 플래그치의 64 번째의 비트 위치는 예약되고 있어 전송 되는 경우는 0 이 아니면 안됩니다.

`Code` 속성의 플래그치는 생략 가능해, 생략 되고 있는 경우는 0 으로 보여집니다. `Code` 속성의 플래그치가 전송 되는 것은,`#archive_options` 의 `have_all_code_flags` 비트가 설정되어 있는지,`Code` 속성에 대응하는 `code_headers` 의 요소에 특수한 값 0 이 설정되어 있는 경우만입니다. 코드 헤더의 상세한 것에 대하여는,아래와 같이를 참조해 주세요.

클래스, 상자의 클래스, 필드, 및 메소드의 경우, 수식자에 대한 flag bit 위치의 할당은, 클래스 파일 형식에서 사용되는 것 것과 같습니다. 예를 들어, Pack200 어카이브(archive) 형식과 클래스 파일 형식의 어디라도, LSB 는 항상 `ACC_PUBLIC` 를 나타냅니다. 「오버플로우 속성」이라고 불리는 속성의 유무는, flag bit로 직접 나타나는 것이 아니라, 다른 밴드에 그 인덱스가 발생하는 것에 의해 나타납니다. 클래스, 필드, 메소드, 및 코드의 경우, 마스크 0x0001000 로 설정되는 비트 16 은, 오버플로우 속성의 유무를 나타냅니다. 상자의 클래스의 경우, flag bit 16 은, 외측의 클래스와 이름에 관한 명시적인 필드의 유무를 나타냅니다. 상세한 것에 대하여는,아래와 같이를 참조해 주세요.

비트 | 의미
0 | ACC_PUBLIC
1 | ACC_PRIVATE
2 | ACC_PROTECTED
3 | ACC_STATIC
4 | ACC_FINAL
5 | ACC_SYNCHRONIZED (ACC_SUPER)
6 | ACC_VOLATILE (ACC_BRIDGE*)
7 | ACC_TRANSIENT (ACC_VARARGS*)
8 | ACC_NATIVE
9 | ACC_INTERFACE
10 | ACC_ABSTRACT
11 | ACC_STRICT
12 | ACC_SYNTHETIC*
13 | ACC_ANNOTATION*
14 | ACC_ENUM*
16 | 오버플로우 (다른 장소에 한층 더 밴드 데이터가 있다)

asterisk (*)로 마크 된 수식자는, Java 의 최근의 버젼으로 새롭게 추가된 것입니다. 이것들은 Pack200 스펙에는 포함되지 않고, 여기에서는 단순한 정보로서 기재되어 있습니다.

##### 5.5. 1. 속성에의 flag bit의 할당

속성에 대한 flag bit 위치의 할당은, 압축 프로그램으로 자유롭게 행해져 4 종류의 플래그 워드 각각 독립해 지정됩니다. 이러한 플래그 워드는, (클래스, 필드, 메소드, 및 코드로) 속성을 보관 유지하는 객체에 관련하는 것입니다. 속성에 flag bit 위치를 할당할 수 있고 있는 경우, 그 비트가 클래스 파일로 가시이면, 압축 해제 프로그램으로 클래스 파일에 기입하기 전에, 그 비트를 클리어 할 필요가 있습니다. 따라서, 특정의 0 이 아닌 flag bit가 압축 해제 프로그램으로 출력으로서 재생성되면(자) 상정되는 경우, 압축 프로그램에서는 그 비트 위치를 속성에 할당하지 않게 할 필요가 있습니다.

특히, 클래스, 필드, 및 메소드의 플래그의 하위 16 비트는 클래스 파일로 가시가 되기 (위해)때문에, 수식자 비트를 보관 유지할 수가 있습니다. 코드 플래그 워드의 비트는 모두 클래스 파일로 불가시가 됩니다. 이러한 flag bit는, 코드의 서브 속성인 만큼 사용됩니다.

이것에 대해, 상자의 클래스 레코드에는 속성이 포함되지 않기 때문에, 상자의 클래스 레코드의 하위 16 비트는 수식자인 만큼 사용됩니다. 속성에 관한 이 마디의 남은 부분에서는, 상자의 클래스 레코드에 관련하는 플래그 워드는 무시하기로 하겠습니다.

압축 프로그램에서는, 특정의 속성의 유무를 압축 해제 프로그램에 나타내기 위해서(때문에), 플래그치의 63 비트의 임의의 위치를 할당할 수가 있습니다. 압축 프로그램에서는, 수식자 비트에 속성의 정의를 할당하는 것에 의해, 수식자 비트를 「상속한다」일이 생깁니다. 그 때문에(위해)는, 그 비트 위치를 기술하는 속성의 정의를 발행합니다.

수식자 비트인가 어떤가에 관계없이, 디폴트로 다른 목적으로 사용되고 있는 비트를 압축 프로그램으로 「덧쓰기한다」경우, 그 비트는 원의 의미를 잃습니다. 다만, 압축 프로그램은, 같은 비트에 대해 (같은 문맥으로) 명시적인 정의를 2 회 발행할 수 없습니다.

각종류의 속성은, 4 개의 정보에 의해 정의됩니다. 즉, 적용 대상인 엔티티 (클래스, 필드, 메소드, 또는 코드), 할당할 수 있고 있는 비트 위치가 있으면 그 비트 위치, 클래스 파일에 나타나는 대로의 속성의 이름, 및 (클래스 파일에 발생하는 속성을 압축 해제 프로그램으로 올바르고 서식 설정할 수 있도록(듯이) 한다) 속성의 레이아웃입니다. 압축 프로그램으로, 같은 이름과 레이아웃을 같은 문맥으로 2 회 지정하는 것은 잘못입니다. 다른 레이아웃으로 같은 이름을 반복하는 것이나, 다른 이름으로 같은 레이아웃을 반복하는 것은, 잘못이 아닙니다.

최초의 2 개의 항목은, 1 바이트의 「헤더」에 비트 단위로 encode 되어`attr_definition_headers` 밴드로 전송 됩니다. 마지막 2 개의 항목은,`attr_definition_name` 밴드와 `attr_definition_layout` 밴드의 대응하는 요소로 `cp_Utf8` 참조로서 전송 됩니다. 따라서, 압축 프로그램은 3 개의 밴드를 사용해 압축 해제 프로그램에 속성의 형태를 선언해, 이러한 각 밴드의 길이는 `#attr_definition_count` 입니다.

      attr_definition_bands:
            *attr_definition_headers :BYTE1 [#attr_definition_count]
            *attr_definition_name :UNSIGNED5 [#attr_definition_count] (cp_Utf8)
            *attr_definition_layout :UNSIGNED5 [#attr_definition_count] (cp_Utf8)

속성 정의의 헤더 바이트의 최하정도 2 비트는, 부호 없음 필드로서 다루어져 속성의 「문맥 타입」을 지정합니다. 문맥 타입이란, 속성의 적용 대상인 엔티티의 종류입니다.

`(h & 0x03)` | 문맥 타입
0 | 속성은 클래스에 적용됩니다
1 | 속성은 필드에 적용됩니다
2 | 속성은 메소드에 적용됩니다
3 | 속성은 Code 속성에 적용됩니다

속성 정의의 헤더 바이트의 최상정도 6 비트는, 부호 없음 필드로서 다루어져 속성이 플래그 워드의 어느 비트 위치에 할당할 수 있을까를 임의로 지정합니다.

`(h >> 2)` | flag bit의 할당
0 | 오버플로우 속성. 어느 비트에도 할당할 수 없습니다
1 | 속성은 비트 0 (하위 워드의 LSB)에 할당할 수 있습니다
2 | 속성은 비트 1 에 할당할 수 있습니다
3 | 속성은 비트 2 에 할당할 수 있습니다
...
32 | 속성은 비트 31 (하위 워드의 MSB)에 할당할 수 있습니다
33 | 속성은 비트 32 (상위 워드의 LSB)에 할당할 수 있습니다
...
63 | 속성은 비트 62 에 할당할 수 있습니다
(값없음) | 비트 63 (상위 워드의 MSB)은 0 이 아니면 안됩니다

각 클래스 속성은, 이 스펙으로 미리 정의되고 있는 속성이나 압축 프로그램으로 명시적으로 정의된 속성인가에 관계없이, 「속성 인덱스」라고 불리는 일의의 번호를 가지고 있습니다. 속성에 flag bit를 할당할 수 있고 있는 경우, 그 속성 인덱스는 flag bit의 위치 (0 에서 62 까지의 번호)와 같게 됩니다. 정의가 끝난 속성에는, 모두 디폴트로 flag bit를 할당할 수 있습니다.

클래스 속성에 flag bit를 할당할 수 있지 않은 경우, 그것은 오버플로우 속성이며, 그 인덱스는 클래스 속성의 정의 순서 (즉 전송 순서)에 따라 차례로 할당할 수 있습니다. 이 방법으로 차례로 할당할 수 있는 최초의 인덱스는,`#have_class_flags_hi` 가 설정되어 있지 않은 경우는 32 로, 설정되어 있는 경우는 63 이 됩니다. 이러한 인덱스는, 개개의 클래스에 발생하는 속성을 선언하기 위해서, 어카이브(archive)내에서 사용됩니다.

같이 필드 속성, 메소드 속성, 및 코드 속성에도, 각각 독자적인 속성 인덱스를 할당할 수 있습니다. 클래스 속성의 인덱스나 이러한 인덱스는, 서로 독립하고 있습니다. 따라서, 속성 (즉 이름과 레이아웃의 페어)은, 그 문맥 타입과 속성 인덱스에 의해 어카이브(archive)내에서 일의로 지정됩니다. 필드 속성과 메소드 속성은, flag bit에 할당할 수 있는 경우가 있어, 그 이외의 경우는 32 이상의 인덱스를 가지는 오버플로우 속성입니다. 다른 속성과 같게, 코드 속성에는 명시적인 수치를 할당하는지, 32 로부터 시작되는 인덱스를 암묵적으로 할당할 수가 있습니다. 클래스 속성의 경우와 같게,`#archive_options` 의 해당하는 비트에 의해 상위 플래그 워드의 밴드가 선택되었을 경우, 필드, 메소드, 및 코드의 오버플로우 속성의 인덱스는 63 이상이 됩니다.

몇개의 속성은 미리 정의되고 있어 압축 프로그램으로 이러한 정의를 발행할 필요는 없습니다. 레이아웃과 flag bit의 할당 (인덱스)은 암묵적으로 정의되고 있습니다.

63 보다 작은 속성 인덱스는 모든 경우에 사용할 수 있습니다만, 정의가 끝난 속성에 할당할 수 있고 있는 인덱스와 충돌할 가능성이 있습니다. 이것에는, Pack200 형식의 장래의 확장으로 정의되는 정의가 끝난 속성 (16 에서 62 까지의 범위)도 포함됩니다. 현재의 버젼에서는, 정의가 끝난 속성의 인덱스는 모두 17 에서 31 까지의 범위에 있기 (위해)때문에, 수식자 플래그가 디폴트로 덧쓰기될 것은 없고, 또, 상위 플래그 워드를 항상 사용할 필요는 없습니다.

정의가 끝난 속성의 이름과 인덱스 할당을 다음에 나타냅니다. 정의 끝난 레이아웃에 대해서는 후술 합니다.

색인 | 문맥 타입 | 이름
16 | C, F, M | (오버플로우 속성)
17 | 클래스 | SourceFile
18 | 클래스 | EnclosingMethod
19 | C, F, M | Signature
20 | C, F, M | Deprecated
21 | C, F, M | RuntimeVisibleAnnotations
22 | C, F, M | RuntimeInvisibleAnnotations
23 | 클래스 | InnerClasses
24 | 클래스 | "class-file version"
17 | 필드 | ConstantValue
17 | 메소드 | Code
18 | 메소드 | Exceptions
23 | 메소드 | RuntimeVisibleParameterAnnotations
24 | 메소드 | RuntimeInvisibleParameterAnnotations
25 | 메소드 | AnnotationDefault
0 | 코드 | StackMapTable
1 | 코드 | LineNumberTable
2 | 코드 | LocalVariableTable
3 | 코드 | LocalVariableTypeTable
16 | 코드 | (오버플로우 속성)

비트 16 은, 클래스, 필드, 메소드, 및 코드의 오버플로우 속성의 유무를 나타내는 인디케이터(indicator)로서 미리 정의되고 있습니다. 엔티티에 오버플로우 속성이 존재하는 경우는, 그 수가 attr_count 밴드에 보관 유지되어 오버플로우 속성의 레이아웃을 지정하는 attr_indexes 밴드에 각 오버플로우 속성이 연속한 값으로 해서 보관 유지됩니다. 이 오버플로우 속성의 처리에 대해 자세하게는,아래와 같이를 참조해 주세요.

이러한 정의가 끝난 속성 인덱스는, 속성을 선택하기 위한 비트 위치 뿐만이 아니라, 속성 데이터를 전송 하는 밴드의 고정 순서도 결정합니다. 상세한 것에 대하여는,아래와 같이를 참조해 주세요.

클래스, 필드, 및 메소드에 관련하는 5 종류의 메타데이타 속성 `RuntimeVisibleAnnotations`,`RuntimeInvisibleAnnotations`,`RuntimeVisibleParameterAnnotations`,`RuntimeInvisibleParameterAnnotations`, 및 `AnnotationDefault` 를 지원하기 위한 비트도 미리 정의되고 있습니다. 마지막 3 종류는 메소드인 만큼 적용됩니다. 이러한 속성의 의미와 형식은, JSR 175 로 정의되고 있습니다.

압축 프로그램에서는, 플래그 워드의 비트 16 이외의 비트를 설정하지 않고 , 모든 속성 레이아웃 인덱스를 명시적으로 `class_attr_indexes` 등의 밴드로 전송 할 수도 있습니다. 압축 해제 프로그램은, 어느 쪽의 방법으로 발생한 속성 인덱스에서도 처리할 수 있을 필요가 있습니다. 무의미합니다만, 속성의 수가 명시적으로 0 으로서 전송 되는 경우도 있습니다. 압축 프로그램에서는 현명한 선택을 실시해, 가능한 경우는 비트 16 을 클리어 해, 할당할 수 있고 있는 것 외의 flag bit를 설정하도록 해 주세요.

정의가 끝난 비트는 모두, 클래스 파일 형식에 포함되는 16 비트 플래그치 중(안)에서 현재 사용되고 있는 flag bit나 장래 사용되는 flag bit와는 간섭하지 않습니다. 다만, 플래그 워드의 하위 16 비트는, 어느 파일에서도 실제로 설정되지 않는 경우, 압축 프로그램으로 자유롭게 다른 속성에 할당해 재사용할 수가 있습니다.

다른 마디로 설명하는 대로,`InnerClasses` 속성은 특별히 다루어지기 (위해)때문에, 압축 프로그램으로 이 속성의 정의를 클래스 문맥으로 발행하는 것은 잘못입니다. `Code` 속성도 특별히 다루어집니다. 이 속성의 정의를 메소드 문맥으로 발행하는 것은 잘못입니다.

이 스펙에서는, 정의가 끝난 상태가 아닌 속성의 유무나 형식을 어떻게 압축 프로그램에 통지할까는 정의되고 있지 않습니다. 이 스펙에서는, 압축 프로그램이 이러한 속성에 대해 통지되면(자) 상정해, 압축 프로그램으로부터 압축 해제 프로그램에 이 정보가 올바르고 전송 되는 것을 의무화 하고 있습니다. 특수한 케이스로서 바이트를 포함하지 않은 속성 (즉, 길이 0 의 속성)을 압축 프로그램으로 전송 하는 경우에, 빈 상태(empty)의 캐릭터 라인으로서 기존의 레이아웃을 가지는 속성인것 같이 전송 하는 것은 타당합니다.

##### 5.5. 2. 속성 레이아웃의 정의

속성 레이아웃은, 압축 프로그램이 클래스 파일로부터 속성의 본체를 해석해 스칼라치의 컬렉션으로 변환할 때, 그 동작을 관리합니다. 또, 압축 해제 프로그램이 그러한 스칼라치의 전송 된 밴드를 복호화 해, 올바른 서식에서 클래스 파일에 포함할 경우에도, 그 동작을 관리합니다. 예를 들어, 클래스 파일로 부호 없음 정수가 속성의 2 바이트에 (빅 endian순서로) 포함되는 경우, 압축 해제 프로그램은 레이아웃 선언을 사용해, 밴드 요소 (이 경우는 65536 보다 작은 32 비트의 정수)를 취득해, 클래스 파일에 올바르게 포함합니다. 클래스 파일 형식에서는 어느쪽이나 구별이 없는 바이트로서 표현됩니다만, 이러한 정수의 전송은 정수 풀의 참조의 전송과는 크게 다릅니다.

이후의 설명에서는, 클래스 파일의 속성에 포함되고 있는 스칼라치를 압축 해제 프로그램으로 클래스 파일에 복구성 할 경우에, 속성 레이아웃의 특정의 요소를 사용할 필요가 있는 경우는, 그 요소가 스칼라치를 「관리한다」라고 부르기로 하겠습니다. 그 특정의 레이아웃 요소가 스칼라치의 전송 되는 밴드를 관리한다, 라고도 부릅니다.

속성 레이아웃은 「잔소리어」의 캐릭터 라인으로 정의됩니다. 압축 해제 프로그램은, 이 캐릭터 라인을 해석해, 「레이아웃 요소」의 순서로 변환할 필요가 있습니다. 이러한 각 요소가, 속성치의 전송과 포함을 관리합니다. 특히, 레이아웃은 정수 풀의 참조의 위치를 모두 선언해, 그 값을 적절한 표현으로 (정수 풀 인덱스 또는 어떠한 수치로서) 전송 할 수 있도록(듯이) 합니다.

사용할 수 있는 속성 레이아웃이라고 해도 와도 단순한 것은, 정수 풀 참조의 선언의 순서에, 다른 모든 것을 관리하는 1 바이트의 선언을 혼합한 것이 되겠지요. 압축 프로그램에서는, 이러한 레이아웃을 임의로 사용해 속성을 기술할 수가 있습니다. 다만, 보다 구체적인 속성 레이아웃을 사용하는 (분)편이, 압축 처리는 향상합니다.

일반적으로, 속성에는 정수 풀의 참조와 주어진수가 포함되어 있습니다. 많은 경우, 이것들에는, 후속의 패턴의 복제를 제어하는 정수가 포함되어 있습니다. 정수 풀의 참조는, 가능하면 강하고 형지를 무늬를 박아서 염색한 것 됩니다. 또, null 참조에 대한 encode의 제공도 선언될 필요가 있습니다. flag bit 또는 바이트 코드 인덱스를 encode 하는 주어진수도, 그처럼 선언될 필요가 있습니다. 거기에 따라, 이러한 주어진수에 특별한 encode 기술을 사용할 수 있게 됩니다.

레이아웃의 선언은, 다음의 문법에 따라 구성된 UTF8 캐릭터 라인입니다. 이 문법은, 밴드 구조를 기술하는 문법이나, 이 스펙의 다른 부분에 기재되어 있는 것 외의 문법으로부터는 독립하고 있습니다.

      attribute_layout:
            ( layout_element )* | ( callable )+
      layout_element:
            ( integral | replication | union | call | reference )

      callable:
            '[' body ']'
      body:
            ( layout_element )+

      integral:
            ( unsigned_int | signed_int | bc_index | bc_offset | flag )
      unsigned_int:
            uint_type
      signed_int:
            'S' uint_type
      any_int:
            ( unsigned_int | signed_int )
      bc_index:
            ( 'P' uint_type | 'PO' uint_type )
      bc_offset:
            'O' any_int
      flag:
            'F' uint_type
      uint_type:
            ( 'B' | 'H' | 'I' | 'V' )

      replication:
            'N' uint_type '[' body ']'

      union:
            'T' any_int (union_case)* '(' ')' '[' (body)?  ']'
      union_case:
            '(' union_case_tag (', ' union_case_tag)* ')' '[' (body)?  ']'
      union_case_tag:
            ( numeral | numeral '-' numeral )
      call:
            '(' numeral ')'

      reference:
            reference_type ( 'N' )?  uint_type
      reference_type:
            ( constant_ref | schema_ref | utf8_ref | untyped_ref )
      constant_ref:
            ( 'KI' | 'KJ' | 'KF' | 'KD' | 'KS' | 'KQ' )
      schema_ref:
            ( 'RC' | 'RS' | 'RD' | 'RF' | 'RM' | 'RI' )
      utf8_ref:
            'RU'
      untyped_ref:
            'RQ'

      numeral:
            '(' ('-')?  (digit)+ ')'
      digit:
            ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )

클래스 파일에 발생하는 속성은, 각각 대응하는 레이아웃 정의에 (압축 프로그램에 의해) 관련지을 수 있습니다. 레이아웃 정의는, 속성의 바이트의 의미를 정확하게 기술하는 것입니다. 압축 프로그램에서는, 각 서식 요소가 연속하는 값을 전송 하기 위해서, 서식 요소 마다 독자적인 밴드를 할당할 필요가 있습니다. 정의가 끝난 속성의 경우, 그 레이아웃 요소에 할당할 수 있는 밴드는, 이 스펙으로 이름에 의해 정의되고 있습니다.

속성의 레이아웃 요소로 관리되는 각 치는, 압축 프로그램에 의해 32 비트치에 변환되어 밴드의 요소로서 전송 됩니다. 이 밴드는, 그 레이아웃 요소를 위해서(때문에) 일의에 작성되어 그 레이아웃 요소에 의해 관리됩니다. `integral` 레이아웃 요소의 경우, 그 변환은 단지, 클래스 파일에 특정의 형태로 포함되고 있는 수치를 나타냅니다. `reference` 요소는, 로컬 정수 풀의 참조 (클래스 파일에 있어 로컬, 이라고 하는 의미)를, 어카이브(archive)내에서 글로벌인 형태 부착 참조로 변환합니다.

같은 종류의 레이아웃 요소가 다수 있는 경우, 그것들은 별개의 레이아웃 요소라고 보여집니다. 또, 레이아웃간에 밴드가 공유될 것은 없습니다. 따라서, 압축 프로그램으로 전송 되는 새로운 레이아웃 정의 마다, 독자적인 밴드 세트가 암묵적으로 정의됩니다. 이전에 정의한 속성 레이아웃을 새로운 인덱스에 다시 할당하면(자) , 새로운 밴드 세트가 작성됩니다. 이전에 정의된 밴드 세트가 재사용될 것은 없습니다.

압축 프로그램으로 새로운 속성을 정의하는 경우는, 그러한 속성에 의해 관리되는 밴드도 작성할 필요가 있습니다. 압축 프로그램은 이러한 밴드를, 정의가 끝난 속성의 밴드 문법으로 예약되고 있는 위치의 직후 (`class_attr_bands`,`field_attr_bands`,`method_attr_bands`, 또는 `code_attr_bands` 의 말미)에 전송 할 필요가 있습니다. 이러한 밴드의 순서는, 그것들을 관리하고 있는 속성 레이아웃 요소의 정의 순서에 대응하고 있을 필요가 있습니다. 이와 같이 하면(자), 압축 해제 프로그램으로 속성치를 찾아낼 수가 있게 됩니다.

동일한 속성 레이아웃 캐릭터 라인에 포함되어 있는 2 개의 레이아웃 요소의 「정의 순서」는, 그 캐릭터 라인에 발생하는 순서에 대응합니다. 동일한 속성 레이아웃 캐릭터 라인에 포함되지 않은 2 개의 레이아웃 요소의 정의 순서는,`attr_definition_layout` 밴드에서의 레이아웃 정의의 인덱스 순서에 대응합니다. 즉, 같은 문맥 타입의 레이아웃의 밴드 끼리에서는, 인덱스의 작은 것이 큰 것보다 전이 됩니다. 작은 인덱스를 가지는 레이아웃이 `attr_definition_layout` 밴드로 나중에 정의되고 있는 경우에서도, 이것은 들어맞읍니다. 정의가 끝난 속성에 의해 관리되는 밴드도, 이러한 순서에 따라 있는 것처럼 보입니다. 다만, 정의 끝난 클래스 속성의 밴드는, 다른 모든 클래스 속성의 밴드보다 전이 됩니다. 필드 속성, 메소드 속성, 코드 속성에 대해서도 같습니다.

속성에 포함되는 정수치의 사이즈는, 서식 문자 'B', 'H', 또는 'I'에 의해 각각 1 바이트, 2 바이트, 또는 4 바이트로 지정됩니다. 정수형은 일반적으로은 부호 없음입니다만, 접두사 'S'를 가지는 것은 부호 첨부입니다. 이 부호부의 지정에 의해, 1 바이트형 또는 2 바이트형을 32 비트치에 확장할 방법 (부호를 확장하는지, 0 을 삽입할지)이 정해집니다. 또, 32 비트치의 전송에 사용되는 primary encode도 정해집니다. 클래스 파일에 포함되는 정수는 모두 「빅 endian」이므로, 어느 정수형 서식 요소도, 상위 비트로부터 먼저 바이트에 encode 되는 정수를 참조합니다.

정수형 레이아웃 (즉,`integral` 비끝어아래에 있는 요소)은, 부호 붙어 또는 부호 없음의 정수치를 관리합니다. ``정수형 레이아웃의 선언에 'P'문자 또는 'O'문자가 포함되어 있는 경우, 그 레이아웃에서는 특수한 primary encode BCI5 또는 BRANCH5 가 사용됩니다 (아래와 같이를 참조). 선언에 'S'문자를 포함하고 있는 것 외의 정수형 레이아웃은, primary encode SIGNED5 를 사용하는 밴드를 관리합니다. 부호 없음 정수 레이아웃 요소와 플래그 레이아웃 요소는, primary encode UNSIGNED5 를 사용하는 밴드를 관리합니다. 다만 예외로서 정수 레이아웃 'B' (부호 없음 바이트)는, primary encode BYTE1 를 사용하는 밴드를 관리합니다.

부호 첨부 바이트용의 특별한 encode는 없습니다. 속성에 부호 첨부 바이트 필드가 포함되어 있는 경우는, 부호 없음 필드와 같게 취급해, 단순한 'B'레이아웃 요소를 할당할 수가 있습니다. 'SB'레이아웃은, 부호 비트가 보기 드물게 밖에 사용되지 않는 바이트 알파벳을 사용해, 절대치의 작은 1 바이트 정수를 전송 할 수 있도록(듯이)하기 위한의 것입니다. 이것은, 포스트패스 압축 프로그램으로 Huffman 코딩을 사용해 바이트를 표현하는 경우에 바람직한 레이아웃입니다. 이러한 encode는, 일관성이 있는 바이트 알파벳이 압축 프로그램에 제공되었을 때에 최적으로 동작하기 (위해)때문에입니다.

포함된 바이트 코드 인덱스는, 레이아웃 접두사 'P'로 선언됩니다. 이 레이아웃 요소는, 메소드 또는 코드에만 사용할 수 있습니다. 바이트 코드 인덱스에는 임의의 수치를 포함할 수 있습니다. 다만, 포함된 수치는, 밴드 요소로서 전송 되기 전에 재설정됩니다. 이 처리는, 명령 경계상에 없는 바이트 위치는 보기 드물게 된다고 하는 전제로 행해집니다.

「BCI 리난바링」을 사용하면(자), 명령 경계의 인덱스를 컴팩트하게 작성할 수 있습니다. 또, 약간 컴팩트한 것은 없어집니다만, 명령내의 바이트의 주소나 바이트 코드의 경계외의 바이트의 주소 등, 다른 모든 32 비트 정수도 encode 할 수 있습니다. 구체적으로는, 최초의 명령의 최초의 바이트에는 0, 2 번째의 명령의 최초의 바이트에는 1, 과 같이 마지막 명령까지 번호를 붙일 수 있습니다. 마지막 명령의 1 개 후의 바이트 위치에는, 다음의 번호를 붙일 수 있습니다. 이것은, 명령의 수와 같은 값입니다. 최초의 복수 바이트 명령의 2 번째의 바이트에는, 다음의 번호를 붙일 수 있습니다. 이것은, 명령의 수부터 1 만 큰 값입니다. 번호를 붙일 수 있지 않은 나머지의 바이트에는, 후속의 번호를 할당할 수 있습니다. 더 이상의 순서의 혼란은 없습니다. 충분히 큰 정의 수치나, 부의 수치에 대해서는, 이 번호재설정은 항등 함수가 됩니다.

BCI 리난바링의 명령 경계의 위치를 검출하기 위해서, _wide 바이트 코드 (0xc4)는 다음의 명령의 일부라고 보여져 그 형식을 조사하는데 이용됩니다. 압축 프로그램으로부터 byte_escape (254) 또는 ref_escape (253)라고 하는 의사 명령이 전송 되었을 경우, 압축 해제 프로그램에서는, BCI 리난바링을 계산할 경우에, 이러한 각 명령에 의해 생성되는 바이트 코드 순서를 정수형의 명령으로서 받아들일 필요가 있습니다. 따라서, _wide 바이트 코드를 제외한 bc_codes 의 각 바이트에 명령 경계가 존재하는 것 외에"aload_0_xxx" 의 각 변화(variation) ("aload_0_getstatic_this" 등)에도 경계가 존재합니다. 이러한 의사 오퍼레이션 코드는, 바이트 코드 명령의 페어에 전개되기 (위해)때문에입니다.

이 개념에 대해서는, 부록의 마디로의사 코드에 관한 설명을 참조해 주세요.

레이아웃 요소의 접두사가 'P'로, 'PO'가 아닌 경우는, 번호재설정 후의 바이트 코드 인덱스가 전송 됩니다. 이 번호재설정은 「바이트 코드 인덱스의 리난바링」이라고 불립니다. 바이트 코드 인덱스를 보관 유지하는 밴드의 primary encode는 BCI5 입니다.

이 처리의 예를 다음에 나타냅니다. 20 바이트의 바이트 코드 데이터와 5 개의 명령을 가지는 메소드가 위치 `{ 0, 4, 6, 10, 17 }` 에 있다고 합니다. BCI 리난바링은 이것들 특정의 수치를 컴팩트하게 `[0..4]` 로 변환합니다. 보다 상세하게는, BCI 리난바링은 `[0..20]` 을 수치 `{ 0, 6, 7, 8, 1, 9, 2, 10, 11, 12, 3, 13, 14, 15, 16, 17, 18, 4, 19, 20, 5 }` 로 변환해,`[0..20]` 의 범위외에 있는 값은 변경하지 않습니다. 이 메소드의 속성에 'P'레이아웃 요소를 할당할 수 있고 있는 경우로, 클래스 파일에 수치 6 이 포함되고 있을 때, 6 은 3 번째의 명령의 오프셋(offset)이므로, 수치 2 가 전송 됩니다.

레이아웃의 접두사가 'PO'의 경우는, 그 전의 레이아웃 요소도 레이아웃 타입 'P'또는 'PO'의 바이트 코드 인덱스가 아니면 안됩니다. 그 사이에 꺽쇄묶음 '['나 ']'등의 구조가 존재 해서는 안됩니다. 이 경우, 'PO'요소에 의해 관리되는 밴드로 전송 되는 값은, 현재의 'PO'요소로 관리되는 번호재설정 후의 바이트 코드 인덱스와 그 전의 'P'또는 'PO'요소로 관리되는 번호재설정 후의 바이트 코드 인덱스와의 차이가 됩니다. 전의 요소가 'P'의 경우, 이것은 실제로 전의 밴드의 대응하는 위치에서 전송 되는 값이 됩니다.

'PO'레이아웃 요소는 'P'요소와 같은 종류의 속성 데이터를 관리합니다만, 인접하는 바이트 코드 인덱스 끼리에게 상관관계가 있는 것을 전제로 한 encode를 사용합니다. 이 번호재설정은, 전의 요소와의 차이를 포함해, 「바이트 코드 오프셋(offset)의 리난바링」이라고 불립니다. 바이트 코드 오프셋(offset)를 보관 유지하는 밴드의 primary encode는 BRANCH5 입니다. 레이아웃 요소에 'S'문자 또는 'B'문자가 포함되어 있는 경우에서도, 이 encode가 사용됩니다.

바이트 코드 오프셋(offset)는, 레이아웃 접두사 'O'로 선언됩니다. 이 레이아웃 요소는, 전의 바이트 코드 인덱스 요소 (접두사가 'P'로, 'PO'는 아닌 것)의 직후에 계속될 필요가 있습니다. 이 레이아웃 요소로 관리되는 값은 모두 오프셋(offset)라고 보여집니다. 전에 포함되고 있는 대응하는 바이트 코드 인덱스에 오프셋(offset)가 적용되어, 다른 바이트 코드 인덱스가 생성됩니다. 즉, 전의 값도, 전의 값과 현재의 값의 합계도, 명령 경계를 참조하는 것이 상정되고 있습니다. 'PO'레이아웃과 같게, 전송 되는 값은, 번호재설정 후의 2 살의 바이트 코드 인덱스의 차이가 됩니다. 'PO'레이아웃에 의해 관리되는 밴드는, 바이트 코드 오프셋(offset)를 보관 유지해, primary encode BRANCH5 를 사용합니다. 'PO'레이아웃과는 달라, 'O'레이아웃에 의해 관리되는 포함된 값은, 2 살의 바이트 코드 인덱스의 차이가 됩니다.

따라서, 'O'레이아웃과 'PO'레이아웃의 양쪽 모두에 의해 관리되는 밴드는, 바이트 코드 오프셋(offset)를 보관 유지해, BRANCH5 를 사용해 이러한 오프셋(offset)를 encode 합니다. 다만, 'P'레이아웃과 'PO'레이아웃의 양쪽 모두에 의해 관리되는 속성치는, 절대적인 바이트 코드 인덱스를 포함합니다. 포함된 바이트 코드 오프셋(offset)를 관리하는 것은 'O'레이아웃 뿐입니다. 포함된 오프셋(offset)는, 'S'문자가 존재하는 경우를 제외해, 클래스 파일에서는 부호 없음 필드로서 다루어집니다. 이것에 대해, 포함된 인덱스는, 항상 부호 없음 필드로서 다루어집니다.

전술의 예로, 20 바이트의 메소드의 속성에 'P'요소에 이어 'PO'레이아웃 요소도 할당할 수 있고 있는 경우로, 클래스 파일에 수치 20 이 포함되고 있을 때, 전송 되는 수치는, 20 을 5 에 재설정하고 나서, 전에 전송 된 수치를 당겼다 (5-2)로서 요구됩니다. 따라서, 수치 3 이 전송 되게 됩니다. 한편, 포함되고 있는 수치가 7 의 경우 (위치 6 에 있는 명령내의 BCI), 전송 되는 수치는 (10-2), 즉 8 이 됩니다. 'PO'는 아니고 'O'레이아웃 요소에 의해 관리되고 있는 경우는, 전송 되는 값이 같이 3 으로 8 이어도, 20 으로 7 은 아니고, 포함된 값 14 (20-6)로 1 (7-6)에 대응하게 됩니다.

접두사 'F'를 가지는 플래그 요소는, 산술치는 아니고 짧은 비트 배열을 encode 하는 것을 상정한 정수치를 encode 합니다. 비트를 액세스 수식자로서 해석할 필요는 없습니다. 플래그 레이아웃 요소를 전송 하는 밴드의 primary encode는 UNSIGNED5 입니다. 다만 예외로서'FB'레이아웃은 primary encode BYTE1 를 사용합니다.

서식 문자 'B', 'H', 또는 'I'대신에 'V'로 전송 되는 정수형의 값은, 클래스 파일 속성내에서 영역을 전혀 점유 하지 않습니다. 이러한 레이아웃 요소를 사용하면(자), 압축 해제 프로그램으로, 클래스 파일 속성에 직접 나타날리가 없는 개수나 태그를 사용해 전송을 제어할 수 있습니다. 예를 들어, 속성이 바이트 배열이며, 그 배열은 자기 사이즈 지정형은 아니고, 클래스 파일의 속성 헤더에 기술된 바이트수를 채우도록(듯이) 확장하는 경우를 생각합니다. 이러한 속성에 레이아웃 'NV[B]'가 지정되고 있다고 합니다. 'V'레이아웃 요소로서 어느 값을 전송 할까는, 압축 프로그램이 결정된다고 합니다. 이러한 결정에는, 이 스펙에는 포함되지 않은 속성의 형식에 관한 상세 정보를 사용할 필요가 있겠지요. 모든 경우에 대해, 압축 해제 프로그램은 이러한 값을 존중할 필요가 있습니다만 (개수나 태그로서 사용되고 있을 때), 클래스 파일에 포함 해서는 안됩니다.

「복제」는 접두사 'N'로 시작되어, 「복제수」라고 불리는 정수 요소와 「복제 본체」라고 불리는 꺽쇄묶음으로 둘러싸인 일련의 요소가 계속됩니다. 이 레이아웃에 의해 관리되는 속성 데이터는, 복제수로 거기에 계속되는 데이터 배열로 구성됩니다. 이 배열의 요소수는 복제수와 같습니다. 각 배열 요소는, 복제 본체내의 레이아웃에 의해 관리됩니다.

복제수의 레이아웃 요소는, 복제수를 전송 하는 밴드를 관리합니다. 이 밴드의 primary encode는 UNSIGNED5 (레이아웃이 'NB'로 시작되는 경우는 BYTE1)입니다. 대응하는 복제 본체에 의해 관리되는 밴드의 사이즈는, 복제수의 밴드로 전송 되는 값을 합계하는 것에 의해 요구할 수가 있습니다.

「공용체」는 접두사 'T'로 시작되어, 「공용체 태그」라고 불리는 정수 요소와 「공용체 케이스」라고 불리는 꺽쇄묶음으로 둘러싸인 일련의 라벨 첨부 요소가 계속됩니다. 수치의 자리수는 임의입니다만, 그 산술치는 밴드치라고 비교되기 전에 32 비트 정수에 절약할 수 있습니다. 밴드치의 사이즈도 32 비트입니다. 마지막 라벨 이외의 각 라벨은, 환괄호로 둘러싸인 1 개(살) 이상의 (경우에 따라서는 부호 첨부의) 10 진수로 구성됩니다. 이것들은 「공용체 태그」라고 불립니다. 디폴트의 케이스가 되는 마지막 라벨은, 빈 상태(empty)의 환괄호의 페어가 아니면 안됩니다. 또, 어느 공용체에도 같은 케이스 태그를 2 개 포함할 수 없습니다. 이 레이아웃에 의해 관리되는 속성 데이터는, 정수형의 태그치와 거기에 계속되는 데이터로 구성됩니다. 이 데이터의 형식은 태그에 의해 정해집니다. 태그에 계속되는 데이터는, 태그의 값에 일치하는 라벨을 가지는 (일의의) 공용체 케이스인가, 디폴트의 케이스에 의해 관리됩니다. 각 공용체 케이스에 의해 관리되는 밴드의 사이즈는, 태그의 레이아웃으로 관리되는 밴드에 포함되어 있는 값의 수를 카운트 하는 것에 의해 요구할 수가 있습니다. 단순한 정수형 밴드와 같게, 공용체 태그 밴드의 primary encode는 SIGNED5, BYTE1, 또는 UNSIGNED5 입니다. 이것은, 레이아웃에 'S'문자가 포함되어 있는지, 레이아웃이 'TB'인가, 또는 그 이외인가에 응해 정해집니다.

공용체 태그에서는, 하이픈으로 단락지어진 2 개의 수치는, 이러한 수치도 포함한 범위를 지정합니다. 2 번째의 수치는 최초의 수치보다 크지 않으면 안됩니다. 최초의 수치로부터 2 번째의 수치까지, 이러한 수치도 포함한 모든 수치의 리스트를 나타내는 생략형입니다. 레이아웃은, 생략형을 완전한 리스트로 옮겨놓았을 경우와 완전히와 같이 다루어집니다.

속성내의 정수 풀의 참조는 강하고 형지를 무늬를 박아서 염색한 것 되어 어카이브(archive)의 몇개의 정수 풀의 인덱스로서 전송 되는 경우가 있습니다. 'KI', 'KJ', 'KF', 'KD', 및 'KS'로 시작되는 레이아웃 타입은, integer, long, float, double, 및 string 의 각 형의 정수에 대해서, 로컬 정수 풀에 포함된 인덱스를 관리할 필요가 있습니다. 같이'RC', 'RS', 'RD', 'RF', 'RM', 'RI', 및 'RU'로 시작되는 레이아웃 타입은, 클래스, 시그니챠, 기술자 (이름과 형태의 페어), 필드 참조, 메소드 참조, 인터페이스 메소드 참조, 및 UTF8 캐릭터 라인의 각 형의 심볼에 대해서, 로컬 정수 풀에 포함된 인덱스를 관리할 필요가 있습니다. 이러한 참조는 모두, 대응하는 글로벌 정수 풀의 32 비트 인덱스로서 primary encode UNSIGNED5 를 사용하는 밴드로 전송 됩니다. 레이아웃에 'B'가 포함되어 있는 경우에서도, 이것은 들어맞읍니다. 아래와 같은 겉(표)를 참조해 주세요.

시그니챠 참조 (레이아웃 'RS')는, 클래스 파일내에서는 Utf8 참조 (레이아웃 'RU')와 동일합니다만, archive파일에서의 encode 방식은 다릅니다. `cp_Utf8` 정수 풀과 `cp_Signature` 정수 풀은 각각 독립한 인덱스를 가져, 다른 방법으로 전송 되기 (위해)때문에입니다.

'KQ'로 시작되는 레이아웃 요소는, 필드에 관련하는 속성에게만 발생할 가능성이 있습니다. 이것들은, 필드의 시그니챠에 의해 지정되는 정수 풀내의 정수를 참조합니다. 이 레이아웃 요소가 도움이 되는 것은, 정의 끝난 `ConstantValue` 속성에 사용하는 경우만이지요. 다음의 겉(표)에, 'KQ'레이아웃에 사용할 수 있는 정당한 피르드시그니챠와 그 포함된 참조가 포함되어 있는 대응하는 정수 풀을 나타냅니다.

피르드시그니챠 | 'KQ'정수 풀
B | cp_Int
S | cp_Int
C | cp_Int
Z | cp_Int
I | cp_Int
J | cp_Long
F | cp_Float
D | cp_Double
Ljava/lang/String; | cp_String
Ljava/lang/Class; | cp_Class

정수 풀 참조를 강하고 형지를 무늬를 박아서 염색한 것 할 수 없는 경우, 압축 프로그램에서는 `untyped_ref` ('RQ')를 사용할 필요가 있습니다. 이러한 형태 지정이 없는 참조의 encode는, 모든 풀에 대한 인덱스이며, Pack200 어카이브(archive)에 발생하는 순서에 따라 번호가 재설정됩니다. 이와 같이 자연스러운 발생 순서에 따라 늘어놓을 수 있던 모든 정수의 순서는 `cp_All` 로 불립니다. 예를 들어,`cp_Utf8` 풀의 모든 요소에, 'RQ'레이아웃과 'RU'레이아웃으로와 같이 번호를 붙일 수 있습니다. 한편, 형태 지정이 없는 참조에 대해서,`cp_Int` 풀의 최초의 요소 (요소 0)에는,`cp_Utf8_count` 라고 하는 번호를 붙일 수 있습니다. 또, 형태 지정이 없는 참조에 대해서,`cp_Float` 풀의 최초의 요소에는,`cp_Utf8_count+cp_Int_count` 라고 하는 번호를 붙일 수 있습니다.

예기치 않은 형태의 정수 풀 인덱스를 포함하고 있는 속성이 발견되었을 경우, 압축 프로그램은, 그 속성을 전송 하는 것을 거부하는지, 강하고 형지를 무늬를 박아서 염색한 것 된 요소 대신에 'RQN'요소를 사용해 완만한 레이아웃 정의로 전송 하는 것을 선택할 수 있습니다. 압축 해제 프로그램은, 압축 프로그램으로부터 전송 되는 정당한 레이아웃 정의를 모두 존중할 필요가 있습니다. 거기에 따라 부정한 서식의 클래스 파일이 생성되는 경우에서도, 이것은 들어맞읍니다. 극단적인 경우, 압축 프로그램은 클래스 파일을 resource file와 같게 취급해 전송 할 수도 있습니다. 이 경우, 클래스 고유의 압축은 행해지지 않습니다만, 예외적인 서식의 속성이 비트 단위로 정확하게 유지됩니다.

`reference` 레이아웃 타입에 문자 'N'가 포함되어 있는 경우, 정수 풀 엔트리를 encode 하는 밴드치는 모두 1 증가해, null 치는 0 으로서 encode 됩니다. 그 이외의 경우, null 치는 부의 1 (-1)으로서 encode 됩니다.

상기의 규칙이 밴드의 primary encode에게 주는 효과는, 레이아웃 요소 마다 우선되는 규칙의 리스트로 해 정리할 수가 있습니다. 그 중에 최초로 해당하는 규칙에 의해, encode가 정해집니다.

- 레이아웃에 'O'가 포함되어 있는 경우는, BRANCH5 를 사용합니다.
- 그 이외의 경우로, 레이아웃에 'P'가 포함되어 있을 때는, BCI5 를 사용합니다.
- 그 이외의 경우로, 레이아웃에 'S'가 포함되어 있지만 'KS'나 'RS'는 포함되지 않을 때는, SIGNED5 를 사용합니다.
- 그 이외의 경우로, 레이아웃에 'B'가 포함되어 있을 때는, BYTE1 를 사용합니다.
- 다른 모든 레이아웃에는 UNSIGNED5 를 사용합니다.

  다음의 겉(표)는, 각종 레이아웃 요소의 밴드와 encode를 집계한 것입니다. (형태와 정수 사이즈의 가능한 편성이 모두 나타나고 있는 것은 아닙니다. )

  레이아웃 요소 | 포함되었다 치 | 전송 된다 치 | primary encode
  B | u1 | x | BYTE1
  FB | u1 | x | BYTE1
  SB | u1 | (byte) x | SIGNED5
  H | u2 | x | UNSIGNED5
  FH | u2 | x | UNSIGNED5
  SH | u2 | (short) x | SIGNED5
  I | u4 | x | UNSIGNED5
  FI | u4 | x | UNSIGNED5
  SI | u4 | x | SIGNED5
  PH | u2 | renumber_bci(x) | BCI5
  POH | u2 | renumber_bci(x) - renumber_bci(x0) | BRANCH5
  OH | u2 | renumber_bci(x0+x) - renumber_bci(x0) | BRANCH5
  NB[...] | u1 | x (사이즈 카운트라고 해도 기능) | BYTE1
  NH[...] | u2 | x (사이즈 카운트라고 해도 기능) | UNSIGNED5
  NI[...] | u4 | x (사이즈 카운트라고 해도 기능) | UNSIGNED5
  TB... | u1 | x | BYTE1
  TSB... | u1 | (byte) x | SIGNED5
  TH... | u2 | x | UNSIGNED5
  TSH... | u2 | (short) x | SIGNED5
  KIB | u1 | indexOf(lcp[x], cp_Int) | UNSIGNED5
  KIH | u2 | indexOf(lcp[x], cp_Int) | UNSIGNED5
  KII | u4 | indexOf(lcp[x], cp_Int) | UNSIGNED5
  KINH | u2 | 1+indexOf(lcp[x], cp_Int) | UNSIGNED5
  KJH | u2 | indexOf(lcp[x], cp_Long) | UNSIGNED5
  KFH | u2 | indexOf(lcp[x], cp_Float) | UNSIGNED5
  KDH | u2 | indexOf(lcp[x], cp_Double) | UNSIGNED5
  KSH | u2 | indexOf(lcp[x], cp_String) | UNSIGNED5
  KQH | u2 | indexOf(lcp[x], cp_fieldSpecific) | UNSIGNED5
  RCH | u2 | indexOf(lcp[x], cp_Class) | UNSIGNED5
  RSH | u2 | indexOf(lcp[x], cp_Signature) | UNSIGNED5
  RDH | u2 | indexOf(lcp[x], cp_Descr) | UNSIGNED5
  RFH | u2 | indexOf(lcp[x], cp_Field) | UNSIGNED5
  RMH | u2 | indexOf(lcp[x], cp_Method) | UNSIGNED5
  RIH | u2 | indexOf(lcp[x], cp_Imethod) | UNSIGNED5
  RUH | u2 | indexOf(lcp[x], cp_Utf8) | UNSIGNED5
  RQH | u2 | indexOf(lcp[x], cp_All) | UNSIGNED5
  RQNH | u2 | 1+indexOf(lcp[x], cp_All) | UNSIGNED5
  RQNI | u4 | 1+indexOf(lcp[x], cp_All) | UNSIGNED5

  여기서, 변수 X 는, 레이아웃 요소에 의해 관리되는, 속성에 포함된 값을 나타냅니다. 변수 X0 는, 'P'로 시작되기 직전의 레이아웃 요소에 의해 관리되는, 포함된 값을 나타냅니다. 식 renumber_bci(I) 는, 명령 경계의 참조를 단축하기 위해서 바이트 코드 인덱스 I 를 재설정하는 것을 나타냅니다 (전술의 설명을 참조). 식 lcp[I] 는, 인덱스 I 에서의 로컬 정수 풀의 참조를 나타냅니다. 또는,I 가 0 의 경우는, 특수한 null 치를 나타냅니다.

  식 indexOf(lcp[I], cp) 는, Pack200 의 글로벌 정수 풀 cp 에서의, 정수 lcp[I] 의 인덱스 (0 으로부터 시작된다)를 나타냅니다. 이 정수는 cp 에 적절한 형태이라고 상정하고 있습니다. lcp[I] 가 특수한 null 치를 가지는 경우, 이 식의 값은 -1 이 됩니다.

  null 참조는 항상, 참조를 보관 유지하는 밴드로 전송 할 수 있습니다. null 를 받아들이도록(듯이) 지정되고 있는 밴드에서는 값 0, 그 이외의 밴드에서는 값 -1 을 전송 합니다. UNSIGNED5 encode에서는,-1 을 5 바이트로 표현할 수 있습니다.

  이름 cp_All 는, Pack200 의 모든 글로벌 정수 풀을 그 전송 순서에 따라 연결하는 것에 의해 작성되는 배열을 나타냅니다 (전술의 설명을 참조). 이름 cp_fieldSpecific 는, 포함 하는 필드의 시그니챠에 의해 선택되는 글로벌 정수 풀을 나타냅니다 (전술의 설명을 참조).

  ##### 5.5. 3. 재귀적인 레이아웃

  레이아웃 스펙의 톱 레벨의 구조체가 일련의 본체로 구성되어 그러한 본체는 개별적으로 「호출해 가능한 (callable)」레이아웃인 경우가 있습니다. 이러한 경우, 레이아웃 스펙 전체에 의해 관리되는 속성 데이터는, 호출 가능 레이아웃의 순서에 포함되어 있는 최초의 본체에 의해 관리됩니다. 다른 호출해 가능 레이아웃은, 실제로 불려 갔을 때만, 데이터를 관리할 수가 있습니다. 즉, 서로 재귀적인 일련의 레이아웃 스펙이 정의되어 최초의 레이아웃 스펙에 제어가 건네받게 됩니다. 다만, 다른 구문내에서는, 호출 가능 레이아웃을 상자로 할 수 없습니다. 이 기능은, 메타데이타와 같이 재귀적 구조를 가지는 클래스 파일 속성을 지원하는데 도움이 됩니다.

  call 레이아웃 요소는, 환괄호로 둘러싸인 부호 첨부 10 진수 N 입니다. 이것은, 이 호출이 출현하는 호출 가능 레이아웃을 기준으로 해, 레이아웃 스펙의 톱 레벨의 구조 체내에서 N 번째의 호출 가능 레이아웃 (callable)을 나타냅니다. 호출이 호출해 가능 레이아웃의 외부에 출현하는 것은 부정합니다. 이 호출 가능 레이아웃을, 호출의 「호출처」라고 부르기로 하겠습니다.

  예를 들어, 레이아웃 요소 '(2)'는, 이 호출이 출현하는 호출 가능 레이아웃보다 2 개 후의 호출 가능 레이아웃을 호출합니다. 어느 호출 가능 레이아웃에도, 일치하는 호출처가 존재할 필요가 있습니다. 레이아웃내에서 마지막 호출 가능 레이아웃에는, '(1)'라고 하는 호출이 발생 해서는 안됩니다. 같이 최초의 호출 가능 레이아웃에는, '(-1)'라고 하는 호출이 발생 해서는 안됩니다. 덧붙여'(0)'라고 하는 자기 호출은 항상 정당합니다.

  call 레이아웃 요소는, 그것이 호출하는 호출 가능 레이아웃 요소에 의해 직접 관리되는 속성 데이터를, 간접적으로 관리합니다. 클래스 파일 형식에 관한한, 호출 가능 레이아웃의 본체에 포함되어 있는 텍스트로 호출을 옮겨놓았을 경우와 같은 효과가 됩니다.

  다만, 이 치환 시멘틱스에서는, 밴드 구조에 대한 호출 레이아웃 요소의 효과는 기술되지 않습니다. 호출 레이아웃 요소는, 밴드를 직접 관리할 것은 없습니다. 대신에, 간접적으로 관리하고 있는 데이터를, 호출해 먼저 따라보다 직접적으로 관리되는 밴드로 전송 하도록(듯이) 지정합니다.

  호출처가 호출해 자체보다 나중에 기재되어 있는 경우, 그 호출은 「순서 방향 호출」입니다. 순서 방향 호출의 효과로서 그 호출이나 같은 호출해 먼저 대하는 것 외의 순서 방향 호출로, 호출처의 밴드를 공유할 수 있게 됩니다. 예를 들어, 다음의 레이아웃 스펙에는 2 개의 밴드가 있어, 후자의 밴드는, 어느 쪽인가의 공용체 케이스에 의해 간접적으로 관리되는 데이터를 전송 합니다. 디폴트의 공용체 케이스는 어느 밴드도 관리하지 않기 때문에, ASCII 문자 'A'또는 'B'이외의 태그 바이트에는, 거기에 계속되는 바이트는 없습니다. 읽기 쉬워지도록(듯이), 이 레이아웃에는 공백이 추가되고 있습니다.

              [TB
                (65) [(1)]
                (66) [(1)]
                (  ) []
                ]
              [H]

  호출처의 기재가 호출해 자체보다 전에 시작하는 경우도 있습니다. 이러한 호출은 「역방향 호출」이라고 불려'(0)'또는 '(-N)'라고 하는 형식에서 기술할 필요가 있습니다. 그 호출처는 「역방향 호출 가능 레이아웃」이라고 불립니다. 호출 가능 레이아웃은, 어느 호출의 대상으로도 되지 않은 것이나 순서 방향 호출만의 대상이 되어 있는 것을 제외해, 모두 역방향 호출 가능 레이아웃입니다. 역방향 호출과 역방향 호출 가능 레이아웃에 의해, 재귀나 루프가 가능하게 됩니다. N 분목의 예를 다음에 나타냅니다. 그 잎은 Utf8 캐릭터 라인으로, 선두에 0 바이트가 부가되고 있습니다. 내부 노드는 트리 노드의 배열로, 선두에 1 바이트가 부가되고 있습니다. 이 예에서는, 호출해 먼저 호출이 포함되어 있어 직접 재귀를 하고 있습니다. 레이아웃은, 요소 'TB', 'NH', 및 'RUH'로 3 개의 밴드를 관리하고 있습니다.

              [TB
                (1) [NH[ (0) ]]
                (0) [RUH]
              ]

  이러한 서로 재귀적인 레이아웃에 의해 관리되는 밴드의 사이즈는, 역방향 호출의 명시적인 개수를 이용해 구할 수 있습니다. 이 개수는, 레이아웃의 속성 밴드의 전에,`class_attr_calls` 밴드 또는 유사한 3 개의 밴드로 전송 됩니다. 이 상세한 것에 대하여는 후술 합니다.

  ##### 5.5. 4. 디폴트의 속성 레이아웃

  정의가 끝난 속성의 레이아웃 정의는 다음과 같습니다.

  문맥 타입 | 이름 | 레이아웃 정의
  클래스 | "class-file version" | (빈 상태(empty)) *(주를 참조)
  클래스 | InnerClasses | (빈 상태(empty)) *(주를 참조)
  클래스 | EnclosingMethod | RCHRDNH
  클래스 | SourceFile | RUNH *(주를 참조)
  클래스 | Signature | RSH
  클래스 | (메타데이타) | (이하를 참조)
  클래스 | Deprecated | (빈 상태(empty))
  필드 | ConstantValue | KQH
  필드 | Signature | RSH
  필드 | (메타데이타) | (이하를 참조)
  필드 | Deprecated | (빈 상태(empty))
  메소드 | Code | (빈 상태(empty)) *(주를 참조)
  메소드 | Exceptions | NH[RCH]
  메소드 | Signature | RSH
  메소드 | (메타데이타) | (이하를 참조)
  메소드 | Deprecated | (빈 상태(empty))
  코드 | StackMapTable | (이하를 참조)
  코드 | LineNumberTable | NH[PHH]
  코드 | LocalVariableTable | NH[PHOHRUHRSHH]
  코드 | LocalVariableTypeTable | NH[PHOHRUHRSHH]

  "class-file version",`InnerClasses`,`SourceFile`, 및 `Code` 의 레이아웃 정의에 포함되어 있는 asterisk (*)는, 이러한 속성에는 특별한 처리가 더해지는 것을 나타내고 있습니다. 클래스에 관한 "class-file version " 의사 속성은, 서식 `VV` 를 사용했을 경우와 같게 전송 됩니다만, 압축 해제 프로그램은 결과를 클래스 파일의 속성에 포함하는 것이 아니라, 클래스 파일의 헤더에 포함합니다. 상세한 것에 대하여는,아래와 같이를 참조해 주세요. 클래스에 관한 `InnerClasses` 속성은, 서식 `NV[RCVTV[(0)[]()[RCNVRUNV]]]` 를 사용했을 경우와 같게 부분적으로 전송 됩니다만, 압축 해제 프로그램은, (아마) `InnerClasses` 속성을 발행하기 전에, 받은 값을 처리합니다. 상세한 것에 대하여는,아래와 같이를 참조해 주세요. 정의가 끝난 레이아웃을 사용해 `SourceFile` 속성을 전송 하는 경우, 특별한 규칙에 의해, 그 디폴트 값는 명확한 표준 캐릭터 라인이 됩니다. 마지막으로, 메소드에 관한 `Code` 속성은,`code_bands` 로 전송 됩니다.

  ##### 5.5. 5. 스택 맵의 레이아웃

  `Code` 속성의 `StackMapTable` 속성에 대해서는, 정의 끝난 속성 레이아웃이 존재합니다. 다음에 예를 나타냅니다 (읽기 쉽게하기 위해(때문에), 공백 문자 및 생략 표기가 추가되고 있다).

        [NH[(1)]]
        [TB
          (64-127)  [(2)]
          (247)     [(1)(2)]
          (248-251) [(1)]
          (252)     [(1)(2)]
          (253)     [(1)(2)(2)]
          (254)     [(1)(2)(2)(2)]
          (255)     [(1) NH[(2)]NH[(2)]]
          ()        []
          ]
        [H]
        [TB
          (7) [RCH]
          (8) [PH]
          ()  []
          ]

  이 레이아웃의 스펙을,`StackMapTable` 속성을 정의하는 클래스 파일 형식의 스펙과 비교하는 것으로, 다음 일을 관찰할 수 있습니다. 2 번째의 호출 가능 레이아웃은, 클래스 파일 형식의 스펙에 근거하는 `stack_map_frame` 구조를 나타냅니다. 2 번째의 호출 가능 레이아웃의 공용 체내부의 각 케이스는,`stack_map_frame` 공용체 멤버 `same_locals_1_stack_item_frame`,`same_locals_1_stack_item_extended`,`chop_frame` ( 및 `same_frame_extended`),`append_frame` (3 레이아웃의 공용체 케이스용),`full_frame`, (디폴트 레이아웃의 공용체 케이스내의) `same_frame` 를 각각 나타냅니다. 3 번째 및 4 번째의 호출 가능 레이아웃은, 클래스 파일 형식의 스펙에 근거하는 `offset_delta` 치 및 `verification_type_info` 구조를 나타냅니다.

  ##### 5.5. 6. 메타데이타레이아우트

  파라미터가 아닌 메타데이타 주석의 정의 끝난 속성 레이아웃은, 3 개의 문맥 모두로 같습니다. 레이아웃은 다음과 같이 됩니다 (읽기 쉽게하기 위해(때문에), 공백 문자가 추가되고 있다).

        [NH[(1)]]
        [RSH NH[RUH(1)]]
        [TB
          (66,67,73,83,90) [KIH]
          (68)  [KDH]
          (70)  [KFH]
          (74)  [KJH]
          (99)  [RSH]
          (101) [RSH RUH]
          (115) [RUH]
          (91)  [NH[(0)]]
          (64)  [RSH [RUH(0)]]
          ()    []
          ]

  이 레이아웃은, 가시의 주석과 불가시의 주석의 양쪽 모두로 사용됩니다. 2 번째의 호출 가능 레이아웃에서는, 메타데이타 스펙에 근거하는``주석 기구가 기술되고 있습니다. 3 번째의 호출 가능 레이아웃에서는, 메타데이타 스펙에 근거하는 `member_value` 구조가 기술되고 있습니다. 이 마지막 호출 가능 레이아웃은, 메소드의 `AnnotationDefault` 속성에 대해서 단독으로 사용됩니다. 메소드 파라미터의 주석 (가시 및 불가시)도, 이 레이아웃을 사용해 사전에 정의됩니다. 그 때, 파라미터의 수를 카운트 하는 호출 가능 레이아웃이 부가됩니다.

        [NB[(1)]]
        [NH[(1)]]
        [RSH NH[RUH(1)]]
        [TB...]

  ##### 5.5. 7. 예외적인 레이아웃의 사용 방법

  압축 프로그램이, 동일한 속성명에 대해서 임의의 수의 정의를 발행하는 것이 가능합니다. 이러한 정의는, 이름은 같습니다만, 다른 속성 인덱스 (그리고 대체로는 다른 flag bit)에 할당할 수 있어 별개의 속성으로서 처리됩니다. 속성이, 레이아웃 언어로 정의하기에는 너무 복잡한 경우는, 그 속성이 발행될 때마다, 압축 프로그램에 의해 별개의 정의를 부여하는 것이 가능합니다. 최소 요건은, 각 레이아웃이 대응하는 속성 발행의 사이즈를 정확하게 선언해, 그 발행 내부에서 모든 정수 풀 참조를 검출하는 것입니다.

  #### 5.6. 원시 파일의 생략 표기

  정의 끝난 `SourceFile` 속성으로 관리된 밴드내에서 null 참조가 전송 되는 경우, 압축 해제 프로그램을 사용해 Utf8 캐릭터 라인에의 참조에 치환할 필요가 있습니다. Utf8 캐릭터 라인의 철에는, 관련하는 클래스 명문자열에 다음의 수정이 더해진 것이, 차례로 포함됩니다.
  - 마지막 slash ( 「/」) 또는 닷 ( 「.」)까지의 모든 문자 (마지막 slash 또는 닷을 포함한다)가 삭제된다. 이것에 의해, 패키지의 접두사가 모두 삭제된다.
  - 나머지의 캐릭터 라인에 코드 0x2D 이하의 문자가 포함되는 경우, 최초 및 후속의 해당하는 문자가 모두 삭제된다. 이것에 의해, 상자가 된 클래스 명분해가 모두 삭제된다.
  - 접미사(suffix)문자 「. java」가 추가된다.

  이 규칙은 다수의 Java 컴파일러의 역사적인 동작에 합치하고 있어 이 규칙을 사용하는 것으로써, 압축 프로그램이 파생한 「명백한」`SourceFile` 명에 Utf8 캐릭터 라인을 할당하는 것을 회피할 수 있습니다. 압축 프로그램이, 진정한 null 참조를 가지는 불규칙한 `SourceFile` 속성을 전송 할 필요가 있는 경우, 비표준의 레이아웃을 사용하지 않으면 안됩니다. 다음에, 클래스명 및 대응하는 파생 `SourceFile` 명의 예를 나타냅니다.

  클래스 | `SourceFile`
  foo | foo.java
  foo/bar | bar.java
  foo/bar$baz | bar.java
  foo/bar#baz#1 | bar.java
  foo.bar.baz#1 | baz.java

  #### 5.7. 상자의 클래스

  클래스 파일의 `InnerClasses` 속성으로 기재되어 있도록(듯이), 상자 클래스의 레코드는, 2 개의 클래스, 1 개의 이름, 및 몇 개의 플래그를 지정하는 4 개의 타풀입니다. 이것은, 주로 4 개의 밴드에 의해 Pack200 어카이브(archive)내에서 표현되어 그 내용은 어카이브(archive)내의 모든 클래스 파일에 균등하게 적용됩니다.

        ic_bands:
              *ic_this_class :UDELTA5 [#ic_count] (cp_Class)
              *ic_flags :UNSIGNED5 [#ic_count]
              *ic_outer_class :DELTA5 [COUNT(1<<16,...)]  (null or cp_Class)
              *ic_name :DELTA5 [LENGTH(*ic_outer_class)] (null or cp_Utf8)

  이것들 4 개의 타풀은, 정수 풀의 엔트리와 같이, 글로벌하게 공유됩니다. 이 스펙에서는, 이것들은, 클래스 파일 형식에서 다른 순서로 포함된다고 해도,`<C, F, C2, N>` 와 종래의 방법으로 기술됩니다. 글로벌하게 정의된 이것들 4 개의 타풀을 정리해 `ic_All` 라고 부릅니다. 일반적으로, 어카이브(archive)내의 개별의 클래스에서 상자 클래스의 레코드에의 명시적인 링키지는 존재하지 않습니다. 그 대신해, Pack200 어카이브(archive)로부터 클래스 파일을 추출할 때에, 상자 클래스의 레코드의 부분집합을 선택할 수 있습니다. 추출되는 클래스 파일의 정수 풀에 실제로 기술 떠날 수 있어 모든 상자 클래스를 기술하려면 , 이것으로 충분합니다. 추출하는 클래스 파일을 X 로 하면(자), 이 부분집합은 `ic_Relevant(X)` 가 됩니다. 이것은,`ic_All` 의 X 에 대한 「관련 부분집합」입니다. 관련 부분집합의 선택 알고리즘에 대해서는,나중에 설명하겠습니다. 옵션으로, 압축 프로그램은, 로컬의 `InnerClasses` 속성을 전송 하는 것으로써, 지정한 임의의 클래스에 대해서, 그 관련 부분집합에의 조정을 실시할 수 있습니다. 이것에 대해서도, 후술의클래스 속성에 관한 섹션으로 설명합니다.

  `ic_this_class` 및 `ic_flags` 밴드는, 어느쪽이나 길이가 `#ic_count` 입니다. 또, 이러한 밴드의 대응하는 요소는, 타풀 마다, 상자 클래스의 식별 정보 (`cp_Class` 참조로 나타내진다) 및 flag bit 마스크를 지정합니다.

  상자 클래스의 flag bit의 위치 16 (마스크 0x00010000 내에서 설정된다)은, archive파일 내부에 있어,`ic_outer_class` 및 `ic_name` 밴드내에 타풀에 대응하는 엔트리가 존재할지 어떨지를 나타냅니다. 이 때문에, 이것들 양쪽 모두의 밴드의 길이는, 위치 16 의 모든 flag bit의 합계가 됩니다. 일반적으로, 이 비트의 설정, 및 외부 필드와 이름 필드의 명시적인 지정이 필요한 것은, 상자 클래스의 몇 퍼센트 뿐입니다.

  타풀이 `ic_outer_class` 및 `ic_name` 밴드내에 엔트리를 보관 유지하는 경우, 이러한 밴드는 그 외부 클래스와 단순명을 지정합니다. 이것들은, null 가 될 수 있는 `cp_Class` 참조 및 null 가 될 수 있는 `cp_Utf8` 참조로서 각각 나타내집니다. 그 이외의 경우, 타풀의 외부 클래스 및 외부명은 「예측되고 있다」라고 말해집니다. 이 경우는, 상자 클래스 자체의 이름의 철을 해석하는 것으로 정확하게 예측 가능하다는 두입니다.

  네스트 한 클래스는, 「바이트 코드명」을 가집니다. 바이트 코드명에 의해, 클래스 파일 내부의 클래스에 이름을 붙일 수 있습니다. 이 이름의 철은 「분해명」이라고도 불려 추가의 구두점 기호가 포함됩니다. 또, 숫자나 포함되는 클래스의 이름이 포함되는 일도 있습니다. 바이트 코드명을 외부 클래스나 클래스명에 해석 가능하고, 이 클래스 및 이름이 상자 클래스의 진정한 외부 클래스 및 클래스명으로 동일한 경우, 외부 클래스 및 클래스명은 「예측 가능하다」라고 말합니다.

  예측 가능한 외부 클래스 및 클래스명을 추출할 때, 상자 클래스명의 철에 적용되는, 클래스의 바이트 코드명에 관한 다음의 문법에 따를 필요가 있습니다. 이것은, 밴드 구조를 관리하는 문법, 및 본스펙외의 개소에서 설명하는 문법과는 별개의 문법입니다. 끝의 DOLLAR 는, 코드가 0x2D 이하의 임의의 문자 ( 「$」, 「#」 등)를 참조합니다. 끝의 SLASH 는, slash 「/」(코드 0x2E) 또는 닷 문자 「.」(코드 0x2F)을 참조합니다. 끝의 DIGIT 는, ASCII 10 진수 (0x30 ? 0x39 의 10 개의 문자 코드의 어느쪽이든)을 참조합니다. 끝의 LETTER 는, 그 외의 임의의 문자를 참조합니다. 즉, 코드가 0x3A 이상의 임의의 문자를 참조합니다.

        bcn:
              (bcnCase1 | bcnCase2 | bcnCase3 | bcnCase4)
        bcnCase1:
              packageQual (namePart)?  DOLLAR number
        bcnCase2:
              packageQual (namePart)?  DOLLAR number DOLLAR predictableICName
        bcnCase3:
              predictableOuter DOLLAR predictableICName
        bcnCase4:
              packageQual (namePart)?

        predictableOuter:
              packageQual namePart
        predictableICName:
              LETTER (LETTER | DIGIT)*

        namePart:
              (LETTER | DIGIT | DOLLAR)+
        number:
              (DIGIT)+
        packageQual:
              (namePart SLASH)*

  이 문법에서는, 임의의 클래스명이 애매한 방법으로 복수의 부분에 분할됩니다. 이것에는, 옵션의 접두사 predictedOuter, 옵션의 접미사(suffix) predictedICName, 및 옵션의 수치접미사(suffix)을 포함할 수 있습니다. 애매함은,`bcn` 비끝용의 대체 케이스를 지정의 순서로 우선하는 것으로써, 해결할 필요가 있습니다. 예를 들어,`bcnCase1` 가 일치하는 경우, 그 외의 1 개 또는 양쪽 모두가 일치한다고 해도 이것이 사용됩니다.

  `predictableICName` 비끝이 해석되었을 경우, 예측 가능한 상자 클래스명은 이것에 대응하는 캐릭터 라인이 됩니다. 그 이외의 경우, 예측 가능한 상자 클래스명은, null 라고 해석됩니다.

  `predictableOuter` 외부비끝이 해석되는 경우, 대응하는 캐릭터 라인은 예측 가능한 외부 클래스명이 됩니다. 그 이외의 경우, 예측 가능한 외부 클래스 참조는, null 라고 해석됩니다. `number` 비끝이 해석되는 경우,`predictableOuter` 는 해석할 수 없습니다. 다음에, 예측, 비예측, 및 오예측의 예를 나타냅니다.

  상자 클래스: | `java/util/Map` 의 멤버 `Entry`
  분해명: | `java/util/Map$Entry`
  외부, 명: | `java/util/Map`, `Entry`
  예측 가능한가 어떤가: | 가능 (`Map.Entry` 는 `Map` 의 멤버이기 (위해)때문에)
  상자 클래스: | anonymous
  분해명: | `java/util/AbstractList$1`
  외부, 이름: | (없음), (없음)
  예측 가능한가 어떤가: | 가능 (ic_name 는 null 이기 (위해)때문에)
  상자 클래스: | `Local` 라는 이름의 비멤버
  분해명: | `java/util/AbstractList$2$Local`
  외부, 이름: | (없음), `Local`
  예측 가능한가 어떤가: | 가능 (ic_name 는 `Local` 이기 (위해)때문에)
  상자 클래스: | `Local` 라는 이름의 비멤버
  분해명: | `java/util/AbstractList#2#Local`
  외부, 이름: | (없음), `Local`
  예측 가능한가 어떤가: | 가능 (ic_name 는 `Local` 이기 (위해)때문에)
  상자 클래스: | `Foo` 의 멤버 `$2$Local`
  분해명: | `Foo$$2$Local`
  외부, 이름: | (없음), `Local`
  예측 가능한가 어떤가: | 불가 (외부명이 없고, ic_name 가 오예측된다)
  상자 클래스: | 클래스 `Red$Herring`
  분해명: | `Red$Herring`
  외부, 명: | `Red`, `Herring`
  예측 가능한가 어떤가: | 불가 (ic_name Herring 가 예측된다)
  상자 클래스: | `X$1` 의 멤버 `Q`
  분해명: | `X$1$Q`
  외부, 이름: | (없음), `Q`
  예측 가능한가 어떤가: | 불가 (`Q` 는 `X$1` 의 멤버이기 (위해)때문에)
  상자 클래스: | `X$Y` 의 멤버 `Z`
  분해명: | `X$Y$Z`
  외부, 명: | `X$Y`, `Z`
  예측 가능한가 어떤가: | 가능 (X$Y.Z 는 X$Y 의 멤버이기 (위해)때문에)
  상자 클래스: | `X` 의 멤버 `Y$Z`
  분해명: | `X$Y$Z`
  외부, 명: | `X$Y`, `Z`
  예측 가능한가 어떤가: | 불가 (외부명 및 ic_name 가 오예측된다)

  압축 해제 프로그램은, 「예측 가능」의 마크를 붙일 수 있었던 상자 클래스명을 처리할 때에, 상자 클래스의 바이트 코드명을 해석해, 포함 하고 있는 클래스, 옵션의 수치, 및 옵션의 이름으로 나눌 필요가 있습니다. 압축 프로그램이 외부 클래스 및 이름을 항상 명시적으로 지정하는 일도 가능합니다. 이 경우, 압축 해제 프로그램이 상자 클래스명의 해석을 실시할 필요는 일절 없게 됩니다. 다만, 압축 해제 프로그램은 이 해석을 언제라도 실행할 수 있을 준비가 되어 있지 않으면 안됩니다.

  압축 프로그램이, 예측된 이름이나 외부 클래스에 대해서 `cp_Utf8` 또는 `cp_Class` 내의 엔트리를 전송 하지 않았던 경우는, 압축 해제 프로그램은 해당하는 정수를 내부에서 작성할 필요가 있습니다. 이것은, 비록 정수 전송 순서 `cp_All` 가 아닌 경우에서도,`cp_Utf8` 또는 `cp_Class` 엔트리로서 참조됩니다. 다만, 압축 프로그램이 예측된 이름 또는 외부 클래스와 같은 철의 정수를 전송 했을 경우, 압축 해제 프로그램은 새로운 정수를 작성하지 않고 , 그 정수를 사용할 필요가 있습니다. 압축 해제 프로그램내에서 작성되는 이런 종류의 내부 정수는, 출력 파일의 정수 풀에 특수한 순서로 삽입되기 (위해)때문에, 출력 파일내에서 검출할 수 있습니다(후술의 출력 순서의 설명을 참조).

  이 개념에 대해서는, 「부록」섹션의「의사 코드」를 참조해 주세요.

  압축 해제 프로그램이 `ic_this_class`,`ic_flags`,`ic_name`, 및 `ic_outer_class` 밴드를 수신해, 필요한 이름 해석을 실행하면(자), 4 타풀의 `ic_All` 세트가 작성됩니다. 이 세트는, 압축 해제 프로그램에 의해 개별의 클래스 파일용으로 합성되는 `InnerClasses` 속성의 주요 소스가 됩니다.

  #### 5.8. 클래스 schema

  Pack200 어카이브(archive)의 목적은, 압축 해제 프로그램이 나중에 클래스 파일의 재구축에 사용할 수 있는 형식에서, 클래스 세트를 전송 하는 것입니다. 일반적으로, 클래스 파일내에 포함되는 데이터의 각종류가, 그 종류의 모든 값전용의 밴드내에서 전송 됩니다. 다음에, 바이트 코드를 제외한 클래스 고유의 전정보에 대응한 밴드 구조를 나타냅니다.

        class_bands:
              *class_this :DELTA5 [#class_count] (cp_Class)
              *class_super :DELTA5 [#class_count] (cp_Class)
              *class_interface_count [#class_count] :DELTA5
              *class_interface :DELTA5 [SUM(*class_interface_count)] (cp_Class)
              *class_field_count :DELTA5 [#class_count]
              *class_method_count :DELTA5 [#class_count]

              *field_descr :DELTA5 [SUM(*class_field_count)] (cp_Descr)
              field_attr_bands

              *method_descr :MDELTA5 [SUM(*class_method_count)] (cp_Descr)
              method_attr_bands

              class_attr_bands
              code_bands

  `class_this`,`class_super`,`class_flags_lo`,`class_flags_hi` (존재하는 경우),`class_interface_count`,`class_field_count`, 및 `class_method_count` 밴드는 모두, 길이 `#class_count` 입니다. 다음에, 이러한 밴드의 대응하는 요소에 의해, 각 클래스의 이름과 슈퍼 클래스, 구현된 인터페이스의 수, 선언된 필드의 수, 및 선언된 메소드의 수가 전송 됩니다. 전술의 정의대로, 각 클래스의 플래그 워드내의 액세스 수식자 비트와 속성 지시자가 조합할 수 있어,`class_flags_lo` 내에서 전송 됩니다.

  `class_interface` 밴드에는, 클래스 인터페이스 선언의 실행 (여러 차례),`class_interface_count` 의 각 요소의 실행 (1 회), 및 대응하는 클래스에의 적용이 포함됩니다.

  `class_this`,`class_super`, 및 `class_interface` 의 각 요소는, 정수 풀 `cp_Class` 에의 참조 (실제는 null 이외의 참조)입니다.

  `java/lang/Object` 가 있는 특수한 케이스에서는, 포함되는 슈퍼 클래스는 null 참조일 필요가 있습니다. `class_super` 밴드외의 요소의 전송을 일절 방해하는 일 없이, 압축 프로그램이, null 의 슈퍼 클래스 참조에 조우했을 때, 그 위치에 현재의 클래스 참조의 복제를 전송 한다고 하는 규칙을 사용합니다. 클래스가 그 자체로부터 상속하는 것은 부정하기 때문에, null 참조의 리난바링은 명쾌한 것이 됩니다.

  `field_descr` 밴드에는,`class_field_count` 의 각 요소에 대응하는 1 회의 요소 실행이 포함됩니다. 또, 이것은 대응하는 클래스내가 연속하는 필드에 적용됩니다. `method_descr` 밴드에는,`class_method_count` 의 각 요소에 대응하는 1 회의 요소 실행이 포함됩니다. 또, 이것은 대응하는 클래스내가 연속하는 메소드에 적용됩니다.

  클래스 파일 형식과는 달라, 필드 및 메소드 기술자는, 이름 참조와 형태 참조의 페어로서가 아니고, 「이름과 형태」정수 풀에의 단일의 참조로서 포함됩니다.

  `method_descr` 밴드가 갖추는 primary encode에서는, 메소드 참조의 대부분이 소트 되고 있는 경우에, 최고의 퍼포먼스를 얻을 수 있습니다. 압축 프로그램은, 각 클래스내에서 메소드를 소트 하는 것으로써, 이 이점을 향수할 수 있습니다. 덧붙여 압축 프로그램이 최고의 압축율을 실현하기 위해서(때문에) 메소드를 늘어놓고 바꾸는 것은, 일반적으로 받아들여지고 있습니다. 다만, 필드의 순서는 리플렉션을 통해서 분명하고, 직렬화등의 일부의 기능에서는 중요하기 때문에, 필드를 늘어놓고 바꾸어서는 안됩니다.

  속성 밴드는, 문법으로 지정된 위치에 배치됩니다. 그것들에 대해, 이후에 설명합니다. 속성 밴드에 포함되는 플래그 밴드에 의해, 대응하는 클래스, 필드, 메소드의 액세스 수식자와 속성 지시자의 양쪽 모두가 전해집니다.

  Pack200 어카이브(archive)는, 메소드 코드 블록 전용의 밴드 및 바이트 코드 자체로 끝납니다. 메소드에 코드 속성이 포함되는 경우, 압축 프로그램은 코드 속성을, 할당처의 flag bit (6 번째의 LSB) 내에 기술하는지, 오버플로우 속성 (인덱스 6)으로서 기술할 필요가 있습니다. Code 속성의 필드는,`code_bands` 비끝내에 편성되는 밴드내에서 전송 됩니다.

  각 Code 속성의 스펙은, 스택 슬롯의 수, 로컬 슬롯의 수, 및 핸들러의 수를 선언하는 3 개의 키파라미터로 시작됩니다. `#Stack` 는, 코드에 의해 사용되는 스택 슬롯의 수입니다. `#NALocal` 는, 코드가 사용하는 인수가 없는 로컬의 수입니다. 클래스 파일내에서 선언되는 로컬의 실제의 수는,`#NALocal` 에, 메소드 파라미터에 의해 요구되는 로컬의 수를 더한 값이 됩니다. 이것은, 메소드의 서명에 의해 결정됩니다. `#Handler` 는, 예외 핸들러의 수입니다.

  `code_headers` 밴드에 포함되는 일련의 바이트는 각각, 코드 속성의 최초의 3 개의 키파라미터를 간결하게 encode 합니다. 제로 이외의 255 의 각 바이트치는, 3 조로 일의가 되는 `#NALocal`,`#Stack`, 및 `#Handler` 를 encode 합니다. 전송 되는 각 Code 속성의 코드 헤더는 (당연히) 1 개입니다.

  특수 코드 헤더 바이트 제로 (0x00)는,`code_max_stack`,`code_max_na_locals`, 및 `code_handler_count` 밴드내에 코드 속성의 3 개의 파라미터가 존재하는 것을 나타냅니다. 코드 헤더 바이트가 제로 이외의 경우, 이것들 3 개의 밴드는 대응하는 Code 속성의 엔트리를 전송 하지 않습니다.

  `code_flags_lo` 밴드는, Code 속성의 코드 헤더 바이트가 제로인,`have_all_code_flags` 비트가 `#archive_options` 워드로 설정되어 있는, 의 한편 또는 양쪽 모두가 진정한 경우에게만, 대응하는 `Code` 속성의 엔트리를 전송 합니다. `Code` 속성이 전송 된 `code_flags_lo` 치를 가지지 않는 경우, 그 플래그 워드는 제로가 되어, 서브 속성을 가지지 않습니다. `code_flags_hi` 밴드는,`code_flags_lo` 치가 전술의 방법으로 전송 되어 또,`#have_code_flags_hi` 도 설정되어 있는 경우에게만, 대응하는 엔트리를 전송 합니다.

  제로 이외의 코드 헤더 바이트가 나타내는 코드 속성 파라미터는, 다음의 방식에 따릅니다.

  헤더 범위 | #Stack | #NALocal | #Handler
  1 <= x <= 144 | (x-1) % 12 | (x-1) / 12 | 0
  145 <= x <= 208 | (x-145) % 8 | (x-145) / 8 | 1
  209 <= x <= 255 | (x-209) % 7 | (x-209) / 7 | 2
  x = 0 | `code_max_stack` | `code_max_na_locals` | `code_handler_count`

  이 방식을 사용하면(자), 전사례의 약 95% 의 Code 속성을 1 바이트로 기술할 수 있습니다. 덧붙여 디버그 속성이 제거되지 않는 경우, 압축 프로그램은 대부분 `have_all_code_flags` 비트를 설정해, 이러한 속성을 위해서(때문에) 특수한 제로 코드 헤더 바이트가 강제적으로 사용되는 것이 없게 합니다.

  예외 핸들러 카운트가 1 바이트 코드 헤더로 encode 될지 어떨지, 또 `code_handler_count` 의 명시적인 요소일지 어떨지에 관계없이, 이러한 밴드가 속성 레이아웃 `'NV[PHPOHPOHRCNH]'` 에 의해 관리되어 있는 것과 같게, 코드 속성 마다 `code_handler_start_P`,`code_handler_end_PO`,`code_handler_catch_PO`, 및 `code_handler_class_RCN` 내의 값의 실행이 각 핸들러에 1 개 존재합니다. `'NV'` 레이아웃 요소 자체가 관리하는 밴드는 존재하지 않습니다. 이것은 핸들러 카운트입니다.

  즉,`Handler.start`,`Handler.end`,`Handler.catch` 치는 3 개로 1 조가 되어, 각 조 마다 (renumber_bci 에 의해) 리난바링 되어 전송 됩니다 . 또,`Handler.end` 가, 그 리난바링과 같은 셋잇단음표내의 `Handler.start` 의 리난바링의 차이로서 전송 되어`Handler.catch` 가, 그 리난바링과 같은 셋잇단음표내의 `Handler.end` 의 리난바링의 차이로서 전송 됩니다. 마지막으로,`cp_Class` 에의 증분 참조로서 `code_handler_class_RCN` 가 전송 됩니다. 핸들러 클래스 참조 null 의 경우에는 제로가 전송 됩니다.

        code_bands:
              *code_headers :BYTE1 [COUNT(Code,...)]

              *code_max_stack :UNSIGNED5 [COUNT(0, *code_headers)]
              *code_max_na_locals :UNSIGNED5 [COUNT(0, *code_headers)]

              *code_handler_count :UNSIGNED5 [COUNT(0, *code_headers)]
              *code_handler_start_P :BCI5 [SUM(*code_handler_count)]
              *code_handler_end_PO :BRANCH5 [SUM(*code_handler_count)]
              *code_handler_catch_PO :BRANCH5 [SUM(*code_handler_count)]
              *code_handler_class_RCN :UNSIGNED5 [SUM(*code_handler_count)] (null or cp_Class)

              code_attr_bands

  #### 5.9. 속성 밴드

  여기에서는, 속성을 전송 하는 밴드에 대해 설명합니다. 압축 프로그램이 클래스, 필드, 또는 메소드의 플래그 워드내에서 비트를 설정해, 이러한 비트를 (압축 프로그램에 의해) 속성에 할당할 수 있으면(자), 압축 프로그램은, 선택된 각 속성 레이아웃이 관리하는 포함 끝난 값을 취득해, 그 레이아웃이 관리하는 밴드내에 전송 할 필요가 있습니다.

  압축 프로그램이 클래스 (필드, 메소드, 또는 코드)에 오버플로우 속성이 있으면(자) 지정하는 경우,`class_attr_count` 밴드내의 대응하는 요소 (각각,`field_attr_count`,`method_attr_count`, 또는 `code_attr_count` 밴드)를 전송 할 필요가 있습니다. 다음에, 이 카운트는, 클래스 (필드, 메소드, 또는 코드)의 속성을 관리하는 속성 레이아웃의 인덱스인 `class_attr_indexes` (각각,`field_attr_indexes`,`method_attr_indexes`, 또는 `code_attr_indexes`) 내의 실행 사이즈를 지정합니다. 압축 프로그램은, 각 오버플로우 속성의 속성 레이아웃 정의 인덱스를 전송 할 필요가 있습니다.

  압축 프로그램은,`class_flags` 의 요소내의 비트 또는 `class_attr_indexes` 의 요소에 의해 선택되는 속성 레이아웃 마다, 레이아웃 요소가 관리하는 데이터를 클래스 속성으로부터 취득해, 이 데이터를 encode 하는 요소를 레이아웃이 관리하는 밴드내에서 전송 할 필요가 있습니다. 필드, 메소드, 및 코드 속성에도 같은 조건이 적용됩니다.

  압축 프로그램은, 데이터를 전송 해, 역방향 호출을 포함한 속성 레이아웃 마다, 압축 해제 프로그램이 속성 레이아웃을 차례로 처리할 때, 각 역방향 호출 가능 레이아웃이 역방향 호출의 대상이 되는 회수를 전송 할 필요가 있습니다. 이러한 호출 카운트는, 적용처의 레이아웃의 문맥형에 응해,`class_attr_calls`,`field_attr_calls`,`method_attr_calls`, 및 `code_attr_calls` 밴드내에서 전송 됩니다. 호출 카운트는, 역방향 호출 가능 레이아웃 마다 1 개(살)씩, 호출 가능 레이아웃의 정의순서에 전송 됩니다(상기를 참조). 호출 카운트의 전송은, 1 회 이상 사용되는 레이아웃 내부에서 발생하는 역방향 호출 가능 레이아웃 에 대해서만 실행됩니다. 호출 카운트는, 호출 가능 레이아웃에 대한 엔트리에 대해서는 순서 방향 호출이기 위해서(때문에) 일절 카운트 하지 않습니다. 또, 호출 가능 레이아웃에 대한 초기 호출 (속성 처리를 개시한다)도 카운트 하지 않습니다. 사용하고 있는 레이아웃으로 역방향 호출 가능 레이아웃이 출현하고 있지만, 우연히 그 역방향 호출 가능 레이아웃에 도달하지 않았던 경우, 호출 카운트가 제로가 되는 일이 있습니다. 이러한 호출 카운트는, 상호 재귀적인 레이아웃의 밴드의 사이즈 설정에 고유의 순환을 중단하기 위해서 필요합니다. 이것들은, 밴드치를 다양한 출력 클래스에 배포하기 전에, 압축 해제 프로그램이 어카이브(archive)내의 전밴드를 검출하는데 필요한 최소 정보를 제공합니다. 이 때문에, 호출 카운트는, 레이아웃 마다 (그 레이아웃의 속성 발행이 모두 요약되어) 제공됩니다.

  압축 해제 프로그램은, 압축 프로그램에 의해 전송 된 명시적인 속성 레이아웃 정의의 처리를 모두 담당합니다. 압축 해제 프로그램은, 이러한 레이아웃에 의해 관리되는 추가 밴드를 수신할 준비가 되어 있을 필요가 있습니다. 이것은, 레이아웃 정의의 인덱스를 읽어낼 때, 각 추가 밴드로 전송 되는 값의 정확한 수를 읽어낼 준비가 되어 있을 필요가 있습니다.

  이 스펙으로 정의되는 밴드의 문법에는, 모든 정의가 끝난 속성 레이아웃으로 관리되는 밴드가 포함됩니다. 명료성을 높이기 (위해)때문에, 일부의 밴드명에는 그것을 작성한 레이아웃 요소의 일부가 포함됩니다. Deprecated 속성은 레이아웃이 빈 상태(empty)이기 (위해)때문에, 이 속성에는 밴드가 존재하지 않습니다.

  「Synthetic」라고 하는 이름의 속성은, 이전의 버젼의 Java 의 표준 클래스 파일 형식입니다만, 최근의 버젼의 Java 에서는 신규 flag bit (ACC_SYNTHETIC, 0x1000)로 옮겨놓을 수 있고 있기 (위해)때문에, 이 스펙에서는 직접 지원되고 있지 않습니다. 다만, 압축 해제 프로그램을 처리할 수 있도록, 미사용의 flag bit를 할당해, 명시적인 제로장의 레이아웃 정의를 발행하는 것으로써, Synthetic 속성, 및 여기서 사전에 정의되어 있지 않은 것 외의 제로장의 속성 모든 것을, 압축 프로그램이 처리하는 것이 추천 되고 있습니다.

  압축 프로그램이 신규 레이아웃의 정의를 선택하는 경우, 이러한 레이아웃에 의해 관리되는 밴드가, 정의가 끝난 레이아웃의 밴드의 직후에 추가됩니다. 정의가 끝난 속성 밴드의 순서 및 구조는, 압축 프로그램이 그것들을 명시적으로 정의했는지와 같이, 일반적으로의 방법에 따르는 정의가 끝난 레이아웃 정의를 반영합니다.

        class_attr_bands:
              *class_flags_hi :UNSIGNED5 [#class_count*#have_class_flags_hi]
              *class_flags_lo :UNSIGNED5 [#class_count]
              *class_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
              *class_attr_indexes :UNSIGNED5 [SUM(*class_attr_count)]
              *class_attr_calls :UNSIGNED5 [...]
              *class_SourceFile_RUN :UNSIGNED5 [COUNT(SourceFile,...)] (null or cp_Utf8)
              *class_EnclosingMethod_RC :UNSIGNED5 [COUNT(EnclosingMethod,...)] (cp_Class)
              *class_EnclosingMethod_RDN :UNSIGNED5 [COUNT(EnclosingMethod,...)] (null or cp_Descr)
              *class_Signature_RS :UNSIGNED5 [COUNT(Signature,..)] (cp_Signature)
              class_metadata_bands
              ic_local_bands
              *class_file_version_minor_H :UNSIGNED5 [COUNT(version,...)]
              *class_file_version_major_H :UNSIGNED5 [COUNT(version,...)]

        field_attr_bands:
              *field_flags_hi :UNSIGNED5 [SUM(*class_field_count) *#have_field_flags_hi]
              *field_flags_lo :UNSIGNED5 [SUM(*class_field_count)]
              *field_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
              *field_attr_indexes :UNSIGNED5 [SUM(*field_attr_count)]
              *field_attr_calls :UNSIGNED5 [...]
              *field_ConstantValue_KQ :UNSIGNED5 [COUNT(ConstantValue,...)] (cp_Int, etc. ; see note)
              *field_Signature_RS :UNSIGNED5 [COUNT(Signature,...)] (cp_Signature)
              field_metadata_bands

        method_attr_bands:
              *method_flags_hi :UNSIGNED5 [SUM(*class_method_count) *#have_method_flags_hi]
              *method_flags_lo :UNSIGNED5 [SUM(*class_method_count)]
              *method_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
              *method_attr_indexes :UNSIGNED5 [SUM(*method_attr_count)]
              *method_attr_calls :UNSIGNED5 [...]
              *method_Exceptions_N :UNSIGNED5 [COUNT(Exceptions,...)]
              *method_Exceptions_RC :UNSIGNED5 [SUM(*method_Exceptions_N)] (cp_Class)
              *method_Signature_RS :UNSIGNED5 [COUNT(Signature,...)] (cp_Signature)
              method_metadata_bands

        code_attr_bands:
              *code_flags_hi :UNSIGNED5 [...*#have_code_flags_hi]
              *code_flags_lo :UNSIGNED5 [...]
              *code_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
              *code_attr_indexes :UNSIGNED5 [SUM(*code_attr_count)]
              *code_attr_calls :UNSIGNED5 [...]
              *code_StackMapTable_N :UNSIGNED5 [COUNT(StackMapTable,...)]
              *code_StackMapTable_frame_T :BYTE1 [SUM(*code_StackMapTable_N)]
              *code_StackMapTable_local_N :UNSIGNED5 [COUNT(255, *code_StackMapTable_frame_T)]
              *code_StackMapTable_stack_N :UNSIGNED5 [COUNT(255, *code_StackMapTable_frame_T)]
              *code_StackMapTable_offset :UNSIGNED5 [...]
              *code_StackMapTable_T :BYTE1 [...]
              *code_StackMapTable_RC :UNSIGNED5 [COUNT(7, *code_StackMapTable_T)]
              *code_StackMapTable_P :BCI5 [COUNT(8, *code_StackMapTable_T)]
              *code_LineNumberTable_N :UNSIGNED5 [...]
              *code_LineNumberTable_bci_P :BCI5 [...]
              *code_LineNumberTable_line :UNSIGNED5 [...]
              *code_LocalVariableTable_N :UNSIGNED5 [...]
              *code_LocalVariableTable_bci_P :BCI5 [...]
              *code_LocalVariableTable_span_O :BRANCH5 [...]
              *code_LocalVariableTable_name_RU :UNSIGNED5 [...] (cp_Utf8)
              *code_LocalVariableTable_type_RS :UNSIGNED5 [...] (cp_Signature)
              *code_LocalVariableTable_slot :UNSIGNED5 [...]
              *code_LocalVariableTypeTable_N :UNSIGNED5 [...]
              *code_LocalVariableTypeTable_bci_P :BCI5 [...]
              *code_LocalVariableTypeTable_span_O :BRANCH5 [...]
              *code_LocalVariableTypeTable_name_RU :UNSIGNED5 [...] (cp_Utf8)
              *code_LocalVariableTypeTable_type_RS :UNSIGNED5 [...] (cp_Signature)
              *code_LocalVariableTypeTable_slot :UNSIGNED5 [...]

  클래스는, 그 클래스 파일의 마이너 버젼과 메이저 버젼이, 각각 `#default_class_minver`,`#default_class_majver` 와 다른 경우,"class-file version" 의 의사 속성을 소유합니다. 이 의사 속성은, 클래스의 파일의 메이저 및 마이너 버젼 번호를 지정하는 16 비트 정수의 페어입니다. 이러한 정수는, 속성 레코드내는 아니고, 클래스의 파일의 헤더내에 포함됩니다. 클래스 파일의 규약 대로, 마이너 버젼 번호가 최초로 배치됩니다. 이 때문에, 마이너 버젼 번호가 밴드 `class_file_version_minor_H` 내에서, 메이저 버젼 번호가 `class_file_version_major_H` 내에서 각각 전송 됩니다. 압축 해제 프로그램은, 스펙으로 처리 대상으로 되어 있는 것보다 큰 마이너 또는 메이저 버젼 번호로, 어카이브(archive)를 처리할 필요는 없습니다. 압축 해제 프로그램은, 같은 메이저 버젼 번호, 또는 같은가보다 작은 마이너 버젼 번호로 어카이브(archive)를 처리할 필요가 있습니다.

  ##### 로컬의 InnerClasses 속성

  전송 된 클래스는, 로컬의 `InnerClasses` 속성을 소유할 수 있습니다. 이것은, 최종적으로 기입해지는, 그 클래스 파일의 `InnerClasses` 속성에의 「조정」으로서 이용됩니다. 특히, 로컬의 `InnerClasses` 속성으로 지정되는 4 타풀세트를,`ic_All` 로부터 취득되는 대응하는 관련 부분집합과 연결시킬 필요가 있습니다. 이것을 실행하기 위한 알고리즘은,나중에 자세하게 설명합니다. 다만, 간단하게 설명하면(자), 출력 정수 풀의 CONSTANT_Class 엔트리 (`InnerClasses` 속성만으로 필요하게 되는 CONSTANT_Class 엔트리를 제외하다)에 속하는 `ic_All` 로부터의 4 타풀의 부분집합을 조작한 후에, 관련하는 세트 및 로컬 `InnerClasses` 속성간세트 대칭차이를 작성합니다.

  모든 로컬 `InnerClasses` 속성의 4 타풀은, 다음의 5 개의 밴드내에서 전송 됩니다.

        ic_local_bands:
              *class_InnerClasses_N :UNSIGNED5 [COUNT(InnerClasses,...)]
              *class_InnerClasses_RC :UNSIGNED5 [SUM(*class_InnerClasses_N)] (cp_Class)
              *class_InnerClasses_F :UNSIGNED5 [SUM(*class_InnerClasses_N)]
              *class_InnerClasses_outer_RCN :UNSIGNED5 [COUNT(! =0, *class_InnerClasses_F)]  (null or cp_Class)
              *class_InnerClasses_name_RUN :UNSIGNED5 [COUNT(! =0, *class_InnerClasses_F)] (null or cp_Utf8)

  이러한 속성 밴드내에서 전송 되는 4 타풀 `<C, F, C2, N>` 는, 각각 「로컬 IC 타풀」이라고 불립니다. 클래스 파일 형식은 이러한 4 타풀의 요소를 다른 순서 `(C, C2, N, F)` 로 포함합니다. 지정의 클래스 파일이 X 의 경우, 로컬　IC 타풀의 순서는 `ic_Local(X)` 로 불립니다.

  각 로컬 IC 타풀로, 압축 프로그램은 적어도 `C` 치 및 `F` 치를 전송 합니다. 전송 되는 플래그치 `F` 가 제로가 아닌 경우, 대응하는 전송 되는 정수 풀 참조 `C2` 및 `N` 도 존재합니다. 전체적으로, 전송 되는 로카르타풀은,`ic_All` 로부터의 그로바르타풀과 동일한 경우도, 동일하지 않은 경우도 있습니다.

  전송 하는 로컬 IC 타풀이 `ic_All` 의 멤버와 등가이며,`ic_All` 외의 멤버가 같은 클래스 `C` 를 정의하지 않는 경우, 압축 프로그램은, 생략 표기로서`C` 및 플래그치 제로만을 전송 할 수 있습니다. 이 경우, 압축 해제 프로그램은, 모든 4 타프르콘포넨트가 명시적으로 전송 되었을 경우와 완전히와 같이 동작할 필요가 있습니다.

  로카르타풀의 4 컴퍼넌트가 모두 전송 되어 전송 되는 플래그치가 사실상 제로의 경우, 플래그로서 제로는 아니고 값 `0x00010000` 를 전송 할 필요가 있습니다.

  많은 경우, 클래스의 `InnerClasses` 속성내에 포함되는 4 타풀세트는 `ic_Relevant(X)` 인 채로 조정 불필요하기 때문에, 압축 프로그램은 로컬 IC 타풀을 일절 전송 할 필요가 없습니다. 부가적인 4 타풀 (최소한의 정수 풀에서 필요하게 되는 것 이외)이 입력 클래스 파일내에서 검출되었을 경우, 추가의 `InnerClasses` 엔트리용의 로컬 「루트」를 제공하기 위해서, 일부의 로컬 IC 타풀이 (제로 플래그 첨부로) 필요하게 됩니다. 이것은, 컴파일러가, 서명인 만큼 기술된 클래스의 `InnerClasses` 엔트리를 필요로 하는 경우에 발생할 가능성이 있습니다. 압축 프로그램은, 이런 종류의 부가적인 로컬 루트가 필요한 클래스를 예측해, 예기치 않은 4 타풀만을 전송 할 필요가 있습니다.

  ##### 5.9. 1. 메타데이타의 전송

  메타데이타레이아우트에 의해 관리되는 밴드 그룹은 9 개 있습니다. 이러한 그룹의 개요를, 다음에 나타냅니다.

        class_metadata_bands:
              class_RVA_bands
              class_RIA_bands

        field_metadata_bands:
              field_RVA_bands
              field_RIA_bands

        method_metadata_bands:
              method_RVA_bands
              method_RIA_bands
              method_RVPA_bands
              method_RIPA_bands
              method_AD_bands

        class_RVA_bands:
              *class_RVA_anno_N :UNSIGNED5 [...]
              *class_RVA_type_RS :UNSIGNED5 [...] (cp_Signature)
              *class_RVA_pair_N :UNSIGNED5 [...]
              *class_RVA_name_RU :UNSIGNED5 [...] (cp_Utf8)
              *class_RVA_T :BYTE1 [...]
              *class_RVA_caseI_KI :UNSIGNED5 [...] (cp_Int)
              *class_RVA_caseD_KD :UNSIGNED5 [...] (cp_Double)
              *class_RVA_caseF_KF :UNSIGNED5 [...] (cp_Float)
              *class_RVA_caseJ_KJ :UNSIGNED5 [...] (cp_Long)
              *class_RVA_casec_RS :UNSIGNED5 [...] (cp_Signature)
              *class_RVA_caseet_RS :UNSIGNED5 [...] (cp_Signature)
              *class_RVA_caseec_RU :UNSIGNED5 [...] (cp_Utf8)
              *class_RVA_cases_RU :UNSIGNED5 [...] (cp_Utf8)
              *class_RVA_casearray_N :UNSIGNED5 [...]
              *class_RVA_nesttype_RS :UNSIGNED5 [...] (cp_Signature)
              *class_RVA_nestpair_N :UNSIGNED5 [...]
              *class_RVA_nestname_RU :UNSIGNED5 [...] (cp_Utf8)

        class_RIA_bands:
              *class_RIA_anno_N :UNSIGNED5 [...]
              (analogous to class_RVA_bands)

        field_RVA_bands:
              *field_RVA_anno_N :UNSIGNED5 [...]
              (analogous to class_RVA_bands)

        field_RIA_bands:
              *field_RIA_anno_N :UNSIGNED5 [...]
              (analogous to field_RVA_bands)

        method_RVA_bands:
              *method_RVA_anno_N :UNSIGNED5 [...]
              (analogous to class_RVA_bands)

        method_RIA_bands:
              *method_RIA_anno_N :UNSIGNED5 [...]
              (analogous to method_RIA_bands)

        method_RVPA_bands:
              *method_RVPA_param_NB :BYTE1 [...]
              *method_RVPA_anno_N :UNSIGNED5 [...]
              (analogous to method_RVA_bands)

        method_RIPA_bands:
              *method_RIPA_param_NB :BYTE1 [...]
              *method_RIPA_anno_N :UNSIGNED5 [...]
              (analogous to method_RVPA_bands)

        method_AD_bands
              *method_AD_T :BYTE1 [...]
              *method_AD_caseI_KI :UNSIGNED5 [...] (cp_Int)
              *method_AD_caseD_KD :UNSIGNED5 [...] (cp_Double)
              *method_AD_caseF_KF :UNSIGNED5 [...] (cp_Float)
              *method_AD_caseJ_KJ :UNSIGNED5 [...] (cp_Long)
              *method_AD_casec_RS :UNSIGNED5 [...] (cp_Signature)
              *method_AD_caseet_RS :UNSIGNED5 [...] (cp_Signature)
              *method_AD_caseec_RU :UNSIGNED5 [...] (cp_Utf8)
              *method_AD_cases_RU :UNSIGNED5 [...] (cp_Utf8)
              *method_AD_casearray_N :UNSIGNED5 [...]
              *method_AD_nesttype_RS :UNSIGNED5 [...] (cp_Signature)
              *method_AD_nestpair_N :UNSIGNED5 [...]
              *method_AD_nestname_RU :UNSIGNED5 [...] (cp_Utf8)

  메타데이타레이아우트를 이해하는 도움으로서 JSR 175 에 준거하는 클래스 파일로 사용되는 각 메소드메타데이타반드에 대해 간단하게 설명합니다. 클래스 및 피르드메타데이타반드는, 같은 방법으로 동작합니다.

  JSR 175 에서는, 클래스에의 참조가 필요한 경우에서도, CONSTANT_Class 엔트리에의 묻어 참조가 허가되지 않는 것에 유의해 주세요. 그 대신해, JSR 175 에서는, 클래스에의 참조를 필드 서명으로서 encode 할 필요가 있습니다. 이러한 이름은 「L」와「;」으로 둘러쌀 필요가 있습니다. Pack200 어카이브(archive)는, 이런 종류의 값 모든 것을,`cp_Class` 는 아니고 `cp_Signature` 에의 참조로서 전송 합니다.

  파라미터 주석 속성을 사용할 때마다,`method_RVPA_param_NB` 밴드 또는 `method_RIPA_param_NB` 밴드 (불가시의 주석용)는, 파라미터 카운트를 나타내는 부호 없음의 바이트를 전송 합니다. 비파라미터 주석 속성을 사용할 때마다,`method_RVA_anno_N` 밴드 또는 `method_RIA_anno_N` 밴드 (불가시의 주석용)는, 주석 카운트를 전송 합니다. 같이 주석 파라미터 마다,`method_RVPA_anno_N` 밴드 또는 `method_RIPA_anno_N` 밴드 (불가시의 주석용)는 주석 카운트를 전송 합니다.

  가시의 비파라미터 주석 마다,`method_RVA_type_RS` 밴드는 주석의 형태를 전송 해,`method_RVA_pair_N` 밴드는 주석의 멤버와 값의 페어의 수를 전송 합니다. 불가시의 주석 및 파라미터 주석의 유사치는, 밴드 `method_RIA_type_RS`,`method_RIA_pair_N`,`method_RVPA_type_RS`,`method_RVPA_pair_N`,`method_RIPA_type_RS`, 및 `method_RIPA_pair_N` 내에서 전송 됩니다. 가시의 비파라미터 주석의 직접 부분으로서 전송 되는 멤버와 값의 페어 마다,`method_RVA_name_RU` 밴드는 멤버명을 전송 합니다. 불가시의 주석 및 파라미터 주석의 유사치는, 밴드 `method_RIA_name_RU`,`method_RVPA_name_RU`, 및 `method_RIPA_name_RU` 내에서 전송 됩니다.

  가시의 비파라미터 주석과 함께 전송 되는 각 치에서는,`method_RVA_T` 밴드에 의해 주석치의 형식을 결정하는 바이트가 전송 되어 유사한 값이 밴드 `method_RIA_T`,`method_RVPA_T`,`method_RIPA_T`, 및 `method_AD_T` (주석의 디폴트) 내에서 전송 됩니다. 이것은, 직접적으로도, 상자의 값 또는 주석을 개입시켜 간접적으로도 실행됩니다. 이러한 값태그 밴드의 직접 사용은, 대응하는 선행의 페어 카운트 밴드 (`method_RVA_pair_N` 등)의 값을 합계해 카운트 됩니다. 이 카운트에는, 대응하는 후속의 상자의 페어 카운트 밴드 (`method_RVA_nestpair_N` 등), 및 상자의 배열장 밴드 (`method_RVA_casearray_N` 등)의 합계도 포함됩니다.

  후자의 합계는, 속성 레이아웃내의 역방향 호출로부터 얻을 수 있기 (위해)때문에, 압축 해제 프로그램으로부터 직접 계산할 수 없습니다. 다만, 그 합계는,`method_attr_calls` 의 요소로서 압축 프로그램에 의해 리포트됩니다. 각 메타데이타레이아우트내의 마지막 호출 가능 레이아웃은, 내부 자체로부터의 2 개의 역방향 호출의 타겟입니다. 그 밴드에는,`method_RVA_T`,`method_RIA_T`,`method_RVPA_T`,`method_RIPA_T`,`method_AD_T` 에 대한 이러한 역방향 호출의 카운트가, 이 순서로 포함됩니다. 메소드메타데이타 속성이 발행되지 않는 경우, 대응하는 역방향 호출은 생략 됩니다. 이 때문에, 최대 5 개의 역방향 호출 카운트가 메소드메타데이타용으로 전송 됩니다. 어카이브(archive)내에 압축 프로그램에 의해 정의된 재귀 레이아웃이 존재하는 경우, 그 역방향 호출 카운트는 `method_attr_calls` 내의 메타데이타의 카운트에 준거합니다.

  「B」, 「C」, 「I」, 「S」, 「Z」의 각 치 태그에,`method_RVA_caseI_KI` 내에서 전송 되는 대응하는 요소가 존재합니다. 이 경우, 값은 `cp_Int` 참조로서 전송 됩니다. 불가시 주석, 파라미터 주석, 및 주석의 디폴트 내부의 유사한 정수 참조가, 밴드 `method_RIA_caseI_KI`,`method_RVPA_caseI_KI`,`method_RIPA_caseI_KI`, 및 `method_AD_caseI_KI` 내에서 전송 됩니다. 「e」의 값태그 마다, 밴드 `method_RVA_caseet_RS` 및 `method_RVA_caseec_RU` 가, 클래스의 서명 및 열거 정수의 멤버명을 `cp_Signature` 및 `cp_Utf8` 에의 참조로서 전송 합니다. 값태그 「[」마다, 밴드 `method_RVA_casearray_N` 가 상자의 값배열의 길이를 전송 합니다. 값태그 「@」마다, 밴드 `method_RVA_nesttype_RS` 및 `method_RVA_nestpair_N` 가, 상자의 주석의 클래스 서명 및 그 페어의 수를 전송 합니다. 이런 종류의 상자 주석의 페어 마다, 밴드 `method_RVA_nestname_RU` 가 페어의 이름을 전송 합니다.

  다음의 겉(표)에 나타내는 밴드는, 특수한 태그 문자가 출현할 때마다, 적절한 형태의 정수 풀 참조를 전송 합니다.

  태그 | 밴드 | 참조
  `「B」, 「C」, 「I」, 「S」, 「Z」` | `method_RVA_caseI_KI` | cp_Int
  `「D」` | `method_RVA_caseD_KD` | cp_Double
  `「F」` | `method_RVA_caseF_KF` | cp_Float
  `「J」` | `method_RVA_caseJ_KJ` | cp_Long
  `「c」` | `method_RVA_casec_RS` | cp_Signature
  `「e」` | `method_RVA_caseet_RS` `method_RVA_caseec_RU` | `cp_Signature` `cp_Utf8`
  `「s」` | `method_RVA_cases_RU` | cp_Utf8

  유사한 밴드 그룹은, 다른 4 개의 메소드 주석형의 내부, 및 클래스와 필드의 가시 주석과 불가시 주석의 내부에서, 값을 전송 합니다.

  #### 5.10. 바이트 코드 명령

  Pack200 어카이브(archive)의 마지막 부분은, 바이트 코드 자체를 전송 하는 일련의 밴드입니다. 각 메소드 코드의 바이트 코드는, 명령 및 오퍼랜드에 구문 분석 되어 독자적인 밴드내에서 전송 됩니다. 각 메소드 코드는, 식별 코드값 0xFF (255)로 끝나는 바이트 코드의 실행에 대응합니다. 이것은, 종료 마커로서 기능합니다. 밴드 데이터가 엔드 마커로 단락지어지는 것은, 일반적으로의 동작이 아닙니다. 일반적으로은, 이전의 밴드내의 카운트에 의해 사이즈가 설정됩니다.

  다음에, 바이트 코드 명령을 전송 하는 밴드를 나타냅니다.

        bc_bands:
              *bc_codes :BYTE1 [...]
              *bc_case_count :UNSIGNED5 [COUNT(switch, *bc_codes)]
              *bc_case_value :DELTA5 [...]
              *bc_byte :BYTE1 [...]
              *bc_short :DELTA5 [...]
              *bc_local :UNSIGNED5 [...]
              *bc_label :BRANCH5 [...]
              *bc_intref :DELTA5 [...] (cp_Int)
              *bc_floatref :DELTA5 [...] (cp_Float)
              *bc_longref :DELTA5 [...] (cp_Long)
              *bc_doubleref :DELTA5 [...] (cp_Double)
              *bc_stringref :DELTA5 [...] (cp_String)
              *bc_classref :UNSIGNED5 [...] (current class or cp_Class)
              *bc_fieldref :DELTA5 [...] (cp_Field)
              *bc_methodref :UNSIGNED5 [...] (cp_Method)
              *bc_imethodref :DELTA5 [...] (cp_Imethod)
              *bc_thisfield :UNSIGNED5 [...] (cp_Field, only for current class)
              *bc_superfield :UNSIGNED5 [...] (cp_Field, only for current super)
              *bc_thismethod :UNSIGNED5 [...] (cp_Method, only for current class)
              *bc_supermethod :UNSIGNED5 [...] (cp_Method, only for current super)
              *bc_initref :UNSIGNED5 [...] (cp_Field, only for most recent new)
              *bc_escref :UNSIGNED5 [...] (cp_All)
              *bc_escrefsize :UNSIGNED5 [...]
              *bc_escsize :UNSIGNED5 [...]
              *bc_escbyte :BYTE1 [...]

  바이트 코드 명령을 보다 효율적으로 전송 하기 위한(해), 일부의 명령을 전송 형식에 고쳐 쓰는 것이 가능합니다. ldc, ldc_w, 및 ldc2_w 바이트 코드는, 압축 프로그램에 의해, 강하고 형지를 무늬를 박아서 염색한 것 된 조작에 고쳐 쓸 필요가 있습니다. 이후의 기술을 참조해 주세요. 일부의 getstatic, putstatic, getfield, putfield, invokevirtual, invokespecial, 및 invokestatic 바이트 코드는, (압축 프로그램의 옵션을 사용해)보다 특수하고 간결한 형식에 고쳐 쓸 수가 있습니다. 이것은, 문맥 의존이기 (위해)때문에, 오퍼랜드의 선택 범위가 보다 한정적이 됩니다.

  어떤 경우라도, 각 명령 (아마 고쳐 쓸 수 있었다)의 최초의 바이트는,`bc_codes` 내에서 전송 되는 바이트에 의해 결정됩니다. 모든 오퍼랜드 바이트는, 오퍼랜드에 복호화 되어 encode 된 오퍼랜드의 형태에 따라 별개의 밴드내에서 전송 됩니다. switch 명령의 패딩 바이트, 및 invokeinterface 명령의 마지막 2 바이트는, 압축 해제 프로그램에 의한 재구축이 가능하기 때문에, 파기됩니다.

  「와이드인」접두사 바이트 코드가,`bc_codes` 내에서 전송 됩니다. 접두사에 계속되는 명령은 와이드 형식에서 복호화 됩니다만, 전송 방법 (iinc 의 경우를 제외하다) 및 밴드는 일반적으로의 (비와이드) 형식과 같습니다. iinc 명령의 와이드 형식에서는, 2 번째의 오퍼랜드의 전송에 `bc_byte` 는 아니고 `bc_short` 가 사용됩니다.

  모든 branch 명령은,`bc_label` 밴드내에서 그 타겟 (switch 가 복수의 경우는 복수의 타겟)을 전송 합니다. 이것은, branch 타겟의 리난바링 된 BCI 와 branch 자체의 리난바링 된 BCI 와의 차이로서 encode 됩니다. 벌써 설명한 것처럼, 리난바링에 의해, 최초의 명령에 0, 2 번째의 명령에 1, 이라고 하는 상태에 번호부를 합니다. 리난바링 된 BCI 간의 차이는 매우 작은 것입니다. BRANCH5 의 primary encode도, 대부분의 경우 이런 종류의 차이가 정인 것을 이용합니다 (대부분의 브랜치(branch)는 순서 방향 브랜치(branch)이기 (위해)때문에).

  `bc_classref` 밴드는, 증분 인덱스를 `cp_Class` 정수 풀내에 전송합니다. 증분 (1단위씩 증가)에서는 코드 제로가 예약되고 있습니다. 코드 제로는, 항상 현재의 클래스를 참조합니다. 이것에 의해, 자기 참조인 대부분의 공통 클래스 참조용의 컴팩트한 형식이 제공됩니다.

  `bc_byte` 및 `bc_short` 밴드는, 고정 사이즈의 오퍼랜드를 전송합니다. 이러한 오퍼랜드는, 명령이, 원래의 정의 대로, 특별히 압축된 전송 형식이 되어 있기 (위해)때문에, 일반의 32 비트 정수로서는 전송 되지 않습니다. 이러한 밴드의 정수치는, 시멘틱스로서는 오퍼랜드로서 부호 붙이고 되고 있는 경우에서도, 부호 없다고 봐 다루어집니다. `bc_byte` 밴드는, multianewarray 및 비와이드 iinc 명령의 마지막 오퍼랜드로서 또 bipush 및 newarray 명령의 오퍼랜드로서 사용됩니다. `bc_short` 밴드는, 와이드 iinc 명령의 마지막 오퍼랜드로서 또 sipush 명령의 오퍼랜드로서 사용됩니다.

  밴드 `bc_intref`,`bc_floatref`,`bc_longref`,`bc_doubleref`,`bc_stringref`,`bc_fieldref`,`bc_methodref`, 및 `bc_imethodref` 는, 일반적으로의 인덱스를 정수 풀 `cp_Int`,`cp_Float`,`cp_Long`,`cp_Double`,`cp_String`,`cp_Field`,`cp_Method`, 및 `cp_Imethod` 내에 각각 전송 합니다.

  모든 lookupswitch 및 tableswitch 명령으로, 케이스의 수가 `bc_case_count` 내에서 전송 되어 디폴트 라벨이 `bc_label` 내에서 전송 됩니다. lookupswitch 의 각 케이스치 및 케이스 타겟은,`bc_case_value` 및 `bc_label` 내에서 각각 전송 됩니다. tableswitch 의 초기 케이스치는,`bc_case_value` 내에서 전송 되어 그 각 케이스 타겟은 `bc_label` 내에서 전송 됩니다.

  명령의 최초의 바이트가 범위 [202..255] 내의 코드인지, 명령의 오퍼랜드를 이 스펙의 요건에 따라 구문 분석 할 수 없는 경우, 그것은 비표준의 명령입니다. 비표준 명령의 각 바이트는, 압축 해제 프로그램이 그것을 문자대로 받아들이도록(듯이), 특수한 소포 (포락선)에 넣어 전송 할 필요가 있습니다. 포락선은,`bc_code` 밴드내의 일련의 「byte_escape」 및 「ref_escape」조작 코드,`bc_escsize` 및 `bc_escrefsize` 내의 대응하는 사이즈,`bc_escbyte` 내의 바이트, 및 `bc_escref` 내의 정수 풀 참조로 구성됩니다. 비표준 명령내의 각 정수 풀 참조는,`bc_escref` 밴드내에서 이스케이프 및 전송 할 필요가 있습니다. 각 ref_escape 는, 이런 종류의 정수 풀 참조를 1 개, 최대 4 바이트까지 랩 합니다. 전송 되는 참조는 `cp_All` 내에의 인덱스이며, 제로가 최초의 CONSTANT_Utf8 정수를 참조해, 1 이 2 번째의 CONSTANT_Utf8 정수를 참조한다, 라고 하는 상태가 됩니다.

  이스케이프 조작 코드 | 사이즈 오퍼랜드 | 오퍼랜드 사이즈 | 사이즈 밴드 | 데이터 밴드 | 조작 코드 치
  byte_escape | N<=255 | N 바이트 | `bc_escsize` | `bc_escbyte` | 254
  ref_escape | N<=2 | N 바이트 | `bc_escrefsize` | `bc_escref` | 253

  Pack200 형식은 정수 풀 참조 이외의 명령 바이트를 모두 정확하게 보존하기 위해(때문에), 비표준 명령 내부외의 오퍼랜드형을, 특수한 방법으로 전송 할 필요는 없습니다. 이 스펙은, 압축 프로그램이 비표준 명령의 존재 및 형식에 대응하는 방법을 나타내는 것이 아닙니다. 압축 해제 프로그램이, 이것들을 정확하게 복호화 하는 것을 요구하고 있을 뿐입니다.

  다음의 겉(표)에, 특별히 고쳐 쓸 수 있었던 명령의 전송 형식을 나타냅니다.

  원의 명령 | 오퍼랜드 | 전송 명령 | 개서가 필요한가 어떤가 | 조작 코드
  ldc | cp_String[i] | aldc | 요점 | 18 (=ldc)
  ldc | cp_Class[i] | cldc | 요점 | 233
  ldc | cp_Int[i] | ildc | 요점 | 234
  ldc | cp_Float[i] | fldc | 요점 | 235
  ldc_w | cp_String[i] | aldc_w | 요점 | 19 (=ldc_w)
  ldc_w | cp_Class[i] | cldc_w | 요점 | 236
  ldc_w | cp_Int[i] | ildc_w | 요점 | 237
  ldc_w | cp_Float[i] | fldc_w | 요점 | 238
  ldc2_w | cp_Long[i] | lldc2_w | 요점 | 20 (=ldc2_w)
  ldc2_w | cp_Double[i] | dldc2_w | 요점 | 239
  getstatic | (이 클래스 멤버) | getstatic_this | 불요 | 202
  putstatic | (이 클래스 멤버) | putstatic_this | 불요 | 203
  getfield | (이 클래스 멤버) | getfield_this | 불요 | 204
  putfield | (이 클래스 멤버) | putfield_this | 불요 | 205
  invokevirtual | (이 클래스 멤버) | invokevirtual_this | 불요 | 206
  invokespecial | (이 클래스 멤버) | invokespecial_this | 불요 | 207
  invokestatic | (이 클래스 멤버) | invokestatic_this | 불요 | 208
  aload_0; getstatic | (이 클래스 멤버) | aload_0_getstatic_this | 불요 | 209
  aload_0; putstatic | (이 클래스 멤버) | aload_0_putstatic_this | 불요 | 210
  aload_0; getfield | (이 클래스 멤버) | aload_0_getfield_this | 불요 | 211
  aload_0; putfield | (이 클래스 멤버) | aload_0_putfield_this | 불요 | 212
  aload_0; invokevirtual | (이 클래스 멤버) | aload_0_invokevirtual_this | 불요 | 213
  aload_0; invokespecial | (이 클래스 멤버) | aload_0_invokespecial_this | 불요 | 214
  aload_0; invokestatic | (이 클래스 멤버) | aload_0_invokestatic_this | 불요 | 215
  getstatic | (슈퍼 클래스 멤버) | getstatic_super | 불요 | 216
  putstatic | (슈퍼 클래스 멤버) | putstatic_super | 불요 | 217
  getfield | (슈퍼 클래스 멤버) | getfield_super | 불요 | 218
  putfield | (슈퍼 클래스 멤버) | putfield_super | 불요 | 219
  invokevirtual | (슈퍼 클래스 멤버) | invokevirtual_super | 불요 | 220
  invokespecial | (슈퍼 클래스 멤버) | invokespecial_super | 불요 | 221
  invokestatic | (슈퍼 클래스 멤버) | invokestatic_super | 불요 | 222
  aload_0; getstatic | (슈퍼 클래스 멤버) | aload_0_getstatic_super | 불요 | 223
  aload_0; putstatic | (슈퍼 클래스 멤버) | aload_0_putstatic_super | 불요 | 224
  aload_0; getfield | (슈퍼 클래스 멤버) | aload_0_getfield_super | 불요 | 225
  aload_0; putfield | (슈퍼 클래스 멤버) | aload_0_putfield_super | 불요 | 226
  aload_0; invokevirtual | (슈퍼 클래스 멤버) | aload_0_invokevirtual_super | 불요 | 227
  aload_0; invokespecial | (슈퍼 클래스 멤버) | aload_0_invokespecial_super | 불요 | 228
  aload_0; invokestatic | (슈퍼 클래스 멤버) | aload_0_invokestatic_super | 불요 | 229
  invokespecial | (이 클래스 <init>) | invokespecial_this_init | 불요 | 230
  invokespecial | (슈퍼 클래스 <init>) | invokespecial_super_init | 불요 | 231
  invokespecial | (신규 클래스 <init>) | invokespecial_new_init | 불요 | 232

  모든 바이트 코드 명령은, 「현재의 클래스」라고 불리는 클래스에 포함할 수 있습니다. 현재의 클래스의 슈퍼 클래스 (존재하는 경우)는, 「현재의 슈퍼 클래스」라고 불립니다. 텍스트라고 해도 와도 가까운 「신규」명령 (동일 메소드내)의 오퍼랜드는, 「현재의 신규 클래스」라고 불립니다.

  명령이 현재의 클래스내의 필드 또는 메소드를 참조하는 경우, 그것을 (압축 프로그램의 옵션으로) 고쳐 써, 「_this」라고 하는 철의 대응하는 조작 코드로서 전송 하는 것이 가능합니다. 같이 현재의 슈퍼 클래스내의 필드 또는 메소드를 참조하는 명령은, 「_super」라고 하는 철의 대응하는 조작 코드로서 고쳐 쓰는 것이 가능합니다. 어느 쪽의 경우도, 직전의 명령이 aload_0 (조작 코드 42)인 경우, 압축 프로그램을 사용해 그 명령의 전송을 억제해, 대신에 「aload_0_」(이)라고 하는 철의 대응하는 명령 코드를 선택할 수 있습니다. 그 이외의 경우, 「aload_0_」의 파생형은 선택할 수 없습니다.

  invokespecial 명령이 현재의 클래스, 현재의 슈퍼 클래스, 또는 현재의 신규 클래스내의 <init> 라는 이름의 메소드를 참조하는 경우, 압축 프로그램은 각각 invokespecial_this_init, invokespecial_super_init, invokespecial_new_init 로서 고쳐 쓸 수가 있습니다.

  「_this」라고 하는 철 ( 「_init」는 아니다)을 고쳐 쓸 수 있었던 명령의 필드 (또는 메소드) 오퍼랜드는, 특수한 밴드 `bc_thisfield` (메소드의 경우는 `bc_thismethod`) 내에서 전송 됩니다. 이러한 오퍼랜드의 번호부는,`cp_Field` (메소드의 경우는 `cp_Method`) 내의 일련의 기호를 취득해, 현재의 클래스의 멤버만을 선택하는 것으로써 정의됩니다. 생성되는 부분집합은, 차례를 변경하는 일 없이, 제로를 선두로서 리난바링 됩니다. 이것에 의해, 현재의 클래스의 멤버에게 작은 정수치를 컴팩트하게 매핑 할 수 있습니다.

  같이 「_super」라고 하는 철을 ( 「_init」는 아니다) 고쳐 쓸 수 있었던 명령의 오퍼랜드는,`bc_superfield` 또는 `bc_supermethod` 밴드내에서 전송 되어`cp_Field` 또는 `cp_Method` 의 부분집합으로서 리난바링 됩니다. 선택되는 것은, 현재의 슈퍼 클래스의 멤버 뿐입니다.

  마지막으로, 「_init」라고 하는 철을 고쳐 쓸 수 있었던 명령의 오퍼랜드는, 밴드 `bc_initref` 내에서 전송 되어`cp_Method` 의 부분집합으로서 리난바링 되어 적절한 클래스 (현재의 클래스, 현재의 슈퍼 클래스, 현재의 신규 클래스)에 맞추어 선택되어 또, 이름 <init> 를 가지도록(듯이) 선택됩니다. 일반적으로, 전송 되는 인덱스는 매우 작은 것입니다. 실제의 곳, 인덱스는 불려 간 메소드의 서명만을 선택해, 대부분의 클래스는 몇개의 생성자 만을 보관 유지합니다.

  다음의 겉(표)에, 복수 바이트의 명령 전송의 개요를 나타냅니다.

  명령 | 오퍼랜드 | 전송 된다 값 | 밴드
  bipush | (byte) x | x & 0xFF | `bc_byte`
  sipush | (short) x | x & 0xFFFF | `bc_short`
  ildc | cp_Int[i] | i | `bc_intref`
  fldc | cp_Float[i] | i | `bc_floatref`
  aldc | cp_String[i] | i | `bc_stringref`
  cldc | 현재의 클래스 | 0 | `bc_classref`
  cldc | cp_Class[i] | i+1 | `bc_classref`
  ildc_w | cp_Int[i] | i | `bc_intref`
  fldc_w | cp_Float[i] | i | `bc_floatref`
  aldc_w | cp_String[i] | i | `bc_stringref`
  cldc_w | 현재의 클래스 | 0 | `bc_classref`
  cldc_w | cp_Class[i] | i+1 | `bc_classref`
  lldc2_w | cp_Long[i] | i | `bc_long`
  dldc2_w | cp_Double[i] | i | `bc_double`
  *load | locals[i] | i | `bc_local`
  *store | locals[i] | i | `bc_local`
  ret | locals[i] | i | `bc_local`
  iinc | locals[i] | i | `bc_local`
  iinc ( 와이드가 아니다) | (byte) x | x & 0xFF | `bc_byte`
  iinc (와이드) | (short) x | x & 0xFFFF | `bc_short`
  if** | pc | (증분 (델타)/리난바링이 끝난) | `bc_label`
  if_** | pc | (증분 (델타)/리난바링이 끝난) | `bc_label`
  goto | pc | (증분 (델타)/리난바링이 끝난) | `bc_label`
  jsr | pc | (증분 (델타)/리난바링이 끝난) | `bc_label`
  goto_w | pc | (증분 (델타)/리난바링이 끝난) | `bc_label`
  jsr_w | pc | (증분 (델타)/리난바링이 끝난) | `bc_label`
  tableswitch | 케이스 카운트 | count | `bc_case_count`
  tableswitch | 디폴트 pc | (증분 (델타)/리난바링이 끝난) | `bc_label`
  tableswitch | 최초의 케이스치 | 치 | `bc_case_value`
  tableswitch | 각 케이스 pc | (증분 (델타)/리난바링이 끝난) | `bc_label`
  lookupswitch | 케이스 카운트 | count | `bc_case_count`
  lookupswitch | 디폴트 pc | (증분 (델타)/리난바링이 끝난) | `bc_label`
  lookupswitch | 각 케이스치 | 치 | `bc_case_value`
  lookupswitch | 각 케이스 pc | (증분 (델타)/리난바링이 끝난) | `bc_label`
  new | 현재의 클래스 | 0 | `bc_classref`
  new | cp_Class[i] | 1+i | `bc_classref`
  newarray | 형 코드 | 치 | `bc_byte`
  anewarray | 현재의 클래스 | 0 | `bc_classref`
  anewarray | cp_Class[i] | 1+i | `bc_classref`
  checkcast | 현재의 클래스 | 0 | `bc_classref`
  checkcast | cp_Class[i] | 1+i | `bc_classref`
  instanceof | 현재의 클래스 | 0 | `bc_classref`
  instanceof | cp_Class[i] | 1+i | `bc_classref`
  multianewarray | cp_Class[i] | 1+i | `bc_classref`
  multianewarray | 랭크 | 랭크 & 0xFF | `bc_byte`
  getstatic | cp_Field[i] | i | `bc_fieldref`
  putstatic | cp_Field[i] | i | `bc_fieldref`
  getfield | cp_Field[i] | i | `bc_fieldref`
  putfield | cp_Field[i] | i | `bc_fieldref`
  invokevirtual | cp_Method[i] | i | `bc_methodref`
  invokespecial | cp_Method[i] | i | `bc_methodref`
  invokestatic | cp_Method[i] | i | `bc_methodref`
  invokeinterface | cp_Imethod[i] | i | `bc_imethodref`
  **_this | this_fields[i] | i | `bc_thisfield`
  **_this | this_methods[i] | i | `bc_thismethod`
  **_super | super_fields[i] | i | `bc_superfield`
  **_super | super_methods[i] | i | `bc_supermethod`
  invokespecial_this_init | this_constructors[i] | i | `bc_initref`
  invokespecial_super_init | super_constructors[i] | i | `bc_initref`
  invokespecial_new_init | new_constructors[i] | i | `bc_initref`

  ## 6. 밴드 코딩의 스펙

  Pack200 밴드는, 작은 정수의 순서로 구성됩니다. 각 정수는 32 비트로 표현 가능합니다. 이러한 수치는, 그 의도한 용도에 근거해, 2 의 보수 기호를 보관 유지한다고 해석할 수 있습니다.

  각 정수는, 이전으로 결정된 encode에 따라, 1 ? 5 바이트를 사용해 바이트 순서로서 전송용으로 코드화 됩니다. encode는, 이 Pack200 어카이브(archive) 형식 스펙의 일부로서 지정된, 현재의 밴드용의 primary encode의 경우도 있으면, encode 된 정수의 발행전에 전송 된 정보에 근거하는 경우도 있습니다.

  덧붙여 이 encode 어카운트에서는, 바이트는 부호 없음의 값 [0,255] 를 나타내는 분할 불가능한 8중창입니다.

  #### 6.1. 주어진수의 복수 encode

  어카이브(archive)에 의해 허가되는, 작지만 유연한 encode 세트가 존재합니다. 이것들은 모두, 부호 없음의 작은 정수용의 encode의 2 파라미터 방식에 근거합니다. 이것은, 기호 표현 및 증분 (델타) encode용의 옵션, 및 완만하게 변화하는 encode용 및 빈번하게 사용하는 값의 간결한 이름 변경용의 특수 모드에 의해, 한층 더 파라미터화 됩니다.

  ##### 6.1. 1. 복수 encode 코딩의 방식

  작은 자연수의 encode는, 2 개의 단독 파라미터 B 및 H, 파생 파라미터 L 에 근거합니다.

  이름 | 범위 | 의미
  B | [1..5] | 최대의 바이트장
  H | [1..256] | 상위 바이트치의 수
  L | [0..255] | 하위 바이트치의 수. (256-H)(으)로서 정의된다

  2 개의 값 B 및 H 를 임의로 지정하는 경우, encode (B, H)가 존재합니다. 이것에 의해, 부 이외의 정수의 초기 순서와 바이트의 쇼트 순서의 「encode 세트」라는 사이로, 1 대 1 의 대응이 확립됩니다.

  게다가 어느 encode 세트내의 바이트 순서는, 같은 세트내의 다른 바이트 순서의 적절한 접두사로는 될 수 없습니다. 이것은, 그 encode가 자기 사이즈 결정, 즉 「구문 분석 가능」인 것을 비공식에 의미합니다.

  또, 충분히 긴 바이트의 각 순서가 encode 세트로부터 취득되는 바이트의 일의의 접두사로 시작되도록(듯이), encode 세트에 가능한 한 대부분이 포함할 수 있습니다. 특히, B 바이트의 각 순서는, (B, H) 코딩용의 encode 세트내에 (일의의) 접두사를 보관 유지합니다.

  ##### 6.1. 2. 바이트 순서의 encode의 정의

  특정의 (B, H) 코딩에 관련해, 그 값이 `[256-H..255]` 내의 범위에 있는 경우에, 바이트가 「상위이다」라고 말합니다. 또, L 가 정으로, 바이트의 값이 `[0..L-1]` 의 범위에 있는 경우, 바이트가 「하위이다」라고 말합니다.

  특정의 (B, H) 코딩에서는, 바이트의 순서는 encode 세트내에 있는 것은, 다음의 모든 것이 진정한 경우 뿐입니다.

  - 순서에는 1 바이트 이상, B 바이트 이하가 포함된다
  - 최후를 제외한 모든 바이트가 「상위」이다
  - 마지막 바이트가 「하위」인지, 순서에 B 바이트가 포함된다

  이 정의의 결과로서, encode 세트는, 상위 바이트와 하위 바이트에 관해서, 이 정규 표현을 채운다고 보여집니다.

        encoding_set = (high* low) | (high) ^B

  덧붙여 이 스펙에서는, caret 기호 「^」은, 전술의 정규 표현 또는 수치의 지수를 나타냅니다.

  n 가 B 미만의 경우, 길이가 정확하게 n 인 (B, H) encode의 수치는 `(H^(n-1) * L)` 가 됩니다. 길이가 정확하게 B 인 (B, H) encode의 수치는,`(H^(B-1) * (L+H))` 가 됩니다. `[1..B]` 내의 모든 n 에 대한 이러한 값의 합계는, (B, H) 코딩의 encode 세트의 합계 사이즈가 됩니다. 이것은 Card(B, H) 로 불려 다음과 같이 정의됩니다.

        Card(B, H) = (L * (1-H^B)/(1-H)) + H^B
          if H>1, or else
        Card(B, 1) = B*255+1

  H 가 256 의 경우, 하위 바이트는 존재하지 않습니다. encode 세트는 정확하게 B 바이트의 실현 가능한 순서 모두로 구성되어 Card(B, H)는 `256^B` 가 됩니다.

  그 이외의 경우, encode 세트는, 1 이상 B 이하의 다양한 길이의 순서로 구성됩니다. 특히, L 개의 1 바이트 순서가 존재합니다. 이것들을 다른 개소에서 사용해, 최고 빈도의 「우선한다」정수를 encode 합니다. 이 문서외의 개소에서 지정하는 encode 룰은, 큰 정수보다 작은 정수를 보다 빈번하게 생성하도록(듯이) 설계되고 있습니다.

  L 는, encode 하는 기대치의 제로에 관한 분포의 샤프니스를 표현하는, 「샤프니스」파라미터라고 볼 수가 있습니다. L 가 커지면(자), encode에 의해, 제로에 가까운 값의 분포가 우선되게 되어, 제로로부터 먼 값의 분포는 거의 없어집니다. H 치는 「평판적인」분포를 우선합니다. 이것에 의해, H=256, L=0 까지의 코딩 범위내에서, 완전하게 랜덤인 데이터의 encode가 우선됩니다.

  ##### 6.1. 3. 복호화 한 자연수치의 정의

  (B, H) 코딩의 범위는,`[0..Card(B, H)-1]` 의 정수입니다. 이 범위는, 이 섹션으로 지금까지 설명해 온 부호 없음의 코딩에만 적용됩니다.

  N 바이트치의 순서가 b[0] .. b[N-1] 인 경우, 전술의 소트 베이스 정의에 의해, 이 바이트 순서의 복호화 된 정수치는 little endian의 H 에 근거해 슬캘링 된 바이트의 합계가 됩니다. 또, 이것은 Decode(B, H; b) 로 불립니다.

        Decode(B, H; b[*]) = Sum[0<=i<N]( b[i] * H^i )

  이 정의의 결과, encode 세트내의 각 바이트 순서는, 그 범위의 산술 정수에 일의에 대응합니다. 이 대응은, 바이트 순서를 최초로 길이로, 다음에 반사전식 (little endian) 순서로 소트 하는 것으로 실현될 수 있습니다. 생성되는 순서내의 각 요소는 복호화 되어 순서 내부에서 제로 베이스의 독자 인덱스가 됩니다.

  수치 제로는, 항상 B 개의 제로 바이트의 순서 (H 가 256 의 경우), 또는 단일의 제로 바이트에 의해 encode 됩니다.

  encode 되는 최대의 산술치는, 항상 값 255 의 B 바이트의 순서에 의해 encode 됩니다.

  (B, H) encode (1,256), (2,256), 및 (4,256)은, 각각 종래의 부호 없음 바이트의 little endian 표현, 부호 없음의 16 비트 정수, 및 부호 없음의 32 비트 정수와 같습니다.

  안에는,`2^31-1` (경우에 따라서는 `2^32-1`)보다 큰 산술치를 나타내는 것도 있습니다. 이것은, (B, H) 코딩 방식의 특징입니다. 다만, 다음에 나타내도록(듯이), 복수의 부호 비트가 사용되는 경우에, 중간의 64 비트치가 필요하게 되는 일이 있습니다. 다음에 나타내는 부호 첨부치의 규칙에서는, 보다 복잡한 순서에 의해 같은 32 비트치 (절약하고 후 )가 생성되는 경우에서도, 압축 프로그램은 필수의 32 비트 정수를 전송 하는데 충분한 가장 단순한 encode를 발행할 필요가 있습니다.

  (B, H) 코딩치를 계산할 때, 구현은 중간치를 항상 자유롭게 절약할 수 있는 것은 아닙니다. 다만, 다음의 섹션으로 설명하도록(듯이), 최종적인 복호화치 (부호의 회복 후)는, 항상 32 비트에 맞추어 실행됩니다.

  #### 6.2. 부호 첨부 정수의 encode

  부호 첨부의 32 비트수를 encode 하기 위해서, (B, H) 코딩 방식으로 다른 파라미터를 추가합니다.

  이름 | 범위 | 의미
  B | [1..5] | 최대의 바이트장
  H | [1..256] | 상위 바이트치의 수
  L | [0..255] | 하위 바이트치의 수. (256-H)(으)로서 정의된다
  S | [0..2] | 부호 비트의 수

  (B, H) 코딩으로부터 취득된 자연수 U 는, 파라미터 S 에 근거하는 방법으로, 부호 첨부 32 비트치 X 에 변환됩니다. 이 처리는, 「부호 변환」이라고 불립니다.

  간단하게 정리하면(자), S=0 의 경우, 부호 변환은 32 비트의 절약해에 의해 실행됩니다. 그 이외의 경우, U 의 하위순서 비트는, 모든 부호 비트가 설정되어 있는 경우에게만 X 가 부가 되도록(듯이), 부호 비트로서 집합적으로 처리됩니다. 다음에 정의하도록(듯이), U 로부터 정의 X 에, 및 U 로부터 부의 X 에의 2 개의 변환은, 각각 독자 또한 반대 방향으로 조밀 및 단조롭습니다.

  (B, H) 코딩과는 달라, (B, H, S) 코딩은 특수한 정의 범위내의 수치만을 나타냅니다. 이 수치가 `[-2^31..2^31-1]` (을)를 넘는 것은 결코 없습니다.

  다음의 부분에서는, (B, H, S) 코딩 마다 Range(B, H, S), 및 이 코딩을 가지는 32 비트 부호치의 표현에 사용하는 메소드를 정의합니다.

  (B, H) encode 바이트 순서는, (B, H, S) 코딩의 범위에 변환되지 않는 자연수 U 를 나타내는 경우, 대응하는 (B, H, S) 코딩에 대한 유효한 입력이 아닙니다. 또, 2 살의 바이트 순서 encode치 U1 및 U2 가 존재해, 양쪽 모두가 부호 첨부 범위내의 동일 포인트 X 에 매핑 되는 경우, U1 와 U2 가 작은 (분)편 바이트 순서만이 유효하게 됩니다.

  이 때문에, (B, H, S) 코딩의 카디나리티는, 무효인 encode 바이트 순서를 위해서(때문에), 대응하는 (B, H) 코딩의 카디나리티보다 작아집니다.

  Card(B, H)가 `2^32` 이상인 경우, (B, H, S) 코딩의 범위에는, 32 비트의 부호 첨부 정수 `[-2^31..2^31-1]` 하지만 모두 포함됩니다. 0 보다 작은 값은 31 비트의 부호 없음 오버플로우로 나타내집니다. 코딩에 의해 encode 되는 부호 없음의 값이 적은 경우, 그 범위의 최상부가 `2^31-1` 에, 최하부가 `-2^31` 에 각각 절약할 수 있습니다.

  보다 정확하게는, (B, H, S) 코딩의 범위는 Range(B, H, S) 로 불려 다음과 같이 정의됩니다 (부분적, S=0 의 경우).

        Range(B, H, S) = [-2^31..2^31-1]
          if S=0, Card(B, H) >= 2^32, or
        Range(B, H, S) = [0..2^31-1]
          if S=0, 2^31 < Card(B, H) < 2^32, or else
        Range(B, H, S) = [0..Card(B, H)-1]
          if S=0, Card(B, H) <= 2^31

  압축 프로그램은, 현재의 코딩에 따라 해석하면(자), 코딩 범위외의 값에 복호화 되는 바이트 순서를 발행할 수 없습니다.

  압축 프로그램은 범위외의 코딩을 발행할 수 없기 때문에, 압축 해제 프로그램은 그것들에 대해서 임의의 대답을 생성할 수 있습니다. 이 때문에, 압축 해제 프로그램은, 바람직하지 않은 rack-around가 실행될 가능성을 무시해, 대부분의 계산으로 32 비트 산술을 사용할 수 있습니다.

  S>0 의 경우, 최초로 바이트 순서를 (B, H) 코딩으로서 복호화 해, 다음에 복호화 한 자연수를 부호 첨부의 32 비트수로 변환하는 것으로, 바이트 순서의 복호화가 실행됩니다. 이 부호 변환은, (B, H) 코딩으로부터 취득하는 산술치 U, 및 S 의 값인 만큼 의존하고 있습니다. 부호 변환에 의해 코딩 범위내의 값이 생성되는 경우, 산술치는 32 비트 정밀도보다 위에서 보존할 필요가 있습니다. (B, H) 코딩의 카디나리티가 `2^32` 이상의 경우, 중간의 부호 없음 자연수의 32 비트 절약해에 의해, 가능성이 있는 부의 부호 첨부 32 비트치가 (B, H, S) 코딩에 의해 모두 생성됩니다. 중간의 부호 없음 산술을, 부호가 없는 32 비트수를 사용해 실행하는 일도 (얼마인가의 주의가 필요), 64 비트의 부호 첨부수 또는 부호 없음수에 대해서 실행할 수도 있습니다.

  보다 정확하게는, 부호 변환 조작 SignConvert(S;U) 는, 다음과 같이 정의됩니다.

        SignConvert(S; U) = Cast32(U)
          if S==0; or
        SignConvert(S; U) = U - Floor(U / 2^S)
          if S>0, (U % 2^S) < 2^S-1, Card(B, H) < 2^32
        SignConvert(S; U) = Cast32(U - Floor(U / 2^S))
          if S>0, (U % 2^S) < 2^S-1, Card(B, H) >= 2^32
        SignConvert(S; U) = -Floor(U / 2^S)-1
          if S>0, (U % 2^S) == 2^S-1

  32 비트로 부의 큰 부호 없음수를 rack-around를 사용해 변환하는 처리는, 부호 첨부의 32 비트 정수에 다운 캐스트 하는 잘 알려진 처리와 같습니다. 이것은, 수학적으로는 다음과 같이 정의할 수 있습니다.

        Cast32(U) = ((U + 2^31) mod 2^32) - 2^31

  ##### 6.2. 1. 부호 변환의 상세

  부호 변환에서는, 항상 제로로부터 제로에의 매핑을 합니다. 독자도 확인할 수 있는 것입니다만, S>0 인 경우, SignConvert 의 범위에는 [-1..1] 이 포함됩니다. 이것은, 어느 정의 정수, 부의 정수의 서브 범위에 대해도 조밀 한편 단조롭습니다.

  `SignConvert(S;U)` 의 정의의 결과로서, U 의 S 개의 하위순서 비트는 부호 비트로서 기능합니다. 실제, U 는 부호 필드 U0 (S 개의 하위순서 비트로 구성된다) 및 유효 숫자 U1 (U 의 그 외 모든 비트로 구성된다) 내에 구분 됩니다.

  `SignConvert` 의 정의의 이 대체 뷰에서는, U0 의 모든 S 비트가 설정되는 경우, 복호화 된 부호 첨부치가 U1 의 보수가 됩니다. 이것에는 U 의 제로 상위순서 비트가 무한의 수 포함되기 (위해)때문에, 생성되는 값은 산술적으로 부가 됩니다.

  그 이외의 경우, U0 의 S 비트의 일부가 클리어이면, 유효 숫자 U1 는 U0 의 지정 가능한 값의 수 (S 가 2 의 경우는 (2^2)-1)을 사용해 확대 축소되어 U0 가 다시 더해집니다.

  이것에 의해, 산술 간격 `[0..Card(B, H)-1]` 및 `Range(B, H, S)` 의 부분간의 1 대 1 의 대응이 제공됩니다.

  이 encode로 「우선된다」정수는, 절대치의 작은 값입니다. 다만, 어느 쪽의 부호에서도 괜찮습니다. S 가 1 의 경우, encode에서는, 정의 우선치 및 부의 우선치의 수의 밸런스가 놓칩니다. S 가 2 (이상)의 경우, encode는 정의 수에 기웁니다만, 몇개의 부의 수도 우선됩니다. 이런 종류의 코딩을 다른 장소에서 사용해, 브랜치(branch)의 치환이나 대부분이 소트 된 데이터의 차분 등, 몇개인가가 부이지만 대부분이 정이라고 하는 값의 encode를 실시합니다.

  S=1 의 경우, 이 부호 변환 정의는, 부호 없음의 오른쪽 쉬프트와 거기에 계속되는, 나머지의 비트 모든 것을 가지는 부호 비트의 배타적 논리합과 동일해집니다.

        SignConvert(1; U) = (U >>> 1) ^ -(U & 1)

  S>0 의 경우, Range(B, H, S)는, 32 비트 부호 범위 `[-2^31..2^31-1]` (와)과 세트 `SignConvert(S; [0..Card(B, H)-1])` 의 교차로서 단순하게 정의됩니다. 이것은, (B, H)의 모든 산술 표현치에의 부호 변환을 실행하는 요소 단위의 어플리케이션에 의해 취득됩니다. 이 때문에, 다음의 방법으로 「범위」의 정의를 완성할 수 있습니다.

        Range(B, H, S) = [-2^31..2^31-1]
          if Card(B, H) >= 2^32, or
        Range(B, H, S) = [0..2^31-1]
          if S=0, 2^31 < Card(B, H) < 2^32, or else
        Range(B, H, S) = [0..Card(B, H)-1]
          if S=0, Card(B, H) <= 2^31

        Range(B, H, S) = [max(  -2^31, min SignConvert(S; Range(B, H, 0)) )
                     .. min( 2^31-1, max SignConvert(S; Range(B, H, 0)) )]

  덧붙여 부호 첨부 encode (B, H, S)의 경계를 계산할 때, (B, H, 0)의 최대의 부호 없음치 M 로부터 개시해, 최초의 정 및 최초의 0 보다 작은 값의 출현에 주의하면서, M, M-1, M-2 라고 하는 상태에 부호 변환을 실행하는 것은 좋은 방법입니다. 이것이, 부호 첨부 encode 범위의 경계가 됩니다 (경계를 범위에 포함한다).

  #### 6.3. 코딩의 속성

  지금까지의 설명으로, (B, H) 코딩의 카디나리티는, 다음과 같이 정의되었습니다.

        Card(B, H) = (L * (1-H^B)/(1-H)) + H^B

  (B, H, S) 코딩의 카디나리티는, 그 범위의 카디나리티에 의해 결정됩니다.

        Card(B, H, S) = Card Range(B, H, S) <= Card(B, H)

  정의에 의하면, 임의의 코딩 (B, H, S)의 범위는 제로에 관해서 조밀이기 (위해)때문에, 폐쇄 구간으로서 표현됩니다.

        Range(B, H, S) = [Min(B, H, S)..Max(B, H, S)]
        -2^31 <= Min(B, H, S) <= 0
        0     <  Max(B, H, S) <= 2^31-1

  특정의 추가 속성을, 코딩에 갖게할 수가 있습니다. 코딩은, 부호 첨부에도 부호없이도 할 수 있습니다. 플랜지에도, 사브렌지에도 (그 어느 쪽도 아닌 코딩으로 할 수도) 할 수 있습니다.

  1 개(살) 이상의 0 보다 작은 값으로 encode 할 수 있는 경우, (B, H, S) 코딩은 「부호 첨부」입니다. 이것은, S 가 제로 이외인지, S 가 제로로 Card(B, H)가 2^32 이상의 경우에게만 실로 됩니다.

  (B, H, S) 코딩이 「플랜지」가 되는 것은, Range(B, H, S)가 `[-2^31..2^31-1]` 의 경우입니다.

  사브렌지의 코딩에서는,2^31 미만의 값이 제공됩니다. 보다 정확하게 말하면(자), Card(B, H, S) <= `2^31-1` 의 경우에, 코딩 (B, H, S)은 「사브렌지」가 됩니다. 코딩안에는, 플랜지도 사브렌지도 아닌 것도 있습니다.

  이러한 정의의 결과로서, B<=3 인 코딩은 모두 사브렌지의 코딩이 됩니다. 이것보다 긴 코딩도, 충분히 「샤프」인 경우에는 사브렌지로 할 수 있습니다. 예를 들어, (4,192,0), (5,32,0), (5,32,1)등이, 이것에 해당합니다.

  또, 부호 없음의 코딩 (4,256,0)은, 부호 첨부의 버젼 (4,256,1)과 같게 플랜지입니다. 다만, 이중 부호 첨부의 버젼 (4,256,2)은 플랜지가 아닙니다.

  코딩 (4,255,0)은, 카디나리티가 2^31 이기 (위해)때문에, 사브렌지에서도 플랜지의 코딩이기도 하지 않습니다. 이것이 표현하는 것은, 부가 아닌 32 비트의 정수 뿐입니다. 카디나리티를 그처럼 나타낼 수 없습니다.

  #### 6.4. 상관관계가 있는 순서의 encode

  어카이브(archive) 형식내의 단일의 정수는 모두, (B, H, S) 코딩 방식내의 코딩에 따라 encode 됩니다. 또, 통계적인 규칙성을 나타내는 정수의 순서 (본문서외의 개소에서 「밴드」라고 불리는 내부)에는 특별한 주의가 기울여집니다. 특히, 정수의 순서가 작고 규칙적인 일차 차분의 패턴을 나타내는 경우, 이러한 차분을 값자체 대신에 encode 할 수 있습니다. 이것은, (B, H, S) 방식으로 추가된 4 번째의 코딩 파라미터에 의해 나타납니다.

  이름 | 범위 | 의미
  B | [1..5] | 최대의 바이트장
  H | [1..256] | 상위 바이트치의 수
  L | [0..255] | 하위 바이트치의 수. (256-H)(으)로서 정의된다
  S | [0..2] | 부호 비트의 수
  D | [0..1] | 증분 (델타) encode의 순서

  D 가 제로의 경우, 차분화는 실행되지 않고, (B, H, S, 0) 코딩은 항상 대응하는 (B, H, S) 코딩과 동일하게 됩니다. D 가 1 의 경우, 값은 후속의 차분과의 관계로 encode 됩니다.

  덧붙여 거의 단조롭게 증가해 가는 순서는, 대체로의 경우, (5, H, 0,1) 형식의 부호 없음 증분 (델타) 코딩을 사용해 순조롭게 encode 됩니다.

  값 X[i] 의 순서가, i 의 범위를 [0..N-1] 로서 지정되었을 경우를 생각해 봅시다. 이 순서는, (B, H, S) 코딩이 사브렌지 또는 플랜지의 코딩인 경우에게만, (B, H, S, 1) 코딩으로 표현할 수 있습니다. 어느 쪽도 아닌 경우, 유효한 (B, H, S, 1) 코딩은 존재하지 않습니다.

  부분화 `Sum[j<=i](D[j])` 로 값 X[i] 를 표현 가능한 일련의 「증분 (델타) 치」 D[i] 가 존재하는 경우, 순서 X[i] 는 표현 가능합니다.

  각 (B, H, S, 1) 코딩의 범위내에, 모든 X[i] 치가 포함됩니다. 이 범위는,`Range(B, H, S, 1) = Range(B, H, 0)` 로서 정의됩니다. 증분 (델타) 코딩 (B, H, S, 1)의 범위에 부의 수치가 포함되는 것은, 플랜지의 코딩 (B, H, S)에 근거하고 있는 경우만입니다. 그 이외의 경우, 증분 (델타) 코딩은 부가 아닌 수치만을 표현할 수 있습니다. 실제의 곳, 부의 밴드 요소는 거의 존재하지 않기 때문에, 이것은 어려운 제한이지 않습니다.

  부분화 Sum[j<=i](D[j])의 경우, 범위를 그대로 해 두는 것이 허가됩니다. 다만, 최종적인 X[i] 치는, Card Range(B, H, 0)의 배수를 가산 또는 감산해 항상 범위내에 되돌려집니다.

  정확하게는, 다음과 같이 됩니다.

        X[i] = Sum[j<=i](D[j]) mod Card(B, H, 0)
          if (B, H, S) is sub-range
        X[i] = (int32) Sum[j<=i](D[j])
          if (B, H, S) is full-range

  여기서,`int32` 에의 캐스트는 절약해에 의해 32 비트로 하는 것을 나타냅니다.

  코딩이 플랜지의 경우, 부분화의 계산시에, 구현은 32 비트의 rack-around를 단지 무시할 수 있습니다. 그 이외의 경우, 범위의 카디나리티의 배수를 감산 또는 가산해, 부분화를 범위내에 주의 깊게 되돌릴 필요가 있습니다. 또, 사이즈의 범위가 2^30 이상의 경우, 32 비트의 rack-around가 위험한 일이 있습니다. 32 비트의 부호 첨부 산술을 사용하는 경우에게만, 이것을 구현할 수 있습니다.

  #### 6.5. 상관관계가 없는 값의 encode

  지금까지 설명해 온 코딩 방법은, 대체로, 제로 또는 이전의 값에 근처 되는 경향을 가지는 값을 우선하도록(듯이) 설계되고 있습니다. 일부의 데이터 세트로 마크 붙이고 된 통계 패턴에서는, 값이 (제로에 대해, 또는 서로) 약한 산술 관계만을 보관 유지합니다만, 특히 일차 통계내에서 강력한 반복 패턴을 나타냅니다.

  이러한 경우, 압축 프로그램은, 생성 베이스의 코딩 변환을 사용하는 일이 있습니다. 이 변환에서는, N 산술치의 순서 S 가 3 개의 값순서에 변환됩니다.

  - F ? 우선치의 테이블 (임의의 길이 K+1 << N)
  - T ? 값토큰의 순서 (길이 N)
  - U ? 비우선치의 순서 (길이 << N, T 에 근거한다)

  다음에, 이러한 각 순서 (F, T, U)는 서브 밴드로서 처리되어 독자적인 encode를 사용해 전송 됩니다. T 내의 제로가 아닌 각 치는, F 로부터 취득한 값을 인덱스화합니다. 한편, T 내의 각 제로치는 U 로부터 값을 순서대로 선택합니다.

        S[i] = F[T[i]-1]
          if T[i] ! = 0
        U = { S[i] such that T[i] == 0 }

  ##### 6.5. 1. 우선치의 겉(표)

  테이블 F 에는, 임의의 수의 정수치가 포함됩니다. 그 수치나 식별 정보에는, F 내의 값은 마지막 값 이외 반복하지 못하는 것, F 에 사용하지 않는 값을 포함해선 안 되는 것을 제외해, 제한은 없습니다. F 의 마지막 값은, 이전에 발행된 F 의 「센치 네루치」의 반복이 아니면 안됩니다. 이 센치 네루에 의해 테이블 F 의 최후가 마크 붙이고 되어 압축 해제 프로그램이 T 및 U 를 읽어낼 준비를 할 수 있습니다.

  F 의 「중앙치」 X 는, F 의 요소로서 정의됩니다. 이것은, 산술적으로 제로에 가장 가까운 값입니다. F 에 최소 절대치인 정의 X 및 부의 -X 의 양쪽 모두가 포함되는 경우, -X 가 중앙치로서 정의됩니다. 즉, 부의 부호에는 균형을 찢는 기능이 있습니다. 중앙치의 선택은, 우선하는 encode를 결정하기 위해서(때문에) 행해집니다.

  구현은, 32 비트의 부호 첨부 int 식 `(X>>31)^(X<<1)` 를 부호 없음의 비교 키로서 사용해 값을 비교해, 중앙을 결정할 수 있습니다.

  유효한 센치 네루치는, F 의 중앙치 또는 F 의 최종치입니다. 이 때문에, F 의 해석시에, 압축 해제 프로그램은 (지금까지의) 중앙치의 반복해, 또는 직전의 값의 반복을 검색합니다.

  K 를 F 내의 값의 수라고 해, 센치 네루치의 반복을 무시하는 경우를 생각합시다. 이 경우, 다음의 밴드에서는,`[1..K]` 내의 값이 1 으로부터 시작되는 인덱스로서 기능해, F 의 대응하는 요소를 참조합니다.

  ##### 6.5. 2. 토큰의 순서

  T 의 순서는, 테이블 F 에 준거해, 생성 변환의 입력을 직접적 또한 요소 마다 encode 합니다.

  T 의 각 요소는, 산술 범위 `[0..K]` 로 encode 된, 우선치 또는 비우선치의 토큰입니다. 제로 이외의 각 치는, F 의 요소에 순서대로 대응해, 그 우선치를 생성합니다. T 내의 각 제로치는, 불명 인 채의 「비우선」치의 플레이스홀더-입니다.

  벌써 설명한 것처럼, F 의 각 요소는 T 의 1 개 이상의 요소에 의해 참조될 필요가 있습니다. 즉, 다음의 2 개세트는 같게 됩니다.

        { F[T[i]-1] such that T[i] ! = 0 }
        { F[j] }

  코더에 의해 F 의 내용에 대해 적절한 선택을 했다고 가정하면, 순서 T 의 통계는 적절한 (B, H) 방식에서 컴팩트한 encode를 실시하는데 있어서 매우 유리합니다. 일반적으로 말해, 가장 자주(잘) 이용되는 입력치를 F 내의 전방으로 배치하도록 해 주세요.

  최장 일치를 실시하는 알고리즘에서는, 입력치를 발행 회수로 소트 해, 가장 자주(잘) 이용되는 값을 F 의 선두에 배치하는 것이 가능합니다. 이것에 의해, 생성되는 입력의 encode가 개선될 가능성이 있습니다. 이런 종류의 수법은, 이 스펙으로 요구되고 있는 것은 아닙니다. 또, 비추천과도 되고 있지 않습니다.

  ##### 6.5. 3. 비우선치의 순서

  3 번째의 서브 순서는, 테이블 F 에의 인덱스에서는 표현되지 않았던 값으로 구성됩니다. Z 가, T 내에서 조우하는 제로의 수인 경우를 생각합시다. 이 경우, T 내의 Z 개의 제로와 U 의 Z 치 모두와의 사이에, 순서 붙이고 된 1 대 1 의 대응이 존재합니다.

  정리하면(자), T 의 요소에 의해 선택되는 F 및 U 의 요소는, 생성 변환의 입력과 값 및 순서가 같게 될 것입니다.

  다음에, 압축 해제 프로그램은, F 를 메모리에 읽어들이고 나서, T 를 메모리에 읽어들여, 그 후 T 를 재차 통과해 토큰치를 변환해, 필요에 따라서 F 를 참조하는지, U 로부터 read를 실시합니다.

  #### 6.6. 적응형의 encode

  때로는, 매우 긴 값순서로 통계가 천천히 변화하기 위해서, 당초는 적절한 코딩 수법이 올바르지 않은 것이 되는 일이 있습니다.

  적응형의 코딩 수법에서는, 값순서를 (효과적으로 서브 밴드에) 구분 해, 각 부분에서 독자적인 코딩을 로컬에 사용하는 것으로, 이 상황에 대응합니다.

  적응형의 코딩 수법은, 카운트 K, K 치의 encode에 사용하는 코딩 수법 A, 및 나머지의 값을 처리하는 다른 코딩 수법 B 에 의해 지정됩니다.

  밴드의 사이즈는 문맥으로 정해지기 (위해)때문에, 적응형의 코딩 수법을 encode 된 밴드의 바이트에 적용할 때, 이 메소드가 복호화 하는 값의 카운트 N 에 사전에 제공됩니다. 이 때문에, 메소드 A 가 K 치를 복호화 한 다음에, 메소드 B 를 사용해 밴드내의 나머지의 (N-K) 값이 복호화 됩니다.

  #### 6.7. 메타 encode

  primary encode가 BYTE1 가 아닌, Pack200 어카이브(archive) 형식내의 각 밴드의 전에, 옵션으로, 「밴드 코딩 지정자」라고 불리는 일련의 바이트가 배치됩니다. 이것에 의해, primary encode 대신에, 세칸다리 encode가 지정되어 밴드내에서 사용됩니다. 압축 해제 프로그램은, 밴드 요소의 어느쪽이든을 읽어내기 전에, 이 코딩 지시자를 해석해 보존할 필요가 있습니다. 몇개의 추가 바이트 정보내에서, 코딩 지시자가 후속의 바이트를 밴드치에 복호화 할 방법을 정확하게 결정할 수 있습니다.

  압축 프로그램이, 밴드 코딩 지시자를 제공하지 않는 것도 가능합니다. 이 경우는, 밴드의 primary encode에 의해 요소의 전송이 관리됩니다. primary encode로, 최초의 밴드 요소의 encode가 우연히 밴드 코딩 지시자인 것처럼 보이는 경우, 압축 프로그램은 명시적인 밴드 코딩 지시자를 전송 해, 밴드의 primary encode를 재확인할 필요가 있습니다. 이것이 필요하게 되는 것은, 보기 드문 일입니다. 이유는, 다음으로 설명하도록(듯이), 밴드 코딩 지시자는 primary encode로 부가 수라고 해 자기 자신을 제시하지만, 대부분의 밴드에서는 부의 수치 빠져 있으라고 되기 때문입니다.

  ##### 6.7. 1. 코딩 지시자의 구조

  밴드 코딩 지시자의 상징적 구조는, 다음의 문법에 따라 결정됩니다. 이것은, 밴드 구조를 관리하는 문법, 및 본스펙외의 개소에서 설명하는 문법과는 별개의 문법입니다.

        BandCodingSpecifier:
              (Default | BHSDCode | RunCode | PopCode)
        BHSDCode:
              CanonicalBHSDCode | ArbitraryBHSDCode
        CanonicalBHSDCode:
              ( '(1,256,0)' | '(1,256,1)' | ... )
        ArbitraryBHSDCode:
              'arb' ( B H S D )
        B, H, S, D:
              Integer
        RunCode:
              'run' K ACode BCode
        K:
              Integer
        ACode:
              (Default | BHSDCode | PopCode)
        BCode:
              (Default | BHSDCode | RunCode | PopCode)
        PopCode:
              'pop' ( FCode TCode UCode )
        FCode:
              (Default | BHSDCode | RunCode)
        TCode:
              (Default | BHSDCode | RunCode)
        UCode:
              (Default | BHSDCode | RunCode)
        Integer:
              ( '0' | '1' | ... )
        Default:
              'default'

  적응형의 코딩 수법 ( 「RunCode」비끝)은, 「BCode」비끝을 개입시켜 연쇄 가능합니다만, 「ACode」비끝을 직접 개입시켜 상자로 할 수 없습니다. 문법이 가리키는 대로, 「PopCode」비끝을 개입시켜 간접적으로 상자로 하는 것은 가능합니다.

  또, 생성형 코딩 수법으로 적응형 코딩 수법을 포함하는 일도, 적응형 코딩 수법으로 생성형 코딩 수법을 포함하는 일도 가능합니다. 다만, 문법에서는 명시되지 않는 점입니다만, 생성형 코딩 수법은 간접적이어도 상자으로서는 안됩니다.

  K 및 L 의 이용 가능한 정수치 모든 것이, 동일하고 충분히 표현 가능한 것이 아닙니다. K 에 대응하는 값은 압축 프로그램 윈도우와 어울리는 값이 되어, L 에 대응하는 값은 BHS encode의 샤프니스 파라미터가 됩니다.

  ##### 6.7. 2. 코딩 지시자의 시멘틱스

  임의의 시점에서, 다음의 3 개의 정보에 근거해 밴드의 내용이 복호화 됩니다.
  - N ? 복호화 하는 밴드치의 예측 수치, 또는 「무한」
  - D ? 디폴트의 BHSD 코딩
  - S ? 코딩 지시자

  S 를 N 및 D 와의 관련으로 적용하면(자), 「S(N, D)」가 됩니다. 이 적용에 의해, 전송 된 밴드 데이터의 N 요소까지 복호화를 합니다.

  밴드를 수신하기 직전에, 압축 해제 프로그램에 의해, 예측되는 밴드장 N 및 디폴트의 코딩 수법 D 가 식별되어 밴드의 primary encode로서 정적으로 지정됩니다. 다음에, 압축 해제 프로그램은, 밴드 encode 지시자를 구성하는 제로 이상의 바이트를 읽어내, 밴드 encode 지시자에 근거해 밴드 데이터의 N 요소를 복호화 합니다.

  코딩 지시자가 「default」의 경우, 밴드의 primary encode인 디폴트 코딩 D 를 사용해 N 치가 복호화 됩니다. 밴드의 최초의 요소가 빈 상태(empty)이 아닌 코딩 지시자를 도입하는 것처럼 보이는 경우, 이 규칙이 필요하게 됩니다. 이 디폴트 코딩 지시자는, 압축 프로그램이 발행할 의무를 지는 유일한 종류입니다. 나머지의 종류의 발행은 모두 옵션입니다.

  코딩 지시자가 다른 BHSDCode 인 경우는, 그 코딩을 사용해 N 치가 복호화 됩니다. 환경의 디폴트 D 는 무시됩니다.

  코딩 지시자가 K, ACode, BCode 에 대해서 「run」인 경우, 2 개의 순서가 실행됩니다. 처음은, ACode(K, D)와 같이, 지시자 ACode 에 제어가 주어집니다. 이것에 의해, N 가 일시적으로 K 로 설정됩니다. 다음에, BCode(N-K, D)와 같이, 지시자 BCode 에 제어가 주어집니다. 덧붙여 N 가 무한의 경우, N-K 도 무한하게 됩니다. 어느 쪽의 순서에 대해도, D 는 변경되지 않습니다. 이것에 의해, ACode 나 BCode 에 대한 「default」의 발행으로, D 가 사용됩니다.

  「run」코딩 지시자의 지정하는 K 를 제로로 하거나 K 이하의 값의 실행을 「run」코딩 지시자를 사용해 복호화 하는 것은, 부정한 조작입니다.

  코딩 지시자가 FCode, TCode, UCode 에 대해서 「pop」인 경우, 3 개의 순서가 실행됩니다. 최초로, FCode 가 FCode(infinity, D)로서 적용됩니다. F 치의 복호화는, 중복치에 처음으로 조우한 시점에서 정지합니다. 생성형 코딩에 관한 전의 섹션으로 설명한 것처럼, 중복치는 센치 네루로서 기능합니다. 또, 읽어내지는 가장 「중앙의」값, 또는 센치 네루치의 직전의 값이 아니면 안됩니다. 여기에서는, K 가 복호화 된 일의의 값의 수이다고 합니다.

  F 치를 FCode 로 encode 할 때, FCode 내의 모든 「run」지시자는, 센치 네루치를 복호화 하는 일 없이 카운트 「K」를 다 써 버릴 필요가 있습니다. 즉, 센치 네루는, FCode 내의 마지막 단순한 BHSD 코딩으로 복호화 할 필요가 있습니다.

  2 번째의 순서에서는, 다른 코딩 TCode 가 사용됩니다. 이것은, T 치는 조밀인 인코딩인 것이 기대되기 (위해)때문에입니다. TCode 는 TCode(N, D)로서 적용됩니다. 또, 토큰이 읽어내져 전달되는 밴드치가 결정됩니다. 지정된 N 치가 유한의 경우는, 「pop」코딩 수법의 적용만이 가능합니다. 이것은,`bc_codes` 등, 무한의 N 를 사용해 읽어내지는 밴드만이 바이트 밴드이기 (위해)때문에입니다. 여기에서는, Z 를, TCode 를 사용해 복호화 되는 제로가 수라고 합니다.

  3 번째의 순서에서는, UCode 를 사용해, 원의 디폴트 encode D 를 이용해 Z 치를 복호화 합니다. UCode 는 U(Z, D)로서 적용됩니다. 벌써 설명한 것처럼, T 순서내의 제로를 후속의 U 치로 옮겨놓아 T 순서외의 요소를 F 순서내에서 인덱스화 된 것과 옮겨놓는 것으로, 밴드가 T 순서로부터 생성됩니다.

  「pop」코딩 지시자를 사용해, 값이 없는, 또는 무한수의 값의 실행을 복호화 하는 것은 부정한 조작입니다. Z (비우선치의 수)가 제로의 경우, UCode 를 「default」이외에 하는 것은 부정한 조작입니다.

  ##### 6.7. 3. 코딩 지시자의 메타 encode

  압축 프로그램은, 신장성이 있는 바이트 지향의 encode를 사용해, 밴드 encode 지시자를 전송 합니다. 전술의 「잔소리어」에 의해 광범위의 encode가 가능하게 됩니다만, 실제의 곳, 그 대부분이, 퍼포먼스 및 적용성의 면에서 유사하고 있습니다. 압축 프로그램에, 생각되는 임의의 밴드 encode 지시자를 지정하는 완전한 자유를 주는 것은, 필요한 일에서도, 바람직한 일이기도 하지 않습니다. 그 대신해, 이 섹션으로 설명하는 메타 encode를 사용해, 한정적이지만 유용한 세칸다리 encode 세트로부터의 선택을 압축 프로그램에 허가합니다. 압축을 개선하는 선택은, 압축 프로그램에 의존하고 있습니다. 이런 종류의 선택을 제어하는 경험칙 또는 알고리즘에 대해 말하는 것은, 이 스펙의 범위를 넘고 있습니다.

  일반적인 밴드 코딩 지시자 「default」는, 많은 경우, 추가의 바이트를 필요로 하지 않는 방법으로 encode 됩니다. 밴드에 요소가 존재하지 않는 경우, 해석은 행해지지 않습니다. 그 이외의 경우, 밴드의 디폴트 encode가 가변 길이이면, 압축 해제 프로그램이 있는 값 X 를, 밴드의 디폴트 코딩 D 를 사용해 밴드의 초기 바이트로부터 복호화 할 필요가 있습니다. 가능한 경우, 값 X 는 부호 없음의 바이트치 XB 에 변환됩니다. 이것이 밴드 코딩 지시자의 최초의 바이트가 되어, X 는 파기됩니다. 그 이외의 경우, 밴드 코딩 지시자가 「default」가 되어, D 가 초기치 X 를 생성하는 바이트를 포함한 밴드 전체에 적용됩니다.

  D 는, (B, H, S) 또는 (B, H, S, D)의 형식이 아니면 안됩니다. 다만, B>1, H<256 입니다. 값 D 는, 최초의 값의 복호화와는 관계가 없습니다. X 의 복호화는, (B, H, S, 0)를 사용해 행해집니다. S 가 제로가 아니고, 값 X 가 [-256..-1] 의 범위내인 경우, 코딩 지시자 바이트 XB 가 `XB = (-1-X)` 로서 정의되어 X 가 파기됩니다. 그 이외의 경우, S 가 제로로, X 의 값이 [(256-H)..(511-H)] 의 범위내이면, 코딩 지시자 바이트 XB 가 `XB = (X-(256-H))` 로서 정의되어 X 가 파기됩니다. 그 이외의 경우, 코딩 지시자 바이트 XB 가 존재하지 않으면, 벌써 설명한 것처럼 X 는 최초의 밴드치가 됩니다.

  값 XB 가 생성되었을 경우는, 이 값이, 실제의 밴드 데이터에 선행하는 코딩 지시자의 초기 바이트가 됩니다. 이 지시자에 대해서 해석이 실행됩니다. 지시자는, XB 를 선두로 해,`band_headers` 로부터 취득된 바이트로 (필요에 따라서) 계속됩니다. 그 후, 해석된 지시자를 사용해, 다음의 바이트로부터 시작되는, 모든 밴드 요소의 복호화가 제어됩니다.

  밴드가, 밴드 지시자 바이트 XB 의 생성을 필요로 하는, 범위 (`[-256..-1]` 또는 `[L, L+255]`) 안의 요소 X1 로 실제로 시작되지만, 압축 프로그램이 디폴트의 encode의 사용을 요구하는 경우, X1 가 압축 해제 프로그램을 오도 하는 것이 없게, 압축 프로그램이 밴드 헤더를 지정할 필요가 있습니다. 압축 프로그램이 디폴트 코딩의 보관 유지를 바라는 경우, 제로의 XB 치를 사용해, 명시적인 코딩 지시자 「default」를 지정할 필요가 있습니다 (자세한 것은 후술). 이 제로 XB 가, 디폴트의 encode에 근거해, X 의 값 -1 (일반적으로은 바이트 1) 또는 L (일반적으로은 바이트 192,0)로서 전송 됩니다.

  이 설계의 직접적인 결과는, 바이트 밴드가 비디폴트의 encode를 보관 유지 불가능하게 되지만, 그 외의 밴드는 모두 보관 유지 가능하다라고 말하는 점입니다. 이유는, 다른 밴드는 모두, 가변 길이 또한 동적 범위의 큰 디폴트 encode를 보관 유지하기 (위해)때문에입니다. X 용으로 「이스케이프」치가 선택되는 것은, 실제의 곳 보기 드물기 때문에, 일반적으로은 실제의 밴드 데이터와 혼동 할 것은 없습니다. 여분으로 제로치를 추가해 디폴트를 재확인하면(자), 실제의 밴드 데이터의 전에 항상 1 바이트 여분으로 필요하게 됩니다. `band_headers` 밴드내에 추가의 바이트는 불필요합니다. 일반적으로, 명시적인 X 치의 encode에서는, S 가 제로의 경우는 항상 2 바이트가 필요하게 됩니다. S 가 제로가 아닌 경우는, 최대로 2 바이트가 필요하게 됩니다.

  밴드 `band_headers` 는, 밴드 헤더를 가지는 각 밴드의 비초기 밴드 헤더 바이트 (존재하는 경우)를 전송 합니다. 전송 순서는, 현재의 스펙의 밴드 문법으로 설명한 것처럼, 어카이브(archive)내의 전밴드의 종합적인 순서와 일치합니다. `band_headers` 의 길이는, 어카이브(archive) 헤더내에서 (`#band_headers_size` 로서) 독자적으로 지정됩니다. 압축 해제 프로그램은, 밴드를 한층 더 읽어내기 전에 `band_headers` 의 끝을 검출할 필요가 있습니다.

  이 때문에, 코딩 지시자의 encode는, 바이트의 순서 (초기 바이트 XB, 및 제로 또는 `band_headers` 로부터 취득된 비초기 바이트)로 구성됩니다. 전의 섹션으로 지정한 잔소리어의 encode는, 다음과 같이 됩니다. encode 「default」는, 제로 바이트입니다. 사용 가능한 모든 BHSDCode encode 중(안)에서, 115 「정규 encode」의 순서 (정의는 후술)가 선택되어 예측되는 사용 범위가 대상이 됩니다. BHSDCode 는, 1 바이트로 표현됩니다. 이 값은, 값이 선택한 정규 코딩의 인덱스 (1 베이스)입니다.

        Enc{default}  = (0)
        Enc{CanonicalBHSDCode} = value in [1..115]

  특수한 값 116 에서는, 임의의 (비정규 BHSD 코드의 가능성이 있다) BHSD 가 도입됩니다. 이것에 대해서는, 계속되는 바이트에 기술됩니다.

        Enc{ arb ( B H S D ) } =
            116
          & (D:[0..1] + 2*S[0..2] + 8*(B:[1..5]-1))
          & (H[1..256]-1):

  B 치는,[1..5] 의 범위내가 아니면 안됩니다. S 치는,[0..2] 의 범위내가 아니면 안됩니다. H 치는,[1..256] 의 범위내가 아니면 안됩니다. D 치는,[0..1] 의 범위내가 아니면 안됩니다. 이러한 범위에는 경계도 포함됩니다. 또, B 가 1 인 경우, H 는 256 이 아니면 안되어, H 가 256 의 경우, B 는 5 이외가 아니면 안됩니다.

  「run」구문의 encode는,[117..140] 내의 바이트로 시작되어, 옵션의 바이트 KB 를 계속할 수가 있습니다. 그 후, 1 또는 2 개의 encode 지시자 ACode 및 BCode 를 계속할 수가 있습니다. 117 으로부터의 오프셋(offset)에 의해, 다음의 데이터가 비트 단위로 표현됩니다.

  - 2 비트의 필드 KX
  - 1 비트의 KBFlag
  - 1 비트의 ADef (ABDef == 1)
  - 1 비트의 BDef (ABDef == 2)
  마지막 2 비트는, 값 ABDef 내에서 정리해 encode 됩니다. 이것들이 양쪽 모두 실로 될 것은 없습니다.

        Enc{ run ( K ACode BCode ) } =
            (117 + (KX:[0..3]) + 4*(KBFlag:[0..1]) + 8*(ABDef:[0..2]))
          & KB: one of [0..255] if KBFlag=1
          & Enc{ ACode } if ADef=0  (ABDef ! = 1)
          & Enc{ BCode } if BDef=0  (ABDef ! = 2)

  KBFlag 가 설정되어 있는 경우는, 선두 바이트의 해석 후에 바이트 KB 가 예측됩니다. 그 이외의 경우, KB 에는 값 3 이 암묵적으로 지정됩니다.

  「run」구문의 K 치는, 값의 범위를 취할 수가 있습니다. 범위는 다음과 같이 결정됩니다.

        K = (KB+1) * 16^KX

  ADef 비트가 설정되어 있는 경우, ACode 의 코딩은 「default」이다고 이해됩니다. 그 이외의 경우는, ACode 의 표기가 다음에 해석됩니다. 마지막으로, BDef 비트가 설정되어 있는 경우, BCode 의 코딩은 「default」이다고 이해됩니다. 그 이외의 경우는, BCode 의 표기가 마지막에 해석됩니다. ADef 와 BDef 의 양쪽 모두를 클리어 하는 것은 가능합니다만, 양쪽 모두를 설정할 수 없습니다.

  「pop」구문의 encode는 [141..188] 내의 바이트로 시작됩니다만, 거기에 1, 2, 또는 3 개의 encode 지시자 FCode, UCode, 및 TCode 를 계속할 수가 있습니다. 141 으로부터의 오프셋(offset)에 의해, 다음의 데이터가 비트 단위로 encode 됩니다.

  - 1 비트의 FDef
  - 1 비트의 UDef
  - 1 비트의 TDef (TDefL > 0)
  - [1..11] 내의 1 개의 값 L (TDef=1 의 경우)
  마지막 2 개의 값은, 값 TDefL 내에서 정리해 encode 됩니다.

        Enc{ pop ( FCode TCode UCode ) }
          = (141 + (FDef:[0..1]) + 2*UDef:[0..1] + 4*(TDefL:[0..11]))
          & Enc{ FCode } if FDef=0
          & Enc{ TCode } if TDef=0  (TDefL==0)
          & Enc{ UCode } if UDef=0

  TDef 가 제로의 경우, 명시적인 encode 지시자에 의해 TCode 가 결정됩니다. L 파라미터는 존재하지 않습니다. TDef 가 1 개의 경우, L 파라미터가 존재합니다. 이 파라미터는, 다음의 겉(표)에 따라 TDefL 로부터 이끌립니다.

  TDefL | L
  1 | 4
  2 | 8
  3 | 16
  4 | 32
  5 | 64
  6 | 128
  7 | 192
  8 | 224
  9 | 240
  10 | 248
  11 | 252

  L 파라미터가 존재하는 경우는, TCode 는 K 및 L 치로부터 이끌립니다. K < 256 의 경우, TCode 는 BYTE1 (1,255,0)가 되어, L 는 무시됩니다. 그 이외의 경우, TCode 는 (B, H, S) 코딩이 됩니다. 여기서, S=0, H=(256-L)입니다. B 는,[0..K] 가 Range(B, H, S)에 포함되는 최소치가 됩니다. Range(5,256-L, 0)에 K 가 포함되지 않을 정도(수록), L 에 큰 값을 지정하는 것은 부정한 조작입니다.

  FDef 비트가 설정되어 있는 경우, FCode 의 코딩은 「default」이다고 이해됩니다. 그 이외의 경우, FCode 의 표기는, 초기 바이트의 다음에 곧바로 해석됩니다. TDef 비트가 설정되어 있는 경우, TCode 의 코딩은 K 및 L 로부터 이끌리는 것이라고 이해됩니다. 그 이외의 경우는, TCode 의 표기가 다음에 해석됩니다. 마지막으로, UDef 비트가 설정되어 있는 경우, UCode 의 코딩은 「default」이다고 이해됩니다. 그 이외의 경우는, UCode 의 표기가 마지막에 해석됩니다.

  ##### 6.7. 4. 정규의 BHSD 코딩

  여기에서는, 정규의 BHSD 코딩을 모두 가리킵니다. 이러한 코딩은, 밴드치의 다양한 범위 및 통계에 맞추어 설계되고 있습니다.

  index | BHSD 코딩
  1 | (1,256,0)
  2 | (1,256,1)
  3 | (1,256,0,1)
  4 | (1,256,1,1)
  5 | (2,256,0)
  6 | (2,256,1)
  7 | (2,256,0,1)
  8 | (2,256,1,1)
  9 | (3,256,0)
  10 | (3,256,1)
  11 | (3,256,0,1)
  12 | (3,256,1,1)
  13 | (4,256,0)
  14 | (4,256,1)
  15 | (4,256,0,1)
  16 | (4,256,1,1)
  17 | (5, 4,0)
  18 | (5, 4,1)
  19 | (5, 4,2)
  20 | (5, 16,0)
  21 | (5, 16,1)
  22 | (5, 16,2)
  23 | (5, 32,0)
  24 | (5, 32,1)
  25 | (5, 32,2)
  26 | (5, 64,0)
  27 | (5, 64,1)
  28 | (5, 64,2)
  29 | (5,128,0)

  index | BHSD 코딩
  30 | (5,128,1)
  31 | (5,128,2)
  32 | (5, 4,0,1)
  33 | (5, 4,1,1)
  34 | (5, 4,2,1)
  35 | (5, 16,0,1)
  36 | (5, 16,1,1)
  37 | (5, 16,2,1)
  38 | (5, 32,0,1)
  39 | (5, 32,1,1)
  40 | (5, 32,2,1)
  41 | (5, 64,0,1)
  42 | (5, 64,1,1)
  43 | (5, 64,2,1)
  44 | (5,128,0,1)
  45 | (5,128,1,1)
  46 | (5,128,2,1)
  47 | (2,192,0)
  48 | (2,224,0)
  49 | (2,240,0)
  50 | (2,248,0)
  51 | (2,252,0)
  52 | (2, 8,0,1)
  53 | (2, 8,1,1)
  54 | (2, 16,0,1)
  55 | (2, 16,1,1)
  56 | (2, 32,0,1)
  57 | (2, 32,1,1)
  58 | (2, 64,0,1)

  index | BHSD 코딩
  59 | (2, 64,1,1)
  60 | (2,128,0,1)
  61 | (2,128,1,1)
  62 | (2,192,0,1)
  63 | (2,192,1,1)
  64 | (2,224,0,1)
  65 | (2,224,1,1)
  66 | (2,240,0,1)
  67 | (2,240,1,1)
  68 | (2,248,0,1)
  69 | (2,248,1,1)
  70 | (3,192,0)
  71 | (3,224,0)
  72 | (3,240,0)
  73 | (3,248,0)
  74 | (3,252,0)
  75 | (3, 8,0,1)
  76 | (3, 8,1,1)
  77 | (3, 16,0,1)
  78 | (3, 16,1,1)
  79 | (3, 32,0,1)
  80 | (3, 32,1,1)
  81 | (3, 64,0,1)
  82 | (3, 64,1,1)
  83 | (3,128,0,1)
  84 | (3,128,1,1)
  85 | (3,192,0,1)
  86 | (3,192,1,1)
  87 | (3,224,0,1)

  index | BHSD 코딩
  88 | (3,224,1,1)
  89 | (3,240,0,1)
  90 | (3,240,1,1)
  91 | (3,248,0,1)
  92 | (3,248,1,1)
  93 | (4,192,0)
  94 | (4,224,0)
  95 | (4,240,0)
  96 | (4,248,0)
  97 | (4,252,0)
  98 | (4, 8,0,1)
  99 | (4, 8,1,1)
  100 | (4, 16,0,1)
  101 | (4, 16,1,1)
  102 | (4, 32,0,1)
  103 | (4, 32,1,1)
  104 | (4, 64,0,1)
  105 | (4, 64,1,1)
  106 | (4,128,0,1)
  107 | (4,128,1,1)
  108 | (4,192,0,1)
  109 | (4,192,1,1)
  110 | (4,224,0,1)
  111 | (4,224,1,1)
  112 | (4,240,0,1)
  113 | (4,240,1,1)
  114 | (4,248,0,1)
  115 | (4,248,1,1)

  ## 7. 압축 해제 프로그램의 출력의 안정성

  지금까지의 설명으로부터, 압축 해제 프로그램에는, 클래스 파일의 내용의 정리에 관해서 매우 자유도의 높은 선택사항이 주어지고 있는 것처럼 생각됩니다. 클래스 파일 형식에서는, 파일의 가치에 영향을 미칠리가 없는, 다양할 수록 번의 자유가 존재합니다. 예를 들어, 정수 풀 엔트리, 속성 리스트, 및 클래스 메소드를 순서를 신경쓰지 않고 배치하거나 압축 해제 프로그램을 사용해, Java 어플리케이션의 목적을 변경하지 않고 자유롭게 상훌 할 수 있습니다.

  다만, 모든 Pack200 어카이브(archive)로, 각 압축 해제 프로그램이, 전송 되는 클래스 파일 마다 특정의 바이트 단위의 이미지를 생성할 필요가 있습니다. 이것은, 메세지 다이제스트 등, 전송 되는 클래스 파일의 최종적인 바이트 단위의 내용에 관련되는 정보를, 압축 프로그램을 전송 할 수 있도록(듯이) 하기 위해서, 압축 해제 프로그램에 부과되는 요건입니다. 이 섹션에서는, 출력 파일의 바이트 단위의 내용을 세련된 입력 함수로 변환하는, 각 압축 해제 프로그램에 과하여지는 제한에 대해 설명합니다.

  일반적으로, 압축 해제된 클래스 파일내의 요소의 순서는, Pack200 어카이브(archive)내의 전송 순서와 일치하고 있을 필요가 있습니다. 예를 들어, 클래스 파일내에서 선언되는 클래스의 필드의 순서는, 클래스의 필드 기술자가 `field_descr` 밴드내에서 전송 된 순서에 대응하고 있을 필요가 있습니다. 이것은,`field_flags` 밴드내의 순서에도 대응합니다. 다음의 겉(표)에서는, 클래스 파일의 순서와 어카이브(archive)의 전송 순서에 관한, 필수의 대응 관계를 모두 가리킵니다.

  클래스 파일내의 요소 | 순서를 결정한다 밴드
  구현되는 인터페이스 | class_interface
  선언되는 필드 | field_descr
  선언되는 메소드 | method_descr
  코드 핸들러의 리스트 | code_handler_start_P
  클래스 속성의 리스트 | class_flags, class_attr_indexes
  필드 속성의 리스트 | field_flags, field_attr_indexes
  메소드 속성의 리스트 | method_flags, method_attr_indexes
  코드 속성의 리스트 | code_attr_indexes
  정수 풀 엔트리 | cp_Utf8 등 (자세한 것은 후술)

  종합 하면(자), 순서에 관한 이러한 필수 대응 관계에 의해, 압축 해제된 클래스 파일의 내용이 엄밀하게 결정됩니다. 인터페이스, 필드, 메소드, 및 예외 핸들러의 순서는, 이것들을 전송 하는 밴드의 순서에 의해 직접 결정됩니다.

  #### 7.1. 속성 리스트의 순서

  클래스, 필드, 및 메소드의 속성 리스트의 선두에는, 설정 flag bit를 위해서(때문에), 전송 되는 모든 속성을 기술할 필요가 있습니다. 이 순서는, 인덱스순서가 아니면 안됩니다 (플래그 워드내의 LSB 로부터 MSB 에). 플래그에 근거하는 모든 속성의 나중에, 오버플로우 속성 모든 것을 리스트에 포함할 필요가 있습니다. 오버플로우 속성을 포함한 속성 리스트의 순서는, 레이아웃이 대응하는 일련의 값 중(안)에서 `class_attr_indexes`,`field_attr_indexes`,`method_attr_indexes`, 또는 `code_attr_indexes` 로부터 전송 된 순서와 같게 됩니다. 인덱스가 32 미만의 속성 레이아웃은, flag bit를 사용해 제로회 또는 1 회 지정할 수 있습니다. 또, 이것은, 오버플로우 속성 레이아웃을 전송 하는 밴드내에서의 발행을 통해, 독자적으로 제로회이상 지정할 수도 있습니다.

  `InnerClasses` 속성을 클래스에 추가할 필요가 있는 경우는, 다음의 섹션으로 설명하는 규칙에 따라, 그 속성을 클래스의 속성 리스트의 마지막에 배치할 필요가 있습니다.

  #### 7.2. 정수 풀의 순서

  압축 해제된 클래스 파일 X 의 정수 풀 `cp(X)` 는, 압축 해제 프로그램이 X 의 대부분을 생성한 후에, X 및 `cp_All` 의 사후 처리를 실행하는것 같이, 정의됩니다. X 의 내용을 정의하는 경우를 구체적으로 생각합시다. 다만, 다음의 상황은 존재하지 않는 것으로 합니다.
  - `cp(X)` 가 미정도리이다
  - X 에 `InnerClasses` 속성이 존재하지 않는 (`ic_Local(X)` 가 전송 되었을 경우에서도)
  - X 내부의 정수 참조의 장소는 기술되고 있지만, 수치로 초기화되어 있지 않다

  그 후,`cp(X)` 가, 다음의 순서에 따르는것 같이 정의됩니다. 이것에 의해,`cp(X)` 가 글로벌 정수 풀 `cp_All` 로부터 생성됩니다. 또, X 의 `InnerClasses` 속성도 생성될 가능성이 있습니다.

  - `cp(X)` 는, 당초, 공백입니다.
  - X 로부터 참조되는 모든 정수가 `cp(X)` 에 추가됩니다.
  - 다음의 순서에서는,`cp_Signature` 로부터의 모든 정수를, 전송 되는 구조에 관계없이, 참조를 추가하지 않는 방법으로 처리할 필요가 있습니다.
  - `cp(X)` 로부터 참조되는 정수는, 아직 존재하지 않는 경우는 모두,`cp(X)` 에 추가됩니다. 예를 들어,`cp_Method` 로부터의 정수는 `cp_Class` 및 `cp_Descr` 로부터의 정수를 참조합니다.
  - 변경이 발생하지 않게 될 때까지, 전의 순서가 반복해집니다. 많은 경우, 이러한 순서는 2 회 이상 반복해집니다.

  이 시점에서, 정수 풀 `cp(X)` 는, 압축 해제 프로그램이 관련하는 상자 클래스세트 `ic_Relevant(X)` 를 계산할 수 있는 만큼, 충분히 정의되고 있습니다.

  - `ic_Relevant(X)` 는, 당초 공백입니다.
  - 현재의 클래스 (X 에 의해 정의)를 외부 클래스로 하는,`ic_All` 로부터의 각 4 타풀이 `ic_Relevant(X)` 에 추가됩니다.
  - `ic_this_class` 와 `cp(X)` 의 양쪽 모두로부터 참조되는 각 클래스 정수 K 로,`ic_All` 로부터의 대응하는 4 타풀이 선택되어,`ic_Relevant(X)` 에 추가됩니다 (존재하지 않는 경우).
  - 전의 순서가, 폐포 될 때까지 반복해집니다. 즉,`ic_Relevant(X)` 가 변경되지 않게 될 때까지입니다.
  - 설정 `ic_Relevant(X)` 가 순서에 순서 붙이고 되어,`ic_All` 와 순서가 일치하게 됩니다. 즉, 이것은 `ic_All` 의 서브 순서입니다.

  `ic_Relevant(X)` 및 옵션으로 전송 된 `ic_Local(X)` 를 제어하에 둔 압축 해제 프로그램은, 여기서 다음의 순서를 실행해, X 의 `InnerClasses` 속성 `ic_Stored(X)` 를 포함할지 어떨지를 결정할 필요가 있습니다.

  - `ic_Local(X)` 가 존재해, 한편 빈 상태(empty)인 경우, X 의 `InnerClasses` 속성은 포함되지 않고, 다음의 순서는 어느 것도 실행되지 않습니다.
  - 또,`ic_Local(X)` 가 존재하지 않고,`ic_Relevant(X)` 가 빈 상태(empty)인 경우는, X 의 `InnerClasses` 속성은 포함되지 않습니다.
  - 그 이외의 경우, 나중에 `ic_Relevant(X)` 의 요소가 계속되는 `ic_Local(X)` 내의 요소로서`ic_Stored(X)` 가 설정됩니다 (어느쪽이나 전송순서).
  - 다음에,`ic_Local(X)` 와 `ic_Relevant(X)` 의 양쪽 모두의 요소가 `ic_Stored(X)` 로부터 「삭제」되어, 대칭차이가 생성됩니다.
  - 생성되는 순서 `ic_Stored(X)` 는, 비록 빈 상태(empty)의 경우에서도,`InnerClasses` 속성으로서 압축 해제 프로그램의 출력에 추가됩니다.
  - 모든 `cp_Class` 및 `cp_Utf8` 엔트리는,`ic_Stored(X)` 에 의해 직접 또는 간접적으로 필요하게 됩니다. 또, 고정의 `cp_Utf8` 엔트리 `"InnerClasses"` 가 `cp(X)` 에 추가됩니다 (존재하지 않는 경우).

  상자 클래스의 레코드로부터의 마지막 처리로서 압축 해제 프로그램에 의해, 다음의 순서로 정수 풀의 마무리를 합니다.

  - `cp(X)` 내의 모든 `cp_Signature` 엔트리가 「평활화」되어, 같은 이름의 `cp_Utf8` 엔트리에 넣어집니다.
  - `cp(X)` 내의 몇개의 `cp_Utf8` 엔트리 E 가 `cp_All` 내에서 전송 되지 않지만, 동등의 철의 서명 S 가 전송 되는 경우,`cp(X)` 내에서 E 가 S 로 옮겨집니다.
  - `cp_All` 내에도 존재하는 `cp(X)` 의 요소는,`cp_All` 내와 같은 순서에 소트 됩니다.
  - `cp_All` 내에 존재하지 않는,`cp(X)` 내의 `cp_Utf8` 정수 모든 것은 `cp(X)` 의 마지막에 옮겨져`String.compareTo` 로 정의된 순서로 소트 됩니다.
  - 다음에,`cp_All` 내에 존재하지 않는,`cp(X)` 내의 `cp_Class` 정수 모든 것이 `cp(X)` 의 마지막에 옮겨져 클래스명에 관해서 `String.compareTo` 로 정의된 순서로 소트 됩니다.
  - 이 시점에서, 압축 해제 프로그램은 `cp(X)` 의 각 요소의 위치를 일의로 결정하고 있습니다.
  - 1 대 1 의 인덱스 (ldc 바이트 코드)를 사용해 참조되는 `cp(X)` 의 모든 요소는, 상대순서를 변경하는 일 없이,`cp(X)` 의 선두에 정리해 옮겨집니다.
  - `cp(X)` 의 모든 요소가 동등의 클래스 파일 정수형에 변환됩니다. 서명은, 같은 철의 CONSTANT_Utf8 정수에 「평활화」됩니다.
  - 생성되는 클래스 파일 정수의 순서 `cp(X)` 는, X 의 정수 풀로서 포함됩니다.

  이 처리의 나중에, X 의 포함이 끝난 정수 풀은 참조 무결성을 유지해, 모든 정수 참조를 `cp(X)` 내에 인덱스로서 코드화할 수 있습니다. 정수 참조의 명확한 순서는,`cp_All` 로부터 이끌립니다. 특히,`cp(X)` 내의 정수가 다른 정수를 참조할 필요가 있는 경우는, 폐포순서 시에, 그 정수가 `cp(X)` 내에 삽입이 끝난 상태일 필요가 있습니다.

  `cp(X)` 의 순서는 `cp_All` 의 순서와 일치하고 있습니다. 다만, 일부의 서명 참조가 `cp_Utf8` 의 동등의 기존 요소에 리다이렉트(redirect) 되는 것, 및 ldc 바이트 코드의 오퍼랜드 모든 것이 정수 풀의 선두에 강제적으로 배치되는 것을 제외합니다.

  로컬 인덱스를 `cp(X)` 의 요소에 할당할 때, 압축 해제 프로그램은, 클래스 파일 형식의 요건에 따라, 인덱스 제로, CONSTANT_Long 및 CONSTANT_Double 정수용의 빈 상태(empty)의 정수 풀 슬롯의 예약을 준수할 필요가 있습니다. 이러한 규칙에 가세해`cp(X)` 의 구축 및 순서부에 의해, X 내부의 정수 참조에 대한 명확한 인덱스 할당이 완전하게 결정됩니다.

  ## 8. 부록

  ### 8.1. 부록:밴드의 리스트

  여기에서는, 모든 밴드의 리스트를, 어카이브(archive)내의 발행순서에 나타냅니다. 이 리스트는, Pack200 스펙의 일부에서는 없습니다만, 밴드의 이름과 순서가 정의된 스펙에 관해서, 그 문법의 의미를 명확하게 이해하는 것을 돕는 목적으로 제공하는 것입니다. 4 개의 생략 기호 ... (은)는, 예외적인 캐릭터 라인이나 표준 이외의 속성의 전송을 지원하기 위해서, 압축 프로그램이 추가 밴드의 가변수를 삽입 가능한 위치를 나타냅니다. 그 다른 생략 기호는, 메타데이타반드의 반복을 나타냅니다. 그것을 포함한다고 기술이 장황하게 되어 버리기 (위해)때문에입니다.

  밴드 | 디폴트 코딩 | 길이: | 참조한다 정수 풀
  `archive_magic` | BYTE1 | `[4]`
  `archive_header` | UNSIGNED5 | `[26]`
  `band_headers` | BYTE1 | `[...]`
  `cp_Utf8_prefix` | DELTA5 | `[MAX(0, #cp_Utf8_count-2)]`
  `cp_Utf8_suffix` | UNSIGNED5 | `[MAX(0, #cp_Utf8_count-1)]`
  `cp_Utf8_chars` | CHAR3 | `[SUM(*cp_Utf8_suffix)]`
  `cp_Utf8_big_suffix` | DELTA5 | `[COUNT(0, *cp_Utf8_suffix)]`
  `{cp_Utf8_big_chars...}` | DELTA5 | `[*cp_Utf8_big_suffix[i]]`
  `cp_Int` | UDELTA5 | `[#cp_Int_count]`
  `cp_Float` | UDELTA5 | `[#cp_Float_count]`
  `cp_Long_hi` | UDELTA5 | `[#cp_Long_count]`
  `cp_Long_lo` | DELTA5 | `[#cp_Long_count]`
  `cp_Double_hi` | UDELTA5 | `[#cp_Double_count]`
  `cp_Double_lo` | DELTA5 | `[#cp_Double_count]`
  `cp_String` | UDELTA5 | `[#cp_String_count]` | `cp_Utf8`
  `cp_Class` | UDELTA5 | `[#cp_Class_count]` | `cp_Utf8`
  `cp_Signature_form` | DELTA5 | `[#cp_Signature_count]` | `cp_Utf8`
  `cp_Signature_classes` | UDELTA5 | `[COUNT('L',...)]` | `cp_Class`
  `cp_Descr_name` | DELTA5 | `[#cp_Descr_count]` | `cp_Utf8`
  `cp_Descr_type` | UDELTA5 | `[#cp_Descr_count]` | `cp_Signature`
  `cp_Field_class` | DELTA5 | `[#cp_Field_count]` | `cp_Class`
  `cp_Field_desc` | UDELTA5 | `[#cp_Field_count]` | `cp_Descr`
  `cp_Method_class` | DELTA5 | `[#cp_Method_count]` | `cp_Class`
  `cp_Method_desc` | UDELTA5 | `[#cp_Method_count]` | `cp_Descr`
  `cp_Imethod_class` | DELTA5 | `[#cp_Imethod_count]` | `cp_Class`
  `cp_Imethod_desc` | UDELTA5 | `[#cp_Imethod_count]` | `cp_Descr`
  `attr_definition_headers` | BYTE1 | `[#attr_definition_count]`
  `attr_definition_name` | UNSIGNED5 | `[#attr_definition_count]` | `cp_Utf8`
  `attr_definition_layout` | UNSIGNED5 | `[#attr_definition_count]` | `cp_Utf8`
  `ic_this_class` | UDELTA5 | `[#ic_count]` | `cp_Class`
  `ic_flags` | UNSIGNED5 | `[#ic_count]`
  `ic_outer_class` | DELTA5 | `[COUNT(1<<16,...)]` | `cp_Class`
  `ic_name` | DELTA5 | `[COUNT(1<<16,...)]` | `cp_Utf8`
  `class_this` | DELTA5 | `[#class_count]` | `cp_Class`
  `class_super` | DELTA5 | `[#class_count]` | `cp_Class`
  `class_interface_count` | DELTA5 | `[#class_count]`
  `class_interface` | DELTA5 | `[SUM(*class_interface_count)]` | `cp_Class`
  `class_field_count` | DELTA5 | `[#class_count]`
  `class_method_count` | DELTA5 | `[#class_count]`
  `field_descr` | DELTA5 | `[SUM(*class_field_count)]` | `cp_Descr`
  `field_flags_hi` | UNSIGNED5 | `[SUM(*class_field_count) *#have_field_flags_hi]`
  `field_flags_lo` | UNSIGNED5 | `[SUM(*class_field_count)]`
  `field_attr_count` | UNSIGNED5 | `[COUNT(1<<16,...)]`
  `field_attr_indexes` | UNSIGNED5 | `[SUM(*field_attr_count)]`
  `field_attr_calls` | UNSIGNED5 | `[...]`
  `field_ConstantValue_KQ` | UNSIGNED5 | `[COUNT(ConstantValue,...)]` | `cp_Int, cp_Float, etc.`
  `field_Signature_RS` | UNSIGNED5 | `[COUNT(Signature,...)]` | `cp_Signature`
  `field_RVA_anno_N` | UNSIGNED5 | `[...]`
  `field_RVA_type_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `field_RVA_pair_N` | UNSIGNED5 | `[...]`
  `field_RVA_name_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `field_RVA_T` | BYTE1 | `[...]`
  `field_RVA_caseI_KI` | UNSIGNED5 | `[...]` | `cp_Int`
  `field_RVA_caseD_KD` | UNSIGNED5 | `[...]` | `cp_Double`
  `field_RVA_caseF_KF` | UNSIGNED5 | `[...]` | `cp_Float`
  `field_RVA_caseJ_KJ` | UNSIGNED5 | `[...]` | `cp_Long`
  `field_RVA_casec_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `field_RVA_caseet_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `field_RVA_caseec_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `field_RVA_cases_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `field_RVA_casearray_N` | UNSIGNED5 | `[...]`
  `field_RVA_nesttype_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `field_RVA_nestpair_N` | UNSIGNED5 | `[...]`
  `field_RVA_nestname_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `field_RIA_anno_N` | UNSIGNED5 | `[...]`
  `{field_RIA_...}` |  | ``
  `field_RIA_nestname_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `{field_attr_bands...}` | (각종) | `[...]` | `(각종)`
  `method_descr` | MDELTA5 | `[SUM(*class_method_count)]` | `cp_Descr`
  `method_flags_hi` | UNSIGNED5 | `[SUM(*class_method_count) *#have_method_flags_hi]`
  `method_flags_lo` | UNSIGNED5 | `[SUM(*class_method_count)]`
  `method_attr_count` | UNSIGNED5 | `[COUNT(1<<16,...)]`
  `method_attr_indexes` | UNSIGNED5 | `[SUM(*method_attr_count)]`
  `method_attr_calls` | UNSIGNED5 | `[...]`
  `method_Exceptions_N` | UNSIGNED5 | `[COUNT(Exceptions,...)]`
  `method_Exceptions_RC` | UNSIGNED5 | `[SUM(*method_Exceptions_N)]` | `cp_Class`
  `method_Signature_RS` | UNSIGNED5 | `[COUNT(Signature,...)]` | `cp_Signature`
  `method_RVA_anno_N` | UNSIGNED5 | `[...]`
  `method_RVA_type_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `method_RVA_pair_N` | UNSIGNED5 | `[...]`
  `method_RVA_name_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `method_RVA_T` | BYTE1 | `[...]`
  `method_RVA_caseI_KI` | UNSIGNED5 | `[...]` | `cp_Int`
  `method_RVA_caseD_KD` | UNSIGNED5 | `[...]` | `cp_Double`
  `method_RVA_caseF_KF` | UNSIGNED5 | `[...]` | `cp_Float`
  `method_RVA_caseJ_KJ` | UNSIGNED5 | `[...]` | `cp_Long`
  `method_RVA_casec_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `method_RVA_caseet_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `method_RVA_caseec_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `method_RVA_cases_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `method_RVA_casearray_N` | UNSIGNED5 | `[...]`
  `method_RVA_nesttype_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `method_RVA_nestpair_N` | UNSIGNED5 | `[...]`
  `method_RVA_nestname_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `method_RIA_anno_N` | UNSIGNED5 | `[...]`
  `{method_RIA_...}` |  | ``
  `method_RIA_nestname_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `method_RVPA_param_NB` | BYTE1 | `[...]`
  `method_RVPA_anno_N` | UNSIGNED5 | `[...]`
  `{method_RVPA_...}` |  | ``
  `method_RVPA_nestname_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `method_RIPA_param_NB` | BYTE1 | `[...]`
  `method_RIPA_anno_N` | UNSIGNED5 | `[...]`
  `{method_RIPA_...}` |  | ``
  `method_RIPA_nestname_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `method_AD_T` | BYTE1 | `[...]`
  `method_AD_caseI_KI` | UNSIGNED5 | `[...]` | `cp_Int`
  `method_AD_caseD_KD` | UNSIGNED5 | `[...]` | `cp_Double`
  `method_AD_caseF_KF` | UNSIGNED5 | `[...]` | `cp_Float`
  `method_AD_caseJ_KJ` | UNSIGNED5 | `[...]` | `cp_Long`
  `method_AD_casec_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `method_AD_caseet_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `method_AD_caseec_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `method_AD_cases_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `method_AD_casearray_N` | UNSIGNED5 | `[...]`
  `method_AD_nesttype_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `method_AD_nestpair_N` | UNSIGNED5 | `[...]`
  `method_AD_nestname_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `{method_attr_bands...}` | (각종) | `[...]` | `(각종)`
  `class_flags_hi` | UNSIGNED5 | `[#class_count*#have_class_flags_hi]`
  `class_flags_lo` | UNSIGNED5 | `[#class_count]`
  `class_attr_count` | UNSIGNED5 | `[COUNT(1<<16,...)]`
  `class_attr_indexes` | UNSIGNED5 | `[SUM(*class_attr_count)]`
  `class_attr_calls` | UNSIGNED5 | `[...]`
  `class_SourceFile_RUN` | UNSIGNED5 | `[COUNT(SourceFile,...)]` | `null|cp_Utf8`
  `class_EnclosingMethod_RC` | UNSIGNED5 | `[COUNT(EnclosingMethod,...)]` | `cp_Class`
  `class_EnclosingMethod_RDN` | UNSIGNED5 | `[COUNT(EnclosingMethod,...)]` | `null|cp_Descr`
  `class_Signature_RS` | UNSIGNED5 | `[COUNT(Signature,...)]` | `cp_Signature`
  `class_RVA_anno_N` | UNSIGNED5 | `[...]`
  `class_RVA_type_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `class_RVA_pair_N` | UNSIGNED5 | `[...]`
  `class_RVA_name_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `class_RVA_T` | BYTE1 | `[...]`
  `class_RVA_caseI_KI` | UNSIGNED5 | `[...]` | `cp_Int`
  `class_RVA_caseD_KD` | UNSIGNED5 | `[...]` | `cp_Double`
  `class_RVA_caseF_KF` | UNSIGNED5 | `[...]` | `cp_Float`
  `class_RVA_caseJ_KJ` | UNSIGNED5 | `[...]` | `cp_Long`
  `class_RVA_casec_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `class_RVA_caseet_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `class_RVA_caseec_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `class_RVA_cases_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `class_RVA_casearray_N` | UNSIGNED5 | `[...]`
  `class_RVA_nesttype_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `class_RVA_nestpair_N` | UNSIGNED5 | `[...]`
  `class_RVA_nestname_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `class_RIA_anno_N` | UNSIGNED5 | `[...]`
  `{class_RIA_...}` |  | ``
  `class_RIA_nestname_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `class_InnerClasses_N` | UNSIGNED5 | `[COUNT(InnerClasses,...)]`
  `class_InnerClasses_RC` | UNSIGNED5 | `[SUM(*class_InnerClasses_N)]` | `cp_Class`
  `class_InnerClasses_F` | UNSIGNED5 | `[SUM(*class_InnerClasses_N)]`
  `class_InnerClasses_outer_RCN` | UNSIGNED5 | `[COUNT(! =0, *class_InnerClasses_F)]` | `null|cp_Class`
  `class_InnerClasses_name_RUN` | UNSIGNED5 | `[COUNT(! =0, *class_InnerClasses_F)]` | `null|cp_Utf8`
  `class_file_version_minor_H` | UNSIGNED5 | `[COUNT(version,...)]`
  `class_file_version_major_H` | UNSIGNED5 | `[COUNT(version,...)]`
  `{class_attr_bands...}` | (각종) | `[...]` | `(각종)`
  `code_headers` | BYTE1 | `[COUNT(Code,...)]`
  `code_max_stack` | UNSIGNED5 | `[COUNT(0, *code_headers)]`
  `code_max_na_locals` | UNSIGNED5 | `[COUNT(0, *code_headers)]`
  `code_handler_count` | UNSIGNED5 | `[COUNT(0, *code_headers)]`
  `code_handler_start_P` | BCI5 | `[SUM(*code_header_count)]`
  `code_handler_end_PO` | BRANCH5 | `[SUM(*code_header_count)]`
  `code_handler_catch_PO` | BRANCH5 | `[SUM(*code_header_count)]`
  `code_handler_class_RCN` | UNSIGNED5 | `[SUM(*code_header_count)]` | `null|cp_Class`
  `code_flags_hi` | UNSIGNED5 | `[...*#have_code_flags_hi]`
  `code_flags_lo` | UNSIGNED5 | `[...]`
  `code_attr_count` | UNSIGNED5 | `[COUNT(1<<16,...)]`
  `code_attr_indexes` | UNSIGNED5 | `[SUM(*code_attr_count)]`
  `code_attr_calls` | UNSIGNED5 | `[...]`
  `code_StackMapTable_N` | UNSIGNED5 | `[COUNT(StackMapTable,...)]`
  `code_StackMapTable_frame_T` | BYTE1 | `[SUM(*code_StackMapTable_N)]`
  `code_StackMapTable_local_N` | UNSIGNED5 | `[COUNT(255, *code_StackMapTable_frame_T)]`
  `code_StackMapTable_stack_N` | UNSIGNED5 | `[COUNT(255, *code_StackMapTable_frame_T)]`
  `code_StackMapTable_offset` | UNSIGNED5 | `[...]`
  `code_StackMapTable_T` | BYTE1 | `[...]`
  `code_StackMapTable_RC` | UNSIGNED5 | `[COUNT(7, *code_StackMapTable_T)]`
  `code_StackMapTable_P` | BCI5 | `[COUNT(8, *code_StackMapTable_T)]`
  `code_LineNumberTable_N` | UNSIGNED5 | `[...]`
  `code_LineNumberTable_bci_P` | BCI5 | `[...]`
  `code_LineNumberTable_line` | UNSIGNED5 | `[...]`
  `code_LocalVariableTable_N` | UNSIGNED5 | `[...]`
  `code_LocalVariableTable_bci_P` | BCI5 | `[...]`
  `code_LocalVariableTable_span_O` | BRANCH5 | `[...]`
  `code_LocalVariableTable_name_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `code_LocalVariableTable_type_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `code_LocalVariableTable_slot` | UNSIGNED5 | `[...]`
  `code_LocalVariableTypeTable_N` | UNSIGNED5 | `[...]`
  `code_LocalVariableTypeTable_bci_P` | BCI5 | `[...]`
  `code_LocalVariableTypeTable_span_O` | BRANCH5 | `[...]`
  `code_LocalVariableTypeTable_name_RU` | UNSIGNED5 | `[...]` | `cp_Utf8`
  `code_LocalVariableTypeTable_type_RS` | UNSIGNED5 | `[...]` | `cp_Signature`
  `code_LocalVariableTypeTable_slot` | UNSIGNED5 | `[...]`
  `{code_attr_bands...}` | (각종) | `[...]` | `(각종)`
  `bc_codes` | BYTE1 | `[...]`
  `bc_case_count` | UNSIGNED5 | `[COUNT(switch, *bc_codes)]`
  `bc_case_value` | DELTA5 | `[...]`
  `bc_byte` | BYTE1 | `[...]`
  `bc_short` | DELTA5 | `[...]`
  `bc_local` | UNSIGNED5 | `[...]`
  `bc_label` | BRANCH5 | `[...]`
  `bc_intref` | DELTA5 | `[...]` | `cp_Int`
  `bc_floatref` | DELTA5 | `[...]` | `cp_Float`
  `bc_longref` | DELTA5 | `[...]` | `cp_Long`
  `bc_doubleref` | DELTA5 | `[...]` | `cp_Double`
  `bc_stringref` | DELTA5 | `[...]` | `cp_String`
  `bc_classref` | UNSIGNED5 | `[...]` | `cp_Class`
  `bc_fieldref` | DELTA5 | `[...]` | `cp_Field`
  `bc_methodref` | UNSIGNED5 | `[...]` | `cp_Method`
  `bc_imethodref` | DELTA5 | `[...]` | `cp_Imethod`
  `bc_thisfield` | UNSIGNED5 | `[...]` | `cp_Field 서브 순서`
  `bc_superfield` | UNSIGNED5 | `[...]` | `cp_Field 서브 순서`
  `bc_thismethod` | UNSIGNED5 | `[...]` | `cp_Method 서브 순서`
  `bc_supermethod` | UNSIGNED5 | `[...]` | `cp_Method 서브 순서`
  `bc_initref` | UNSIGNED5 | `[...]` | `cp_Method 서브 순서`
  `bc_escref` | UNSIGNED5 | `[...]` | `cp_All`
  `bc_escrefsize` | UNSIGNED5 | `[...]`
  `bc_escsize` | UNSIGNED5 | `[...]`
  `bc_escbyte` | BYTE1 | `[...]`
  `file_name` | UNSIGNED5 | `[#file_count]` | `cp_Utf8`
  `file_size_hi` | UNSIGNED5 | `[#file_count*(#have_file_size_hi)]`
  `file_size_lo` | UNSIGNED5 | `[#file_count]`
  `file_modtime` | DELTA5 | `[#file_count*(#have_file_modtime)]`
  `file_options` | UNSIGNED5 | `[#file_count*(#have_file_options)]`
  `file_bits` | BYTE1 | `[SUM(*file_size)]`

  ### 8.2. 부록:의사 코드의 예

  #### 8.2. 1. `cp_Utf8` 정수 풀의 표현

  다음에 나타내는 의사 코드는,벌써 설명한, 밴드의 길이와 내용, 및 `cp_Utf8` 정수 풀 요소간의 관계를 나타냅니다. 이 코드는, 전술의 스펙에 관한 주해에 지나지 않고, 스펙에 새로운 정보를 추가하는 것이 아닙니다.

        assert(cp_Utf8[0]. equals(""));
        int cursor = 0;
        int big_cursor = 0;
        for (int i = 1; i < cp_Utf8_count; i++) {
          String thisString = cp_Utf8[i];

          int prefix = (i == 1)?  0: cp_Utf8_prefix[i-2];
          int suffix = thisString.length() - prefix;
          String prevString = cp_Utf8[i-1];
          String prevPrefix = prevString.substring(0, prefix);
          String thisPrefix = thisString.substring(0, prefix);
          assert(prevPrefix.equals(thisPrefix));

          int small_suffix = cp_Utf8_suffix[i-1];
          char[] suffix_chars;
          int offset;
          if (small_suffix ! = 0) {
            assert(suffix == small_suffix);
            suffix_chars = cp_Utf8_chars;
            offset = cursor;
            cursor += suffix;
          } else {
            assert(suffix == cp_Utf8_big_suffix[big_cursor]);
            suffix_chars = cp_Utf8_big_chars[big_cursor];
            offset = 0;
            assert(suffix == suffix_chars.length);
            big_cursor += 1;
          }
          String thisSuffix = thisString.substring(prefix);
          String theseChars = new String(suffix_chars, offset, suffix);
          assert(thisSuffix.equals(theseChars));
        }
        assert(cp_Utf8_prefix.length == Math.max(0, cp_Utf8_count-2));
        assert(cp_Utf8_suffix.length == Math.max(0, cp_Utf8_count-1));
        assert(cp_Utf8_chars.length == cursor);
        assert(cp_Utf8_big_suffix.length == big_cursor);
        assert(cp_Utf8_big_chars.length == big_cursor);

  #### 8.2. 2. `cp_Signature` 정수 풀의 표현

  다음에 나타내는 의사 코드는,벌써 설명한, 밴드의 길이와 내용, 및 `cp_Signature` 정수 풀 요소간의 관계를 나타냅니다. 이 코드는, 전술의 스펙에 관한 주해에 지나지 않고, 스펙에 새로운 정보를 추가하는 것이 아닙니다.

        int cursor = 0;
        for (int i = 0; i < cp_Signature_count; i++) {
          String sign = cp_Signature[i];
          String form = cp_Signature_form[i];
          int form_ptr = 0;
          int sign_ptr = 0;
          for (; form_ptr < form.length(); form_ptr++) {
            assert(form.charAt(form_ptr) == sign.charAt(sign_ptr));
            sign_ptr += 1;
            if (form.charAt(form_ptr) == 'L') {
              String cls = cp_Class[cursor];
              assert(sign.startsWith(cls, sign_ptr));
              cursor += 1;
              sign_ptr += cls.length();
            }
          }
          assert(sign_ptr == sign.length());
        }
        assert(cp_Signature_form.length == cp_Signature_count);
        assert(cp_Signature_classes.length == cursor);

  #### 8.2. 3. 바이트 오프셋(offset)의 표현

  다음에 나타내는 의사 코드는,벌써 설명한,`bc_index` 레이아웃 요소로 관리되는 밴드내의 바이트 오프셋(offset) 및 encode의 관계를 나타냅니다. 이 코드는, 전술의 스펙에 관한 주해에 지나지 않고, 스펙에 새로운 정보를 추가하는 것이 아닙니다.

        // ins_pos is a display of all instruction boundaries
        int[] ins_pos;
        ...
        Arrays.sort(ins_pos);
        assert(ins_pos[0] == 0);
        assert(ins_pos[ins_pos.length-1] == bytecodes.length);
        int regulars = ins_pos.length; //  # instruction boundaries
        ...
        int renumber_bci(int bci) {
          int i = Arrays.binarySearch(ins_pos, bci);
          return (i >= 0) ?  i : (i == -1) ?  bci : ins_pos.length + bci - (-i-1);
        }
        ...
        for (int bci = -100; bci <= bytecodes.length+100; bci++) {
          int bci_numbering_for_band = renumber_bci(bci);
          int i = Arrays.binarySearch(ins_pos, bci);
          if (i >= 0) {
            assert(ins_pos[i] == bci);
            assert(bci_numbering_for_band < regulars);
            assert(bci_numbering_for_band == i);
          } else if (0 < bci && bci < bytecodes.length) {
            int nexti = (-i-1);  // index of next instruction
            assert(ins_pos[nexti-1] < bci && bci < ins_pos[nexti]);
            int prevRegulars = nexti;
            int prevAll = bci;
            int prevIrregulars = prevAll - prevRegulars;
            assert(bci_numbering_for_band >= regulars);
            assert(bci_numbering_for_band == regulars + prevIrregulars);
          } else {
            // other (random) numbers are unchanged by renumbering
            assert(bci_numbering_for_band >= bytecodes.length ||
      	     bci_numbering_for_band < 0);
            assert(bci_numbering_for_band == bci);
          }
        }

  #### 8.2. 4. 예측 가능한 상자 클래스명의 표현

  다음에 나타내는 의사 코드는,벌써 설명한, 상자 클래스의 분해명 및 예측 가능한 외부명과 단순명과의 관계를 나타냅니다. 리터럴 문자 「/」 및 「$」의 검색은, SLASH 및 DOLLAR 비끝과 관련지을 수 있었던 문자 범위를 검색해, 현실의 구현으로 옮겨놓을 필요가 있습니다. 이 코드는, 전술의 스펙에 관한 주해에 지나지 않고, 스펙에 새로운 정보를 추가하는 것이 아닙니다.

        String bcn, predictableOuter, predictableICName;
        ...
        String name = bcn.substring(bcn.lastIndexOf('/')+1);
        int dollar2 = name.lastIndexOf('$');
        assert(predictableICName == null ||
               (predictableICName.charAt(0) > '9' &&
                predictableICName.indexOf('$') < 0));
        if (predictableICName == null) {
          // bcnCase1 or bcnCase4
          assert(predictableOuter == null);
          assert(dollar2 == -1 ||
                 dollar2+1 == name.length() ||
                 isDigit(name.charAt(dollar2+1)));
        } else if (predictableOuter == null) {
          // bcnCase2
          assert(name.endsWith("$"+predictableICName));
          int dollar1 = name.substring(0, dollar2). lastIndexOf('$');
          assert(dollar1 >= 0 && dollar1+1 < dollar2);
          assert(isDigitString(name.substring(dollar1+1, dollar2)));
        } else {
          // bcnCase3
          assert(bcn.equals(predictableOuter+"$"+predictableICName));
        }

  ### 8.3. 부록 :Java 컬렉션 API 의 설계에 관한 FAQ

  질문에 대해서는,jsr-200-comments@Sun.COM 에 메일을 전송해 주세요. 여기에 정리하고 있는 Pack200 어카이브(archive) 형식에 관한 FAQ 는, 설계 원리로서 참고로 해 주세요.

  #### 8.3. 1. 일반적인 질문

  1. `. jar`,`. zip`,`. tar.gz` 파일등의, 기존의 총칭 압축기구를 사용하지 않는 것은 왜입니까. 최초로, 압축 대상의 구조에 대해 이해하는 것은 좋은 방법입니다. 제 2 에, zip 나 JAR 어카이브(archive)에서는, 글로벌은 아니고 요소 단위에서의 압축을 합니다. 이것은, 복수의 클래스에서 공유되고 있는 심볼을, 각 클래스 파일내에서 독자적으로 기술할 필요가 있는 것을 의미합니다. 제 3 에, 개별의 클래스 파일의 구조에는, 다양한 종류의 대량의 데이터가 인터리브 되고 있습니다. 각 파일이 독자적인 통계를 보관 유지하기 위해서, gzip 등의 단일 스트림의 압축 프로그램에서는 유효성에 한계가 있습니다. 데이터를 밴드내에 재순서 붙이고 하는 이점은, 구체적으로 말하면(자) 약 2 배가 됩니다. 이것은, 포스트패스로 해서 사용되는 기제의 압축 프로그램의 품질과는 관계가 없습니다. 또, 형태 고유의 다양한 재코딩 수법으로부터 얻을 수 있는 이점은, 적게 추측해도 중요한 것이 됩니다. 결과적으로, 실질의 압축율이 2 ? 4 배에서 7 ? 9 배에 개선됩니다.

  2. 스펙이 이 정도 복잡한 것은 왜입니까. 여기서 설명하고 있는 수법은, 몇년에도 건너는 대량의 실험의 결과입니다. 이 스펙의 각 기능은, 이 테크놀러지로 달성되는 전체의 압축율에 크게 공헌하고 있다고 생각됩니다. 압축 퍼포먼스를 손실하는 일 없이 일부의 기능을 생략 하는 것이 가능한 것을, 벤치마크를 사용해 나타나면, 작성자들은 기뻐하겠지요.

     일부의 수법에서는 압축 퍼포먼스 승수 1.002 이상은, 퍼포먼스에 용이하게 반영되어 최종 사용자의 주목을 끌기 (위해)때문에, 큰 의미를 가집니다. 1.0005 미만의 승수는 의미를 만들어내지 않습니다.

  3. Pack200 의 전송 형식은 현재의 클래스 파일 형식과 긴밀히 연결시킬 수 있고 있습니다. 클래스 파일 형식이 한층 더 발전해 나가자, 곧바로 시대에 뒤떨어져 버리는 것은 아닐까요. 새로운 발전은, 아마 새로운 속성이나 새로운 바이트 코드의 형태로 이룰 수 있어 가겠지요. Pack200 로 정의되고 있는 레이아웃 언어는, 바이트 및 정수 풀 참조의 임의의 편성을 포함한, 매우 광범위한 속성 형식을 지원하고 있습니다. 같이 바이트 코드 표현에 포함되는 이스케이프 연산자는, 데이터 및 정수 풀 참조의 임의의 편성을 표현할 수 있습니다. 이런 종류의 구문에 의한 압축은, 이 스펙의 직접적인 설계 목적의 기능(정도)만큼 압축율이 높지는 않습니다가, 장래의 대체로의 확장 기능에서도, 현재의 기능에 의한 압축을 방해하는 일 없이, 또 압축 해제 프로그램의 갱신을 필요로 하지 않고 , 계속 전송 가능하다라고 생각됩니다.

  4. Pack200 는 불가역압축 알고리즘이므로, 서명 첨부 JAR 파일이 파괴되어 버릴 것은 없습니까. 서명 첨부 JAR 파일에는, 개별의 클래스 파일의 바이트 단위의 내용에 대한 시큐어 해시가 포함됩니다. 클래스 파일의 비트에 대한 어떠한 변경에서도, 해시 코드가 변경되기 (위해)때문에, Pack200 에 의한 무해인 변경과 어플리케이션 코드에 대한 공격과의 구별이 가지 않게 됩니다.

     Pack200 는, 그 외 많은 압축 알고리즘과 같게, 압축하는 어카이브(archive)의 내용 선택에 관해서 상당한 정도의 자유를 압축 프로그램에게 주고 있습니다만, 압축 해제되는 JAR 파일의 내용의 선택에 대해서는, 일절의 자유를 주고 있지 않습니다. Pack200 에 준거한 모든 압축 해제 프로그램은, 압축된 어카이브(archive)가 지정되었다면, 전송 된 클래스 파일 마다 같은 클래스 파일 바이트를 생성할 필요가 있습니다. 이 클래스 파일에 관한 출력 안정성은, resource file (Manifest등)의 내용이 변경되어도 지속합니다. 이 때문에, 지정한 클래스 파일에 관해서는, 압축은 불가역이어도, Pack200 의 스펙에 정의된 유효한 방법을 사용해 압축 해제로 정확하게 같은 결과를 얻을 수 있습니다.

     이 때문에, 올바른 안정성 프로퍼티을 가지는 압축 프로그램을 사용해, 팩 된 서명 첨부 JAR 를 생성할 수 있습니다. 다음의 순서를 실행합니다.

     1. 원의 서명 첨부 JAR 파일을 팩 합니다.
     2. 이것을 unpack 해, 섭동 클래스 파일을 생성합니다.
     3. 이것에 재서명을 실시해, Manifest만의 변경을 보증합니다.
     4. 갱신한 Manifest를 사용해, 이것을 재차 팩 합니다.

     덧붙여 이 스펙에 준거한 2 개의 압축 해제 프로그램이, 동일한 압축이 끝난 어카이브(archive) 입력에 대해서 다른 JAR 어카이브(archive) 요소를 생성하는 일이 있다면, 그것은 스펙의 버그입니다. 스펙에는, 이런 종류의 버그는 존재하지 않는다고 생각되고 있습니다만, 만일 찾아냈을 경우는 리포트를 보내 주세요.

  5. Pack200 어카이브(archive)의 파일명과 JAR (또는 ZIP) 어카이브(archive)나 디스크 파일의 파일명과의 관계에 대해 가르쳐 주세요. Pack200 는, 파일명이 Utf8 캐릭터 라인으로 전송 되는 것을 지정합니다. 이러한 캐릭터 라인은, Java 어플리케이션내에서 동작하는 JAR 요소의 이름으로서 사용하는 것을 의도하고 있기 (위해)때문에, Java 의 사용법에도 준거하고 있을 필요가 있습니다. 이 경우, 경로명은 JAR 파일내에서 Utf8 캐릭터 라인으로 표현되어 메모리내에서 16 비트 Unicode 라고 해도 표현됩니다. 또, JAR 파일내에서는, 경로명 컴퍼넌트는, 시스템 고유의 문자는 아니고 slash 문자 ( 「/」)로 단락지어집니다. 이 때문에, 클래스 로더는, 클래스명의 내부 표현 (java/lang/Object 등)을 간단하게 경로명 (java/lang/Object.class 등)으로 변환할 수 있습니다

     Pack200 스펙에서는, 파일명 캐릭터 라인의 해석이, 다른 툴이나 operating system와의 관계로 규정될 것은 없습니다. 다만, 자연스러운 매핑이 가능한 한 Java 의 사용법으로 가까운 것이 됩니다.

  6. JAR (또는 ZIP) 어카이브(archive) 또는 디스크 파일내의, 각 파일의 일자에는 어떠한 관계가 있습니까. Pack200 는, 파일의 일자를, Java 의 시간 베이스에 대한 32 비트의 초카운트로서 지정합니다 (즉,`System.currentTimeMillis` 를 1000 으로 제산한 값). 이것에 의해, UTC 에 대한 절대 시간이 1 초의 입도로 제공됩니다. operating system가 보다 정확한 파일의 시각을 제공하는 경우는, Pack200 어카이브(archive)로 전송 하기 전에, 초단위의 바로 옆 시각에 맞출 수 있습니다.

     JAR 및 ZIP 는, 일자를, 타임 존의 지정을 포함하지 않는 로컬 형식 (`"YYYY/MM/DD HH:MM:SS"`)에서 포함합니다. 이 때문에, Java 의 UTC 베이스의 시간과의 상호 변환을 실시하려면 , 압축 프로그램이 동작하고 있던 타임 존을 추측할 필요가 있습니다. 이것은 Pack200 에 특유의 문제가 아닙니다. ZIP 및 JAR 어카이브(archive)의 용도 모두로 발생하는 문제입니다. 다양한 장면에서 사용되는 표준적인 추정 방법은, 압축 해제 프로그램과 압축 프로그램이 같은 타임 존, 및 같은 섬머 타임 제도 기간중에 동작했다고 보는 방법입니다. 다만, Pack200 어카이브(archive)내에서의 시간 전송의 안정성을 높이기 (위해)때문에, ZIP 형식의 로컬 시간을 해석할 때에, 대부분의 압축 프로그램 및 압축 해제 프로그램이 타임 존으로서 UTC 를 사용하는 것에 동의 하는 것이 기대되고 있습니다.

  7. JEFFtm 파일 형식도 클래스 고유의 압축 알고리즘을 제공하는 것은 아닙니까. 네. JEFF Working Group 의 정의한 표준 파일 형식 (ISO/IEC 20970)에서는, 클래스 파일을 약 50% 압축함과 함께, 메모리에 직접 로드해 해석 실행하는 것이 가능합니다. 압축 퍼포먼스에 관해서는, 이것은 JAR 어카이브(archive) 내부에서 사용되는 DEFLATE 알고리즘에 필적합니다. Pack200 는, 한층 더 강력한 압축을 제공합니다. 다만, Pack200 어카이브(archive)는, 가상 머신으로부터의 직접 실행용으로 설계되고 있지 않습니다. Pack200 의 높은 압축 레벨을 실현하기 위해서(때문에), unpack 프로그램이 복잡하게 되어 있습니다. 그리고 unpack 프로그램의 complex system는, 직접적인 로드나 실행의 요건을 채우는 것이 아닙니다.

  8. Pack200 가 Huffman encode를 사용하지 않는 것은 왜입니까. (LZW, BWT, move-to-front, 그 외의 표준 압축 수법에 대해서도 같은 질문을 들 수 있습니다. ) 간결성 및 작업 분할을 용이하게 하기 위한(해), Pack200 는 클래스 파일에 고유의 대규모 장황성을 검출해 제거하는 것에 의도적으로 주력 하고 있습니다. Pack200 는, 바이트 지향의 출력을 생성하기 위해(때문에), 그 출력이 명쾌한 패턴 및 단순한 알파벳 통계를 가지는 것이 기대되고 있습니다. 이것은, 포스트패스 압축 프로그램을 사용해, 보다 효율적인 캐릭터 라인 공유의 비트 슬라이스 표현으로 이러한 바이트가 encode 되는 것에 의존하고 있습니다.

     이 설계를 지원하기 위한 고려사항은, 다음과 같습니다.

     - 유사한 압축 기법을 변환 파이프라인내의 2 개소에서 반복하면(자), 전체의 압축율이 실질적으로 저하하는 일이 있습니다. 예를 들어, Pack200 밴드 전송내에서 move-to-front 를 실행하면(자), DEFLATE 알고리즘이 반복해지는 패턴을 검출하는 것이 곤란하게 됩니다. 이것은, DEFLATE 의 감시하는 토큰내에는 다양한 철이 존재할 가능성이 있기 (위해)때문에입니다. 증분 (델타) encode에도 이 위험이 있기 (위해)때문에, Pack200 에서는 옵션 취급이 되어 있습니다. 다만, 일반적으로, 기제의 연구 최종 단계는 증분 (델타) encode를 실행하지 않습니다.
     - 최종적인 압축을 기제의 연구 최종 단계에 의존하면(자), Pack200 의 설계가 간략화됩니다.
     - 또, 이것에 의해 Pack200 가 최신의 바이트 지향 압축 툴을 사용하는 것이 가능하게 됩니다.
     - 이러한 요소를 위해서(때문에), 팩 프로그램 경험칙의 엔지니어링이 간략화됩니다.
     - Pack200 의 역할은, 클래스 및 패키지 레벨로 장황성과 패턴을 찾아내는 것입니다. 바이트 레벨에서의 혼란을 피하는 것으로, 명쾌성이 높아지는 것이 기대됩니다.
     - 특정의 표준 압축 수법안에는, 단순하고 자명의 수법이어도, 특허를 위해서(때문에) 여전히 사용할 수 없는 것이 있습니다. 이런 종류의 특허를 회피하기 위해서는, 압축 프로그램의 엔지니어링에 있어 대단한 코스트가 듭니다. 우리는 표준의 툴을 사용하는 것으로, 이 코스트를 회피합니다.

  9. 이 스펙은 어카이브(archive) 형식의 변경에 어떻게 대응합니까. Pack200 어카이브(archive)의 메이저 및 마이너 버젼 번호는, 팩 프로그램에 의해 생성되었던 것이, 이 표준의 어느 버젼일까를 분명히 합니다. 2005 년의 시점에서는, Java 6 용의 160.1 으로 Java 5 용의 150.7 의 2 개의 버젼이 존재하고 있습니다. 속성 레이아웃의 유연성을 위해서(때문에), 가끔 , 팩 프로그램이 낡은 어카이브(archive) 형식내에서 신규 클래스 파일 형식을 표현할 가능성이 있습니다. 다만, 기능이나 퍼포먼스의 이유로써, 보다 새로운 어카이브(archive) 형식이 필요하게 되는 일이 있습니다.

     unpack 프로그램의 구현에서는, 각 표준 버젼의 어카이브(archive) 포맷을 지원하는 것이 강하고 추천 되고 있습니다. 이것은, 배치 채널의 각 측에 있는 팩 프로그램과 unpack 프로그램의 버젼간에, 강력한 조정 기능이 항상 존재한다고는 할 수 없기 때문입니다. 팩 프로그램의 구현에서는, unpack 프로그램과의 호환성을 최대한 유지하기 위해서, 이전의 어카이브(archive) 형식의 발행 기능을 보관 유지하는 것이 추천 되고 있습니다.

     입력 JAR 어카이브(archive)에 1.5 (이하의) 클래스 파일이 포함되는 경우, 참조 구현은 1.5 팩 형식을 생성해 하위 호환성을 유지합니다. 그 이외의 경우는, 1.6 팩 파일이 생성됩니다. 참조 구현의 unpack 프로그램은, 이전의 모든 표준 버젼과 호환성이 있습니다.