/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016, 2019 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package malik.emulator.io.cloud;
import java.io.*;
import malik.emulator.io.vfs.*;
import malik.emulator.time.*;
public final class CloudFileSystem extends Object
implements VirtualFileSystemReadOnly, VirtualFileSystemReadWrite
{
private static final VirtualFileSystemReadWrite INSTANCE;
static
{
INSTANCE = new CloudFileSystem();
}
public static VirtualFileSystemReadWrite getInstance()
{
return INSTANCE;
}
static long computeFields(long time)
{
return GregorianCalendar.computeFields(time, 0);
}
static long computeTime(long fields)
{
return GregorianCalendar.computeTime(fields, 0);
}
private CloudFileSystem()
{
}
public String toString()
{
return "Файловая система текущего приложения";
}
public void readAttributes(String fileName, FileAttributes attr)
throws FileNotExistsException
{
int len;
char[] fn;
AttributesDescriptor descriptor;
if(fileName == null)
{
throw new NullPointerException("CloudFileSystem.readAttributes: " +
"параметр fileName равен нулевой ссылке.");
}
if(attr == null)
{
throw new NullPointerException("CloudFileSystem.readAttributes: " +
"параметр attr равен нулевой ссылке.");
}
fileName.getChars(0, len = fileName.length(), fn = new char[len + 1], 0);
if(((int) MalikSystem.syscall(Array.getFirstElementAddress(fn),
(descriptor = new AttributesDescriptor()).getDescriptorAddress(), 0x001c)) == 0)
{
throw new FileNotExistsException("CloudFileSystem.readAttributes: " +
"файл " + fileName + " не существует.");
}
attr.setAttributes(
computeTime(descriptor.creationTime), computeTime(descriptor.lastAccessTime),
computeTime(descriptor.lastWriteTime), descriptor.attributes);
}
public int getFileNameMaxLength()
{
return (int) MalikSystem.syscall(0L, 0x0016);
}
public FileEnumerator findFirst()
{
char[] fileName;
char[] directory;
FileInfoDescriptor descriptor;
directory = new char[] {
'/', 0
};
(descriptor = new FileInfoDescriptor()).length =
(fileName = new char[getFileNameMaxLength() + 1]).length;
descriptor.chars = Array.getFirstElementAddress(fileName);
return new CloudFileEnumerator((int) MalikSystem.syscall(
Array.getFirstElementAddress(directory),
descriptor.getDescriptorAddress(), 0x0018), fileName, descriptor);
}
public FileEnumerator findFirst(String dirName)
throws DirectoryNotExistsException
{
int lim;
int handle;
char[] fileName;
char[] directory;
FileInfoDescriptor descriptor;
if(dirName == null)
{
throw new NullPointerException("CloudFileSystem.findFirst: " +
"параметр dirName равен нулевой ссылке.");
}
if((lim = dirName.length()) > 0)
{
if(dirName.charAt(0) == '/')
{
if(dirName.charAt(lim - 1) == '/')
{
dirName.getChars(0, lim, directory = new char[lim + 1], 0);
} else
{
dirName.getChars(0, lim, directory = new char[lim + 2], 0);
directory[lim] = '/';
}
} else
{
if(dirName.charAt(lim - 1) == '/')
{
dirName.getChars(0, lim, directory = new char[lim + 2], 1);
} else
{
dirName.getChars(0, lim, directory = new char[lim + 3], 1);
directory[lim + 1] = '/';
}
directory[0] = '/';
}
} else
{
directory = new char[] {
'/', 0
};
}
(descriptor = new FileInfoDescriptor()).length =
(fileName = new char[getFileNameMaxLength() + 1]).length;
descriptor.chars = Array.getFirstElementAddress(fileName);
if((handle = (int) MalikSystem.syscall(Array.getFirstElementAddress(directory),
descriptor.getDescriptorAddress(), 0x0018)) == 0)
{
throw new DirectoryNotExistsException("CloudFileSystem.findFirst: " +
"папка " + dirName + " не существует.");
}
return handle > 0 ? new CloudFileEnumerator(handle, fileName, descriptor) : null;
}
public InputStream openFileForRead(String fileName)
throws IOException
{
FileInputStream result;
(result = new FileInputStream(fileName)).checkOpenError();
return result;
}
public void writeAttributes(String fileName, FileAttributes attr)
throws FileNotExistsException
{
int len;
char[] fn;
AttributesDescriptor descriptor;
if(fileName == null)
{
throw new NullPointerException("CloudFileSystem.writeAttributes: " +
"параметр fileName равен нулевой ссылке.");
}
if(attr == null)
{
throw new NullPointerException("CloudFileSystem.writeAttributes: " +
"параметр attr равен нулевой ссылке.");
}
fileName.getChars(0, len = fileName.length(), fn = new char[len + 1], 0);
(descriptor = new AttributesDescriptor()).attributes = attr.getAttributes() &
(~FileAttributes.ATTR_DIRECTORY);
descriptor.creationTime = computeFields(attr.getCreationTime());
descriptor.lastAccessTime = computeFields(attr.getLastAccessTime());
descriptor.lastWriteTime = computeFields(attr.getLastWriteTime());
if(((int) MalikSystem.syscall(Array.getFirstElementAddress(fn),
descriptor.getDescriptorAddress(), 0x001d)) == 0)
{
throw new FileNotExistsException("CloudFileSystem.writeAttributes: " +
"файл " + fileName + " занят или не существует.");
}
}
public void move(String oldFileName, String newFileName)
throws IOException
{
int len;
char[] ofn;
char[] nfn;
if(oldFileName == null)
{
throw new NullPointerException("CloudFileSystem.move: " +
"параметр oldFileName равен нулевой ссылке.");
}
if(newFileName == null)
{
throw new NullPointerException("CloudFileSystem.move: " +
"параметр newFileName равен нулевой ссылке.");
}
oldFileName.getChars(0, len = oldFileName.length(), ofn = new char[len + 1], 0);
newFileName.getChars(0, len = newFileName.length(), nfn = new char[len + 1], 0);
if(((int) MalikSystem.syscall(Array.getFirstElementAddress(ofn),
Array.getFirstElementAddress(nfn), 0x001b)) == 0)
{
throw new IOException("CloudFileSystem.move: " +
"не удалось переместить файл " + oldFileName +
" на новое место " + newFileName + ".");
}
}
public void deleteDirectory(String dirName)
throws IOException
{
int len;
char[] dn;
if(dirName == null)
{
throw new NullPointerException("CloudFileSystem.deleteDirectory: " +
"параметр dirName равен нулевой ссылке.");
}
dirName.getChars(0, len = dirName.length(), dn = new char[len + 1], 0);
if(((int) MalikSystem.syscall((long) Array.getFirstElementAddress(dn), 0x001f)) == 0)
{
throw new IOException("CloudFileSystem.deleteDirectory: " +
"не удалось удалить папку " + dirName + ".");
}
}
public void deleteFile(String fileName)
throws IOException
{
int len;
char[] fn;
if(fileName == null)
{
throw new NullPointerException("CloudFileSystem.deleteFile: " +
"параметр fileName равен нулевой ссылке.");
}
fileName.getChars(0, len = fileName.length(), fn = new char[len + 1], 0);
if(((int) MalikSystem.syscall((long) Array.getFirstElementAddress(fn), 0x0017)) == 0)
{
throw new IOException("CloudFileSystem.deleteFile: " +
"не удалось удалить файл " + fileName + ".");
}
}
public void createDirectory(String dirName)
throws IOException
{
int len;
char[] dn;
if(dirName == null)
{
throw new NullPointerException("CloudFileSystem.createDirectory: " +
"параметр dirName равен нулевой ссылке.");
}
dirName.getChars(0, len = dirName.length(), dn = new char[len + 1], 0);
if(((int) MalikSystem.syscall((long) Array.getFirstElementAddress(dn), 0x001e)) == 0)
{
throw new IOException("CloudFileSystem.createDirectory: " +
"не удалось создать папку " + dirName + ".");
}
}
public OutputStream createFile(String fileName)
throws IOException
{
FileOutputStream result;
(result = new FileOutputStream(fileName, false)).checkOpenError();
return result;
}
public OutputStream openFileForAppending(String fileName)
throws IOException
{
FileOutputStream result;
(result = new FileOutputStream(fileName, true)).checkOpenError();
return result;
}
}