1/*
2 * Copyright 2012 Sebastian Annies, Hamburg
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.googlecode.mp4parser.authoring.builder;
17
18import java.nio.ByteBuffer;
19import java.nio.MappedByteBuffer;
20import java.util.ArrayList;
21import java.util.List;
22
23/**
24 * Used to merge adjacent byte buffers.
25 */
26public class ByteBufferHelper {
27    public static List<ByteBuffer> mergeAdjacentBuffers(List<ByteBuffer> samples) {
28        ArrayList<ByteBuffer> nuSamples = new ArrayList<ByteBuffer>(samples.size());
29        for (ByteBuffer buffer : samples) {
30            int lastIndex = nuSamples.size() - 1;
31            if (lastIndex >= 0 && buffer.hasArray() && nuSamples.get(lastIndex).hasArray() && buffer.array() == nuSamples.get(lastIndex).array() &&
32                    nuSamples.get(lastIndex).arrayOffset() + nuSamples.get(lastIndex).limit() == buffer.arrayOffset()) {
33                ByteBuffer oldBuffer = nuSamples.remove(lastIndex);
34                ByteBuffer nu = ByteBuffer.wrap(buffer.array(), oldBuffer.arrayOffset(), oldBuffer.limit() + buffer.limit()).slice();
35                // We need to slice here since wrap([], offset, length) just sets position and not the arrayOffset.
36                nuSamples.add(nu);
37            } else if (lastIndex >= 0 &&
38                    buffer instanceof MappedByteBuffer && nuSamples.get(lastIndex) instanceof MappedByteBuffer &&
39                    nuSamples.get(lastIndex).limit() == nuSamples.get(lastIndex).capacity() - buffer.capacity()) {
40                // This can go wrong - but will it?
41                ByteBuffer oldBuffer = nuSamples.get(lastIndex);
42                oldBuffer.limit(buffer.limit() + oldBuffer.limit());
43            } else {
44                buffer.rewind();
45                nuSamples.add(buffer);
46            }
47        }
48        return nuSamples;
49    }
50}
51