/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016–2017, 2019–2023 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package malik.emulator.util;
import malik.emulator.fileformats.*;
public abstract class Queue extends Object implements DataHolder
{
protected int head;
protected int tail;
protected int capacity;
protected Queue(int initialCapacity) {
if(initialCapacity < 1) initialCapacity = 1;
capacity = initialCapacity + 1;
}
public abstract void removeHeadElement();
public void clear() {
tail = 0;
head = 0;
}
public final boolean isEmpty() {
return tail == head;
}
public final int length() {
int t = tail;
int h = head;
return t >= h ? t - h : t - h + capacity;
}
public final int capacity() {
return capacity - 1;
}
protected void reset(int newCapacity) {
int t = tail;
int h = head;
head = 0;
tail = t >= h ? t - h : t - h + capacity;
capacity = newCapacity;
}
protected int freeElements() {
int t = tail;
int h = head;
return (t >= h ? capacity + h - t : h - t) - 1;
}
protected int nextIndex(int index, int capacity) {
return (index + 1) % capacity;
}
protected int[] expand(int[] queue, int newCapacity) {
int t;
int h;
int len;
int[] result;
if(queue == null)
{
throw new NullPointerException("Queue.expand: аргумент queue равен нулевой ссылке.");
}
if(queue.length != (len = capacity))
{
throw new IllegalArgumentException("Queue.expand: длина очереди не соответствует заданной ёмкости.");
}
if(newCapacity <= len)
{
throw new IllegalArgumentException("Queue.expand: новая ёмкость может быть только больше прежней.");
}
result = new int[newCapacity];
if((t = tail) > (h = head))
{
Array.copy(queue, h, result, 0, t - h);
}
else if(t < h)
{
int tmp = len - h;
Array.copy(queue, h, result, 0, tmp);
Array.copy(queue, 0, result, tmp, t);
}
return result;
}
protected long[] expand(long[] queue, int newCapacity) {
int t;
int h;
int len;
long[] result;
if(queue == null)
{
throw new NullPointerException("Queue.expand: аргумент queue равен нулевой ссылке.");
}
if(queue.length != (len = capacity))
{
throw new IllegalArgumentException("Queue.expand: длина очереди не соответствует заданной ёмкости.");
}
if(newCapacity <= len)
{
throw new IllegalArgumentException("Queue.expand: новая ёмкость может быть только больше прежней.");
}
result = new long[newCapacity];
if((t = tail) > (h = head))
{
Array.copy(queue, h, result, 0, t - h);
}
else if(t < h)
{
int tmp = len - h;
Array.copy(queue, h, result, 0, tmp);
Array.copy(queue, 0, result, tmp, t);
}
return result;
}
protected Object[] expand(Object[] queue, int newCapacity) {
int t;
int h;
int len;
Object[] result;
if(queue == null)
{
throw new NullPointerException("Queue.expand: аргумент queue равен нулевой ссылке.");
}
if(queue.length != (len = capacity))
{
throw new IllegalArgumentException("Queue.expand: длина очереди не соответствует заданной ёмкости.");
}
if(newCapacity <= len)
{
throw new IllegalArgumentException("Queue.expand: новая ёмкость может быть только больше прежней.");
}
result = (Object[]) Array.create(newCapacity, queue.getClass());
if((t = tail) > (h = head))
{
Array.copy(queue, h, result, 0, t - h);
}
else if(t < h)
{
int tmp = len - h;
Array.copy(queue, h, result, 0, tmp);
Array.copy(queue, 0, result, tmp, t);
}
return result;
}
protected final void advanceHead(int head) {
this.head = nextIndex(head, capacity);
}
protected final void advanceTail(int tail) {
this.tail = nextIndex(tail, capacity);
}
}