File Android

/**
 * Copyright (C) 2009 Michael A. MacDonald
 */
package com.antlersoft.util;
/**
 * @author Michael A. MacDonald
 *
 */
public class ByteBufferStack {
  private byte[] m_buffer;
  private int[] m_offsets;
  private int m_depth;
  private int m_max_depth;
  private int m_max_size;
  
  public static final int MAX_DEPTH = 20;
  public static final int MAX_SIZE = 1048;
  public ByteBufferStack(int maxDepth, int maxSize)
  {
    m_depth = 0;
    m_max_depth = maxDepth;
    m_max_size = maxSize;
    m_offsets= new int[maxDepth];
    m_buffer = new byte[maxSize];
  }
  
  public ByteBufferStack()
  {
    this(MAX_DEPTH, MAX_SIZE);
  }
  
  /**
   * 
   * @return Start of the buffer; this value is valid at least until the next call of reserve()
   */
  public byte[] getBuffer()
  {
    return m_buffer;
  }
  /**
   * 
   * @return Offset in getBuffer() of last reserved region
   */
  public int getOffset()
  {
    return m_offsets[m_depth];
  }
  
  public int reserve(int count)
  {
    if (count < 0 || (count + m_max_size < 0))
      throw new IllegalArgumentException("Count must by greater than 0");
    if (m_depth == m_max_depth)
    {
      m_max_depth *= 2;
      int[] new_offsets = new int[m_max_depth];
      System.arraycopy(m_offsets, 0, new_offsets, 0, m_depth);
      m_offsets = new_offsets;
    }
    int result = m_offsets[m_depth];
    int new_size = result + count;
    m_offsets[m_depth++] = new_size;
    if (new_size > m_max_size)
    {
      m_max_size = Math.max(2 * m_max_size, new_size);
      byte[] new_buffer = new byte[m_max_size];
      System.arraycopy(m_buffer, 0, new_buffer, 0, result);
      m_buffer = new_buffer;
    }
    
    return result;
  }
  
  public void release()
  {
    if (m_depth<1)
    {
      throw new IllegalStateException("release() without reserve()");
    }
    m_depth--;
  }
}