/*
Реализация среды исполнения языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024, 2026 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package platform.dependent.mswindows.services;
import avt.io.*;
import avt.io.extension.*;
import avt.lang.array.*;
import platform.dependent.*;
import platform.dependent.mswindows.kernel.*;
import platform.independent.filesystem.*;
import platform.independent.osservices.*;
import platform.independent.util.*;
package class CriticalSection(Object, Mutex)
{
private final long fldPointer;
private final platform.dependent.mswindows.kernel.CriticalSection fldInstance;
public () {
platform.dependent.mswindows.kernel.CriticalSection instance = new platform.dependent.mswindows.kernel.CriticalSection();
fldPointer = instance.getPointer();
fldInstance = instance;
}
public void lock() { Kernel.enterCriticalSection(fldPointer); }
public void unlock() { Kernel.leaveCriticalSection(fldPointer); }
public boolean isHold() { return fldInstance.owningThread != 0; }
protected void afterConstruction() { Kernel.initializeCriticalSection(fldPointer); }
protected void beforeDestruction() { Kernel.deleteCriticalSection(fldPointer); }
}
package class Monitor(CriticalSection, Mutex, Waitable, platform.dependent.Monitor)
{
private static final long ENTRY_STATE_OWNEDBY = 0x00794264656e774fL;
private static final long ENTRY_STATE_BLOCKED = 0x0064656b636f6c42L;
private static final long ENTRY_STATE_WAITING = 0x00676e6974696157L;
private long fldNotifies;
private long4 fldOwnedBy;
private long4[] fldEntries;
/* схема хранения данных: new long4 { state, threadId, lockCount, interrupted } */
public () { }
public void lock() {
boolean isBlocked = false;
long currentId = Kernel.getCurrentThreadId();
super.lock();
try
{
long4 entry = fldOwnedBy;
if(entry == 0)
{
fldOwnedBy = new long4 { ENTRY_STATE_OWNEDBY, currentId, 1, 0 };
} else if(entry[1] == currentId)
{
fldOwnedBy = entry + new byte4 { 0, 0, 1, 0 };
} else
{
appendEntry(new long4 { ENTRY_STATE_BLOCKED, currentId, 1, 0 });
isBlocked = true;
}
} finally
{
super.unlock();
}
if(isBlocked) ThreadEvent.get(currentId).waitSignalled(0, 0);
}
public void unlock() {
boolean isNotOwnedBy = false;
long currentId = Kernel.getCurrentThreadId();
super.lock();
try
{
long4 entry = fldOwnedBy;
if(entry == 0 || entry[1] != currentId)
{
isNotOwnedBy = true;
} else if((fldOwnedBy = entry - new byte4 { 0, 0, 1, 0 })[2] == 0)
{
extractEntry();
}
} finally
{
super.unlock();
}
if(isNotOwnedBy)
{
throw new IllegalMonitorStateException(avt.lang.package.getResourceString("illegal-state.monitor"));
}
}
public boolean isHold() { return fldOwnedBy != 0; }
public void interruptio(long threadId) {
super.lock();
try
{
int index = getEntryIndexByThreadId(threadId);
if(index >= 0)
{
long4[] entries = fldEntries;
long4 entry = entries[index];
if(entry[0] == ENTRY_STATE_WAITING)
{
entries[index] = entry | -new byte4 { 0, 0, 0, 1 };
if(fldOwnedBy == 0) extractEntry();
}
}
} finally
{
super.unlock();
}
}
public void notify(boolean isAll, long threadId) {
boolean isNotOwnedBy = false;
long currentId = Kernel.getCurrentThreadId();
super.lock();
try
{
long4 entry = fldOwnedBy;
if(entry == 0 || entry[1] != currentId)
{
isNotOwnedBy = true;
} else if(isAll)
{
for(long4[] entries = fldEntries, int index = entries == null ? 0 : entries.length; index-- > 0; )
{
entries[index] = Long4.setElement(entries[index], 0, ENTRY_STATE_BLOCKED);
}
} else
{
int index = -1;
if(threadId == 0 || (index = getEntryIndexByThreadId(threadId)) < 0) index = getEntryIndexByState(ENTRY_STATE_WAITING);
long4[] entries = fldEntries;
if(index < 0 || (entry = entries[index])[0] != ENTRY_STATE_WAITING)
{
fldNotifies++;
} else
{
entries[index] = Long4.setElement(entry, 0, ENTRY_STATE_BLOCKED);
}
}
} finally
{
super.unlock();
}
if(isNotOwnedBy)
{
throw new IllegalMonitorStateException(avt.lang.package.getResourceString("illegal-state.monitor"));
}
}
public void wait(int timeInMillis, InterruptioHandler handler) throws InterruptedException { wait((long) timeInMillis, handler); }
public void wait(long timeInMillis, InterruptioHandler handler) throws InterruptedException {
boolean isWaiting = false;
boolean isNotOwnedBy = false;
boolean isInterrupted = false;
long currentId = Kernel.getCurrentThreadId();
super.lock();
try
{
long4 entry = fldOwnedBy;
if(entry == 0 || entry[1] != currentId)
{
isNotOwnedBy = true;
} else
{
long notifies = fldNotifies;
if(notifies == 0)
{
extractEntry();
appendEntry(Long4.setElement(entry, 0, ENTRY_STATE_WAITING));
isWaiting = true;
} else if(handler != null && handler.isInterrupted())
{
isInterrupted = true;
} else
{
fldNotifies = notifies - 1;
}
}
} finally
{
super.unlock();
}
if(isNotOwnedBy)
{
throw new IllegalMonitorStateException(avt.lang.package.getResourceString("illegal-state.monitor"));
}
if(isWaiting)
{
ThreadEvent event = ThreadEvent.get(currentId);
if(handler != null) handler.setWaitable(this);
event.waitSignalled(timeInMillis, 0);
do
{
super.lock();
try
{
long4 entry = fldOwnedBy;
if((isNotOwnedBy = entry == 0) || entry[1] == currentId)
{
if(isNotOwnedBy)
{
extractEntry(currentId);
entry = fldOwnedBy;
}
fldOwnedBy = entry & -new byte4 { 1, 1, 1, 0 };
isInterrupted = entry[3] != 0;
isWaiting = false;
} else
{
int index = getEntryIndexByThreadId(currentId);
long4[] entries = fldEntries;
entries[index] = Long4.setElement(entries[index], 0, ENTRY_STATE_BLOCKED);
}
} finally
{
super.unlock();
}
if(!isWaiting) break;
event.waitSignalled(0, 0);
} while(true);
if(handler != null) handler.setWaitable(null);
}
if(isInterrupted)
{
throw new InterruptedException(avt.lang.package.getResourceString("interrupted.wait"));
}
}
private void resume(long4 entry, boolean needSignal) {
fldOwnedBy = Long4.setElement(entry, 0, ENTRY_STATE_OWNEDBY);
if(needSignal) ThreadEvent.get(entry[1]).setSignalled();
}
private void extractEntry() {
long4[] entries = fldEntries;
if(entries == null)
{
fldOwnedBy = 0;
return;
}
int length = entries.length;
long4 entry;
int index;
label0:
{
for(index = 0; index < length; index++) if((entry = entries[index])[3] != 0) break label0;
for(index = 0; index < length; index++) if((entry = entries[index])[0] == ENTRY_STATE_BLOCKED) break label0;
fldOwnedBy = 0;
return;
}
Array.copy(entries, index + 1, entries, index, --length - index);
entries[length] = 0;
entries.length = length;
resume(entry, true);
}
private void extractEntry(long threadId) {
long4[] entries = fldEntries;
if(entries == null)
{
fldOwnedBy = 0;
return;
}
int length = entries.length;
long4 entry;
int index;
label0:
{
for(index = 0; index < length; index++) if((entry = entries[index])[1] == threadId) break label0;
fldOwnedBy = 0;
return;
}
Array.copy(entries, index + 1, entries, index, --length - index);
entries[length] = 0;
entries.length = length;
resume(entry, false);
}
private void appendEntry(long4 entry) {
long4[] entries = fldEntries;
if(entries == null)
{
(fldEntries = entries = new long4[0x0f]).length = 1;
entries[0] = entry;
return;
}
int length = entries.length;
if(length == entries.capacity) Array.copy(entries, 0, fldEntries = entries = new long4[length << 1 | 1], 0, length);
entries.length = length + 1;
entries[length] = entry;
}
private int getEntryIndexByState(long state) {
long4[] entries = fldEntries;
if(entries == null) return -1;
int length = entries.length;
int index;
label0:
{
long4 entry;
for(index = 0; index < length; index++) if((entry = entries[index])[0] == state && entry[3] != 0) break label0;
for(index = 0; index < length; index++) if(entries[index][0] == state) break label0;
return -1;
}
return index;
}
private int getEntryIndexByThreadId(long threadId) {
long4[] entries = fldEntries;
if(entries == null) return -1;
int length = entries.length;
int index;
label0:
{
for(index = 0; index < length; index++) if(entries[index][1] == threadId) break label0;
return -1;
}
return index;
}
}
package class FileSystemDescriptor(FileSystemRoot)
{
private char[] fldCanonicalPath;
private FileSystem fldFileSystem;
public (String rootPath, String currentDirectory): super(rootPath) {
int length = rootPath.length;
char[] canonical = new char[length + 1];
rootPath.getChars(1, length, canonical, 0);
canonical[length - 1] = '\\';
fldCanonicalPath = canonical;
fldFileSystem = new VolumeFileSystem(PlatformServices.getInstance().toInternalPath(rootPath), currentDirectory.replaceAll('/', '\\'));
}
public FileSystem fileSystem { read = fldFileSystem }
public String name { read = getName }
private String getName() {
char[] result = new char[Kernel.MAX_PATH + 1];
int length = Kernel.getVolumeName(fldCanonicalPath.getPointer(), result.getPointer(), Kernel.MAX_PATH + 1);
return length < 0 ? null : new String(result, 0, length);
}
}
package class Extensions(Object, Extendable)
{
protected Extension[] fldExtensions;
protected () { }
public Extension[] getExtensions() {
Extension[] exts = fldExtensions;
int length = exts == null ? 0 : exts.length;
Extension[] result = new Extension[length];
Array.copy(exts, 0, result, 0, length);
return result;
}
public Extension getExtension(Class type) {
Extension[] exts = fldExtensions;
if(exts != null) for(int length = exts.length, int index = 0; index < length; index++)
{
Extension ext = exts[index];
if(ext != null && (type == null || type.isAssignableFrom(ext.getClass()))) return ext;
}
return null;
}
}
package class HandleInputStream(Extensions, Closeable, ByteReader)
{
protected long fldHandle;
public (long handle) { fldHandle = handle; }
public void close() throws IOException { }
public int read() throws IOException {
long handle = handleNeeded();
int2 result = Kernel.readFile(handle, 0);
if(result[0] == 0)
{
throw new IOException(avt.io.package.getResourceString("io.read"));
}
return result[1];
}
public int read(byte[] dst, int offset, int length) throws IOException {
long handle = handleNeeded();
if(dst == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "dst" }));
}
Array.checkBounds(dst, offset, length);
if(length <= 0) return 0;
int2 result = Kernel.readFile(handle, dst.getPointer() + offset, length, 0);
if(result[0] == 0)
{
throw new IOException(avt.io.package.getResourceString("io.read"));
}
int readed = result[1];
return readed <= 0 ? -1 : readed;
}
public long skip(long bytesQuantity) throws IOException {
long handle = handleNeeded();
if(bytesQuantity <= 0) return 0;
long skiped = 0;
do
{
if(Kernel.readFile(handle, 0)[0] == 0)
{
if(skiped > 0) break;
throw new IOException(avt.io.package.getResourceString("io"));
}
skiped++;
} while(--bytesQuantity > 0);
return skiped;
}
protected final long handleNeeded() throws ClosedFileException {
long handle = fldHandle;
if(handle == 0)
{
throw new ClosedFileException(platform.independent.filesystem.package.getResourceString("closed-file"));
}
return handle;
}
package final long handle { read = fldHandle }
}
package class HandleOutputStream(Extensions, Closeable, ByteWriter)
{
protected long fldHandle;
protected char[] fldRootPath;
public (long handle, char[] rootPath) {
fldHandle = handle;
fldRootPath = rootPath;
}
public void close() throws IOException { }
public void write(int byteData) throws IOException {
long handle = handleNeeded();
int2 result = Kernel.writeFile(handle, byteData, 0);
if(result[0] == 0)
{
if(Kernel.getLastError() == Kernel.ERROR_DISK_FULL)
{
throw new FileSystemFullException(String.format(platform.independent.osservices.package.getResourceString("file-system.full"), new Object[] { fldRootPath }));
}
throw new IOException(avt.io.package.getResourceString("io.write"));
}
if(result[1] < 1)
{
throw new FileSystemFullException(String.format(platform.independent.osservices.package.getResourceString("file-system.full"), new Object[] { fldRootPath }));
}
}
public void write(byte[] src, int offset, int length) throws IOException {
long handle = handleNeeded();
if(src == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "src" }));
}
Array.checkBounds(src, offset, length);
if(length <= 0) return;
int2 result = Kernel.writeFile(handle, src.getPointer() + offset, length, 0);
if(result[0] == 0)
{
if(Kernel.getLastError() == Kernel.ERROR_DISK_FULL)
{
throw new FileSystemFullException(String.format(platform.independent.osservices.package.getResourceString("file-system.full"), new Object[] { fldRootPath }));
}
throw new IOException(avt.io.package.getResourceString("io.write"));
}
if(result[1] < length)
{
throw new FileSystemFullException(String.format(platform.independent.osservices.package.getResourceString("file-system.full"), new Object[] { fldRootPath }));
}
}
public void flush() throws IOException { }
protected final long handleNeeded() throws ClosedFileException {
long handle = fldHandle;
if(handle == 0)
{
throw new ClosedFileException(platform.independent.filesystem.package.getResourceString("closed-file"));
}
return handle;
}
package final long handle { read = fldHandle }
}
package abstract class HandleBidirectStream(Extensions, Closeable, ByteStream)
{
protected long fldHandleForRead;
protected long fldHandleForWrite;
protected HandleInputStream fldReader;
protected HandleOutputStream fldWriter;
public (long handleForRead, long handleForWrite) {
fldHandleForRead = handleForRead;
fldHandleForWrite = handleForWrite;
}
public void close() throws IOException {
long handleForRead = fldHandleForRead;
long handleForWrite = fldHandleForWrite;
{
fldHandleForRead = 0;
fldHandleForWrite = 0;
fldReader.fldHandle = 0;
fldWriter.fldHandle = 0;
}
if((handleForRead | handleForWrite) != 0 && (!Kernel.closeHandle(handleForRead) || handleForRead != handleForWrite && !Kernel.closeHandle(handleForWrite)))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
public ByteReader reader { read = fldReader }
public ByteWriter writer { read = fldWriter }
protected void beforeDestruction() {
long handleForRead = fldHandleForRead;
long handleForWrite = fldHandleForWrite;
if((handleForRead | handleForWrite) != 0)
{
Kernel.closeHandle(handleForRead);
if(handleForRead != handleForWrite) Kernel.closeHandle(handleForWrite);
}
}
}
package final class PipeStream(HandleBidirectStream)
{
public (long handleForRead, long handleForWrite): super(handleForRead, handleForWrite) {
fldReader = new HandleInputStream(handleForRead);
fldWriter = new HandleOutputStream(handleForWrite, null);
}
}
package final class EnvironmentTable(Object, platform.dependent.EnvironmentTable, Measureable, ObjectArray)
{
private final OrderedTable fldVariables;
public () { fldVariables = new OrderedTable(); }
public boolean equals(Object anot) {
OrderedTable tvars = fldVariables;
OrderedTable avars = ((EnvironmentTable) anot).fldVariables;
int length = tvars.length;
if(length != avars.length) return false;
for(int tindex = length; tindex-- > 0; )
{
String aname;
String tname = (String) tvars[tindex];
String avalue = (String) avars[tname];
String tvalue = (String) tvars[tname];
if(avalue != null)
{
if(avalue.equalsIgnoreCase(tvalue)) continue;
return false;
}
label0:
{
for(int aindex = length; aindex-- > 0; ) if((aname = (String) avars[aindex]).equalsIgnoreCase(tname)) break label0;
return false;
}
if(!((String) avars[aname]).equalsIgnoreCase(tvalue)) return false;
}
return true;
}
public void clear() { fldVariables.clear(); }
public boolean isCaseSensitive() { return false; }
public boolean contains(String envName) {
OrderedTable vars = fldVariables;
if(vars.contains(envName)) return true;
for(int index = vars.length; index-- > 0; ) if(((String) vars[index]).equalsIgnoreCase(envName)) return true;
return false;
}
public int length { read = fldVariables.length }
public void operator []=(String envName, String newValue) {
OrderedTable vars = fldVariables;
if(!vars.contains(envName)) for(int index = vars.length; index-- > 0; )
{
String name = (String) vars[index];
if(name.equalsIgnoreCase(envName))
{
vars[name] = newValue;
return;
}
}
vars[envName] = newValue;
}
public String operator [](String envName) {
OrderedTable vars = fldVariables;
String value = (String) vars[envName];
if(value != null) return value;
for(int index = vars.length; index-- > 0; )
{
String name = (String) vars[index];
if(name.equalsIgnoreCase(envName)) return (String) vars[name];
}
return null;
}
public String operator [](int index) { return (String) fldVariables[index]; }
}
package final class CurrentProcess(Process)
{
private static String[] parseCommandLine() {
try
{
final char SPACE = '\u0020';
final char QUOTE = '\u0022';
long2 cmdDs = Kernel.getCommandLine();
long cmdPtr = cmdDs[0];
int cmdLen = (int) cmdDs[1];
char[] cmdChars = (char[]) char[].class.newArrayAt(cmdPtr, cmdLen);
int length = 0;
boolean quoted = false;
char prev = SPACE;
for(int index = 0; index < cmdLen; index++)
{
char curr = cmdChars[index];
if(curr == QUOTE)
{
quoted = !quoted;
} else
{
if(!quoted && prev != SPACE && curr == SPACE) length++;
}
if(cmdLen - index == 1 && curr != SPACE) length++;
prev = curr;
}
String[] arguments = new String[length];
char[] argChars = new char[cmdLen];
int argLength = 0;
length = 0;
quoted = false;
prev = SPACE;
for(int index = 0; index < cmdLen; index++)
{
char curr = cmdChars[index];
if(curr == QUOTE)
{
quoted = !quoted;
} else if(quoted || curr != SPACE)
{
argChars[argLength++] = curr;
} else if(prev != SPACE)
{
arguments[length++] = new String(argChars, 0, argLength);
argLength = 0;
}
if(cmdLen - index == 1 && curr != SPACE)
{
arguments[length++] = new String(argChars, 0, argLength);
}
prev = curr;
}
argChars = new char[Kernel.MAX_PATH + 1];
argLength = Kernel.getModuleFileName(0, argChars.getPointer(), Kernel.MAX_PATH + 1);
if(length <= 0) return new String[] { new String(argChars, 0, argLength) };
arguments[0] = new String(argChars, 0, argLength);
return arguments;
} catch(Exception exception)
{
return null;
}
}
private final CriticalSection fldWorkingDirectoryOperation;
public () {
long stdIn = Kernel.getStdHandle(Kernel.STD_INPUT);
long stdOut = Kernel.getStdHandle(Kernel.STD_OUTPUT);
long stdErr = Kernel.getStdHandle(Kernel.STD_ERROR);
String[] commandLine = parseCommandLine();
if(stdIn != Kernel.INVALID_HANDLE_VALUE) super.setStandardInput(new HandleInputStream(stdIn));
if(stdOut != Kernel.INVALID_HANDLE_VALUE) super.setStandardOutput(new HandleOutputStream(stdOut, null));
if(stdErr != Kernel.INVALID_HANDLE_VALUE) super.setStandardError(new HandleOutputStream(stdErr, null));
if(commandLine != null) commandLine.finalize();
fldCommandLine = commandLine;
fldWorkingDirectoryOperation = new CriticalSection();
}
public void start() {
throw new IllegalProcessStateException(platform.independent.osservices.package.getResourceString("illegal-state.process.already-started"));
}
public boolean isTerminated() { return false; }
public int getExitCode() { return STILL_ACTIVE; }
protected void setPriority(int newPriority) {
if(newPriority < MIN_PRIORITY) newPriority = MIN_PRIORITY;
if(newPriority > MAX_PRIORITY) newPriority = MAX_PRIORITY;
switch(newPriority)
{
case MIN_PRIORITY:
{
newPriority = Kernel.IDLE_PRIORITY_CLASS;
break;
}
case LOW_PRIORITY - 1:
case LOW_PRIORITY:
{
newPriority = Kernel.BELOW_NORMAL_PRIORITY_CLASS;
break;
}
case NORM_PRIORITY - 1:
case NORM_PRIORITY:
case NORM_PRIORITY + 1:
{
newPriority = Kernel.NORMAL_PRIORITY_CLASS;
break;
}
case HIGH_PRIORITY:
case HIGH_PRIORITY + 1:
{
newPriority = Kernel.ABOVE_NORMAL_PRIORITY_CLASS;
break;
}
case MAX_PRIORITY:
{
newPriority = Kernel.HIGH_PRIORITY_CLASS;
break;
}
}
Kernel.setPriorityClass(Kernel.getCurrentProcess(), newPriority);
}
protected void setCommandLine(String[] newCommandLine) {
throw new ReadOnlyPropertyException(String.format(avt.lang.package.getResourceString("unsupported-operation.property.read-only"), new Object[] { "commandLine", class.canonicalName }));
}
protected void setWorkingDirectory(String newWorkingDirectory) {
if(newWorkingDirectory == null)
{
throw new IllegalPropertyValueException(String.format(avt.lang.package.getResourceString("illegal-property"), new Object[] { "workingDirectory" }));
}
int length = (newWorkingDirectory = PlatformServices.getInstance().toInternalPath(newWorkingDirectory)).length;
char[] internalFullPath = new char[length + 1];
newWorkingDirectory.getChars(0, length, internalFullPath, 0);
CriticalSection operation = fldWorkingDirectoryOperation;
operation.lock();
try
{
if(!Kernel.setCurrentDirectory(internalFullPath.getPointer()))
{
throw new IllegalPropertyValueException(String.format(avt.lang.package.getResourceString("illegal-property"), new Object[] { "workingDirectory" }));
}
} finally
{
operation.unlock();
}
}
protected void setStandardInput(ByteReader newStandardInput) {
throw new ReadOnlyPropertyException(String.format(avt.lang.package.getResourceString("unsupported-operation.property.read-only"), new Object[] { "standardInput", class.canonicalName }));
}
protected void setStandardOutput(ByteWriter newStandardOutput) {
throw new ReadOnlyPropertyException(String.format(avt.lang.package.getResourceString("unsupported-operation.property.read-only"), new Object[] { "standardOutput", class.canonicalName }));
}
protected void setStandardError(ByteWriter newStandardError) {
throw new ReadOnlyPropertyException(String.format(avt.lang.package.getResourceString("unsupported-operation.property.read-only"), new Object[] { "standardError", class.canonicalName }));
}
protected int getPriority() {
switch(Kernel.getPriorityClass(Kernel.getCurrentProcess()))
{
case Kernel.IDLE_PRIORITY_CLASS : return MIN_PRIORITY;
case Kernel.BELOW_NORMAL_PRIORITY_CLASS: return LOW_PRIORITY;
case Kernel.NORMAL_PRIORITY_CLASS : return NORM_PRIORITY;
case Kernel.ABOVE_NORMAL_PRIORITY_CLASS: return HIGH_PRIORITY;
case Kernel.HIGH_PRIORITY_CLASS : return MAX_PRIORITY;
default : return 0;
}
}
protected String getWorkingDirectory() {
int length;
char[] internalFullPath;
CriticalSection operation = fldWorkingDirectoryOperation;
operation.lock();
try
{
length = Kernel.getCurrentDirectory(0, 0);
internalFullPath = new char[length];
Kernel.getCurrentDirectory(length--, internalFullPath.getPointer());
} finally
{
operation.unlock();
}
if(length > 0 && internalFullPath[length - 1] != '\\') internalFullPath[length++] = '\\';
return PlatformServices.getInstance().toObjectPath(new String(internalFullPath, 0, length));
}
protected Environment createEnvironment() { return new CurrentEnvironment(); }
}
final class VolumeFileSystem(Object, FileSystem, RequiredAttributes, VolumeRequiredAttributes)
{
private static final int AT_OBJECT = 0;
private static final int AT_FILE = 1;
private static final int AT_DIRECTORY = 2;
private static final int OBJECT_NAME_MAXIMUM_LENGTH = 255;
private static final String[] reserved = new String[] {
"con", "prn", "aux", "nul",
"com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", "com\u00b9", "com\u00b2", "com\u00b3",
"lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "lpt\u00b9", "lpt\u00b2", "lpt\u00b3"
};
private static boolean isComponentReserved(String component) {
int length = component.length;
if(length > 0) switch(component[length - 1])
{
case ' ': return true;
case '.': return length > 1 && (length > 2 || component[0] != '.');
}
int index = component.indexOf('.');
String name = index < 0 ? component : component.substring(0, index);
if((length = name.length) >= 3 && length <= 4) for(length = reserved.length, index = 0; index < length; index++) if(reserved[index].equalsIgnoreCase(name)) return true;
return false;
}
private static char[] toZeroTerminatedArray(String str) {
int length = str.length;
char[] result = new char[length + 1];
str.getChars(0, length, result, 0);
return result;
}
private boolean fldCurrentUnreliableBlock;
private long fldCurrentHandle;
private char[] fldCanonicalRootPath; /* C:\ */
private String fldInternalRootPath; /* C: */
private String fldCurrentDirectory; /* \Windows\ */
private CriticalSection fldCurrentOperation;
public (String rootPath, String currentDirectory) {
int length = rootPath.length;
char[] canonical = new char[length + 2];
rootPath.getChars(0, length, canonical, 0);
canonical[length++] = '\\';
canonical.length = length;
fldCurrentUnreliableBlock = true;
fldCurrentHandle = Kernel.INVALID_HANDLE_VALUE;
fldCanonicalRootPath = canonical;
fldInternalRootPath = rootPath;
fldCurrentDirectory = currentDirectory;
fldCurrentOperation = new CriticalSection();
tryMakeCurrentReliableBlock();
}
public void changeCurrentDirectory(String directoryPath) throws DirectoryNotFoundException, IOException {
String internalFullPath;
if(directoryPath == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "directoryPath" }));
}
if(directoryPath.length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "directoryPath" }));
}
if(!isObjectNameValid(directoryPath))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "directoryPath" }));
}
if((internalFullPath = toVolumeFullPath(directoryPath)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "directoryPath" }));
}
internalFullPath = makeInternalFullPathAndCheckExist(internalFullPath, AT_DIRECTORY);
if(internalFullPath.endsWith("\\")) internalFullPath = internalFullPath.substring(0, internalFullPath.length - 1);
int rootPathLength = fldInternalRootPath.length;
String newCurrentDirectory = internalFullPath.substring(rootPathLength) + '\\';
CriticalSection operation = fldCurrentOperation;
operation.lock();
try
{
if(!fldCurrentDirectory.equalsIgnoreCase(newCurrentDirectory))
{
boolean unreliableBlock = false;
long newHandle = Kernel.INVALID_HANDLE_VALUE;
if(internalFullPath.length > rootPathLength)
{
unreliableBlock = true;
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
long zerotermFullPathPtr = zerotermFullPath.getPointer();
newHandle = Kernel.createFile(
zerotermFullPathPtr,
/* Kernel.DELETE */ 0x00010000,
Kernel.FILE_SHARE_READ | Kernel.FILE_SHARE_WRITE,
0,
Kernel.OPEN_EXISTING,
Kernel.FILE_ATTRIBUTE_NORMAL | Kernel.FILE_FLAG_BACKUP_SEMANTICS,
0
);
if(newHandle != Kernel.INVALID_HANDLE_VALUE)
{
unreliableBlock = false;
} else
{
newHandle = Kernel.createFile(
zerotermFullPathPtr,
0,
0,
0,
Kernel.OPEN_EXISTING,
Kernel.FILE_ATTRIBUTE_NORMAL | Kernel.FILE_FLAG_BACKUP_SEMANTICS,
0
);
}
label0:
{
if(newHandle != Kernel.INVALID_HANDLE_VALUE)
{
if((Kernel.getFileAttributes(zerotermFullPathPtr) & Kernel.FILE_ATTRIBUTE_DIRECTORY) != 0) break label0;
Kernel.closeHandle(newHandle);
} else switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND: break;
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(
String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath })
);
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
throw new DirectoryNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.directory")) { directoryName = internalFullPath };
}
}
long oldHandle = fldCurrentHandle;
if(oldHandle != Kernel.INVALID_HANDLE_VALUE) Kernel.closeHandle(oldHandle);
fldCurrentUnreliableBlock = unreliableBlock;
fldCurrentDirectory = newCurrentDirectory;
fldCurrentHandle = newHandle;
}
} finally
{
operation.unlock();
}
}
public void readAttributes(String objectName, ObjectAttributes objectAttr) throws ObjectNotFoundException, ObjectReadAttributesException, IOException {
int standardNameLength;
String internalFullPath;
if(objectName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectName" }));
}
if((standardNameLength = objectName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "objectName" }));
}
if(standardNameLength <= 0 || objectName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "objectName" }));
}
if(!isObjectNameValid(objectName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "objectName" }));
}
if((internalFullPath = toVolumeFullPath(objectName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "objectName" }));
}
internalFullPath = makeInternalFullPathAndCheckExist(internalFullPath, AT_OBJECT);
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
long zerotermFullPathPtr = zerotermFullPath.getPointer();
long objHandle = Kernel.createFile(
zerotermFullPathPtr,
Kernel.GENERIC_READ,
Kernel.FILE_SHARE_READ | Kernel.FILE_SHARE_WRITE | Kernel.FILE_SHARE_DELETE,
0,
Kernel.OPEN_EXISTING,
Kernel.FILE_ATTRIBUTE_NORMAL | Kernel.FILE_FLAG_BACKUP_SEMANTICS,
0
);
if(objHandle == Kernel.INVALID_HANDLE_VALUE) switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
{
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) { objectName = internalFullPath };
}
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
FileTime internalCreationTime = new FileTime();
FileTime internalLastWriteTime = new FileTime();
FileTime internalLastAccessTime = new FileTime();
int internalAttributes = Kernel.getFileAttributes(zerotermFullPathPtr);
boolean objReadTime = Kernel.getFileTime(objHandle, internalCreationTime.getPointer(), internalLastAccessTime.getPointer(), internalLastWriteTime.getPointer());
if(!Kernel.closeHandle(objHandle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
if(internalAttributes == Kernel.INVALID_FILE_ATTRIBUTES || !objReadTime)
{
throw new ObjectReadAttributesException(platform.independent.filesystem.package.getResourceString("object.read-attributes")) { objectName = internalFullPath };
}
if(objectAttr == null) return;
if(objectAttr.isSupportedAttributeId(B_DIRECTORY)) objectAttr.setBooleanAttribute(B_DIRECTORY, (internalAttributes & Kernel.FILE_ATTRIBUTE_DIRECTORY) != 0);
if(objectAttr.isSupportedAttributeId(B_READ_ONLY)) objectAttr.setBooleanAttribute(B_READ_ONLY, (internalAttributes & Kernel.FILE_ATTRIBUTE_READONLY) != 0);
if(objectAttr.isSupportedAttributeId(B_ARCHIVE)) objectAttr.setBooleanAttribute(B_ARCHIVE, (internalAttributes & Kernel.FILE_ATTRIBUTE_ARCHIVE) != 0);
if(objectAttr.isSupportedAttributeId(B_HIDDEN)) objectAttr.setBooleanAttribute(B_HIDDEN, (internalAttributes & Kernel.FILE_ATTRIBUTE_HIDDEN) != 0);
if(objectAttr.isSupportedAttributeId(B_SYSTEM)) objectAttr.setBooleanAttribute(B_SYSTEM, (internalAttributes & Kernel.FILE_ATTRIBUTE_SYSTEM) != 0);
if(objectAttr.isSupportedAttributeId(L_CREATION_TIME)) objectAttr.setLongAttribute(L_CREATION_TIME, toObjectTime(internalCreationTime.ftFileTime));
if(objectAttr.isSupportedAttributeId(L_LAST_WRITE_TIME)) objectAttr.setLongAttribute(L_LAST_WRITE_TIME, toObjectTime(internalLastWriteTime.ftFileTime));
if(objectAttr.isSupportedAttributeId(L_LAST_ACCESS_TIME)) objectAttr.setLongAttribute(L_LAST_ACCESS_TIME, toObjectTime(internalLastAccessTime.ftFileTime));
}
public void writeAttributes(String objectName, ObjectAttributes objectAttr) throws ReadOnlyFileSystemException, ObjectNotFoundException, ObjectWriteAttributesException, IOException {
int standardNameLength;
String internalFullPath;
if(objectName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectName" }));
}
if((standardNameLength = objectName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "objectName" }));
}
if(standardNameLength <= 0 || objectName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "objectName" }));
}
if(!isObjectNameValid(objectName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "objectName" }));
}
if((internalFullPath = toVolumeFullPath(objectName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "objectName" }));
}
if(objectAttr == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectAttr" }));
}
int internalAttributes = 0;
FileTime internalCreationTime = new FileTime();
FileTime internalLastWriteTime = new FileTime();
FileTime internalLastAccessTime = new FileTime();
if(objectAttr.isSupportedAttributeId(B_DIRECTORY) && objectAttr.getBooleanAttribute(B_DIRECTORY)) internalAttributes |= Kernel.FILE_ATTRIBUTE_DIRECTORY;
if(objectAttr.isSupportedAttributeId(B_READ_ONLY) && objectAttr.getBooleanAttribute(B_READ_ONLY)) internalAttributes |= Kernel.FILE_ATTRIBUTE_READONLY;
if(objectAttr.isSupportedAttributeId(B_ARCHIVE) && objectAttr.getBooleanAttribute(B_ARCHIVE)) internalAttributes |= Kernel.FILE_ATTRIBUTE_ARCHIVE;
if(objectAttr.isSupportedAttributeId(B_HIDDEN) && objectAttr.getBooleanAttribute(B_HIDDEN)) internalAttributes |= Kernel.FILE_ATTRIBUTE_HIDDEN;
if(objectAttr.isSupportedAttributeId(B_SYSTEM) && objectAttr.getBooleanAttribute(B_SYSTEM)) internalAttributes |= Kernel.FILE_ATTRIBUTE_SYSTEM;
if(objectAttr.isSupportedAttributeId(L_CREATION_TIME))
{
long time = toInternalTime(objectAttr.getLongAttribute(L_CREATION_TIME));
internalCreationTime.ftFileTime = time < 0 ? 0 : time;
}
if(objectAttr.isSupportedAttributeId(L_LAST_WRITE_TIME))
{
long time = toInternalTime(objectAttr.getLongAttribute(L_LAST_WRITE_TIME));
internalLastWriteTime.ftFileTime = time < 0 ? 0 : time;
}
if(objectAttr.isSupportedAttributeId(L_LAST_ACCESS_TIME))
{
long time = toInternalTime(objectAttr.getLongAttribute(L_LAST_ACCESS_TIME));
internalLastAccessTime.ftFileTime = time < 0 ? 0 : time;
}
internalFullPath = makeInternalFullPathAndCheckExist(internalFullPath, AT_OBJECT);
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
long zerotermFullPathPtr = zerotermFullPath.getPointer();
boolean objWriteAttr = Kernel.setFileAttributes(zerotermFullPathPtr, Kernel.FILE_ATTRIBUTE_NORMAL);
long objHandle = Kernel.createFile(
zerotermFullPathPtr,
Kernel.GENERIC_WRITE,
Kernel.FILE_SHARE_READ | Kernel.FILE_SHARE_WRITE | Kernel.FILE_SHARE_DELETE,
0,
Kernel.OPEN_EXISTING,
Kernel.FILE_ATTRIBUTE_NORMAL | Kernel.FILE_FLAG_BACKUP_SEMANTICS,
0
);
if(objHandle == Kernel.INVALID_HANDLE_VALUE) switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
{
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) { objectName = internalFullPath };
}
case Kernel.ERROR_WRITE_PROTECT:
{
throw new ReadOnlyFileSystemException(String.format(platform.independent.osservices.package.getResourceString("file-system.read-only"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
boolean objWriteTime = Kernel.setFileTime(objHandle, internalCreationTime.getPointer(), internalLastAccessTime.getPointer(), internalLastWriteTime.getPointer());
objWriteAttr = Kernel.setFileAttributes(zerotermFullPathPtr, internalAttributes) && objWriteAttr;
if(!Kernel.closeHandle(objHandle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
if(!objWriteAttr || !objWriteTime)
{
throw new ObjectWriteAttributesException(platform.independent.filesystem.package.getResourceString("object.write-attributes")) { objectName = internalFullPath };
}
}
public void move(String objectOldName, String objectNewName) throws ReadOnlyFileSystemException, ObjectNotFoundException, MoveOperationException, IOException {
int standardNameLength;
String internalOldFullPath;
String internalNewFullPath;
if(objectOldName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectOldName" }));
}
if((standardNameLength = objectOldName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "objectOldName" }));
}
if(standardNameLength <= 0 || objectOldName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "objectOldName" }));
}
if(!isObjectNameValid(objectOldName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "objectOldName" }));
}
if((internalOldFullPath = toVolumeFullPath(objectOldName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "objectOldName" }));
}
if(objectNewName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectNewName" }));
}
if((standardNameLength = objectNewName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "objectNewName" }));
}
if(standardNameLength <= 0 || objectNewName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "objectNewName" }));
}
if(!isObjectNameValid(objectNewName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "objectNewName" }));
}
if((internalNewFullPath = toVolumeFullPath(objectNewName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "objectNewName" }));
}
tryMakeCurrentReliableBlock();
internalOldFullPath = makeInternalFullPathAndCheckExist(internalOldFullPath, AT_OBJECT);
internalNewFullPath = makeInternalFullPathAndCheckCreat(internalNewFullPath);
char[] zerotermOldFullPath = toZeroTerminatedArray(internalOldFullPath);
char[] zerotermNewFullPath = toZeroTerminatedArray(internalNewFullPath);
if(Kernel.moveFile(zerotermOldFullPath.getPointer(), zerotermNewFullPath.getPointer())) return;
switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_EXISTS:
case Kernel.ERROR_ALREADY_EXISTS:
{
throw new MoveOperationException(platform.independent.filesystem.package.getResourceString("move-operation")) {
objectOldName = internalOldFullPath,
objectNewName = internalNewFullPath
};
}
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
{
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) { objectName = internalOldFullPath };
}
case Kernel.ERROR_DISK_FULL:
{
throw new FileSystemFullException(String.format(platform.independent.osservices.package.getResourceString("file-system.full"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_WRITE_PROTECT:
{
throw new ReadOnlyFileSystemException(String.format(platform.independent.osservices.package.getResourceString("file-system.read-only"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
public void deleteFile(String fileName) throws ReadOnlyFileSystemException, FileNotFoundException, FileDeletionException, IOException {
int standardNameLength;
String internalFullPath;
if(fileName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "fileName" }));
}
if((standardNameLength = fileName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "fileName" }));
}
if(standardNameLength <= 0 || fileName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "fileName" }));
}
if(!isObjectNameValid(fileName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "fileName" }));
}
if((internalFullPath = toVolumeFullPath(fileName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "fileName" }));
}
internalFullPath = makeInternalFullPathAndCheckExist(internalFullPath, AT_FILE);
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
if(Kernel.deleteFile(zerotermFullPath.getPointer())) return;
switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
{
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) { fileName = internalFullPath };
}
case Kernel.ERROR_WRITE_PROTECT:
{
throw new ReadOnlyFileSystemException(String.format(platform.independent.osservices.package.getResourceString("file-system.read-only"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
if(Kernel.getLastStatus() != Kernel.STATUS_FILE_IS_A_DIRECTORY)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
throw new FileDeletionException(platform.independent.filesystem.package.getResourceString("file.deletion")) { fileName = internalFullPath };
}
public void deleteDirectory(String directoryName) throws ReadOnlyFileSystemException, DirectoryNotFoundException, DirectoryDeletionException, IOException {
int standardNameLength;
String internalFullPath;
if(directoryName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "directoryName" }));
}
if((standardNameLength = directoryName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "directoryName" }));
}
if(standardNameLength <= 0 || directoryName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "directoryName" }));
}
if(!isObjectNameValid(directoryName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "directoryName" }));
}
if((internalFullPath = toVolumeFullPath(directoryName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "directoryName" }));
}
tryMakeCurrentReliableBlock();
internalFullPath = makeInternalFullPathAndCheckExist(internalFullPath, AT_DIRECTORY);
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
if(Kernel.removeDirectory(zerotermFullPath.getPointer())) return;
switch(Kernel.getLastError())
{
case Kernel.ERROR_DIR_NOT_EMPTY: break;
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
{
throw new DirectoryNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.directory")) { directoryName = internalFullPath };
}
case Kernel.ERROR_WRITE_PROTECT:
{
throw new ReadOnlyFileSystemException(String.format(platform.independent.osservices.package.getResourceString("file-system.read-only"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
if(Kernel.getLastStatus() != Kernel.STATUS_NOT_A_DIRECTORY)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
throw new DirectoryDeletionException(platform.independent.filesystem.package.getResourceString("directory.deletion")) { directoryName = internalFullPath };
}
public void createDirectory(String directoryName) throws ReadOnlyFileSystemException, DirectoryCreationException, IOException {
int standardNameLength;
String internalFullPath;
if(directoryName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "directoryName" }));
}
if((standardNameLength = directoryName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "directoryName" }));
}
if(standardNameLength <= 0 || directoryName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "directoryName" }));
}
if(!isObjectNameValid(directoryName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "directoryName" }));
}
if((internalFullPath = toVolumeFullPath(directoryName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "directoryName" }));
}
internalFullPath = makeInternalFullPathAndCheckCreat(internalFullPath);
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
if(Kernel.createDirectory(zerotermFullPath.getPointer(), 0)) return;
switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_EXISTS:
case Kernel.ERROR_ALREADY_EXISTS:
{
throw new DirectoryCreationException(platform.independent.filesystem.package.getResourceString("directory.creation")) { directoryName = internalFullPath };
}
case Kernel.ERROR_DISK_FULL:
{
throw new FileSystemFullException(String.format(platform.independent.osservices.package.getResourceString("file-system.full"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_WRITE_PROTECT:
{
throw new ReadOnlyFileSystemException(String.format(platform.independent.osservices.package.getResourceString("file-system.read-only"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
public boolean isAttached() throws IOException {
Kernel.setErrorMode(Kernel.SEM_FAILCRITICALERRORS);
if(Kernel.getVolumeFlags(fldCanonicalRootPath.getPointer()) == Kernel.INVALID_VOLUME_FLAGS)
{
if(Kernel.getLastError() == Kernel.ERROR_NOT_READY) return false;
throw new IOException(avt.io.package.getResourceString("io"));
}
return true;
}
public boolean isReadOnly() throws IOException {
char[] canonicalRootPath = fldCanonicalRootPath;
Kernel.setErrorMode(Kernel.SEM_FAILCRITICALERRORS);
int flags = Kernel.getVolumeFlags(canonicalRootPath.getPointer());
if(flags == Kernel.INVALID_VOLUME_FLAGS) switch(Kernel.getLastError())
{
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { canonicalRootPath }));
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
return (flags & Kernel.FILE_READ_ONLY_VOLUME) != 0;
}
public boolean isObjectNameCaseSensitive() throws IOException {
char[] canonicalRootPath = fldCanonicalRootPath;
Kernel.setErrorMode(Kernel.SEM_FAILCRITICALERRORS);
if(Kernel.getVolumeFlags(canonicalRootPath.getPointer()) == Kernel.INVALID_VOLUME_FLAGS) switch(Kernel.getLastError())
{
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { canonicalRootPath }));
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
return false;
}
public boolean isObjectExists(String objectName) throws IOException {
int standardNameLength;
String internalFullPath;
if(objectName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectName" }));
}
if((standardNameLength = objectName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "objectName" }));
}
if(standardNameLength <= 0 || objectName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "objectName" }));
}
if(!isObjectNameValid(objectName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "objectName" }));
}
if((internalFullPath = toVolumeFullPath(objectName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "objectName" }));
}
if((internalFullPath = makeInternalFullPathAndIsExist(internalFullPath)) == null) return false;
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
if(Kernel.getFileAttributes(zerotermFullPath.getPointer()) == Kernel.INVALID_FILE_ATTRIBUTES) switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND: return false;
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
return true;
}
public boolean isObjectNameValid(String objectName) {
if(objectName == null) return false;
int length = objectName.length;
if(length > OBJECT_NAME_MAXIMUM_LENGTH || objectName.indexOf("//") >= 0) return false;
for(int index = 0; index < length; index++)
{
char chr = objectName[index];
if(chr >= '\0' && chr < '\u0020' || chr == '<' || chr == '>' || chr == ':' || chr == '\"' || chr == '\\' || chr == '|' || chr == '?' || chr == '*') return false;
}
if(length > 0)
{
int beginIndex = 0;
if(objectName[0] == '/') beginIndex++;
while(beginIndex >= 0 && beginIndex < length)
{
int endIndex = objectName.indexOf('/', beginIndex);
if(endIndex < 0) endIndex = length;
if(isComponentReserved(objectName.substring(beginIndex, endIndex))) return false;
beginIndex = endIndex + 1;
}
}
return true;
}
public boolean isInternalNameFull(String internalName) { return internalName != null && internalName.startsWith("\\"); }
public boolean isInternalNameValid(String internalName) {
if(internalName == null) return false;
int length = internalName.length;
if(length > OBJECT_NAME_MAXIMUM_LENGTH || internalName.indexOf("\\\\") >= 0) return false;
for(int index = 0; index < length; index++)
{
char chr = internalName[index];
if(chr >= '\0' && chr < '\u0020' || chr == '<' || chr == '>' || chr == ':' || chr == '\"' || chr == '/' || chr == '|' || chr == '?' || chr == '*') return false;
}
if(length > 0)
{
int beginIndex = 0;
if(internalName[0] == '\\') beginIndex++;
while(beginIndex >= 0 && beginIndex < length)
{
int endIndex = internalName.indexOf('\\', beginIndex);
if(endIndex < 0) endIndex = length;
if(isComponentReserved(internalName.substring(beginIndex, endIndex))) return false;
beginIndex = endIndex + 1;
}
}
return true;
}
public int getObjectNameMaximumLength() { return OBJECT_NAME_MAXIMUM_LENGTH; }
public long totalSize() throws IOException {
char[] canonicalRootPath = fldCanonicalRootPath;
long4 freeSpace = Kernel.getDiskFreeSpaceEx(canonicalRootPath.getPointer());
if(freeSpace[0] == 0) switch(Kernel.getLastError())
{
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { canonicalRootPath }));
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
return freeSpace[2];
}
public long usedSize() throws IOException {
char[] canonicalRootPath = fldCanonicalRootPath;
long4 freeSpace = Kernel.getDiskFreeSpaceEx(canonicalRootPath.getPointer());
if(freeSpace[0] == 0) switch(Kernel.getLastError())
{
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { canonicalRootPath }));
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
return freeSpace[2] - freeSpace[3];
}
public long availableSize() throws IOException {
char[] canonicalRootPath = fldCanonicalRootPath;
long4 freeSpace = Kernel.getDiskFreeSpaceEx(canonicalRootPath.getPointer());
if(freeSpace[0] == 0) switch(Kernel.getLastError())
{
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { canonicalRootPath }));
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
return freeSpace[3];
}
public String toInternalName(String objectName) {
if(objectName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectName" }));
}
return objectName.replaceAll('/', '\\');
}
public String toObjectName(String internalName) {
if(internalName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "internalName" }));
}
return internalName.replaceAll('\\', '/');
}
public ObjectEnumeration findFirst(String objectPath) throws ObjectNotFoundException, IOException {
String internalFullPath;
if(objectPath == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectPath" }));
}
if(objectPath.length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "objectPath" }));
}
if(!isObjectNameValid(objectPath))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "objectPath" }));
}
if((internalFullPath = toVolumeFullPath(objectPath)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "objectPath" }));
}
internalFullPath = makeInternalFullPathAndCheckExist(internalFullPath, AT_OBJECT);
if(internalFullPath.endsWith("\\")) internalFullPath = internalFullPath + '*';
Win32FindData info = new Win32FindData();
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
long handle = Kernel.findFirstFile(zerotermFullPath.getPointer(), info.getPointer());
if(handle != Kernel.INVALID_HANDLE_VALUE)
{
return new VolumeObjectEnumeration(handle, info);
}
switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
{
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) { objectName = internalFullPath };
}
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
public ByteWriter createFile(String fileName) throws ReadOnlyFileSystemException, FileCreationException, IOException {
int standardNameLength;
String internalFullPath;
if(fileName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "fileName" }));
}
if((standardNameLength = fileName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "fileName" }));
}
if(standardNameLength <= 0 || fileName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "fileName" }));
}
if(!isObjectNameValid(fileName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "fileName" }));
}
if((internalFullPath = toVolumeFullPath(fileName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "fileName" }));
}
internalFullPath = makeInternalFullPathAndCheckCreat(internalFullPath);
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
long handle = Kernel.createFile(
zerotermFullPath.getPointer(),
Kernel.GENERIC_WRITE,
0,
0,
Kernel.CREATE_NEW,
Kernel.FILE_ATTRIBUTE_NORMAL,
0
);
if(handle != Kernel.INVALID_HANDLE_VALUE)
{
return new FileOutputStream(handle, fldCanonicalRootPath, null, null);
}
switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_EXISTS:
case Kernel.ERROR_ALREADY_EXISTS: break;
case Kernel.ERROR_DISK_FULL:
{
throw new FileSystemFullException(String.format(platform.independent.osservices.package.getResourceString("file-system.full"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_WRITE_PROTECT:
{
throw new ReadOnlyFileSystemException(String.format(platform.independent.osservices.package.getResourceString("file-system.read-only"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
if(Kernel.getLastStatus() != Kernel.STATUS_FILE_IS_A_DIRECTORY)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
throw new FileCreationException(platform.independent.filesystem.package.getResourceString("file.creation")) { fileName = internalFullPath };
}
public ByteWriter rewriteFile(String fileName) throws ReadOnlyFileSystemException, FileCreationException, IOException {
int standardNameLength;
String internalFullPath;
if(fileName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "fileName" }));
}
if((standardNameLength = fileName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "fileName" }));
}
if(standardNameLength <= 0 || fileName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "fileName" }));
}
if(!isObjectNameValid(fileName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "fileName" }));
}
if((internalFullPath = toVolumeFullPath(fileName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "fileName" }));
}
internalFullPath = makeInternalFullPathAndCheckCreat(internalFullPath);
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
long handle = Kernel.createFile(
zerotermFullPath.getPointer(),
Kernel.GENERIC_WRITE,
0,
0,
Kernel.CREATE_ALWAYS,
Kernel.FILE_ATTRIBUTE_NORMAL,
0
);
if(handle != Kernel.INVALID_HANDLE_VALUE)
{
return new FileOutputStream(handle, fldCanonicalRootPath, null, null);
}
switch(Kernel.getLastError())
{
case Kernel.ERROR_DISK_FULL:
{
throw new FileSystemFullException(String.format(platform.independent.osservices.package.getResourceString("file-system.full"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_WRITE_PROTECT:
{
throw new ReadOnlyFileSystemException(String.format(platform.independent.osservices.package.getResourceString("file-system.read-only"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
if(Kernel.getLastStatus() != Kernel.STATUS_FILE_IS_A_DIRECTORY)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
throw new FileCreationException(platform.independent.filesystem.package.getResourceString("file.creation")) { fileName = internalFullPath };
}
public ByteWriter openFileForAppend(String fileName) throws ReadOnlyFileSystemException, FileNotFoundException, FileOpeningException, IOException {
int standardNameLength;
String internalFullPath;
if(fileName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "fileName" }));
}
if((standardNameLength = fileName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "fileName" }));
}
if(standardNameLength <= 0 || fileName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "fileName" }));
}
if(!isObjectNameValid(fileName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "fileName" }));
}
if((internalFullPath = toVolumeFullPath(fileName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "fileName" }));
}
internalFullPath = makeInternalFullPathAndCheckExist(internalFullPath, AT_FILE);
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
long handle = Kernel.createFile(
zerotermFullPath.getPointer(),
Kernel.GENERIC_WRITE,
0,
0,
Kernel.OPEN_EXISTING,
Kernel.FILE_ATTRIBUTE_NORMAL,
0
);
if(handle != Kernel.INVALID_HANDLE_VALUE)
{
Kernel.setFilePointer(handle, 0, Kernel.FILE_END);
return new FileOutputStream(handle, fldCanonicalRootPath, null, null);
}
switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
{
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) { fileName = internalFullPath };
}
case Kernel.ERROR_WRITE_PROTECT:
{
throw new ReadOnlyFileSystemException(String.format(platform.independent.osservices.package.getResourceString("file-system.read-only"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
if(Kernel.getLastStatus() != Kernel.STATUS_FILE_IS_A_DIRECTORY)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
throw new FileOpeningException(platform.independent.filesystem.package.getResourceString("file.opening.append")) { fileName = internalFullPath };
}
public ByteReader openFileForRead(String fileName) throws FileNotFoundException, FileOpeningException, IOException {
int standardNameLength;
String internalFullPath;
if(fileName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "fileName" }));
}
if((standardNameLength = fileName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "fileName" }));
}
if(standardNameLength <= 0 || fileName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "fileName" }));
}
if(!isObjectNameValid(fileName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "fileName" }));
}
if((internalFullPath = toVolumeFullPath(fileName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "fileName" }));
}
internalFullPath = makeInternalFullPathAndCheckExist(internalFullPath, AT_FILE);
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
long handle = Kernel.createFile(
zerotermFullPath.getPointer(),
Kernel.GENERIC_READ,
Kernel.FILE_SHARE_READ,
0,
Kernel.OPEN_EXISTING,
Kernel.FILE_ATTRIBUTE_NORMAL,
0
);
if(handle != Kernel.INVALID_HANDLE_VALUE)
{
return new FileInputStream(handle, null);
}
switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
{
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) { fileName = internalFullPath };
}
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
if(Kernel.getLastStatus() != Kernel.STATUS_FILE_IS_A_DIRECTORY)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
throw new FileOpeningException(platform.independent.filesystem.package.getResourceString("file.opening.read")) { fileName = internalFullPath };
}
public ByteStream openFile(String fileName) throws ReadOnlyFileSystemException, FileNotFoundException, FileOpeningException, IOException {
int standardNameLength;
String internalFullPath;
if(fileName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "fileName" }));
}
if((standardNameLength = fileName.length) > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "fileName" }));
}
if(standardNameLength <= 0 || fileName.endsWith("/"))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.path"), new Object[] { "fileName" }));
}
if(!isObjectNameValid(fileName))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name"), new Object[] { "fileName" }));
}
if((internalFullPath = toVolumeFullPath(fileName)).length > OBJECT_NAME_MAXIMUM_LENGTH)
{
throw new ObjectNameTooLongException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"), new Object[] { "fileName" }));
}
internalFullPath = makeInternalFullPathAndCheckExist(internalFullPath, AT_FILE);
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
long handle = Kernel.createFile(
zerotermFullPath.getPointer(),
Kernel.GENERIC_READ | Kernel.GENERIC_WRITE,
0,
0,
Kernel.OPEN_EXISTING,
Kernel.FILE_ATTRIBUTE_NORMAL,
0
);
if(handle != Kernel.INVALID_HANDLE_VALUE)
{
return new FileBidirectStream(handle, fldCanonicalRootPath);
}
switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
{
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) { fileName = internalFullPath };
}
case Kernel.ERROR_WRITE_PROTECT:
{
throw new ReadOnlyFileSystemException(String.format(platform.independent.osservices.package.getResourceString("file-system.read-only"), new Object[] { fldCanonicalRootPath }));
}
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath }));
}
default:
{
if(Kernel.getLastStatus() != Kernel.STATUS_FILE_IS_A_DIRECTORY)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
throw new FileOpeningException(platform.independent.filesystem.package.getResourceString("file.opening")) { fileName = internalFullPath };
}
public Attributes newAttributes() { return new VolumeObjectAttributes(); }
public String currentDirectory { read = fldCurrentDirectory.replaceAll('\\', '/') }
private void tryMakeCurrentReliableBlock() {
CriticalSection operation = fldCurrentOperation;
operation.lock();
try
{
label0:
if(fldCurrentUnreliableBlock)
{
String internalFullPath = fldCurrentDirectory;
int length = internalFullPath.length;
if(length <= 1)
{
fldCurrentUnreliableBlock = false;
break label0;
}
internalFullPath = fldInternalRootPath + internalFullPath.substring(0, length - 1);
char[] zerotermFullPath = toZeroTerminatedArray(internalFullPath);
long zerotermFullPathPtr = zerotermFullPath.getPointer();
long newHandle = Kernel.createFile(
zerotermFullPathPtr,
/* Kernel.DELETE */ 0x00010000,
Kernel.FILE_SHARE_READ | Kernel.FILE_SHARE_WRITE,
0,
Kernel.OPEN_EXISTING,
Kernel.FILE_ATTRIBUTE_NORMAL | Kernel.FILE_FLAG_BACKUP_SEMANTICS,
0
);
if(newHandle != Kernel.INVALID_HANDLE_VALUE)
{
fldCurrentUnreliableBlock = false;
} else
{
newHandle = Kernel.createFile(
zerotermFullPathPtr,
0,
0,
0,
Kernel.OPEN_EXISTING,
Kernel.FILE_ATTRIBUTE_NORMAL | Kernel.FILE_FLAG_BACKUP_SEMANTICS,
0
);
}
long oldHandle = fldCurrentHandle;
if(oldHandle != Kernel.INVALID_HANDLE_VALUE) Kernel.closeHandle(oldHandle);
fldCurrentHandle = newHandle;
}
} finally
{
operation.unlock();
}
}
private String toVolumeFullPath(String objectName) {
String internalName = objectName.replaceAll('/', '\\');
return isInternalNameFull(internalName) ? internalName : fldCurrentDirectory + internalName;
}
private String makeInternalFullPathAndIsExist(String volumeFullPath) throws IOException {
String internalRootPath = fldInternalRootPath;
String internalFullPath = volumeFullPath;
int dotPosition = 0;
do
{
if((dotPosition = internalFullPath.indexOf("\\.\\", dotPosition)) < 0)
{
if(!internalFullPath.endsWith("\\.")) break;
dotPosition = internalFullPath.length - 2;
}
internalFullPath = internalFullPath.substring(0, dotPosition) + internalFullPath.substring(dotPosition + 2);
} while(true);
dotPosition = 0;
do
{
if((dotPosition = internalFullPath.indexOf("\\..\\", dotPosition)) < 0)
{
if(!internalFullPath.endsWith("\\..")) break;
dotPosition = internalFullPath.length - 3;
}
label0:
{
if(dotPosition > 0)
{
char[] zerotermFullPath = toZeroTerminatedArray(internalRootPath + internalFullPath.substring(0, dotPosition));
int attributes = Kernel.getFileAttributes(zerotermFullPath.getPointer());
if(attributes != Kernel.INVALID_FILE_ATTRIBUTES && (attributes & Kernel.FILE_ATTRIBUTE_DIRECTORY) != 0) break label0;
switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND: break;
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(
String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath })
);
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
return null;
}
int reductionPosition = internalFullPath.lastIndexOf('\\', dotPosition - 1);
internalFullPath = internalFullPath.substring(0, reductionPosition) + internalFullPath.substring(dotPosition + 3);
dotPosition = reductionPosition;
} while(true);
return internalRootPath + internalFullPath;
}
private String makeInternalFullPathAndCheckCreat(String volumeFullPath) throws IOException {
int position = volumeFullPath.lastIndexOf('\\') + 1;
String dirFullPath = makeInternalFullPathAndCheckExist(volumeFullPath.substring(0, position), AT_DIRECTORY);
String checkFullPath = dirFullPath + '.';
char[] zerotermFullPath = toZeroTerminatedArray(checkFullPath);
if(Kernel.getFileAttributes(zerotermFullPath.getPointer()) == Kernel.INVALID_FILE_ATTRIBUTES) switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
{
throw new DirectoryNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.directory")) { directoryName = checkFullPath };
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
return dirFullPath + volumeFullPath.substring(position);
}
private String makeInternalFullPathAndCheckExist(String volumeFullPath, int argumentType) throws IOException {
String internalRootPath = fldInternalRootPath;
String internalFullPath = volumeFullPath;
int dotPosition = 0;
do
{
if((dotPosition = internalFullPath.indexOf("\\.\\", dotPosition)) < 0)
{
if(!internalFullPath.endsWith("\\.")) break;
dotPosition = internalFullPath.length - 2;
}
internalFullPath = internalFullPath.substring(0, dotPosition) + internalFullPath.substring(dotPosition + 2);
} while(true);
dotPosition = 0;
do
{
if((dotPosition = internalFullPath.indexOf("\\..\\", dotPosition)) < 0)
{
if(!internalFullPath.endsWith("\\..")) break;
dotPosition = internalFullPath.length - 3;
}
label0:
{
if(dotPosition > 0)
{
char[] zerotermFullPath = toZeroTerminatedArray(internalRootPath + internalFullPath.substring(0, dotPosition));
int attributes = Kernel.getFileAttributes(zerotermFullPath.getPointer());
if(attributes != Kernel.INVALID_FILE_ATTRIBUTES && (attributes & Kernel.FILE_ATTRIBUTE_DIRECTORY) != 0) break label0;
switch(Kernel.getLastError())
{
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND: break;
case Kernel.ERROR_NOT_READY:
{
throw new FileSystemNotAttachedException(
String.format(platform.independent.osservices.package.getResourceString("file-system.not-attached"), new Object[] { fldCanonicalRootPath })
);
}
default:
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
switch(argumentType)
{
case AT_FILE:
{
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) { fileName = internalRootPath + internalFullPath };
}
case AT_DIRECTORY:
{
throw new DirectoryNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.directory")) { directoryName = internalRootPath + internalFullPath };
}
default:
{
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) { objectName = internalRootPath + internalFullPath };
}
}
}
int reductionPosition = internalFullPath.lastIndexOf('\\', dotPosition - 1);
internalFullPath = internalFullPath.substring(0, reductionPosition) + internalFullPath.substring(dotPosition + 3);
dotPosition = reductionPosition;
} while(true);
return internalRootPath + internalFullPath;
}
}
service VolumeRequiredAttributes(Object, RequiredAttributes)
{
public static final String B_HIDDEN = "bHidden";
public static final String B_SYSTEM = "bSystem";
public static final String B_ARCHIVE = "bArchive";
public static final String L_CREATION_TIME = "lCreationTime";
public static long toObjectTime(long internalTime) { return internalTime < 0 ? Long.MIN_VALUE : internalTime / 10000 + 0x2debe1767000L; }
public static long toInternalTime(long objectTime) { return objectTime < 0x2debe1767000L || objectTime > 0x000374c83ed9f865L ? Long.MIN_VALUE : (objectTime - 0x2debe1767000L) * 10000; }
}
final class VolumeObjectAttributes(Object, Attributes, RequiredAttributes, VolumeRequiredAttributes)
{
private static final long[] attrHashes;
private static final String[] attrIds;
private static {
attrIds = new String[] { B_READ_ONLY, B_HIDDEN, B_SYSTEM, null, B_DIRECTORY, B_ARCHIVE, null, null, L_CREATION_TIME, L_LAST_ACCESS_TIME, L_LAST_WRITE_TIME };
int index = attrIds.length;
attrHashes = new long[index];
while(index-- > 0) {
String attrId = attrIds[index];
if(attrId != null) attrHashes[index] = attrId.hashCodeAsLong();
}
}
private static void stringAttributeIdIsInvalid(String attrId) {
if(attrId == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "attrId" }));
}
if(attrId.isEmpty())
{
throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument"), new Object[] { "attrId" }));
}
if(attrId[0] == 's')
{
throw new IllegalArgumentException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.attribute-id"), new Object[] { attrId }));
}
throw new IllegalArgumentException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.attribute-type"), new Object[] { attrId }));
}
private static int booleanAttributeIdToIndex(String attrId) {
if(attrId == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "attrId" }));
}
if(attrId.isEmpty())
{
throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument"), new Object[] { "attrId" }));
}
int index = Array.indexOf(attrId.hashCodeAsLong(), attrHashes, 0, 8);
if(index >= 0 && attrId.equals(attrIds[index])) return index - 0;
if(attrId[0] == 'b')
{
throw new IllegalArgumentException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.attribute-id"), new Object[] { attrId }));
}
throw new IllegalArgumentException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.attribute-type"), new Object[] { attrId }));
}
private static int longAttributeIdToIndex(String attrId) {
if(attrId == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "attrId" }));
}
if(attrId.isEmpty())
{
throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument"), new Object[] { "attrId" }));
}
int index = Array.indexOf(attrId.hashCodeAsLong(), attrHashes, 8, 8);
if(index >= 0 && attrId.equals(attrIds[index])) return index - 8;
if(attrId[0] == 'l')
{
throw new IllegalArgumentException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.attribute-id"), new Object[] { attrId }));
}
throw new IllegalArgumentException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.attribute-type"), new Object[] { attrId }));
}
private int fldAttributes;
private final long[] fldTimes;
public () { fldTimes = new long[3]; }
public void setBooleanAttribute(String attrId, boolean newValue) {
int mask = 1 << booleanAttributeIdToIndex(attrId);
if(newValue)
{
fldAttributes |= mask;
return;
}
fldAttributes &= ~mask;
}
public void setLongAttribute(String attrId, long newValue) {
int index = longAttributeIdToIndex(attrId);
fldTimes[index] = newValue;
}
public void setStringAttribute(String attrId, String newValue) { stringAttributeIdIsInvalid(attrId); }
public boolean isSupportedAttributeId(String attrId) {
if(attrId == null || attrId.isEmpty()) return false;
int index = Array.indexOf(attrId.hashCodeAsLong(), attrHashes, 0, 0);
return index >= 0 && attrId.equals(attrIds[index]);
}
public boolean getBooleanAttribute(String attrId) {
int mask = 1 << booleanAttributeIdToIndex(attrId);
return (fldAttributes & mask) != 0;
}
public long getLongAttribute(String attrId) {
int index = longAttributeIdToIndex(attrId);
return fldTimes[index];
}
public String getStringAttribute(String attrId) {
stringAttributeIdIsInvalid(attrId);
return null; /* недостижимый код */
}
public String displayName(String attrId) {
if(attrId == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "attrId" }));
}
if(attrId.isEmpty())
{
throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument"), new Object[] { "attrId" }));
}
int index = Array.indexOf(attrId.hashCodeAsLong(), attrHashes, 0, 0);
if(index >= 0 && attrId.equals(attrIds[index])) switch(index)
{
case 0: return platform.independent.filesystem.package.getResourceString("display-name.object-attributes.read-only");
case 1: return package.getResourceString("display-name.object-attributes.hidden");
case 2: return package.getResourceString("display-name.object-attributes.system");
case 4: return platform.independent.filesystem.package.getResourceString("display-name.object-attributes.directory");
case 5: return package.getResourceString("display-name.object-attributes.archive");
case 8: return package.getResourceString("display-name.object-attributes.creation-time");
case 9: return platform.independent.filesystem.package.getResourceString("display-name.object-attributes.last-access-time");
case 10: return platform.independent.filesystem.package.getResourceString("display-name.object-attributes.last-write-time");
}
throw new IllegalArgumentException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.attribute-id"), new Object[] { attrId }));
}
public String[] getSupportedAttributeIds() { return new String[] { B_READ_ONLY, B_HIDDEN, B_SYSTEM, B_DIRECTORY, B_ARCHIVE, L_CREATION_TIME, L_LAST_ACCESS_TIME, L_LAST_WRITE_TIME }; }
}
final class VolumeObjectEnumeration(ObjectEnumeration, Closeable, Attributes, RequiredAttributes, VolumeRequiredAttributes)
{
private long fldHandle;
private final long fldPointer;
private final Win32FindData fldInfo;
private void setAttributes() {
Win32FindData info = fldInfo;
int oattr = info.dwFileAttributes;
char[] oname = info.cFileName;
int length = Array.indexOf(0, oname, 0, 0);
if(length < 0) length = oname.length;
name = new String(oname, 0, length);
size = (oattr & Kernel.FILE_ATTRIBUTE_DIRECTORY) != 0 ? 0 : ^^^^info.nFileSizeHigh | ####info.nFileSizeLow;
setBooleanAttribute(B_DIRECTORY, (oattr & Kernel.FILE_ATTRIBUTE_DIRECTORY) != 0);
setBooleanAttribute(B_READ_ONLY, (oattr & Kernel.FILE_ATTRIBUTE_READONLY) != 0);
setBooleanAttribute(B_ARCHIVE, (oattr & Kernel.FILE_ATTRIBUTE_ARCHIVE) != 0);
setBooleanAttribute(B_HIDDEN, (oattr & Kernel.FILE_ATTRIBUTE_HIDDEN) != 0);
setBooleanAttribute(B_SYSTEM, (oattr & Kernel.FILE_ATTRIBUTE_SYSTEM) != 0);
setLongAttribute(L_CREATION_TIME, toObjectTime(info.ftCreationTime));
setLongAttribute(L_LAST_WRITE_TIME, toObjectTime(info.ftLastWriteTime));
setLongAttribute(L_LAST_ACCESS_TIME, toObjectTime(info.ftLastAccessTime));
}
public (long handle, Win32FindData info): super(new VolumeObjectAttributes()) {
fldHandle = handle;
fldPointer = info.getPointer();
fldInfo = info;
setAttributes();
}
public void close() throws IOException {
long handle = fldHandle;
{
fldHandle = 0;
}
if(handle != 0 && !Kernel.findClose(handle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
public boolean findNext() throws ObjectEnumerationException, IOException {
if(Kernel.findNextFile(fldHandle, fldPointer))
{
setAttributes();
return true;
}
if(Kernel.getLastError() != Kernel.ERROR_NO_MORE_FILES)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
return false;
}
protected void beforeDestruction() {
long handle = fldHandle;
if(handle != 0) Kernel.findClose(handle);
}
}
class FileSeekExtension(Object, Extension, LimitedSizeExtension, SeekExtension)
{
long fldHandle;
public (long handle) { fldHandle = handle; }
public long available() throws IOException {
long handle = handleNeeded();
long size = Kernel.getFileSize(handle);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
long pos = Kernel.setFilePointer(handle, 0, Kernel.FILE_CURRENT);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
return size - pos;
}
public long seek(long offset, int from) throws IOException {
long handle = handleNeeded();
if(from < BEGIN || from > END)
{
throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument"), new Object[] { "from" }));
}
long size = Kernel.getFileSize(handle);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
long pos;
switch(from)
{
case BEGIN:
{
pos = offset;
break;
}
case END:
{
pos = offset + size;
break;
}
default:
{
long curr = Kernel.setFilePointer(handle, 0, Kernel.FILE_CURRENT);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
pos = offset + curr;
}
}
if(pos < 0) pos = 0;
if(pos > size) pos = size;
pos = Kernel.setFilePointer(handle, pos, Kernel.FILE_BEGIN);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
return pos;
}
public long position() throws IOException {
long handle = handleNeeded();
long result = Kernel.setFilePointer(handle, 0, Kernel.FILE_CURRENT);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
return result;
}
public long size() throws IOException {
long handle = handleNeeded();
long result = Kernel.getFileSize(handle);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
return result;
}
protected final long handleNeeded() throws ClosedFileException {
long handle = fldHandle;
if(handle == 0)
{
throw new ClosedFileException(platform.independent.filesystem.package.getResourceString("closed-file"));
}
return handle;
}
}
class FileInputStream(HandleInputStream, Closeable, Extension, MarkExtension)
{
long fldMarked;
private boolean fldOwned;
private FileSeekExtension fldSeekable;
public (long handle, FileSeekExtension seekable): super(handle) {
if(seekable == null)
{
seekable = new FileSeekExtension(handle);
fldOwned = true;
}
fldSeekable = seekable;
fldExtensions = new Extension[] { this, seekable };
}
public void close() throws IOException {
long handle = fldHandle;
{
fldHandle = 0;
if(fldOwned) fldSeekable.fldHandle = 0;
}
if(handle != 0 && !Kernel.closeHandle(handle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
public long skip(long bytesQuantity) throws IOException {
long handle = handleNeeded();
if(bytesQuantity <= 0) return 0;
long size = Kernel.getFileSize(handle);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
long opos = Kernel.setFilePointer(handle, 0, Kernel.FILE_CURRENT);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
long npos = size - opos;
if(bytesQuantity > npos) bytesQuantity = npos;
npos = Kernel.setFilePointer(handle, opos + bytesQuantity, Kernel.FILE_BEGIN);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
return npos - opos;
}
public void mark() throws IOException {
long handle = handleNeeded();
long pos = Kernel.setFilePointer(handle, 0, Kernel.FILE_CURRENT);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
fldMarked = pos;
}
public void reset() throws IOException {
long handle = handleNeeded();
Kernel.setFilePointer(handle, fldMarked, Kernel.FILE_BEGIN);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
protected void beforeDestruction() {
long handle = fldHandle;
if(handle != 0) Kernel.closeHandle(handle);
}
}
class FileOutputStream(HandleOutputStream, Closeable, Extension, MarkExtension, TruncateExtension)
{
private boolean fldOwned;
private long fldMarked;
private FileInputStream fldReader;
private FileSeekExtension fldSeekable;
public (long handle, char[] rootPath, FileSeekExtension seekable, FileInputStream reader): super(handle, rootPath) {
if(seekable == null)
{
seekable = new FileSeekExtension(handle);
fldOwned = true;
}
fldReader = reader;
fldSeekable = seekable;
fldExtensions = new Extension[] { this, seekable };
}
public void close() throws IOException {
long handle = fldHandle;
{
fldHandle = 0;
if(fldOwned) fldSeekable.fldHandle = 0;
}
if(handle != 0 && !Kernel.closeHandle(handle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
public void flush() throws IOException {
long handle = handleNeeded();
if(!Kernel.flushFileBuffers(handle))
{
if(Kernel.getLastError() == Kernel.ERROR_DISK_FULL)
{
throw new FileSystemFullException(String.format(platform.independent.osservices.package.getResourceString("file-system.full"), new Object[] { fldRootPath }));
}
throw new IOException(avt.io.package.getResourceString("io"));
}
}
public void mark() throws IOException {
long handle = handleNeeded();
long pos = Kernel.setFilePointer(handle, 0, Kernel.FILE_CURRENT);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
fldMarked = pos;
}
public void reset() throws IOException {
long handle = handleNeeded();
Kernel.setFilePointer(handle, fldMarked, Kernel.FILE_BEGIN);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
public void truncate() throws IOException {
long handle = handleNeeded();
if(!Kernel.setEndOfFile(handle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
long size = Kernel.setFilePointer(handle, 0, Kernel.FILE_CURRENT);
if(Kernel.getLastError() != Kernel.NO_ERROR)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
FileInputStream reader = fldReader;
if(fldMarked > size) fldMarked = size;
if(reader != null && reader.fldMarked > size) reader.fldMarked = size;
}
protected void beforeDestruction() {
long handle = fldHandle;
if(handle != 0) Kernel.closeHandle(handle);
}
}
class FileBidirectStream(HandleBidirectStream)
{
public (long handle, char[] rootPath): super(handle, handle) {
FileSeekExtension seekable = new FileSeekExtension(handle);
FileInputStream reader = new FileBidirectStreamReader(handle, seekable);
FileOutputStream writer = new FileBidirectStreamWriter(handle, rootPath, seekable, reader);
fldExtensions = new Extension[] { seekable };
fldReader = reader;
fldWriter = writer;
}
}
service FileBidirectStreamReader(FileInputStream)
{
public void close() { }
protected void beforeDestruction() { }
}
service FileBidirectStreamWriter(FileOutputStream)
{
public void close() { }
protected void beforeDestruction() { }
}
final class CurrentEnvironment(Environment)
{
private static native Mutex getOperation(Environment env);
private static native platform.dependent.EnvironmentTable getVariables(Environment env);
public () { update(); }
public void assign(Environment anot) {
if(anot == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "anot" }));
}
if(anot == this) return;
StringBuilder block = new StringBuilder();
platform.dependent.EnvironmentTable vars = getVariables(anot);
Mutex operation = getOperation(anot);
operation.lock();
try
{
for(int length = vars.length, int index = 0; index < length; index++)
{
String name = vars[index];
block.append(name).append('=').append(vars[name]).append('\0');
}
} finally
{
operation.unlock();
}
int length = block.append('\0').length;
char[] envChars = new char[length];
block.getChars(0, length, envChars, 0);
if(Kernel.setEnvironmentStrings(envChars.getPointer())) update();
}
public void operator []=(String envName, String newValue) {
if(envName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "envName" }));
}
if(envName.indexOf(0) >= 0 || envName.indexOf('=') >= 0)
{
throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument"), new Object[] { "envName" }));
}
if(newValue == null)
{
int length = envName.length;
char[] envChars = new char[length + 1];
envName.getChars(0, length, envChars, 0);
if(Kernel.setEnvironmentVariable(envChars.getPointer(), 0)) update();
return;
}
if(newValue.indexOf(0) >= 0)
{
throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument"), new Object[] { "newValue" }));
}
int nlength = envName.length + 1;
int vlength = newValue.length + 1;
char[] envChars = new char[nlength + vlength];
long envPtr = envChars.getPointer();
envName.getChars(0, nlength - 1, envChars, 0);
newValue.getChars(0, vlength - 1, envChars, nlength);
if(Kernel.setEnvironmentVariable(envPtr, envPtr + (nlength << 1))) update();
}
private void update() {
try
{
long2 envDs = Kernel.getEnvironmentStrings();
long envPtr = envDs[0];
try
{
int envLen = (int) envDs[1];
char[] envChars = (char[]) char[].class.newArrayAt(envPtr, envLen);
platform.dependent.EnvironmentTable vars = getVariables(this);
Mutex operation = getOperation(this);
operation.lock();
try
{
for(vars.clear(), int beginIndex = 0; beginIndex >= 0 && beginIndex < envLen; )
{
int endIndex = Array.indexOf(0, envChars, beginIndex, 0);
int eqIndex = Array.indexOf('=', envChars, beginIndex, endIndex - beginIndex);
String name = new String(envChars, beginIndex, eqIndex - beginIndex);
String value = new String(envChars, eqIndex + 1, endIndex - eqIndex - 1);
vars[name] = value;
beginIndex = endIndex + 1;
}
} finally
{
operation.unlock();
}
} finally
{
Kernel.freeEnvironmentStrings(envPtr);
}
} catch(Exception exception) { }
}
}