package abstrasy.libraries.io;
/**
* Abstrasy Interpreter
*
* Copyright : Copyright (c) 2006-2012, Luc Bruninx.
*
* Concédée sous licence EUPL, version 1.1 uniquement (la «Licence»).
*
* Vous ne pouvez utiliser la présente oeuvre que conformément à la Licence.
* Vous pouvez obtenir une copie de la Licence à l’adresse suivante:
*
* http://www.osor.eu/eupl
*
* Sauf obligation légale ou contractuelle écrite, le logiciel distribué sous
* la Licence est distribué "en l’état", SANS GARANTIES OU CONDITIONS QUELLES
* QU’ELLES SOIENT, expresses ou implicites.
*
* Consultez la Licence pour les autorisations et les restrictions
* linguistiques spécifiques relevant de la Licence.
*
*
* @author Luc Bruninx
* @version 1.0
*/
import abstrasy.Bivalence;
import abstrasy.Buffer;
import abstrasy.Node;
import abstrasy.SELF;
import abstrasy.externals.AExtCachable;
import abstrasy.externals.AExtClonable;
import abstrasy.externals.AExtTools;
import abstrasy.interpreter.InterpreterException;
import abstrasy.interpreter.ORef;
import abstrasy.interpreter.StdErrors;
import java.io.EOFException;
import java.io.File;
import java.io.RandomAccessFile;
public class External_RandomAccessFile implements AExtClonable,AExtCachable {
private boolean inUse = false;
private File file = null;
private String mode = null;
private RandomAccessFile raf = null;
public External_RandomAccessFile() {
}
public Node external_mutator_open(Node startAt) throws Exception {
startAt.isGoodArgsCnt(3);
SELF.require_SELF_mutable();
if (inUse) {
throw new InterpreterException(StdErrors.extend(StdErrors.Already_used, "File already open"));
}
file = new File(startAt.getSubNode(1, Node.TYPE_STRING).getString());
mode = startAt.getSubNode(2, Node.TYPE_STRING).getString().toLowerCase().trim();
if(mode.equals("r")||mode.equals("rw")||mode.equals("rws")||mode.equals("rwd")){
raf=new RandomAccessFile(file,mode);
inUse = true;
}
else{
throw new InterpreterException(StdErrors.extend(StdErrors.Invalid_parameter, "Mode not supported"));
}
return null;
}
public Node external_mutator_close(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
SELF.require_SELF_mutable();
if(raf!=null){
raf.close();
raf=null;
}
mode = null;
file = null;
if (inUse) {
inUse=false;
}
return null;
}
public Node external_length(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(raf.length());
}
public Node external_mutator_set_length(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
SELF.require_SELF_mutable();
long offset = (long)startAt.getSubNode(1, Node.TYPE_NUMBER).getNumber();
if(offset<0){
throw new InterpreterException(StdErrors.extend(StdErrors.Out_of_range,"length:"+offset));
}
raf.setLength(offset);
/*
* Sets the length of this file.
* If the present length of the file as returned by the length method is greater than the newLength
* argument then the file will be truncated. In this case, if the file offset as returned by the
* getFilePointer method is greater than newLength then after this method returns the offset will
* be equal to newLength.
*
* If the present length of the file as returned by the length method is smaller than the newLength
* argument then the file will be extended. In this case, the contents of the extended portion of
* the file are not defined.
*
* - JavaDoc: RandomAccessFile.setLength(newLength).
*
*/
return null;
}
public Node external_get_offset(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(raf.getFilePointer());
}
public Node external_mutator_set_offset(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
SELF.require_SELF_mutable();
long offset = (long)startAt.getSubNode(1, Node.TYPE_NUMBER).getNumber();
if(offset<0){
throw new InterpreterException(StdErrors.extend(StdErrors.Out_of_range,"offset:"+offset));
}
raf.seek(offset);
return null;
}
public Node external_mutator_read_byte(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
SELF.require_SELF_mutable();
int cread = -1;
try {
cread = raf.read();
}
catch (EOFException e) {
cread = -1;
}
if (cread == -1)
return Node.createNothing();
else
return new Node(cread);
}
public Node external_mutator_write_byte(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
SELF.require_SELF_mutable();
raf.write(((int) startAt.getSubNode(1, Node.TYPE_NUMBER).getNumber()) & 0xff);
return null;
}
public Node external_mutator_write_buffer(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
SELF.require_SELF_mutable();
Buffer buffer = ((External_Buffer) AExtTools.getArgExternalInstance(startAt, 1, External_Buffer.class,Node.ACCESSVTYPE_MUTABLE_WRITELOCK)).getBuffer();
if(buffer.length()>0){
byte[] buf=buffer.read_bytes();
raf.write(buf);
}
return null;
}
public Node external_mutator_read_buffer(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1,2);
SELF.require_SELF_mutable();
Buffer buffer=new Buffer();
if(startAt.size()==2){
int sz=(int)startAt.getSubNode(1, Node.TYPE_NUMBER).getNumber();
byte[] buf = new byte[sz];
int cread=raf.read(buf);
if(cread>0){ buffer.write_bytes(buf, cread); }
}
else{
byte[] buf = new byte[4096];
int cread;
while ((cread = raf.read(buf)) != -1) {
if(cread>0){ buffer.write_bytes(buf, cread); }
}
}
External_Buffer res=new External_Buffer();
res.setBuffer(buffer);
return Node.createExternal(res);
}
public Node external_mutator_read_chunked_buffer(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
SELF.require_SELF_mutable();
Buffer buffer=new Buffer();
int sz = raf.readInt();
byte[] buf = new byte[sz];
int cread=raf.read(buf);
if(cread>0){ buffer.write_bytes(buf, cread); }
External_Buffer res=new External_Buffer();
res.setBuffer(buffer);
return Node.createExternal(res);
}
public Node external_mutator_write_chunked_buffer(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
SELF.require_SELF_mutable();
Buffer buffer = ((External_Buffer) AExtTools.getArgExternalInstance(startAt, 1, External_Buffer.class,Node.ACCESSVTYPE_MUTABLE_WRITELOCK)).getBuffer();
int len=buffer.length();
raf.writeInt(len);
if(buffer.length()>0){
byte[] buf=buffer.read_bytes();
raf.write(buf);
}
return null;
}
public Object clone_my_self(Bivalence bival) {
return null;
}
/*
* ----------------------------------------------------------------------------
*
* Optimisation par cache d'instanciantion (mars 2012) rev 1.0-6321.0
*
* ----------------------------------------------------------------------------
*/
private static ORef _optim_symbols_cache_ = new ORef();
@Override
public Object getSymbolsCache() {
return _optim_symbols_cache_.getRef();
}
@Override
public void setSymbolsCache(Object cache) {
_optim_symbols_cache_.setRef(cache);
}
}