/*
Реализация среды исполнения языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package platform.dependent.mswindows.runtime;
import avt.io.*;
import avt.io.extension.*;
import avt.lang.array.*;
import platform.dependent.*;
import platform.dependent.mswindows.kernel.*;
import platform.independent.filesystem.*;
package service Constants(Object, RequiredAttributes)
{
public static final char INTERNAL_ANY_OBJECT = '*';
public static final char INTERNAL_DRIVE_SEPARATOR = ':';
public static final char INTERNAL_DIRECTORY_SEPARATOR = '\\';
public static final int MAX_PATH = 260;
public static final int MAX_ENV = 32767;
public static final int SEEKABLE = 0x00000001;
public static final int TRUNCATABLE = 0x00000002;
public static final int CLOSEABLE = 0x80000000;
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; }
}
package class CriticalSection(Object, Mutex)
{
private final long fldOperationPointer;
private final platform.dependent.mswindows.kernel.CriticalSection fldOperationObject;
public () { fldOperationPointer = (fldOperationObject = new platform.dependent.mswindows.kernel.CriticalSection()).getPointer(); }
public void lock() { Kernel.enterCriticalSection(fldOperationPointer); }
public void unlock() { Kernel.leaveCriticalSection(fldOperationPointer); }
public boolean isHold() { return fldOperationObject.owningThread != 0L; }
protected final void afterConstruction() { Kernel.initializeCriticalSection(fldOperationPointer); }
protected final void beforeDestruction() { Kernel.deleteCriticalSection(fldOperationPointer); }
}
package class Heap64(Object, Measureable, Long2Array)
{
public static final long BLOCK_SIZE = 1L << 8;
public static final long MIN_ALLOC_SIZE = 128L << 20;
public static final long MAX_ALLOC_SIZE = 128L << 30;
public static int getMemoryMapLength(long allocationSize) {
return (int) (allocationSize >> 8);
}
public static long getAllocationSize(long instanceSize) {
if(instanceSize < MIN_ALLOC_SIZE)
{
instanceSize = MIN_ALLOC_SIZE;
}
else if(instanceSize > MAX_ALLOC_SIZE)
{
instanceSize = MAX_ALLOC_SIZE;
}
return instanceSize + (-instanceSize & MIN_ALLOC_SIZE - 1);
}
private int fldAttributes;
private int fldHeapLength;
private int fldHeapCapacity;
private int fldInsertIndex;
private int4 fldInsertElement;
private long fldAllocationPointer;
private long fldAllocationSize;
private int4[] fldMemoryMap;
public () { }
public void initialize(long allocationPointer, int attributes, int4[] memoryMap) {
int capacity = memoryMap.capacity;
memoryMap.length = 0;
fldAttributes = attributes;
fldHeapLength = 0;
fldHeapCapacity = capacity;
fldAllocationPointer = allocationPointer;
fldAllocationSize = (long) capacity << 8;
fldMemoryMap = memoryMap;
}
public void allocateFinish() {
int index = fldInsertIndex;
int length = fldHeapLength;
int4[] map = fldMemoryMap;
if(index > 0)
{
map[--index] = (int2) map[index++];
}
map.length = ++length;
insert(index);
map[index] = fldInsertElement;
fldHeapLength = length;
}
public long allocateStart(long instanceSize) {
int blockLength = (int) (instanceSize + (-instanceSize & BLOCK_SIZE - 1) >> 8);
if(blockLength <= 0)
{
return 0;
}
int index = findFreeSpace(blockLength);
if(index < 0)
{
return 0;
}
int4[] map = fldMemoryMap;
int4 previous = 0;
if(index > 0)
{
previous = map[index - 1];
}
int blockOffset = previous[0] + previous[1];
fldInsertIndex = index;
fldInsertElement = new int4 { blockOffset, blockLength, (index >= fldHeapLength ? fldHeapCapacity : (int) map[index]) - blockOffset - blockLength, 0 };
return fldAllocationPointer + ((long) blockOffset << 8);
}
public long allocate(long instanceSize) {
int blockLength = (int) (instanceSize + (-instanceSize & BLOCK_SIZE - 1) >> 8);
if(blockLength <= 0)
{
return 0;
}
int index = findFreeSpace(blockLength);
if(index < 0)
{
return 0;
}
int4[] map = fldMemoryMap;
int2 previous = 0;
if(index > 0)
{
map[--index] = previous = (int2) map[index++];
}
int length = fldHeapLength;
int blockOffset = previous[0] + previous[1];
int4 element = new int4 { blockOffset, blockLength, (index >= length ? fldHeapCapacity : (int) map[index]) - blockOffset - blockLength, 0 };
map.length = ++length;
insert(index);
map[index] = element;
fldHeapLength = length;
return fldAllocationPointer + ((long) blockOffset << 8);
}
public long free(long instancePointer) {
if((instancePointer -= fldAllocationPointer) < 0 || instancePointer >= fldAllocationSize || (instancePointer & BLOCK_SIZE - 1) != 0)
{
return 0;
}
int index = indexOf((int) (instancePointer >> 8));
if(index < 0)
{
return 0;
}
int4[] map = fldMemoryMap;
int4 element = map[index];
int length = fldHeapLength;
int blockLength = element[1];
fldHeapLength = --length;
delete(index);
map[length] = 0;
map.length = length;
if(index > 0)
{
map[index - 1] += new int4 { 0, 0, blockLength + element[2], 0 };
}
return (long) blockLength << 8;
}
public long freeMemory() {
int index = fldHeapLength - 1;
return index < 0 ? fldAllocationSize : (long) fldMemoryMap[index][2] << 8;
}
public int length { read = fldHeapLength }
public int attributes { read = fldAttributes }
public long allocationPointer { read = fldAllocationPointer }
public long allocationSize { read = fldAllocationSize }
public long2 operator [](int index) { return fldAllocationPointer + ((long2) fldMemoryMap[index] << 8); }
private native void insert(int index);
private native void delete(int index);
private native int findFreeSpace(int length);
private native int indexOf(int offset);
}
package class Monitor(CriticalSection, platform.dependent.Monitor, platform.dependent.Waitable)
{
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 = (long) 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)
{
Event.getInstanceFor(currentId, Win32Runtime.getSecurityContext()).waitSignalled(0i);
}
}
public void unlock() {
boolean isNotOwnedBy = false;
long currentId = (long) 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 = (long) 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 {
boolean isWaiting = false;
boolean isNotOwnedBy = false;
boolean isInterrupted = false;
long currentId = (long) 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)
{
Event event = Event.getInstanceFor(currentId, Win32Runtime.getSecurityContext());
if(handler != null) handler.setWaitable(this);
event.waitSignalled(timeInMillis);
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(0i);
} 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) Event.getInstanceFor(entry[1], Win32Runtime.getSecurityContext()).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;
long4 entry;
int index;
label0:
{
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 Services(Object, ProcessEnvironment, FileSystem, TimeBase, ProcessEnvironmentVariables, Constants, RequiredAttributes)
{
private static final char SPACE = '\u0020';
private static final char QUOTE = '\u0022';
private static boolean isDriveLetter(char character) {
return character >= 'A' && character <= 'Z' || character >= 'a' && character <= 'z';
}
private static int getDaysCount(int year, int month) {
switch(month + 1)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31;
case 4:
case 6:
case 9:
case 11:
return 30;
case 2:
return ++year % (year % 100 == 0 ? 400 : 4) == 0 ? 29 : 28;
}
return 0;
}
private static int getReadOnlyPathLength(char[] internalNameChars) throws DirectoryNotFoundException, IOException {
if(!isDriveLetter(internalNameChars[0]) || internalNameChars[1] != INTERNAL_DRIVE_SEPARATOR || internalNameChars[2] != INTERNAL_DIRECTORY_SEPARATOR)
{
throw new IllegalObjectNameException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.illegal-syntax"));
}
char character = internalNameChars[3];
internalNameChars[3] = '\0';
try
{
switch(Kernel.getDriveType(internalNameChars.getPointer()))
{
case Kernel.DRIVE_NO_ROOT_DIR:
throw new DirectoryNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.directory")) {
directoryName = new String(internalNameChars, 0, 3)
};
case Kernel.DRIVE_UNKNOWN:
throw new IOException(avt.io.package.getResourceString("io"));
case Kernel.DRIVE_CDROM:
return 3;
default:
return 0;
}
} finally
{
internalNameChars[3] = character;
}
}
private static char[] toInternalNameChars(String objectName, String methodName) {
/* Преобразование полных стандартных имён объектов во внутренние по следующей схеме:
/ =>
/d: => D:\
/d:/ => D:\*
/d:/obj => D:\obj
/d:/dir/ => D:\dir\*
/d:/dir/obj => D:\dir\obj
*/
int nlength = objectName.length;
if(nlength > MAX_PATH - 1)
{
throw new ObjectNameTooLongException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"));
}
if(!objectName.startsWith("" + DIRECTORY_SEPARATOR))
{
throw new IllegalObjectNameException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.not-begins-with-separator"));
}
if(methodName != null && objectName.endsWith("" + DIRECTORY_SEPARATOR))
{
throw new IllegalObjectNameException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.ends-with-separator"),
new Object[] { methodName }
));
}
if((
objectName.indexOf('\0') & objectName.indexOf('<') & objectName.indexOf('>') &
objectName.indexOf('\"') & objectName.indexOf('?') & objectName.indexOf('|') &
objectName.indexOf(INTERNAL_ANY_OBJECT) &
objectName.indexOf(INTERNAL_DIRECTORY_SEPARATOR) &
objectName.indexOf(INTERNAL_DRIVE_SEPARATOR, 3)
) >= 0)
{
throw new IllegalObjectNameException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.illegal-characters"));
}
if(
nlength == 2 || objectName.indexOf("" + DIRECTORY_SEPARATOR + DIRECTORY_SEPARATOR) >= 0 ||
nlength >= 3 && (!isDriveLetter(objectName[1]) || objectName[2] != INTERNAL_DRIVE_SEPARATOR) ||
nlength >= 4 && (objectName[3] != DIRECTORY_SEPARATOR)
)
{
throw new IllegalObjectNameException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.illegal-syntax"));
}
int rlength = 0;
char[] result = new char[MAX_PATH];
for(int beginIndex = 0, int cindex = 0; beginIndex < nlength; )
{
int endIndex = objectName.indexOf(DIRECTORY_SEPARATOR, ++beginIndex);
if(endIndex < 0) endIndex = nlength;
int clength = endIndex - beginIndex;
String component = objectName.substring(beginIndex, endIndex);
if(component.equals(".") || component.equals(".."))
{
throw new IllegalObjectNameException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.illegal-syntax"));
}
if(cindex > 0 && clength <= 0)
{
clength = (component = "" + INTERNAL_ANY_OBJECT).length;
}
if(cindex > 1)
{
result[rlength++] = INTERNAL_DIRECTORY_SEPARATOR;
}
component.getChars(0, clength, result, rlength);
if(cindex < 1 && clength == 2)
{
result[rlength] = Char.toUpperCase(result[rlength]);
rlength += clength;
result[rlength++] = INTERNAL_DIRECTORY_SEPARATOR;
} else
{
rlength += clength;
}
beginIndex = endIndex;
cindex++;
}
return result;
}
private static String[] newArguments() {
try
{
long2 descriptor = Kernel.getCommandLine();
char[] commandLineChars = (char[]) char[].class.newArrayAt((long) descriptor, (int) descriptor[1]);
int commandLineLength = commandLineChars.length;
int length = 0;
for(boolean quote = false, char prev = SPACE, int pos = 0; pos < commandLineLength; pos++)
{
char curr = commandLineChars[pos];
if(curr == QUOTE)
{
quote = !quote;
}
else if(!quote && prev != SPACE && curr == SPACE)
{
length++;
}
if(commandLineLength - pos == 1 && curr != SPACE)
{
length++;
}
prev = curr;
}
String[] result = new String[length];
for(boolean quote = false, char prev = SPACE, StringBuilder argument = new StringBuilder(commandLineLength), int pos = length = 0; pos < commandLineLength; pos++)
{
char curr = commandLineChars[pos];
if(curr == QUOTE)
{
quote = !quote;
}
else if(quote || curr != SPACE)
{
argument + curr;
}
else if(prev != SPACE)
{
result[length++] = argument.toString();
argument.clear();
}
if(commandLineLength - pos == 1 && curr != SPACE)
{
result[length++] = argument.toString();
}
prev = curr;
}
if(length > 0)
{
char[] moduleNameChars = new char[MAX_PATH];
int moduleNameLength = Kernel.getModuleFileName(0, moduleNameChars.getPointer(), MAX_PATH);
result[0] = new String(moduleNameChars, 0, moduleNameLength);
}
result.finalize();
return result;
}
catch(Exception exception)
{
throw exception instanceof RuntimeException ? (RuntimeException) exception : new RuntimeException(exception.message, exception);
}
}
private final String[] fldArguments;
private final Win32FindData fldDummyFindData;
private final ByteReader fldStandardInput;
private final ByteWriter fldStandardError;
private final ByteWriter fldStandardOutput;
private final String fldConsoleInputCharsetName;
private final String fldConsoleOutputCharsetName;
public () {
fldArguments = newArguments();
fldDummyFindData = new Win32FindData();
fldStandardInput = new FileInputStream(Kernel.getStdHandle(Kernel.STD_INPUT));
fldStandardError = new FileOutputStream(Kernel.getStdHandle(Kernel.STD_ERROR));
fldStandardOutput = new FileOutputStream(Kernel.getStdHandle(Kernel.STD_OUTPUT));
fldConsoleInputCharsetName = ("CP" + Int.toString(Kernel.getConsoleInputCP())).intern();
fldConsoleOutputCharsetName = ("CP" + Int.toString(Kernel.getConsoleOutputCP())).intern();
}
public void setCurrentDirectory(String directoryName) throws DirectoryNotFoundException, DirectoryOperationException, IOException {
if(directoryName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "directoryName" }));
}
char[] internalNameChars = toInternalNameChars(directoryName, "setCurrentDirectory");
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(!Kernel.setCurrentDirectory(internalNameChars.getPointer())) switch(Kernel.getLastError())
{
default:
if(Kernel.getLastStatus() != Kernel.STATUS_NOT_A_DIRECTORY)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
throw new DirectoryOperationException(platform.dependent.package.getResourceString("current-directory.set")) {
directoryName = new String(internalNameChars, 0, internalNameLength)
};
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new DirectoryNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.directory")) {
directoryName = new String(internalNameChars, 0, internalNameLength)
};
}
}
public void readAttributes(String objectName, ObjectAttributes objectAttr) throws ObjectNotFoundException, IOException {
if(objectName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectName" }));
}
char[] internalNameChars = toInternalNameChars(objectName, "readAttributes");
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(internalNameLength <= 3)
{
if((long) Kernel.getDiskFreeSpaceEx(internalNameChars.getPointer()) == 0)
{
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) {
objectName = new String(internalNameChars, 0, internalNameLength)
};
}
if(objectAttr != null)
{
if(objectAttr.isSupportedAttributeId(B_DIRECTORY)) objectAttr.setBooleanAttribute(B_DIRECTORY, true);
if(objectAttr.isSupportedAttributeId(B_READ_ONLY)) objectAttr.setBooleanAttribute(B_READ_ONLY, false);
if(objectAttr.isSupportedAttributeId(B_ARCHIVE)) objectAttr.setBooleanAttribute(B_ARCHIVE, true);
if(objectAttr.isSupportedAttributeId(B_HIDDEN)) objectAttr.setBooleanAttribute(B_HIDDEN, false);
if(objectAttr.isSupportedAttributeId(B_SYSTEM)) objectAttr.setBooleanAttribute(B_SYSTEM, true);
if(objectAttr.isSupportedAttributeId(L_LAST_ACCESS_TIME)) objectAttr.setLongAttribute(L_LAST_ACCESS_TIME, Long.MIN_VALUE);
if(objectAttr.isSupportedAttributeId(L_LAST_WRITE_TIME)) objectAttr.setLongAttribute(L_LAST_WRITE_TIME, Long.MIN_VALUE);
if(objectAttr.isSupportedAttributeId(L_CREATION_TIME)) objectAttr.setLongAttribute(L_CREATION_TIME, Long.MIN_VALUE);
}
} else
{
Win32FindData internalFindData = new Win32FindData();
long findHandle = Kernel.findFirstFile(internalNameChars.getPointer(), internalFindData.getPointer());
if(findHandle == Kernel.INVALID_HANDLE_VALUE) switch(Kernel.getLastError())
{
default:
throw new IOException(avt.io.package.getResourceString("io"));
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) {
objectName = new String(internalNameChars, 0, internalNameLength)
};
}
if(!Kernel.findClose(findHandle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
if(objectAttr != null)
{
int attributes = internalFindData.dwFileAttributes;
if(objectAttr.isSupportedAttributeId(B_DIRECTORY)) objectAttr.setBooleanAttribute(B_DIRECTORY, (attributes & Kernel.FILE_ATTRIBUTE_DIRECTORY) != 0);
if(objectAttr.isSupportedAttributeId(B_READ_ONLY)) objectAttr.setBooleanAttribute(B_READ_ONLY, (attributes & Kernel.FILE_ATTRIBUTE_READONLY) != 0);
if(objectAttr.isSupportedAttributeId(B_ARCHIVE)) objectAttr.setBooleanAttribute(B_ARCHIVE, (attributes & Kernel.FILE_ATTRIBUTE_ARCHIVE) != 0);
if(objectAttr.isSupportedAttributeId(B_HIDDEN)) objectAttr.setBooleanAttribute(B_HIDDEN, (attributes & Kernel.FILE_ATTRIBUTE_HIDDEN) != 0);
if(objectAttr.isSupportedAttributeId(B_SYSTEM)) objectAttr.setBooleanAttribute(B_SYSTEM, (attributes & Kernel.FILE_ATTRIBUTE_SYSTEM) != 0);
if(objectAttr.isSupportedAttributeId(L_LAST_ACCESS_TIME)) objectAttr.setLongAttribute(L_LAST_ACCESS_TIME, toObjectTime(internalFindData.ftLastAccessTime));
if(objectAttr.isSupportedAttributeId(L_LAST_WRITE_TIME)) objectAttr.setLongAttribute(L_LAST_WRITE_TIME, toObjectTime(internalFindData.ftLastWriteTime));
if(objectAttr.isSupportedAttributeId(L_CREATION_TIME)) objectAttr.setLongAttribute(L_CREATION_TIME, toObjectTime(internalFindData.ftCreationTime));
}
}
}
public void writeAttributes(String objectName, ObjectAttributes objectAttr) throws ReadOnlyFileSystemException, ObjectNotFoundException, ObjectWriteAttributesException, IOException {
if(objectName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectName" }));
}
if(objectAttr == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectAttr" }));
}
char[] internalNameChars = toInternalNameChars(objectName, "writeAttributes");
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(internalNameLength <= 3)
{
if((long) Kernel.getDiskFreeSpaceEx(internalNameChars.getPointer()) == 0)
{
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) {
objectName = new String(internalNameChars, 0, internalNameLength)
};
}
throw new ObjectWriteAttributesException(platform.independent.filesystem.package.getResourceString("object.write-attributes")) {
objectName = new String(internalNameChars, 0, internalNameLength)
};
}
{
int internalNameReadOnlyLength = getReadOnlyPathLength(internalNameChars);
if(internalNameReadOnlyLength > 0)
{
throw new ReadOnlyFileSystemException(platform.independent.filesystem.package.getResourceString("file-system.read-only")) {
directoryName = new String(internalNameChars, 0, internalNameReadOnlyLength)
};
}
long internalNamePointer = internalNameChars.getPointer();
int attributes = Kernel.getFileAttributes(internalNamePointer);
if(attributes == Kernel.INVALID_FILE_ATTRIBUTES) switch(Kernel.getLastError())
{
default:
throw new IOException(avt.io.package.getResourceString("io"));
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) {
objectName = new String(internalNameChars, 0, internalNameLength)
};
}
long fileHandle = Kernel.createFile(internalNamePointer, Kernel.GENERIC_WRITE, 0, 0, Kernel.OPEN_EXISTING, attributes | Kernel.FILE_FLAG_BACKUP_SEMANTICS, 0);
if(fileHandle == Kernel.INVALID_HANDLE_VALUE) switch(Kernel.getLastError())
{
default:
throw new ObjectWriteAttributesException(platform.independent.filesystem.package.getResourceString("object.write-attributes")) {
objectName = new String(internalNameChars, 0, internalNameLength)
};
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) {
objectName = new String(internalNameChars, 0, internalNameLength)
};
}
try
{
FileTime creationTime = new FileTime() { ftFileTime = Long.MIN_VALUE };
FileTime lastWriteTime = new FileTime() { ftFileTime = Long.MIN_VALUE };
FileTime lastAccessTime = new FileTime() { ftFileTime = Long.MIN_VALUE };
if(objectAttr.isSupportedAttributeId(L_CREATION_TIME)) creationTime.ftFileTime = toInternalTime(objectAttr.getLongAttribute(L_CREATION_TIME));
if(objectAttr.isSupportedAttributeId(L_LAST_WRITE_TIME)) lastWriteTime.ftFileTime = toInternalTime(objectAttr.getLongAttribute(L_LAST_WRITE_TIME));
if(objectAttr.isSupportedAttributeId(L_LAST_ACCESS_TIME)) lastAccessTime.ftFileTime = toInternalTime(objectAttr.getLongAttribute(L_LAST_ACCESS_TIME));
if(!Kernel.setFileTime(fileHandle, creationTime.getPointer(), lastAccessTime.getPointer(), lastWriteTime.getPointer()))
{
throw new ObjectWriteAttributesException(platform.independent.filesystem.package.getResourceString("object.write-attributes")) {
objectName = new String(internalNameChars, 0, internalNameLength)
};
}
} finally
{
if(!Kernel.closeHandle(fileHandle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
attributes &= ~(Kernel.FILE_ATTRIBUTE_READONLY | Kernel.FILE_ATTRIBUTE_HIDDEN | Kernel.FILE_ATTRIBUTE_SYSTEM | Kernel.FILE_ATTRIBUTE_ARCHIVE);
if(objectAttr.isSupportedAttributeId(B_READ_ONLY) && objectAttr.getBooleanAttribute(B_READ_ONLY)) attributes |= Kernel.FILE_ATTRIBUTE_READONLY;
if(objectAttr.isSupportedAttributeId(B_HIDDEN) && objectAttr.getBooleanAttribute(B_HIDDEN)) attributes |= Kernel.FILE_ATTRIBUTE_HIDDEN;
if(objectAttr.isSupportedAttributeId(B_SYSTEM) && objectAttr.getBooleanAttribute(B_SYSTEM)) attributes |= Kernel.FILE_ATTRIBUTE_SYSTEM;
if(objectAttr.isSupportedAttributeId(B_ARCHIVE) && objectAttr.getBooleanAttribute(B_ARCHIVE)) attributes |= Kernel.FILE_ATTRIBUTE_ARCHIVE;
if(!Kernel.setFileAttributes(internalNamePointer, attributes))
{
throw new ObjectWriteAttributesException(platform.independent.filesystem.package.getResourceString("object.write-attributes")) {
objectName = new String(internalNameChars, 0, internalNameLength)
};
}
}
}
public void move(String objectOldName, String objectNewName) throws ReadOnlyFileSystemException, ObjectNotFoundException, MoveOperationException, IOException {
if(objectOldName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectOldName" }));
}
if(objectNewName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectNewName" }));
}
char[] internalOldNameChars = toInternalNameChars(objectOldName, "move");
char[] internalNewNameChars = toInternalNameChars(objectNewName, "move");
int internalOldNameLength = Array.indexOf(0, internalOldNameChars, 0, 0);
int internalNewNameLength = Array.indexOf(0, internalNewNameChars, 0, 0);
if(internalOldNameLength <= 3)
{
if((long) Kernel.getDiskFreeSpaceEx(internalOldNameChars.getPointer()) == 0)
{
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) {
objectName = new String(internalOldNameChars, 0, internalOldNameLength)
};
}
throw new MoveOperationException(platform.independent.filesystem.package.getResourceString("move-operation")) {
objectOldName = new String(internalOldNameChars, 0, internalOldNameLength),
objectNewName = new String(internalNewNameChars, 0, internalNewNameLength)
};
}
if(internalNewNameLength <= 3)
{
throw new MoveOperationException(platform.independent.filesystem.package.getResourceString("move-operation")) {
objectOldName = new String(internalOldNameChars, 0, internalOldNameLength),
objectNewName = new String(internalNewNameChars, 0, internalNewNameLength)
};
}
{
int internalOldNameReadOnlyLength = getReadOnlyPathLength(internalOldNameChars);
if(internalOldNameReadOnlyLength > 0)
{
throw new ReadOnlyFileSystemException(platform.independent.filesystem.package.getResourceString("file-system.read-only")) {
directoryName = new String(internalOldNameChars, 0, internalOldNameReadOnlyLength)
};
}
int internalNewNameReadOnlyLength = getReadOnlyPathLength(internalNewNameChars);
if(internalNewNameReadOnlyLength > 0)
{
throw new ReadOnlyFileSystemException(platform.independent.filesystem.package.getResourceString("file-system.read-only")) {
directoryName = new String(internalNewNameChars, 0, internalNewNameReadOnlyLength)
};
}
if(!Kernel.moveFile(internalOldNameChars.getPointer(), internalNewNameChars.getPointer())) switch(Kernel.getLastError())
{
default:
throw new IOException(avt.io.package.getResourceString("io"));
case Kernel.ERROR_FILE_EXISTS:
case Kernel.ERROR_ALREADY_EXISTS:
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new MoveOperationException(platform.independent.filesystem.package.getResourceString("move-operation")) {
objectOldName = new String(internalOldNameChars, 0, internalOldNameLength),
objectNewName = new String(internalNewNameChars, 0, internalNewNameLength)
};
}
}
}
public void deleteFile(String fileName) throws ReadOnlyFileSystemException, FileNotFoundException, FileDeletionException, IOException {
if(fileName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "fileName" }));
}
char[] internalNameChars = toInternalNameChars(fileName, "deleteFile");
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(internalNameLength <= 3)
{
if((long) Kernel.getDiskFreeSpaceEx(internalNameChars.getPointer()) == 0)
{
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
throw new FileDeletionException(platform.independent.filesystem.package.getResourceString("file.deletion")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
{
int internalNameReadOnlyLength = getReadOnlyPathLength(internalNameChars);
if(internalNameReadOnlyLength > 0)
{
throw new ReadOnlyFileSystemException(platform.independent.filesystem.package.getResourceString("file-system.read-only")) {
directoryName = new String(internalNameChars, 0, internalNameReadOnlyLength)
};
}
if(!Kernel.deleteFile(internalNameChars.getPointer())) switch(Kernel.getLastError())
{
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 = new String(internalNameChars, 0, internalNameLength)
};
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
}
}
public void deleteDirectory(String directoryName) throws ReadOnlyFileSystemException, DirectoryNotFoundException, DirectoryDeletionException, IOException {
if(directoryName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "directoryName" }));
}
char[] internalNameChars = toInternalNameChars(directoryName, "deleteDirectory");
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(internalNameLength <= 3)
{
if((long) Kernel.getDiskFreeSpaceEx(internalNameChars.getPointer()) == 0)
{
throw new DirectoryNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.directory")) {
directoryName = new String(internalNameChars, 0, internalNameLength)
};
}
throw new DirectoryDeletionException(platform.independent.filesystem.package.getResourceString("directory.deletion")) {
directoryName = new String(internalNameChars, 0, internalNameLength)
};
}
{
int internalNameReadOnlyLength = getReadOnlyPathLength(internalNameChars);
if(internalNameReadOnlyLength > 0)
{
throw new ReadOnlyFileSystemException(platform.independent.filesystem.package.getResourceString("file-system.read-only")) {
directoryName = new String(internalNameChars, 0, internalNameReadOnlyLength)
};
}
if(!Kernel.removeDirectory(internalNameChars.getPointer())) switch(Kernel.getLastError())
{
default:
if(Kernel.getLastStatus() != Kernel.STATUS_NOT_A_DIRECTORY)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
/* падение через */
case Kernel.ERROR_DIR_NOT_EMPTY:
throw new DirectoryDeletionException(platform.independent.filesystem.package.getResourceString("directory.deletion")) {
directoryName = new String(internalNameChars, 0, internalNameLength)
};
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new DirectoryNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.directory")) {
directoryName = new String(internalNameChars, 0, internalNameLength)
};
}
}
}
public void createDirectory(String directoryName) throws ReadOnlyFileSystemException, DirectoryCreationException, IOException {
if(directoryName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "directoryName" }));
}
char[] internalNameChars = toInternalNameChars(directoryName, "createDirectory");
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(internalNameLength <= 3)
{
throw new DirectoryCreationException(platform.independent.filesystem.package.getResourceString("directory.creation")) {
directoryName = new String(internalNameChars, 0, internalNameLength)
};
}
{
int internalNameReadOnlyLength = getReadOnlyPathLength(internalNameChars);
if(internalNameReadOnlyLength > 0)
{
throw new ReadOnlyFileSystemException(platform.independent.filesystem.package.getResourceString("file-system.read-only")) {
directoryName = new String(internalNameChars, 0, internalNameReadOnlyLength)
};
}
if(!Kernel.createDirectory(internalNameChars.getPointer(), 0)) switch(Kernel.getLastError())
{
default:
throw new IOException(avt.io.package.getResourceString("io"));
case Kernel.ERROR_FILE_EXISTS:
case Kernel.ERROR_ALREADY_EXISTS:
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new DirectoryCreationException(platform.independent.filesystem.package.getResourceString("directory.creation")) {
directoryName = new String(internalNameChars, 0, internalNameLength)
};
}
}
}
public boolean isObjectExists(String objectName) throws IOException {
if(objectName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectName" }));
}
char[] internalNameChars = toInternalNameChars(objectName, "isObjectExists");
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(internalNameLength <= 3)
{
return (long) Kernel.getDiskFreeSpaceEx(internalNameChars.getPointer()) != 0;
}
{
int attributes = Kernel.getFileAttributes(internalNameChars.getPointer());
if(attributes == Kernel.INVALID_FILE_ATTRIBUTES) switch(Kernel.getLastError())
{
default:
throw new IOException(avt.io.package.getResourceString("io"));
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
return false;
}
}
return true;
}
public boolean isObjectNameCaseSensitive() throws DirectoryNotFoundException, IOException {
return false;
}
public boolean isObjectNameCaseSensitive(String objectPath) throws DirectoryNotFoundException, IOException {
if(objectPath == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectPath" }));
}
char[] internalPathChars = toInternalNameChars(objectPath.substring(0, objectPath.lastIndexOf(DIRECTORY_SEPARATOR) + 1), null);
int internalPathLength = Array.indexOf(0, internalPathChars, 0, 0);
if(internalPathLength <= 3)
{
return false;
}
{
long findHandle = Kernel.findFirstFile(internalPathChars.getPointer(), fldDummyFindData.getPointer());
if(findHandle == Kernel.INVALID_HANDLE_VALUE) switch(Kernel.getLastError())
{
default:
throw new IOException(avt.io.package.getResourceString("io"));
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new DirectoryNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.directory")) {
directoryName = new String(internalPathChars, 0, internalPathLength - (internalPathLength <= 4 ? 1 : 2))
};
}
if(!Kernel.findClose(findHandle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
return false;
}
public boolean isReadOnly() throws DirectoryNotFoundException, IOException {
return false;
}
public boolean isReadOnly(String objectPath) throws DirectoryNotFoundException, IOException {
if(objectPath == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectPath" }));
}
char[] internalPathChars = toInternalNameChars(objectPath.substring(0, objectPath.lastIndexOf(DIRECTORY_SEPARATOR) + 1), null);
int internalPathLength = Array.indexOf(0, internalPathChars, 0, 0);
if(internalPathLength <= 3)
{
return false;
}
{
long findHandle = Kernel.findFirstFile(internalPathChars.getPointer(), fldDummyFindData.getPointer());
if(findHandle == Kernel.INVALID_HANDLE_VALUE) switch(Kernel.getLastError())
{
default:
throw new IOException(avt.io.package.getResourceString("io"));
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new DirectoryNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.directory")) {
directoryName = new String(internalPathChars, 0, internalPathLength - (internalPathLength <= 4 ? 1 : 2))
};
}
if(!Kernel.findClose(findHandle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
return getReadOnlyPathLength(internalPathChars) > 0;
}
public boolean isInternalNameFull(String internalName) {
if(internalName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "internalName" }));
}
int nlength = internalName.length;
return nlength <= 0 || nlength >= 3 && isDriveLetter(internalName[0]) && internalName[1] == INTERNAL_DRIVE_SEPARATOR && internalName[2] == INTERNAL_DIRECTORY_SEPARATOR;
}
public boolean isInternalNameValid(String internalName) {
if(internalName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "internalName" }));
}
int nlength = internalName.length;
if(nlength <= 0) return true;
if(nlength > MAX_PATH - 1) return false;
int beginIndex = nlength >= 3 && isDriveLetter(internalName[0]) && internalName[1] == INTERNAL_DRIVE_SEPARATOR && internalName[2] == INTERNAL_DIRECTORY_SEPARATOR ? 3 : 0;
int apos = internalName.indexOf(INTERNAL_ANY_OBJECT);
if(
(
internalName.indexOf('\0') & internalName.indexOf('<') & internalName.indexOf('>') &
internalName.indexOf('\"') & internalName.indexOf('?') & internalName.indexOf('|') &
internalName.indexOf(DIRECTORY_SEPARATOR) &
internalName.indexOf(INTERNAL_DRIVE_SEPARATOR, beginIndex)
) >= 0 || apos >= 0 && apos < nlength - 1 ||
internalName.indexOf("" + INTERNAL_DIRECTORY_SEPARATOR + INTERNAL_DIRECTORY_SEPARATOR) >= 0 ||
nlength > beginIndex && internalName[nlength - 1] == INTERNAL_DIRECTORY_SEPARATOR ||
apos > 0 && internalName[apos - 1] != INTERNAL_DIRECTORY_SEPARATOR
) return false;
for(beginIndex--; beginIndex < nlength; )
{
int endIndex = internalName.indexOf(INTERNAL_DIRECTORY_SEPARATOR, ++beginIndex);
if(endIndex < 0) endIndex = nlength;
String component = internalName.substring(beginIndex, endIndex);
if(component.equals(".") || component.equals("..")) return false;
beginIndex = endIndex;
}
return true;
}
public boolean isObjectNameValid(String objectName) {
if(objectName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectName" }));
}
int nlength = objectName.length;
if(nlength > MAX_PATH - 1) return false;
int beginIndex = 0;
if(objectName.startsWith("" + DIRECTORY_SEPARATOR))
{
if(nlength < 2) return true;
if(nlength < 3 || !isDriveLetter(objectName[1]) || objectName[2] != INTERNAL_DRIVE_SEPARATOR || nlength > 3 && objectName[3] != DIRECTORY_SEPARATOR) return false;
beginIndex = 4;
}
if(
(
objectName.indexOf('\0') & objectName.indexOf('<') & objectName.indexOf('>') &
objectName.indexOf('\"') & objectName.indexOf('?') & objectName.indexOf('|') &
objectName.indexOf(INTERNAL_ANY_OBJECT) &
objectName.indexOf(INTERNAL_DIRECTORY_SEPARATOR) &
objectName.indexOf(INTERNAL_DRIVE_SEPARATOR, beginIndex)
) >= 0 ||
objectName.indexOf("" + DIRECTORY_SEPARATOR + DIRECTORY_SEPARATOR) >= 0
) return false;
for(beginIndex--; beginIndex < nlength; )
{
int endIndex = objectName.indexOf(DIRECTORY_SEPARATOR, ++beginIndex);
if(endIndex < 0) endIndex = nlength;
String component = objectName.substring(beginIndex, endIndex);
if(component.equals(".") || component.equals("..")) return false;
beginIndex = endIndex;
}
return true;
}
public int getObjectNameMaximumLength() {
return MAX_PATH - 1;
}
public String toInternalName(String objectName) {
if(objectName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectName" }));
}
/* Преобразование полных и неполных стандартных имён объектов во внутренние по следующей схеме:
/ =>
/d: => D:\
/d:/ => D:\*
/d:/obj => D:\obj
/d:/dir/ => D:\dir\*
/d:/dir/obj => D:\dir\obj
=> *
obj => obj
dir/ => dir\*
dir/obj => dir\obj
*/
int nlength = objectName.length;
if(nlength > MAX_PATH - 1)
{
throw new ObjectNameTooLongException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"));
}
int beginIndex = 0;
int rlength = 0;
char[] result = new char[MAX_PATH];
if(objectName.startsWith("" + DIRECTORY_SEPARATOR))
{
if(nlength < 2)
{
return "";
}
char letter = objectName[1];
if(nlength < 3 || !isDriveLetter(letter) || objectName[2] != INTERNAL_DRIVE_SEPARATOR || nlength > 3 && objectName[3] != DIRECTORY_SEPARATOR)
{
throw new IllegalObjectNameException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.illegal-syntax"));
}
result[0] = Char.toUpperCase(letter);
result[1] = INTERNAL_DRIVE_SEPARATOR;
result[2] = INTERNAL_DIRECTORY_SEPARATOR;
rlength = 3;
beginIndex = 4;
}
if((
objectName.indexOf('\0') & objectName.indexOf('<') & objectName.indexOf('>') &
objectName.indexOf('\"') & objectName.indexOf('?') & objectName.indexOf('|') &
objectName.indexOf(INTERNAL_ANY_OBJECT) &
objectName.indexOf(INTERNAL_DIRECTORY_SEPARATOR) &
objectName.indexOf(INTERNAL_DRIVE_SEPARATOR, beginIndex)
) >= 0)
{
throw new IllegalObjectNameException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.illegal-characters"));
}
if(objectName.indexOf("" + DIRECTORY_SEPARATOR + DIRECTORY_SEPARATOR) >= 0)
{
throw new IllegalObjectNameException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.illegal-syntax"));
}
for(beginIndex--; beginIndex < nlength; )
{
int endIndex = objectName.indexOf(DIRECTORY_SEPARATOR, ++beginIndex);
if(endIndex < 0) endIndex = nlength;
int clength = endIndex - beginIndex;
String component = objectName.substring(beginIndex, endIndex);
if(component.equals(".") || component.equals(".."))
{
throw new IllegalObjectNameException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.illegal-syntax"));
}
if(clength <= 0)
{
clength = (component = "" + INTERNAL_ANY_OBJECT).length;
}
component.getChars(0, clength, result, rlength);
rlength += clength;
if(endIndex < nlength)
{
result[rlength++] = INTERNAL_DIRECTORY_SEPARATOR;
}
beginIndex = endIndex;
}
return new String(result, 0, rlength);
}
public String toObjectName(String internalName) {
if(internalName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "internalName" }));
}
/* Преобразование полных и неполных внутренних имён объектов в стандартные по следующей схеме:
=> /
D:\ => /D:
D:\* => /D:/
D:\obj => /D:/obj
D:\dir\* => /D:/dir/
D:\dir\obj => /D:/dir/obj
* =>
obj => obj
dir\* => dir/
dir\obj => dir/obj
*/
int nlength = internalName.length;
if(nlength <= 0)
{
return "" + DIRECTORY_SEPARATOR;
}
if(nlength > MAX_PATH - 1)
{
throw new ObjectNameTooLongException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.too-long"));
}
char letter = internalName[0];
int beginIndex = 0;
int rlength = 0;
char[] result = new char[MAX_PATH];
if(nlength >= 3 && isDriveLetter(letter) && internalName[1] == INTERNAL_DRIVE_SEPARATOR && internalName[2] == INTERNAL_DIRECTORY_SEPARATOR)
{
result[0] = DIRECTORY_SEPARATOR;
result[1] = Char.toUpperCase(letter);
result[2] = INTERNAL_DRIVE_SEPARATOR;
rlength = 3;
if(nlength > 3) result[rlength++] = DIRECTORY_SEPARATOR;
beginIndex = 3;
}
int apos = internalName.indexOf(INTERNAL_ANY_OBJECT);
if((
internalName.indexOf('\0') & internalName.indexOf('<') & internalName.indexOf('>') &
internalName.indexOf('\"') & internalName.indexOf('?') & internalName.indexOf('|') &
internalName.indexOf(DIRECTORY_SEPARATOR) &
internalName.indexOf(INTERNAL_DRIVE_SEPARATOR, beginIndex)
) >= 0 || apos >= 0 && apos < nlength - 1)
{
throw new IllegalObjectNameException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.illegal-characters"));
}
if(
internalName.indexOf("" + INTERNAL_DIRECTORY_SEPARATOR + INTERNAL_DIRECTORY_SEPARATOR) >= 0 ||
nlength > beginIndex && internalName[nlength - 1] == INTERNAL_DIRECTORY_SEPARATOR ||
apos > 0 && internalName[apos - 1] != INTERNAL_DIRECTORY_SEPARATOR
)
{
throw new IllegalObjectNameException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.illegal-syntax"));
}
for(beginIndex--; beginIndex < nlength; )
{
int endIndex = internalName.indexOf(INTERNAL_DIRECTORY_SEPARATOR, ++beginIndex);
if(endIndex < 0) endIndex = nlength;
int clength = endIndex - beginIndex;
String component = internalName.substring(beginIndex, endIndex);
if(component.equals(".") || component.equals(".."))
{
throw new IllegalObjectNameException(platform.independent.filesystem.package.getResourceString("illegal-argument.object-name.illegal-syntax"));
}
if(clength == 1 && component[0] == INTERNAL_ANY_OBJECT)
{
clength = (component = "").length;
}
component.getChars(0, clength, result, rlength);
rlength += clength;
if(endIndex < nlength)
{
result[rlength++] = DIRECTORY_SEPARATOR;
}
beginIndex = endIndex;
}
return rlength <= 0 ? "" : new String(result, 0, rlength);
}
public ObjectEnumeration findFirst() throws ObjectNotFoundException, IOException {
return new DriveEnumeration();
}
public ObjectEnumeration findFirst(String objectPath) throws ObjectNotFoundException, IOException {
if(objectPath == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "objectPath" }));
}
char[] internalNameChars = toInternalNameChars(objectPath, null);
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(internalNameLength <= 2)
{
return new DriveEnumeration();
}
if(internalNameLength == 3)
{
if((long) Kernel.getDiskFreeSpaceEx(internalNameChars.getPointer()) == 0)
{
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) {
objectName = new String(internalNameChars, 0, internalNameLength)
};
}
return new DriveInfo(new String(internalNameChars, 0, 2));
}
if(internalNameLength == 4 && internalNameChars[3] == INTERNAL_ANY_OBJECT)
{
internalNameChars[--internalNameLength] = '\0';
if((long) Kernel.getDiskFreeSpaceEx(internalNameChars.getPointer()) == 0)
{
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) {
objectName = new String(internalNameChars, 0, internalNameLength)
};
}
return new ObjectInDriveRootEnumeration(internalNameChars);
}
{
Win32FindData internalFindData = new Win32FindData();
long findHandle = Kernel.findFirstFile(internalNameChars.getPointer(), internalFindData.getPointer());
if(findHandle == Kernel.INVALID_HANDLE_VALUE) switch(Kernel.getLastError())
{
default:
throw new IOException(avt.io.package.getResourceString("io"));
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new ObjectNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.object")) {
objectName = new String(internalNameChars, 0, internalNameLength)
};
}
return new ObjectInDirectoryEnumeration(findHandle, internalFindData);
}
}
public ByteWriter createFile(String fileName) throws ReadOnlyFileSystemException, FileCreationException, IOException {
if(fileName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "fileName" }));
}
char[] internalNameChars = toInternalNameChars(fileName, "createFile");
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(internalNameLength <= 3)
{
if((long) Kernel.getDiskFreeSpaceEx(internalNameChars.getPointer()) == 0)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
throw new FileCreationException(platform.independent.filesystem.package.getResourceString("file.creation")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
{
int internalNameReadOnlyLength = getReadOnlyPathLength(internalNameChars);
if(internalNameReadOnlyLength > 0)
{
throw new ReadOnlyFileSystemException(platform.independent.filesystem.package.getResourceString("file-system.read-only")) {
directoryName = new String(internalNameChars, 0, internalNameReadOnlyLength)
};
}
long fileHandle = Kernel.createFile(internalNameChars.getPointer(), Kernel.GENERIC_WRITE, 0, 0, Kernel.CREATE_NEW, Kernel.FILE_FLAG_RANDOM_ACCESS, 0);
if(fileHandle == Kernel.INVALID_HANDLE_VALUE) switch(Kernel.getLastError())
{
default:
if(Kernel.getLastStatus() != Kernel.STATUS_FILE_IS_A_DIRECTORY)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
/* падение через */
case Kernel.ERROR_FILE_EXISTS:
case Kernel.ERROR_ALREADY_EXISTS:
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new FileCreationException(platform.independent.filesystem.package.getResourceString("file.creation")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
return new FileOutputStream(fileHandle, CLOSEABLE | SEEKABLE | TRUNCATABLE);
}
}
public ByteWriter rewriteFile(String fileName) throws ReadOnlyFileSystemException, FileCreationException, IOException {
if(fileName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "fileName" }));
}
char[] internalNameChars = toInternalNameChars(fileName, "rewriteFile");
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(internalNameLength <= 3)
{
if((long) Kernel.getDiskFreeSpaceEx(internalNameChars.getPointer()) == 0)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
throw new FileCreationException(platform.independent.filesystem.package.getResourceString("file.creation")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
{
int internalNameReadOnlyLength = getReadOnlyPathLength(internalNameChars);
if(internalNameReadOnlyLength > 0)
{
throw new ReadOnlyFileSystemException(platform.independent.filesystem.package.getResourceString("file-system.read-only")) {
directoryName = new String(internalNameChars, 0, internalNameReadOnlyLength)
};
}
long fileHandle = Kernel.createFile(internalNameChars.getPointer(), Kernel.GENERIC_WRITE, 0, 0, Kernel.CREATE_ALWAYS, Kernel.FILE_FLAG_RANDOM_ACCESS, 0);
if(fileHandle == Kernel.INVALID_HANDLE_VALUE) switch(Kernel.getLastError())
{
default:
if(Kernel.getLastStatus() != Kernel.STATUS_FILE_IS_A_DIRECTORY)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
/* падение через */
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new FileCreationException(platform.independent.filesystem.package.getResourceString("file.creation")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
return new FileOutputStream(fileHandle, CLOSEABLE | SEEKABLE | TRUNCATABLE);
}
}
public ByteWriter openFileForAppend(String fileName) throws ReadOnlyFileSystemException, FileNotFoundException, FileOpeningException, IOException {
if(fileName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "fileName" }));
}
char[] internalNameChars = toInternalNameChars(fileName, "openFileForAppend");
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(internalNameLength <= 3)
{
if((long) Kernel.getDiskFreeSpaceEx(internalNameChars.getPointer()) == 0)
{
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
throw new FileOpeningException(platform.independent.filesystem.package.getResourceString("file.opening.append")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
{
int internalNameReadOnlyLength = getReadOnlyPathLength(internalNameChars);
if(internalNameReadOnlyLength > 0)
{
throw new ReadOnlyFileSystemException(platform.independent.filesystem.package.getResourceString("file-system.read-only")) {
directoryName = new String(internalNameChars, 0, internalNameReadOnlyLength)
};
}
long fileHandle = Kernel.createFile(internalNameChars.getPointer(), Kernel.GENERIC_WRITE, 0, 0, Kernel.OPEN_ALWAYS, Kernel.FILE_FLAG_RANDOM_ACCESS, 0);
if(fileHandle == Kernel.INVALID_HANDLE_VALUE) switch(Kernel.getLastError())
{
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 = new String(internalNameChars, 0, internalNameLength)
};
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
ByteWriter result = new FileOutputStream(fileHandle, CLOSEABLE | SEEKABLE | TRUNCATABLE);
((SeekExtension) result.getExtension(SeekExtension.class)).seek(0, SeekExtension.END);
return result;
}
}
public ByteReader openFileForRead(String fileName) throws FileNotFoundException, FileOpeningException, IOException {
if(fileName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "fileName" }));
}
char[] internalNameChars = toInternalNameChars(fileName, "openFileForRead");
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(internalNameLength <= 3)
{
if((long) Kernel.getDiskFreeSpaceEx(internalNameChars.getPointer()) == 0)
{
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
throw new FileOpeningException(platform.independent.filesystem.package.getResourceString("file.opening.read")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
{
long fileHandle = Kernel.createFile(internalNameChars.getPointer(), Kernel.GENERIC_READ, Kernel.FILE_SHARE_READ, 0, Kernel.OPEN_EXISTING, Kernel.FILE_FLAG_RANDOM_ACCESS, 0);
if(fileHandle == Kernel.INVALID_HANDLE_VALUE) switch(Kernel.getLastError())
{
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 = new String(internalNameChars, 0, internalNameLength)
};
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
return new FileInputStream(fileHandle, CLOSEABLE | SEEKABLE);
}
}
public ByteStream openFile(String fileName) throws ReadOnlyFileSystemException, FileNotFoundException, FileOpeningException, IOException {
if(fileName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "fileName" }));
}
char[] internalNameChars = toInternalNameChars(fileName, "openFile");
int internalNameLength = Array.indexOf(0, internalNameChars, 0, 0);
if(internalNameLength <= 3)
{
if((long) Kernel.getDiskFreeSpaceEx(internalNameChars.getPointer()) == 0)
{
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
throw new FileOpeningException(platform.independent.filesystem.package.getResourceString("file.opening")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
{
int internalNameReadOnlyLength = getReadOnlyPathLength(internalNameChars);
if(internalNameReadOnlyLength > 0)
{
throw new ReadOnlyFileSystemException(platform.independent.filesystem.package.getResourceString("file-system.read-only")) {
directoryName = new String(internalNameChars, 0, internalNameReadOnlyLength)
};
}
long fileHandle = Kernel.createFile(internalNameChars.getPointer(), Kernel.GENERIC_READ | Kernel.GENERIC_WRITE, 0, 0, Kernel.OPEN_ALWAYS, Kernel.FILE_FLAG_RANDOM_ACCESS, 0);
if(fileHandle == Kernel.INVALID_HANDLE_VALUE) switch(Kernel.getLastError())
{
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 = new String(internalNameChars, 0, internalNameLength)
};
case Kernel.ERROR_FILE_NOT_FOUND:
case Kernel.ERROR_PATH_NOT_FOUND:
throw new FileNotFoundException(platform.independent.filesystem.package.getResourceString("not-found.file")) {
fileName = new String(internalNameChars, 0, internalNameLength)
};
}
return new FileBidirectStream(fileHandle);
}
}
public Attributes newAttributes() {
return new Win32ObjectAttributes();
}
public int currentOffsetInMillis() {
TimeZoneInformation tzinfo = new TimeZoneInformation();
Kernel.getTimeZoneInformation(tzinfo.getPointer());
return -60000 * tzinfo.bias;
}
public long currentTimeInMillis() {
SystemTime time = new SystemTime();
Kernel.getSystemTime(time.getPointer());
int yer;
int year = yer = time.year - 1 & 0xffff;
int month = time.month - 1;
int day = time.dayOfMonth - 1;
int hour = time.hour;
int minute = time.minute;
int second = time.second;
int millisecond = time.millisecond;
int days = 146097 * (year / 400);
year %= 400;
days += 36524 * (year / 100);
year %= 100;
days += 1461 * (year / 4) + 365 * (year % 4) + day;
for(int mnt = 0; mnt < month; mnt++) days += getDaysCount(yer, mnt);
return days * 86400000L + hour * 3600000L + minute * 60000L + second * 1000L + millisecond;
}
public String[] getEnvironmentVariables() {
long2 env = Kernel.getEnvironmentStrings();
long envPointer = (long) env;
int envLength = (int) env[1];
if(envPointer != 0 && envLength > 1) try
{
int length = 0;
try
{
char[] envChars = (char[]) char[].class.newArrayAt(envPointer, envLength);
for(int index = 0; (index = Array.indexOf(0, envChars, index, 0)) >= 0; index++) length++;
String[] result = new String[length];
for(int beginIndex = length = 0; beginIndex < envLength; )
{
int endIndex = Array.indexOf(0, envChars, beginIndex, 0);
result[length++] = new String(envChars, beginIndex, endIndex - beginIndex);
beginIndex = endIndex + 1;
}
return result;
}
catch(Exception exception)
{
throw exception instanceof RuntimeException ? (RuntimeException) exception : new RuntimeException(exception.message, exception);
}
} finally
{
Kernel.freeEnvironmentStrings(envPointer);
}
return new String[0];
}
public String[] arguments { read = fldArguments }
public ByteReader standardInput { read = fldStandardInput }
public ByteWriter standardOutput { read = fldStandardOutput }
public ByteWriter standardError { read = fldStandardError }
public String consoleInputCharsetName { read = fldConsoleInputCharsetName }
public String consoleOutputCharsetName { read = fldConsoleOutputCharsetName }
public String currentDirectory { read = getCurrentDirectory }
public void operator []=(String environmentVariableName, String environmentVariableValue) {
if(environmentVariableName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "environmentVariableName" }));
}
if(environmentVariableValue == null)
{
int nameLength = environmentVariableName.length;
if(nameLength < MAX_ENV && (environmentVariableName.indexOf('=') & environmentVariableName.indexOf('\0')) < 0)
{
char[] nameChars = new char[MAX_ENV];
environmentVariableName.getChars(0, nameLength, nameChars, 0);
Kernel.setEnvironmentVariable(nameChars.getPointer(), 0);
}
} else
{
int nameLength = environmentVariableName.length;
int valueLength = environmentVariableValue.length;
if(nameLength < MAX_ENV && valueLength < MAX_ENV && (environmentVariableName.indexOf('=') & environmentVariableName.indexOf('\0') & environmentVariableValue.indexOf('\0')) < 0)
{
char[] nameChars = new char[MAX_ENV];
char[] valueChars = new char[MAX_ENV];
environmentVariableName.getChars(0, nameLength, nameChars, 0);
environmentVariableValue.getChars(0, valueLength, valueChars, 0);
Kernel.setEnvironmentVariable(nameChars.getPointer(), valueChars.getPointer());
}
}
}
public String operator [](String environmentVariableName) {
if(environmentVariableName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "environmentVariableName" }));
}
{
int nameLength = environmentVariableName.length;
if(nameLength < MAX_ENV && (environmentVariableName.indexOf('=') & environmentVariableName.indexOf('\0')) < 0)
{
char[] nameChars = new char[MAX_ENV];
char[] valueChars = new char[MAX_ENV];
environmentVariableName.getChars(0, nameLength, nameChars, 0);
int valueLength = Kernel.getEnvironmentVariable(nameChars.getPointer(), valueChars.getPointer(), valueChars.length);
return Kernel.getLastError() == Kernel.ERROR_ENVVAR_NOT_FOUND ? null : new String(valueChars, 0, valueLength);
}
}
return null;
}
private String getCurrentDirectory() {
char[] internalNameChars = new char[MAX_PATH];
int internalNameLength = Kernel.getCurrentDirectory(internalNameChars.length, internalNameChars.getPointer());
if(internalNameLength < 3 || internalNameLength > MAX_PATH - 1)
{
throw new RuntimeException(platform.dependent.package.getResourceString("current-directory.get"));
}
String internalName = new String(internalNameChars, 0, internalNameLength);
if(!isInternalNameFull(internalName))
{
throw new RuntimeException(platform.dependent.package.getResourceString("current-directory.get"));
}
return toObjectName(internalName);
}
}
package class Win32Event(Event)
{
private static int internalCounter = 0x007fffff;
private static native int getInternalCounterValue();
private static int writeStringToCharArray(String value, char[] array, int index) {
int length = value.length;
value.getChars(0, length, array, index);
return index + length;
}
private static int writeLongToCharArray(long value, char[] array, int index) {
for(array[index++] = '.', int bits = 60; bits >= 0; bits -= 5) array[index++] = Char.toChar((int) (value >> bits) & 0x1f);
return index;
}
private long fldEventHandle;
public (long threadId): super(threadId, new CriticalSection()) { }
public void setSignalled() { Kernel.setEvent(fldEventHandle); }
public void waitSignalled(int timeInMillis) { Kernel.waitForSingleObject(fldEventHandle, timeInMillis <= 0 ? Kernel.INFINITE : timeInMillis); }
protected void afterConstruction() {
char[] name = new char[0x50];
int index = writeStringToCharArray("Event", name, 0);
index = writeLongToCharArray(Kernel.getCurrentProcessId(), name, index);
index = writeLongToCharArray(Kernel.getCurrentThreadId(), name, index);
index = writeLongToCharArray(System.currentTimeInMillis(), name, index);
index = writeLongToCharArray(System.identityHashCode(this), name, index);
writeLongToCharArray(getInternalCounterValue(), name, index);
fldEventHandle = Kernel.createEvent(0, false, false, name.getPointer());
}
protected void beforeDestruction() {
long eventHandle = fldEventHandle;
if(eventHandle != 0)
{
fldEventHandle = 0;
Kernel.closeHandle(eventHandle);
}
}
}
class FileStreamExtension(Object, Extension)
{
protected long fldFileHandle;
protected (long fileHandle) {
fldFileHandle = fileHandle;
}
}
service FileStreamPositioningExtension(FileStreamExtension, SeekExtension, LimitedSizeExtension)
{
public long seek(long offset, int from) throws IOException {
if(from < BEGIN || from > END)
{
throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument"), new Object[] { "from" }));
}
long fileHandle = fldFileHandle;
if(fileHandle == Kernel.INVALID_HANDLE_VALUE)
{
throw new ClosedFileException(platform.independent.filesystem.package.getResourceString("closed-file"));
}
long filePointer = Kernel.setFilePointer(fileHandle, offset, from);
if(filePointer == Kernel.INVALID_SET_FILE_POINTER)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
return filePointer;
}
public long size() throws IOException {
long fileHandle = fldFileHandle;
if(fileHandle == Kernel.INVALID_HANDLE_VALUE)
{
throw new ClosedFileException(platform.independent.filesystem.package.getResourceString("closed-file"));
}
long fileSize = Kernel.getFileSize(fileHandle);
if(fileSize == Kernel.INVALID_FILE_SIZE)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
return fileSize;
}
public long available() throws IOException {
long fileHandle = fldFileHandle;
if(fileHandle == Kernel.INVALID_HANDLE_VALUE)
{
throw new ClosedFileException(platform.independent.filesystem.package.getResourceString("closed-file"));
}
long fileSize = Kernel.getFileSize(fileHandle);
if(fileSize == Kernel.INVALID_FILE_SIZE)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
long filePointer = Kernel.setFilePointer(fileHandle, 0, CURRENT);
if(filePointer == Kernel.INVALID_SET_FILE_POINTER)
{
throw new IOException(avt.io.package.getResourceString("io"));
}
return fileSize - filePointer;
}
}
service FileStreamTruncatingExtension(FileStreamExtension, TruncateExtension)
{
public void truncate() throws IOException {
long fileHandle = fldFileHandle;
if(fileHandle == Kernel.INVALID_HANDLE_VALUE)
{
throw new ClosedFileException(platform.independent.filesystem.package.getResourceString("closed-file"));
}
if(!Kernel.setEndOfFile(fileHandle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
}
}
class FileStream(Object, Constants, Closeable, Extendable)
{
protected long fldFileHandle;
protected final boolean fldIsCloseable;
protected final FileStreamExtension[] fldExtensions;
protected (long fileHandle, int features) {
fldFileHandle = fileHandle;
fldIsCloseable = (features & CLOSEABLE) != 0;
switch(features & (TRUNCATABLE | SEEKABLE))
{
default:
fldExtensions = new FileStreamExtension[] { };
break;
case SEEKABLE:
fldExtensions = new FileStreamExtension[] { new FileStreamPositioningExtension(fileHandle) };
break;
case TRUNCATABLE:
fldExtensions = new FileStreamExtension[] { new FileStreamTruncatingExtension(fileHandle) };
break;
case TRUNCATABLE | SEEKABLE:
fldExtensions = new FileStreamExtension[] { new FileStreamTruncatingExtension(fileHandle), new FileStreamPositioningExtension(fileHandle) };
}
}
protected (long fileHandle, int features, FileStreamExtension[] extensions) {
fldFileHandle = fileHandle;
fldIsCloseable = (features & CLOSEABLE) != 0;
fldExtensions = extensions;
}
public void close() throws IOException {
if(fldIsCloseable)
{
long fileHandle = fldFileHandle;
if(fileHandle != Kernel.INVALID_HANDLE_VALUE)
{
if(!Kernel.closeHandle(fileHandle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
clearHandlers();
}
}
}
public Extension[] getExtensions() {
Extension[] result = fldExtensions;
int length = result.length;
Array.copy(result, 0, result = new Extension[length], 0, length);
return result;
}
protected void beforeDestruction() {
if(fldIsCloseable)
{
long fileHandle = fldFileHandle;
if(fileHandle != Kernel.INVALID_HANDLE_VALUE) Kernel.closeHandle(fileHandle);
}
}
protected void clearHandlers() {
for(fldFileHandle = Kernel.INVALID_HANDLE_VALUE, FileStreamExtension[] extensions = fldExtensions, int index = extensions.length; index-- > 0; )
{
extensions[index].fldFileHandle = Kernel.INVALID_HANDLE_VALUE;
}
}
}
class FileInputStream(FileStream, ByteReader)
{
public (long stdHandle): super(stdHandle, 0) { }
public (long fileHandle, int features): super(fileHandle, features) { }
public (long fileHandle, int features, FileStreamExtension[] extensions): super(fileHandle, features, extensions) { }
public int read() throws IOException {
long fileHandle = fldFileHandle;
if(fileHandle == Kernel.INVALID_HANDLE_VALUE)
{
throw new ClosedFileException(platform.independent.filesystem.package.getResourceString("closed-file"));
}
int2 result = Kernel.readFile(fileHandle, 0);
if((int) result == 0)
{
throw new IOException(avt.io.package.getResourceString("io.read"));
}
return result[1];
}
public int read(byte[] dst, int offset, int length) throws IOException {
if(dst == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "dst" }));
}
Array.checkBounds(dst, offset, length);
long fileHandle = fldFileHandle;
if(fileHandle == Kernel.INVALID_HANDLE_VALUE)
{
throw new ClosedFileException(platform.independent.filesystem.package.getResourceString("closed-file"));
}
if(length <= 0) return 0;
int2 result = Kernel.readFile(fileHandle, dst.getPointer() + offset, length, 0);
if((int) result == 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 {
SeekExtension positioning = (SeekExtension) getExtension(SeekExtension.class);
return positioning == null ? ByteReader.super.skip(bytesQuantity) : bytesQuantity <= 0 ? 0 : -positioning.position() + positioning.seek(bytesQuantity, SeekExtension.CURRENT);
}
}
class FileOutputStream(FileStream, ByteWriter)
{
public (long stdHandle): super(stdHandle, 0) { }
public (long fileHandle, int features): super(fileHandle, features) { }
public (long fileHandle, int features, FileStreamExtension[] extensions): super(fileHandle, features, extensions) { }
public void write(int byteData) throws IOException {
long fileHandle = fldFileHandle;
if(fileHandle == Kernel.INVALID_HANDLE_VALUE)
{
throw new ClosedFileException(platform.independent.filesystem.package.getResourceString("closed-file"));
}
int2 result = Kernel.writeFile(fileHandle, byteData, 0);
if((int) result == 0 || result[1] != 1)
{
throw new IOException(avt.io.package.getResourceString("io.write"));
}
}
public void write(byte[] src, int offset, int length) throws IOException {
if(src == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "src" }));
}
Array.checkBounds(src, offset, length);
long fileHandle = fldFileHandle;
if(fileHandle == Kernel.INVALID_HANDLE_VALUE)
{
throw new ClosedFileException(platform.independent.filesystem.package.getResourceString("closed-file"));
}
if(length <= 0) return;
int2 result = Kernel.writeFile(fileHandle, src.getPointer() + offset, length, 0);
if((int) result == 0 || result[1] != length)
{
throw new IOException(avt.io.package.getResourceString("io.write"));
}
}
public void flush() throws IOException {
long fileHandle = fldFileHandle;
if(fileHandle == Kernel.INVALID_HANDLE_VALUE)
{
throw new ClosedFileException(platform.independent.filesystem.package.getResourceString("closed-file"));
}
if(!Kernel.flushFileBuffers(fileHandle))
{
throw new IOException(avt.io.package.getResourceString("io.write"));
}
}
}
class FileBidirectStream(FileStream, ByteStream)
{
private final FileInputStream fldReader;
private final FileOutputStream fldWriter;
public (long fileHandle): super(fileHandle, CLOSEABLE | TRUNCATABLE | SEEKABLE) {
FileStreamExtension[] extensions = fldExtensions;
fldReader = new FileInputStream(fileHandle, 0, new FileStreamExtension[] { extensions[1] });
fldWriter = new FileOutputStream(fileHandle, 0, extensions);
}
public ByteReader reader { read = fldReader }
public ByteWriter writer { read = fldWriter }
protected void clearHandlers() {
super.clearHandlers();
fldReader.fldFileHandle = Kernel.INVALID_HANDLE_VALUE;
fldWriter.fldFileHandle = Kernel.INVALID_HANDLE_VALUE;
}
}
class Win32ObjectAttributes(Object, Constants, Attributes)
{
private static void stringAttributeIdIsInvalid(String attributeId) {
if(attributeId == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "attributeId" }));
}
throw new IllegalArgumentException(String.format(
platform.independent.filesystem.package.getResourceString(attributeId.startsWith("s") ? "illegal-argument.attribute-id" : "illegal-argument.attribute-type"), new Object[] { attributeId }
));
}
private static int booleanAttributeIdToIndex(String attributeId) {
if(attributeId == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "attributeId" }));
}
if(attributeId.equals(B_DIRECTORY)) return 4;
if(attributeId.equals(B_READ_ONLY)) return 0;
if(attributeId.equals(B_HIDDEN)) return 1;
if(attributeId.equals(B_SYSTEM)) return 2;
if(attributeId.equals(B_ARCHIVE)) return 5;
throw new IllegalArgumentException(String.format(
platform.independent.filesystem.package.getResourceString(attributeId.startsWith("b") ? "illegal-argument.attribute-id" : "illegal-argument.attribute-type"), new Object[] { attributeId }
));
}
private static int longAttributeIdToIndex(String attributeId) {
if(attributeId == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "attributeId" }));
}
if(attributeId.equals(L_LAST_ACCESS_TIME)) return 1;
if(attributeId.equals(L_LAST_WRITE_TIME)) return 2;
if(attributeId.equals(L_CREATION_TIME)) return 0;
throw new IllegalArgumentException(String.format(
platform.independent.filesystem.package.getResourceString(attributeId.startsWith("l") ? "illegal-argument.attribute-id" : "illegal-argument.attribute-type"), new Object[] { attributeId }
));
}
protected int fldAttributes;
protected final long[] fldTimes;
public () {
fldTimes = new long[3];
}
public void setBooleanAttribute(String attributeId, boolean attributeValue) {
int mask = 1 << booleanAttributeIdToIndex(attributeId);
fldAttributes = attributeValue ? fldAttributes | mask : fldAttributes & ~mask;
}
public void setLongAttribute(String attributeId, long attributeValue) {
int index = longAttributeIdToIndex(attributeId);
fldTimes[index] = attributeValue;
}
public void setStringAttribute(String attributeId, String attributeValue) {
stringAttributeIdIsInvalid(attributeId);
}
public boolean isSupportedAttributeId(String attributeId) {
return attributeId != null && (
attributeId.equals(B_DIRECTORY) ||
attributeId.equals(B_READ_ONLY) ||
attributeId.equals(B_HIDDEN) ||
attributeId.equals(B_SYSTEM) ||
attributeId.equals(B_ARCHIVE) ||
attributeId.equals(L_LAST_ACCESS_TIME) ||
attributeId.equals(L_LAST_WRITE_TIME) ||
attributeId.equals(L_CREATION_TIME)
);
}
public boolean getBooleanAttribute(String attributeId) {
int mask = 1 << booleanAttributeIdToIndex(attributeId);
return (fldAttributes & mask) != 0;
}
public long getLongAttribute(String attributeId) {
int index = longAttributeIdToIndex(attributeId);
return fldTimes[index];
}
public String getStringAttribute(String attributeId) {
stringAttributeIdIsInvalid(attributeId);
return null; /* недостижимый код */
}
public String displayName(String attributeId) {
if(attributeId == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "attributeId" }));
}
if(attributeId.equals(B_DIRECTORY)) return platform.independent.filesystem.package.getResourceString("display-name.object-attributes.directory");
if(attributeId.equals(B_READ_ONLY)) return platform.independent.filesystem.package.getResourceString("display-name.object-attributes.read-only");
if(attributeId.equals(B_HIDDEN)) return package.getResourceString("display-name.object-attributes.hidden");
if(attributeId.equals(B_SYSTEM)) return package.getResourceString("display-name.object-attributes.system");
if(attributeId.equals(B_ARCHIVE)) return package.getResourceString("display-name.object-attributes.archive");
if(attributeId.equals(L_LAST_ACCESS_TIME)) return platform.independent.filesystem.package.getResourceString("display-name.object-attributes.last-access-time");
if(attributeId.equals(L_LAST_WRITE_TIME)) return platform.independent.filesystem.package.getResourceString("display-name.object-attributes.last-write-time");
if(attributeId.equals(L_CREATION_TIME)) return package.getResourceString("display-name.object-attributes.creation-time");
throw new IllegalArgumentException(String.format(platform.independent.filesystem.package.getResourceString("illegal-argument.attribute-id"), new Object[] { attributeId }));
}
public String[] getSupportedAttributeIds() {
return new String[] { B_DIRECTORY, B_READ_ONLY, B_HIDDEN, B_SYSTEM, B_ARCHIVE, L_LAST_ACCESS_TIME, L_LAST_WRITE_TIME, L_CREATION_TIME };
}
}
class Win32ObjectEnumeration(ObjectEnumeration, Constants)
{
protected (): super(new Win32ObjectAttributes()) { }
public boolean findNext() throws ObjectEnumerationException, IOException {
return false;
}
protected void fillRootAttributes(String rootName) {
name = rootName;
size = 0;
setBooleanAttribute(B_DIRECTORY, true);
setBooleanAttribute(B_READ_ONLY, false);
setBooleanAttribute(B_ARCHIVE, false);
setBooleanAttribute(B_HIDDEN, false);
setBooleanAttribute(B_SYSTEM, true);
setLongAttribute(L_LAST_ACCESS_TIME, Long.MIN_VALUE);
setLongAttribute(L_LAST_WRITE_TIME, Long.MIN_VALUE);
setLongAttribute(L_CREATION_TIME, Long.MIN_VALUE);
}
protected void fillDriveAttributes(String driveName) {
name = driveName;
size = 0;
setBooleanAttribute(B_DIRECTORY, true);
setBooleanAttribute(B_READ_ONLY, false);
setBooleanAttribute(B_ARCHIVE, true);
setBooleanAttribute(B_HIDDEN, false);
setBooleanAttribute(B_SYSTEM, true);
setLongAttribute(L_LAST_ACCESS_TIME, Long.MIN_VALUE);
setLongAttribute(L_LAST_WRITE_TIME, Long.MIN_VALUE);
setLongAttribute(L_CREATION_TIME, Long.MIN_VALUE);
}
protected void fillObjectAttributes(Win32FindData findData) {
int attributes = findData.dwFileAttributes;
char[] nameChars = findData.cFileName;
int nameLength = Array.indexOf(0, nameChars, 0, 0);
if(nameLength < 0) nameLength = MAX_PATH;
name = new String(nameChars, 0, nameLength);
size = ####findData.nFileSizeLow | ^^^^findData.nFileSizeHigh;
setBooleanAttribute(B_DIRECTORY, (attributes & Kernel.FILE_ATTRIBUTE_DIRECTORY) != 0);
setBooleanAttribute(B_READ_ONLY, (attributes & Kernel.FILE_ATTRIBUTE_READONLY) != 0);
setBooleanAttribute(B_ARCHIVE, (attributes & Kernel.FILE_ATTRIBUTE_ARCHIVE) != 0);
setBooleanAttribute(B_HIDDEN, (attributes & Kernel.FILE_ATTRIBUTE_HIDDEN) != 0);
setBooleanAttribute(B_SYSTEM, (attributes & Kernel.FILE_ATTRIBUTE_SYSTEM) != 0);
setLongAttribute(L_LAST_ACCESS_TIME, toObjectTime(findData.ftLastAccessTime));
setLongAttribute(L_LAST_WRITE_TIME, toObjectTime(findData.ftLastWriteTime));
setLongAttribute(L_CREATION_TIME, toObjectTime(findData.ftCreationTime));
}
}
class DriveInfo(Win32ObjectEnumeration)
{
public (String driveName) {
fillDriveAttributes(driveName);
}
}
class DriveEnumeration(Win32ObjectEnumeration)
{
private final char[] fldDriveChars;
public () {
fillRootAttributes(".");
fldDriveChars = new char[] { 'A', INTERNAL_DRIVE_SEPARATOR, INTERNAL_DIRECTORY_SEPARATOR, '\0' };
}
public boolean findNext() throws ObjectEnumerationException, IOException {
for(char[] driveChars = fldDriveChars, long drivePointer = driveChars.getPointer(); driveChars[0] <= 'Z'; driveChars[0]++) if((long) Kernel.getDiskFreeSpaceEx(drivePointer) != 0)
{
fillDriveAttributes(new String(driveChars, 0, 2));
driveChars[0]++;
return true;
}
return false;
}
}
class CustomObjectEnumeration(Win32ObjectEnumeration)
{
protected long fldFindHandle;
protected Win32FindData fldFindData;
protected () { }
public void close() throws IOException {
long findHandle = fldFindHandle;
if(findHandle != Kernel.INVALID_HANDLE_VALUE && !Kernel.findClose(findHandle))
{
throw new IOException(avt.io.package.getResourceString("io"));
}
fldFindHandle = Kernel.INVALID_HANDLE_VALUE;
}
public boolean findNext() throws ObjectEnumerationException, IOException {
long findHandle = fldFindHandle;
if(findHandle == Kernel.INVALID_HANDLE_VALUE)
{
throw new ClosedEnumerationException(platform.independent.filesystem.package.getResourceString("closed-enumeration"));
}
Win32FindData findData = fldFindData;
if(Kernel.findNextFile(findHandle, findData.getPointer()))
{
fillObjectAttributes(findData);
return true;
}
if(Kernel.getLastError() != Kernel.ERROR_NO_MORE_FILES)
{
throw new ObjectEnumerationException(platform.independent.filesystem.package.getResourceString("object.enumeration"));
}
return false;
}
protected void beforeDestruction() {
long findHandle = fldFindHandle;
if(findHandle != Kernel.INVALID_HANDLE_VALUE) Kernel.findClose(findHandle);
}
}
class ObjectInDriveRootEnumeration(CustomObjectEnumeration)
{
private boolean fldFindStatus;
private final char[] fldDriveChars;
public (char[] driveChars) {
fillDriveAttributes(".");
fldFindHandle = Kernel.INVALID_HANDLE_VALUE;
fldFindData = new Win32FindData();
fldDriveChars = driveChars;
}
public boolean findNext() throws ObjectEnumerationException, IOException {
if(!fldFindStatus)
{
if((long) Kernel.getDiskFreeSpaceEx(fldDriveChars.getPointer()) != 0)
{
fillRootAttributes("..");
return fldFindStatus = true;
}
throw new ObjectEnumerationException(platform.independent.filesystem.package.getResourceString("object.enumeration"));
}
if(fldFindHandle == Kernel.INVALID_HANDLE_VALUE)
{
char[] driveChars = fldDriveChars;
Win32FindData findData = fldFindData;
driveChars[3] = INTERNAL_ANY_OBJECT;
if((fldFindHandle = Kernel.findFirstFile(driveChars.getPointer(), findData.getPointer())) != Kernel.INVALID_HANDLE_VALUE)
{
fillObjectAttributes(findData);
return true;
}
if(Kernel.getLastError() != Kernel.ERROR_FILE_NOT_FOUND)
{
throw new ObjectEnumerationException(platform.independent.filesystem.package.getResourceString("object.enumeration"));
}
return false;
}
return super.findNext();
}
}
class ObjectInDirectoryEnumeration(CustomObjectEnumeration)
{
public (long findHandle, Win32FindData findData) {
fillObjectAttributes(findData);
fldFindHandle = findHandle;
fldFindData = findData;
}
}