/*
This file is part of jpcsp.
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.HLE.kernel.types;
import static jpcsp.util.Utilities.min;
/**
* Implements a circular buffer in PSP memory that can
* be fed from a file.
* Used by sceAtrac3plus and sceMp3 modules.
*
* @author gid15
*
*/
public class pspFileBuffer {
private int addr;
private int maxSize;
private int currentSize;
private int readPosition;
private int writePosition;
private int filePosition;
private int fileMaxSize;
public pspFileBuffer() {
}
public pspFileBuffer(int addr, int maxSize) {
this.addr = addr;
this.maxSize = maxSize;
}
public pspFileBuffer(int addr, int maxSize, int readSize) {
this.addr = addr;
this.maxSize = maxSize;
notifyWrite(readSize);
}
public pspFileBuffer(int addr, int maxSize, int readSize, int filePosition) {
this.addr = addr;
this.maxSize = maxSize;
notifyWrite(readSize);
this.filePosition = filePosition;
}
public void setFileMaxSize(int fileMaxSize) {
this.fileMaxSize = fileMaxSize;
}
public boolean isFileEnd() {
return filePosition >= fileMaxSize;
}
public int getWriteAddr() {
return addr + writePosition;
}
public int getWriteSize() {
return min(getNoFileWriteSize(), getFileWriteSize());
}
public int getFileWriteSize() {
return fileMaxSize - filePosition;
}
public int getNoFileWriteSize() {
return min(maxSize - currentSize, maxSize - writePosition);
}
public int getFilePosition() {
return filePosition;
}
public void setFilePosition(int filePosition) {
this.filePosition = filePosition;
}
public int getReadAddr() {
return addr + readPosition;
}
public int getReadSize() {
return min(currentSize, maxSize - readPosition);
}
public int getCurrentSize() {
return currentSize;
}
public void reset(int readSize, int filePosition) {
currentSize = 0;
readPosition = 0;
writePosition = 0;
this.filePosition = filePosition;
notifyWrite(readSize);
}
public void notifyRead(int size) {
if (size > 0) {
size = min(size, currentSize);
readPosition = incrementPosition(readPosition, size);
currentSize -= size;
}
}
public void notifyReadAll() {
notifyRead(currentSize);
}
public void notifyWrite(int size) {
if (size > 0) {
size = min(size, getMaxSize() - currentSize);
writePosition = incrementPosition(writePosition, size);
filePosition += size;
currentSize += size;
}
}
private int incrementPosition(int position, int size) {
position += size;
if (position >= maxSize) {
position -= maxSize;
}
return position;
}
public int getMaxSize() {
return maxSize;
}
public int getAddr() {
return addr;
}
public void setAddr(int addr) {
this.addr = addr;
}
public boolean isEmpty() {
return currentSize == 0;
}
@Override
public String toString() {
return String.format("pspFileBuffer(addr=0x%08X, maxSize=0x%X, currentSize=0x%X, readPosition=0x%X, writePosition=0x%X, filePosition=0x%X, fileMaxSize=0x%X)", getAddr(), getMaxSize(), currentSize, readPosition, writePosition, getFilePosition(), fileMaxSize);
}
}