1dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu/*
2dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Copyright 2008 CoreMedia AG, Hamburg
3dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu *
4dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Licensed under the Apache License, Version 2.0 (the License);
5dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * you may not use this file except in compliance with the License.
6dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * You may obtain a copy of the License at
7dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu *
8dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu *     http://www.apache.org/licenses/LICENSE-2.0
9dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu *
10dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Unless required by applicable law or agreed to in writing, software
11dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * distributed under the License is distributed on an AS IS BASIS,
12dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * See the License for the specific language governing permissions and
14dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * limitations under the License.
15dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */
16dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
17dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupackage com.coremedia.iso.boxes;
18dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
19dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
20dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.IsoTypeReader;
21dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.IsoTypeReaderVariable;
22dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.IsoTypeWriter;
23dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.IsoTypeWriterVariable;
24dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.googlecode.mp4parser.AbstractFullBox;
25dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
26dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.IOException;
27dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.nio.ByteBuffer;
28dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.LinkedList;
29dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.List;
30dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
31dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu/**
32dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * aligned(8) class ItemLocationBox extends FullBox(‘iloc’, version, 0) {
33dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(4) offset_size;
34dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(4) length_size;
35dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(4) base_offset_size;
36dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * if (version == 1)
37dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(4) index_size;
38dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * else
39dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(4) reserved;
40dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(16) item_count;
41dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * for (i=0; i<item_count; i++) {
42dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(16) item_ID;
43dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * if (version == 1) {
44dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(12) reserved = 0;
45dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(4) construction_method;
46dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * }
47dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(16) data_reference_index;
48dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(base_offset_size*8) base_offset;
49dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(16) extent_count;
50dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * for (j=0; j<extent_count; j++) {
51dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * if ((version == 1) && (index_size > 0)) {
52dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(index_size*8) extent_index;
53dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * }
54dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(offset_size*8) extent_offset;
55dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(length_size*8) extent_length;
56dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * }
57dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * }
58dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * }
59dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */
60dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupublic class ItemLocationBox extends AbstractFullBox {
61dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int offsetSize = 8;
62dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int lengthSize = 8;
63dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int baseOffsetSize = 8;
64dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int indexSize = 0;
65dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public List<Item> items = new LinkedList<Item>();
66dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
67dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public static final String TYPE = "iloc";
68dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
69dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public ItemLocationBox() {
70dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        super(TYPE);
71dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
72dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
73dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    @Override
74dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    protected long getContentSize() {
75dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        long size = 8;
76dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        for (Item item : items) {
77dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            size += item.getSize();
78dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
79dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return size;
80dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
81dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
82dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
83dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    @Override
84dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    protected void getContent(ByteBuffer byteBuffer) {
85dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        writeVersionAndFlags(byteBuffer);
86dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        IsoTypeWriter.writeUInt8(byteBuffer, ((offsetSize << 4) | lengthSize));
87dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        if (getVersion() == 1) {
88dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            IsoTypeWriter.writeUInt8(byteBuffer, (baseOffsetSize << 4 | indexSize));
89dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        } else {
90dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            IsoTypeWriter.writeUInt8(byteBuffer, (baseOffsetSize << 4));
91dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
92dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        IsoTypeWriter.writeUInt16(byteBuffer, items.size());
93dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        for (Item item : items) {
94dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            item.getContent(byteBuffer);
95dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
96dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
97dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
98dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    @Override
99dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public void _parseDetails(ByteBuffer content) {
100dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        parseVersionAndFlags(content);
101dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int tmp = IsoTypeReader.readUInt8(content);
102dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        offsetSize = tmp >>> 4;
103dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        lengthSize = tmp & 0xf;
104dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        tmp = IsoTypeReader.readUInt8(content);
105dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        baseOffsetSize = tmp >>> 4;
106dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
107dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        if (getVersion() == 1) {
108dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            indexSize = tmp & 0xf;
109dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
110dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int itemCount = IsoTypeReader.readUInt16(content);
111dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        for (int i = 0; i < itemCount; i++) {
112dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            items.add(new Item(content));
113dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
114dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
115dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
116dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
117dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int getOffsetSize() {
118dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return offsetSize;
119dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
120dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
121dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public void setOffsetSize(int offsetSize) {
122dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        this.offsetSize = offsetSize;
123dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
124dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
125dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int getLengthSize() {
126dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return lengthSize;
127dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
128dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
129dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public void setLengthSize(int lengthSize) {
130dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        this.lengthSize = lengthSize;
131dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
132dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
133dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int getBaseOffsetSize() {
134dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return baseOffsetSize;
135dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
136dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
137dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public void setBaseOffsetSize(int baseOffsetSize) {
138dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        this.baseOffsetSize = baseOffsetSize;
139dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
140dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
141dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int getIndexSize() {
142dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return indexSize;
143dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
144dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
145dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public void setIndexSize(int indexSize) {
146dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        this.indexSize = indexSize;
147dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
148dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
149dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public List<Item> getItems() {
150dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return items;
151dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
152dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
153dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public void setItems(List<Item> items) {
154dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        this.items = items;
155dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
156dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
157dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
158dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public Item createItem(int itemId, int constructionMethod, int dataReferenceIndex, long baseOffset, List<Extent> extents) {
159dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return new Item(itemId, constructionMethod, dataReferenceIndex, baseOffset, extents);
160dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
161dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
162dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    Item createItem(ByteBuffer bb) {
163dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return new Item(bb);
164dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
165dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
166dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public class Item {
167dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public int itemId;
168dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public int constructionMethod;
169dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public int dataReferenceIndex;
170dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public long baseOffset;
171dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public List<Extent> extents = new LinkedList<Extent>();
172dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
173dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public Item(ByteBuffer in) {
174dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            itemId = IsoTypeReader.readUInt16(in);
175dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
176dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (getVersion() == 1) {
177dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                int tmp = IsoTypeReader.readUInt16(in);
178dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                constructionMethod = tmp & 0xf;
179dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            }
180dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
181dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            dataReferenceIndex = IsoTypeReader.readUInt16(in);
182dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (baseOffsetSize > 0) {
183dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                baseOffset = IsoTypeReaderVariable.read(in, baseOffsetSize);
184dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            } else {
185dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                baseOffset = 0;
186dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            }
187dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            int extentCount = IsoTypeReader.readUInt16(in);
188dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
189dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
190dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            for (int i = 0; i < extentCount; i++) {
191dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                extents.add(new Extent(in));
192dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            }
193dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
194dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
195dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public Item(int itemId, int constructionMethod, int dataReferenceIndex, long baseOffset, List<Extent> extents) {
196dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            this.itemId = itemId;
197dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            this.constructionMethod = constructionMethod;
198dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            this.dataReferenceIndex = dataReferenceIndex;
199dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            this.baseOffset = baseOffset;
200dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            this.extents = extents;
201dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
202dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
203dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public int getSize() {
204dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            int size = 2;
205dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
206dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (getVersion() == 1) {
207dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                size += 2;
208dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            }
209dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
210dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            size += 2;
211dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            size += baseOffsetSize;
212dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            size += 2;
213dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
214dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
215dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            for (Extent extent : extents) {
216dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                size += extent.getSize();
217dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            }
218dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            return size;
219dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
220dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
221dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public void setBaseOffset(long baseOffset) {
222dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            this.baseOffset = baseOffset;
223dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
224dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
225dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public void getContent(ByteBuffer bb)  {
226dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            IsoTypeWriter.writeUInt16(bb, itemId);
227dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
228dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (getVersion() == 1) {
229dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                IsoTypeWriter.writeUInt16(bb, constructionMethod);
230dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            }
231dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
232dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
233dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            IsoTypeWriter.writeUInt16(bb, dataReferenceIndex);
234dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (baseOffsetSize > 0) {
235dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                IsoTypeWriterVariable.write(baseOffset, bb, baseOffsetSize);
236dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            }
237dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            IsoTypeWriter.writeUInt16(bb, extents.size());
238dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
239dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            for (Extent extent : extents) {
240dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                extent.getContent(bb);
241dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            }
242dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
243dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
244dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        @Override
245dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public boolean equals(Object o) {
246dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (this == o) return true;
247dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (o == null || getClass() != o.getClass()) return false;
248dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
249dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            Item item = (Item) o;
250dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
251dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (baseOffset != item.baseOffset) return false;
252dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (constructionMethod != item.constructionMethod) return false;
253dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (dataReferenceIndex != item.dataReferenceIndex) return false;
254dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (itemId != item.itemId) return false;
255dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (extents != null ? !extents.equals(item.extents) : item.extents != null) return false;
256dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
257dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            return true;
258dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
259dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
260dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        @Override
261dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public int hashCode() {
262dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            int result = itemId;
263dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            result = 31 * result + constructionMethod;
264dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            result = 31 * result + dataReferenceIndex;
265dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            result = 31 * result + (int) (baseOffset ^ (baseOffset >>> 32));
266dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            result = 31 * result + (extents != null ? extents.hashCode() : 0);
267dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            return result;
268dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
269dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
270dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        @Override
271dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public String toString() {
272dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            return "Item{" +
273dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                    "baseOffset=" + baseOffset +
274dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                    ", itemId=" + itemId +
275dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                    ", constructionMethod=" + constructionMethod +
276dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                    ", dataReferenceIndex=" + dataReferenceIndex +
277dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                    ", extents=" + extents +
278dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                    '}';
279dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
280dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
281dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
282dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
283dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public Extent createExtent(long extentOffset, long extentLength, long extentIndex) {
284dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return new Extent(extentOffset, extentLength, extentIndex);
285dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
286dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
287dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    Extent createExtent(ByteBuffer bb) {
288dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return new Extent(bb);
289dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
290dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
291dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
292dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public class Extent {
293dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public long extentOffset;
294dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public long extentLength;
295dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public long extentIndex;
296dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
297dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public Extent(long extentOffset, long extentLength, long extentIndex) {
298dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            this.extentOffset = extentOffset;
299dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            this.extentLength = extentLength;
300dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            this.extentIndex = extentIndex;
301dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
302dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
303dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
304dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public Extent(ByteBuffer in) {
305dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if ((getVersion() == 1) && indexSize > 0) {
306dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                extentIndex = IsoTypeReaderVariable.read(in, indexSize);
307dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            }
308dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            extentOffset = IsoTypeReaderVariable.read(in, offsetSize);
309dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            extentLength = IsoTypeReaderVariable.read(in, lengthSize);
310dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
311dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
312dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public void getContent(ByteBuffer os)  {
313dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if ((getVersion() == 1) && indexSize > 0) {
314dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                IsoTypeWriterVariable.write(extentIndex, os, indexSize);
315dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            }
316dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            IsoTypeWriterVariable.write(extentOffset, os, offsetSize);
317dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            IsoTypeWriterVariable.write(extentLength, os, lengthSize);
318dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
319dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
320dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public int getSize() {
321dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            return (indexSize > 0 ? indexSize : 0) + offsetSize + lengthSize;
322dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
323dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
324dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
325dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        @Override
326dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public boolean equals(Object o) {
327dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (this == o) return true;
328dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (o == null || getClass() != o.getClass()) return false;
329dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
330dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            Extent extent = (Extent) o;
331dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
332dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (extentIndex != extent.extentIndex) return false;
333dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (extentLength != extent.extentLength) return false;
334dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            if (extentOffset != extent.extentOffset) return false;
335dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
336dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            return true;
337dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
338dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
339dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        @Override
340dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public int hashCode() {
341dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            int result = (int) (extentOffset ^ (extentOffset >>> 32));
342dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            result = 31 * result + (int) (extentLength ^ (extentLength >>> 32));
343dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            result = 31 * result + (int) (extentIndex ^ (extentIndex >>> 32));
344dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            return result;
345dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
346dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
347dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        @Override
348dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        public String toString() {
349dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            final StringBuilder sb = new StringBuilder();
350dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            sb.append("Extent");
351dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            sb.append("{extentOffset=").append(extentOffset);
352dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            sb.append(", extentLength=").append(extentLength);
353dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            sb.append(", extentIndex=").append(extentIndex);
354dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            sb.append('}');
355dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            return sb.toString();
356dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
357dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
358dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
359dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
360dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu}
361