/* * Copyright (C) 2013 gujicheng * * Licensed under the GPL License Version 2.0; * you may not use this file except in compliance with the License. * * If you have any question, please contact me. * ************************************************************************* ** Author information ** ************************************************************************* ** Email: gujicheng197@126.com ** ** QQ : 29600731 ** ** Weibo: http://weibo.com/gujicheng197 ** ************************************************************************* */ package com.libra.sinvoice; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class Buffer { private final static String TAG = "Buffer"; private BlockingQueue<BufferData> mProducerQueue; private BlockingQueue<BufferData> mConsumeQueue; private int mBufferCount; private int mBufferSize; // when mData is null, means it is end of input public static class BufferData { public byte mData[]; private int mFilledSize; private int mMaxBufferSize; private static BufferData sEmptyBuffer = new BufferData(0); public BufferData(int maxBufferSize) { mMaxBufferSize = maxBufferSize; reset(); if (maxBufferSize > 0) { mMaxBufferSize = maxBufferSize; mData = new byte[mMaxBufferSize]; } else { mData = null; } } public static BufferData getEmptyBuffer() { return sEmptyBuffer; } final public void reset() { mFilledSize = 0; } final public int getMaxBufferSize() { return mMaxBufferSize; } final public void setFilledSize(int size) { mFilledSize = size; } final public int getFilledSize() { return mFilledSize; } } public Buffer() { this(Common.DEFAULT_BUFFER_COUNT, Common.DEFAULT_BUFFER_SIZE); } public Buffer(int bufferCount, int bufferSize) { mBufferSize = bufferSize; mBufferCount = bufferCount; mProducerQueue = new LinkedBlockingQueue<BufferData>(mBufferCount); // we want to put the end buffer, so need to add 1 mConsumeQueue = new LinkedBlockingQueue<BufferData>(mBufferCount + 1); try { for (int i = 0; i < mBufferCount; ++i) { mProducerQueue.put(new BufferData(mBufferSize)); } } catch (InterruptedException e) { e.printStackTrace(); LogHelper.e(TAG, "put buffer data error"); } } public void reset() { int size = mProducerQueue.size(); for (int i = 0; i < size; ++i) { BufferData data = mProducerQueue.peek(); if (null == data || null == data.mData) { mProducerQueue.poll(); } } size = mConsumeQueue.size(); for (int i = 0; i < size; ++i) { BufferData data = mConsumeQueue.poll(); if (null != data && null != data.mData) { mProducerQueue.add(data); } } LogHelper.d(TAG, "reset ProducerQueue Size:" + mProducerQueue.size() + " ConsumeQueue Size:" + mConsumeQueue.size()); } final public int getEmptyCount() { return mProducerQueue.size(); } final public int getFullCount() { return mConsumeQueue.size(); } public BufferData getEmpty() { return getImpl(mProducerQueue); } public boolean putEmpty(BufferData data) { return putImpl(data, mProducerQueue); } public BufferData getFull() { return getImpl(mConsumeQueue); } public boolean putFull(BufferData data) { return putImpl(data, mConsumeQueue); } private BufferData getImpl(BlockingQueue<BufferData> queue) { if (null != queue) { try { return queue.take(); } catch (InterruptedException e) { e.printStackTrace(); } } return null; } private boolean putImpl(BufferData data, BlockingQueue<BufferData> queue) { if (null != queue && null != data) { try { queue.put(data); return true; } catch (InterruptedException e) { e.printStackTrace(); } } return false; } }