1cafd30f96355ad446943d60cd2595d08423944e2Owen Lin/*
2cafd30f96355ad446943d60cd2595d08423944e2Owen Lin * Copyright (C) 2012 The Android Open Source Project
3cafd30f96355ad446943d60cd2595d08423944e2Owen Lin *
4cafd30f96355ad446943d60cd2595d08423944e2Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
5cafd30f96355ad446943d60cd2595d08423944e2Owen Lin * you may not use this file except in compliance with the License.
6cafd30f96355ad446943d60cd2595d08423944e2Owen Lin * You may obtain a copy of the License at
7cafd30f96355ad446943d60cd2595d08423944e2Owen Lin *
8cafd30f96355ad446943d60cd2595d08423944e2Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
9cafd30f96355ad446943d60cd2595d08423944e2Owen Lin *
10cafd30f96355ad446943d60cd2595d08423944e2Owen Lin * Unless required by applicable law or agreed to in writing, software
11cafd30f96355ad446943d60cd2595d08423944e2Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
12cafd30f96355ad446943d60cd2595d08423944e2Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cafd30f96355ad446943d60cd2595d08423944e2Owen Lin * See the License for the specific language governing permissions and
14cafd30f96355ad446943d60cd2595d08423944e2Owen Lin * limitations under the License.
15cafd30f96355ad446943d60cd2595d08423944e2Owen Lin */
16cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
17cafd30f96355ad446943d60cd2595d08423944e2Owen Linpackage com.android.gallery3d.data;
18cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
19cafd30f96355ad446943d60cd2595d08423944e2Owen Linimport com.android.gallery3d.util.ThreadPool.JobContext;
20cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
21cafd30f96355ad446943d60cd2595d08423944e2Owen Linimport java.io.FileDescriptor;
22cafd30f96355ad446943d60cd2595d08423944e2Owen Linimport java.io.FileInputStream;
23cafd30f96355ad446943d60cd2595d08423944e2Owen Linimport java.io.IOException;
24cafd30f96355ad446943d60cd2595d08423944e2Owen Linimport java.util.ArrayList;
25cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
26cafd30f96355ad446943d60cd2595d08423944e2Owen Linpublic class BytesBufferPool {
27cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
28cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    private static final int READ_STEP = 4096;
29cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
30cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    public static class BytesBuffer {
31cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        public byte[] data;
32cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        public int offset;
33cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        public int length;
34cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
35cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        private BytesBuffer(int capacity) {
36cafd30f96355ad446943d60cd2595d08423944e2Owen Lin            this.data = new byte[capacity];
37cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        }
38cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
39cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        // an helper function to read content from FileDescriptor
40cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        public void readFrom(JobContext jc, FileDescriptor fd) throws IOException {
41cafd30f96355ad446943d60cd2595d08423944e2Owen Lin            FileInputStream fis = new FileInputStream(fd);
42cafd30f96355ad446943d60cd2595d08423944e2Owen Lin            length = 0;
43cafd30f96355ad446943d60cd2595d08423944e2Owen Lin            try {
44cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                int capacity = data.length;
45cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                while (true) {
46cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                    int step = Math.min(READ_STEP, capacity - length);
47cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                    int rc = fis.read(data, length, step);
48cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                    if (rc < 0 || jc.isCancelled()) return;
49cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                    length += rc;
50cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
51cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                    if (length == capacity) {
52cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                        byte[] newData = new byte[data.length * 2];
53cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                        System.arraycopy(data, 0, newData, 0, data.length);
54cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                        data = newData;
55cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                        capacity = data.length;
56cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                    }
57cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                }
58cafd30f96355ad446943d60cd2595d08423944e2Owen Lin            } finally {
59cafd30f96355ad446943d60cd2595d08423944e2Owen Lin                fis.close();
60cafd30f96355ad446943d60cd2595d08423944e2Owen Lin            }
61cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        }
62cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    }
63cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
64cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    private final int mPoolSize;
65cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    private final int mBufferSize;
66cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    private final ArrayList<BytesBuffer> mList;
67cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
68cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    public BytesBufferPool(int poolSize, int bufferSize) {
69cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        mList = new ArrayList<BytesBuffer>(poolSize);
70cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        mPoolSize = poolSize;
71cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        mBufferSize = bufferSize;
72cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    }
73cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
74cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    public synchronized BytesBuffer get() {
75cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        int n = mList.size();
76cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        return n > 0 ? mList.remove(n - 1) : new BytesBuffer(mBufferSize);
77cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    }
78cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
79cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    public synchronized void recycle(BytesBuffer buffer) {
80cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        if (buffer.data.length != mBufferSize) return;
81cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        if (mList.size() < mPoolSize) {
82cafd30f96355ad446943d60cd2595d08423944e2Owen Lin            buffer.offset = 0;
83cafd30f96355ad446943d60cd2595d08423944e2Owen Lin            buffer.length = 0;
84cafd30f96355ad446943d60cd2595d08423944e2Owen Lin            mList.add(buffer);
85cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        }
86cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    }
87cafd30f96355ad446943d60cd2595d08423944e2Owen Lin
88cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    public synchronized void clear() {
89cafd30f96355ad446943d60cd2595d08423944e2Owen Lin        mList.clear();
90cafd30f96355ad446943d60cd2595d08423944e2Owen Lin    }
91cafd30f96355ad446943d60cd2595d08423944e2Owen Lin}
92