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.coremedia.iso;
17
18import java.io.EOFException;
19import java.io.IOException;
20import java.nio.ByteBuffer;
21import java.nio.channels.FileChannel;
22import java.nio.channels.ReadableByteChannel;
23import java.nio.channels.SelectionKey;
24import java.nio.channels.WritableByteChannel;
25
26import static com.googlecode.mp4parser.util.CastUtils.l2i;
27
28
29public class ChannelHelper {
30    public static ByteBuffer readFully(final ReadableByteChannel channel, long size) throws IOException {
31
32        if (channel instanceof FileChannel && size > 1024 * 1024) {
33            ByteBuffer bb = ((FileChannel) channel).map(FileChannel.MapMode.READ_ONLY, ((FileChannel) channel).position(), size);
34            ((FileChannel) channel).position(((FileChannel) channel).position() + size);
35            return bb;
36        } else {
37            ByteBuffer buf = ByteBuffer.allocate(l2i(size));
38            readFully(channel, buf, buf.limit());
39            buf.rewind();
40            assert buf.limit() == size;
41
42            return buf;
43        }
44
45    }
46
47
48    public static void readFully(final ReadableByteChannel channel, final ByteBuffer buf)
49            throws IOException {
50        readFully(channel, buf, buf.remaining());
51    }
52
53    public static int readFully(final ReadableByteChannel channel, final ByteBuffer buf, final int length)
54            throws IOException {
55        int n, count = 0;
56        while (-1 != (n = channel.read(buf))) {
57            count += n;
58            if (count == length) {
59                break;
60            }
61        }
62        if (n == -1) {
63            throw new EOFException("End of file. No more boxes.");
64        }
65        return count;
66    }
67
68
69    public static void writeFully(final WritableByteChannel channel, final ByteBuffer buf)
70            throws IOException {
71        do {
72            int written = channel.write(buf);
73            if (written < 0) {
74                throw new EOFException();
75            }
76        } while (buf.hasRemaining());
77    }
78
79
80    public static void close(SelectionKey key) {
81        try {
82            key.channel().close();
83        } catch (IOException e) {
84            // nop
85        }
86
87    }
88
89
90}