pluotsorbet/midp/fs.js

658 строки
23 KiB
JavaScript
Исходник Обычный вид История

/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set shiftwidth=4 tabstop=4 autoindent cindent expandtab: */
2014-08-29 01:13:45 +04:00
'use strict';
2014-09-30 20:17:16 +04:00
var RECORD_STORE_BASE = "/RecordStore";
Native.create("com/sun/midp/io/j2me/storage/File.initConfigRoot.(I)Ljava/lang/String;", function(storageId) {
return "assets/" + storageId + "/";
});
Native.create("com/sun/midp/midletsuite/MIDletSuiteStorage.getSecureFilenameBase.(I)Ljava/lang/String;", function(id) {
return "";
});
2014-10-17 02:04:31 +04:00
Native.create("com/sun/midp/rms/RecordStoreUtil.exists.(Ljava/lang/String;Ljava/lang/String;I)Z",
function(filenameBase, name, ext) {
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
var path = RECORD_STORE_BASE + "/" + util.fromJavaString(filenameBase) + "/" + util.fromJavaString(name) + "." + ext;
fs.exists(path, resolve);
});
}, true);
Native.create("com/sun/midp/rms/RecordStoreUtil.deleteFile.(Ljava/lang/String;Ljava/lang/String;I)V",
function(filenameBase, name, ext) {
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
var path = RECORD_STORE_BASE + "/" + util.fromJavaString(filenameBase) + "/" + util.fromJavaString(name) + "." + ext;
2014-10-17 02:04:31 +04:00
fs.remove(path, resolve);
});
}, true);
Native.create("com/sun/midp/rms/RecordStoreFile.spaceAvailableNewRecordStore0.(Ljava/lang/String;I)I", function(filenameBase, storageId) {
// Pretend there is 50MiB available. Our implementation is backed
// by IndexedDB, which has no actual limit beyond space available on device,
// which I don't think we can determine. But this should be sufficient
// to convince the MIDlet to use the API as needed.
return 50 * 1024 * 1024;
});
Native.create("com/sun/midp/rms/RecordStoreFile.spaceAvailableRecordStore.(ILjava/lang/String;I)I", function(handle, filenameBase, storageId) {
// Pretend there is 50MiB available. Our implementation is backed
// by IndexedDB, which has no actual limit beyond space available on device,
// which I don't think we can determine. But this should be sufficient
// to convince the MIDlet to use the API as needed.
return 50 * 1024 * 1024;
});
2014-10-17 02:04:31 +04:00
Native.create("com/sun/midp/rms/RecordStoreFile.openRecordStoreFile.(Ljava/lang/String;Ljava/lang/String;I)I",
function(filenameBase, name, ext) {
var ctx = $.ctx;
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
var path = RECORD_STORE_BASE + "/" + util.fromJavaString(filenameBase) + "/" + util.fromJavaString(name) + "." + ext;
2014-10-17 02:04:31 +04:00
function openCallback(fd) {
ctx.setAsCurrentContext();
2014-10-17 02:04:31 +04:00
if (fd == -1) {
reject($.newIOException("openRecordStoreFile: open failed"));
2014-10-17 02:04:31 +04:00
} else {
resolve(fd); // handle
}
}
2014-10-17 02:04:31 +04:00
fs.exists(path, function(exists) {
if (exists) {
fs.open(path, openCallback);
} else {
// Per the reference impl, create the file if it doesn't exist.
var dirname = fs.dirname(path);
fs.mkdirp(dirname, function(created) {
if (created) {
fs.create(path, new Blob(), function(created) {
ctx.setAsCurrentContext();
2014-10-17 02:04:31 +04:00
if (created) {
fs.open(path, openCallback);
}
else {
reject($.newIOException("openRecordStoreFile: create failed"));
2014-10-17 02:04:31 +04:00
}
});
} else {
ctx.setAsCurrentContext();
reject($.newIOException("openRecordStoreFile: mkdirp failed"));
2014-10-17 02:04:31 +04:00
}
});
}
});
});
}, true);
Native.create("com/sun/midp/rms/RecordStoreFile.setPosition.(II)V", function(handle, pos) {
fs.setpos(handle, pos);
});
Native.create("com/sun/midp/rms/RecordStoreFile.readBytes.(I[BII)I", function(handle, buf, offset, numBytes) {
var from = fs.getpos(handle);
var to = from + numBytes;
var readBytes = fs.read(handle, from, to);
if (readBytes.byteLength <= 0) {
throw $.newIOException("handle invalid or segment indices out of bounds");
}
var subBuffer = buf.subarray(offset, offset + readBytes.byteLength);
for (var i = 0; i < readBytes.byteLength; i++) {
subBuffer[i] = readBytes[i];
}
return readBytes.byteLength;
});
Native.create("com/sun/midp/rms/RecordStoreFile.writeBytes.(I[BII)V", function(handle, buf, offset, numBytes) {
fs.write(handle, buf.subarray(offset, offset + numBytes));
});
Native.create("com/sun/midp/rms/RecordStoreFile.commitWrite.(I)V", function(handle) {
2014-11-24 12:49:56 +03:00
fs.flush(handle);
});
Native.create("com/sun/midp/rms/RecordStoreFile.closeFile.(I)V", function(handle) {
2014-11-24 12:49:56 +03:00
fs.close(handle);
});
Native.create("com/sun/midp/rms/RecordStoreFile.truncateFile.(II)V", function(handle, size) {
2014-11-24 12:49:56 +03:00
fs.flush(handle);
fs.ftruncate(handle, size);
});
MIDP.RecordStoreCache = [];
Native.create("com/sun/midp/rms/RecordStoreSharedDBHeader.getLookupId0.(ILjava/lang/String;I)I",
function(suiteId, jStoreName, headerDataSize) {
var storeName = util.fromJavaString(jStoreName);
var sharedHeader =
MIDP.RecordStoreCache.filter(function(v) { return (v && v.suiteId == suiteId && v.storeName == storeName); })[0];
if (!sharedHeader) {
sharedHeader = {
suiteId: suiteId,
storeName: storeName,
headerVersion: 0,
headerData: null,
headerDataSize: headerDataSize,
refCount: 0,
// Use cache indices as IDs, so we can look up objects by index.
lookupId: MIDP.RecordStoreCache.length,
};
MIDP.RecordStoreCache.push(sharedHeader);
}
++sharedHeader.refCount;
return sharedHeader.lookupId;
});
Native.create("com/sun/midp/rms/RecordStoreSharedDBHeader.shareCachedData0.(I[BI)I", function(lookupId, headerData, headerDataSize) {
var sharedHeader = MIDP.RecordStoreCache[lookupId];
if (!sharedHeader) {
throw $.newIllegalStateException("invalid header lookup ID");
}
if (!headerData) {
throw $.newIllegalArgumentException("header data is null");
}
var size = headerDataSize;
if (size > sharedHeader.headerDataSize) {
size = sharedHeader.headerDataSize;
}
sharedHeader.headerData = headerData.buffer.slice(0, size);
++sharedHeader.headerVersion;
return sharedHeader.headerVersion;
});
Native.create("com/sun/midp/rms/RecordStoreSharedDBHeader.updateCachedData0.(I[BII)I",
function(lookupId, headerData, headerDataSize, headerVersion) {
var sharedHeader = MIDP.RecordStoreCache[lookupId];
if (!sharedHeader) {
throw $.newIllegalStateException("invalid header lookup ID");
}
if (!headerData) {
throw $.newIllegalArgumentException("header data is null");
}
if (sharedHeader.headerVersion > headerVersion && sharedHeader.headerData) {
var size = sharedHeader.headerDataSize;
if (size > headerDataSize) {
size = headerDataSize;
}
2014-12-12 01:35:12 +03:00
var sharedHeaderData = new Int8Array(sharedHeader.headerData);
for (var i = 0; i < size; i++) {
2014-12-12 00:53:58 +03:00
headerData[i] = sharedHeaderData[i];
}
return sharedHeader.headerVersion;
}
return headerVersion;
});
Native.create("com/sun/midp/rms/RecordStoreSharedDBHeader.getHeaderRefCount0.(I)I", function(lookupId) {
var sharedHeader = MIDP.RecordStoreCache[lookupId];
if (!sharedHeader) {
throw $.newIllegalStateException("invalid header lookup ID");
}
return sharedHeader.refCount;
});
Native.create("com/sun/midp/rms/RecordStoreSharedDBHeader.cleanup0.()V", function() {
2014-11-27 05:40:02 +03:00
var lookupId = this.klass.classInfo.getField("I.lookupId.I").get(this);
2014-10-21 11:21:51 +04:00
if (MIDP.RecordStoreCache[lookupId] &&
--MIDP.RecordStoreCache[lookupId].refCount <= 0) {
// Set to null instead of removing from array to maintain
// correspondence between lookup IDs and array indices.
MIDP.RecordStoreCache[lookupId] = null;
}
});
// In the reference implementation, finalize is identical to cleanup0.
Native["com/sun/midp/rms/RecordStoreSharedDBHeader.finalize.()V"] =
Native["com/sun/midp/rms/RecordStoreSharedDBHeader.cleanup0.()V"];
Native.create("com/sun/midp/rms/RecordStoreRegistry.getRecordStoreListeners.(ILjava/lang/String;)[I",
function(suiteId, storeName) {
console.warn("RecordStoreRegistry.getRecordStoreListeners.(IL...String;)[I not implemented (" +
suiteId + ", " + util.fromJavaString(storeName) + ")");
return null;
});
Native.create("com/sun/midp/rms/RecordStoreRegistry.sendRecordStoreChangeEvent.(ILjava/lang/String;II)V",
function(suiteId, storeName, changeType, recordId) {
console.warn("RecordStoreRegistry.sendRecordStoreChangeEvent.(IL...String;II)V not implemented (" +
suiteId + ", " + util.fromJavaString(storeName) + ", " + changeType + ", " + recordId + ")");
});
Native.create("com/sun/midp/rms/RecordStoreRegistry.startRecordStoreListening.(ILjava/lang/String;)V",
function(suiteId, storeName) {
2014-09-04 20:54:20 +04:00
console.warn("RecordStoreRegistry.startRecordStoreListening.(IL...String;)V not implemented (" +
suiteId + ", " + util.fromJavaString(storeName) + ")");
});
2014-09-04 20:54:20 +04:00
Native.create("com/sun/midp/rms/RecordStoreRegistry.stopRecordStoreListening.(ILjava/lang/String;)V",
function(suiteId, storeName) {
console.warn("RecordStoreRegistry.stopRecordStoreListening.(IL...String;)V not implemented (" +
suiteId + ", " + util.fromJavaString(storeName) + ")");
});
Native.create("com/sun/midp/rms/RecordStoreRegistry.stopAllRecordStoreListeners.(I)V", function(taskId) {
console.warn("RecordStoreRegistry.stopAllRecordStoreListeners.(I)V not implemented (" + taskId + ")");
});
2014-09-09 03:36:43 +04:00
Native.create("com/ibm/oti/connection/file/Connection.isValidFilenameImpl.([B)Z", function(path) {
2014-09-09 03:36:43 +04:00
var invalid = ['<', '>', ':', '"', '/', '\\', '|', '*', '?'].map(function(char) {
return char.charCodeAt(0);
});
for (var i = 0; i < path.length; i++) {
if (path[i] <= 31 || invalid.indexOf(path[i]) != -1) {
return false;
2014-09-09 03:36:43 +04:00
}
}
return true;
});
Native.create("com/ibm/oti/connection/file/Connection.availableSizeImpl.([B)J", function(path) {
// Pretend there is 1 GB available
return Long.fromNumber(1024 * 1024 * 1024);
});
Native.create("com/ibm/oti/connection/file/Connection.setHiddenImpl.([BZ)V", function(path, value) {
console.warn("Connection.setHiddenImpl.([BZ)V not implemented (" + util.decodeUtf8(path) + ")");
});
2014-09-04 04:08:56 +04:00
Native.create("com/ibm/oti/connection/file/Connection.existsImpl.([B)Z", function(path) {
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
fs.exists(util.decodeUtf8(path), resolve);
});
}, true);
Native.create("com/ibm/oti/connection/file/Connection.fileSizeImpl.([B)J", function(path) {
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
fs.size(util.decodeUtf8(path), function(size) {
resolve(Long.fromNumber(size));
});
});
}, true);
Native.create("com/ibm/oti/connection/file/Connection.isDirectoryImpl.([B)Z", function(path) {
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
fs.stat(util.decodeUtf8(path), function(stat) {
resolve(!!stat && stat.isDir);
});
});
}, true);
2014-10-17 02:04:31 +04:00
Native.create("com/ibm/oti/connection/file/Connection.listImpl.([B[BZ)[[B",
function(jPath, filterArray, includeHidden) {
2014-10-17 02:04:31 +04:00
var path = util.decodeUtf8(jPath);
return new Promise(function(resolve, reject) {
var filter = "";
if (filterArray) {
filter = util.decodeUtf8(filterArray);
if (filter.contains("?")) {
console.warn("Our implementation of Connection::listImpl assumes the filter doesn't contain the ? wildcard character");
}
2014-10-17 02:04:31 +04:00
// Translate the filter to a regular expression
2014-10-17 02:04:31 +04:00
// Escape regular expression (everything but * and ?)
// Source of the regexp: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
filter = filter.replace(/([.+^${}()|\[\]\/\\])/g, "\\$1");
2014-10-17 02:04:31 +04:00
// Transform * to .+
filter = filter.replace(/\*/g, ".+");
2014-10-17 02:04:31 +04:00
filter += "$";
}
2014-10-17 02:04:31 +04:00
fs.list(path, function(files) {
var regexp = new RegExp(filter);
2014-10-17 02:04:31 +04:00
files = files.filter(regexp.test.bind(regexp));
var filesArray = J2ME.newArray(J2ME.PrimitiveArrayClassInfo.B.klass, files.length);
2014-10-17 02:04:31 +04:00
var added = 0;
2014-10-17 02:04:31 +04:00
function checkDone() {
if (added === files.length) {
resolve(filesArray);
2014-10-17 02:04:31 +04:00
return true;
}
2014-10-17 02:04:31 +04:00
return false;
}
2014-10-17 02:04:31 +04:00
if (checkDone()) {
return;
}
2014-10-17 02:04:31 +04:00
files.forEach(function(file) {
fs.stat(path + "/" + file, function(stat) {
if (stat.isDir) {
file += "/";
}
2014-10-17 02:04:31 +04:00
var bytesFile = new TextEncoder("utf-8").encode(file);
var fileArray = util.newPrimitiveArray("B", bytesFile.byteLength);
2014-10-17 02:04:31 +04:00
fileArray.set(bytesFile);
2014-10-17 02:04:31 +04:00
filesArray[added++] = fileArray;
2014-10-17 02:04:31 +04:00
checkDone();
});
});
});
});
}, true);
Native.create("com/ibm/oti/connection/file/Connection.mkdirImpl.([B)I", function(path) {
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
fs.mkdir(util.decodeUtf8(path), function(created) {
// IBM's implementation returns different error numbers, we don't care
resolve(created ? 0 : 42);
});
});
}, true);
Native.create("com/ibm/oti/connection/file/Connection.newFileImpl.([B)I", function(jPath) {
2014-10-17 02:04:31 +04:00
var path = util.decodeUtf8(jPath);
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
// IBM's implementation returns different error numbers, we don't care
2014-10-17 02:04:31 +04:00
fs.exists(path, function(exists) {
if (exists) {
fs.truncate(path, function(truncated) {
resolve(truncated ? 0 : 42);
});
} else {
fs.create(path, new Blob(), function(created) {
resolve(created ? 0 : 42);
});
}
});
});
}, true);
Native.create("com/ibm/oti/connection/file/Connection.deleteFileImpl.([B)Z", function(path) {
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
fs.remove(util.decodeUtf8(path), resolve);
});
}, true);
2014-10-17 02:04:31 +04:00
Native["com/ibm/oti/connection/file/Connection.deleteDirImpl.([B)Z"] =
Native["com/ibm/oti/connection/file/Connection.deleteFileImpl.([B)Z"]
Native.create("com/ibm/oti/connection/file/Connection.isReadOnlyImpl.([B)Z", function(path) {
console.warn("Connection.isReadOnlyImpl.([B)Z not implemented (" + util.decodeUtf8(path) + ")");
return false;
});
Native.create("com/ibm/oti/connection/file/Connection.isWriteOnlyImpl.([B)Z", function(path) {
console.warn("Connection.isWriteOnlyImpl.([B)Z not implemented (" + util.decodeUtf8(path) + ")");
return false;
});
Native.create("com/ibm/oti/connection/file/Connection.lastModifiedImpl.([B)J", function(path) {
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
fs.stat(util.decodeUtf8(path), function(stat) {
resolve(Long.fromNumber(stat != null ? stat.mtime : 0));
});
2014-09-17 03:40:34 +04:00
});
}, true);
2014-09-11 03:42:44 +04:00
Native.create("com/ibm/oti/connection/file/Connection.renameImpl.([B[B)V", function(oldPath, newPath) {
var ctx = $.ctx;
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
fs.rename(util.decodeUtf8(oldPath), util.decodeUtf8(newPath), function(renamed) {
ctx.setAsCurrentContext();
2014-10-17 02:04:31 +04:00
if (!renamed) {
reject($.newIOException("Rename failed"));
2014-10-17 02:04:31 +04:00
return;
}
2014-10-02 04:19:33 +04:00
2014-10-17 02:04:31 +04:00
resolve();
});
});
}, true);
Native.create("com/ibm/oti/connection/file/Connection.truncateImpl.([BJ)V", function(path, newLength) {
var ctx = $.ctx;
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
fs.open(util.decodeUtf8(path), function(fd) {
ctx.setAsCurrentContext();
if (fd == -1) {
reject($.newIOException("truncate failed"));
return;
2014-10-17 02:04:31 +04:00
}
fs.ftruncate(fd, newLength.toNumber());
2014-11-24 12:49:56 +03:00
fs.close(fd);
resolve();
});
});
}, true);
Native.create("com/ibm/oti/connection/file/FCInputStream.openImpl.([B)I", function(path) {
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
fs.open(util.decodeUtf8(path), resolve);
});
}, true);
Native.create("com/ibm/oti/connection/file/FCInputStream.availableImpl.(I)I", function(fd) {
return fs.getsize(fd) - fs.getpos(fd);
});
2014-09-11 03:59:10 +04:00
Native.create("com/ibm/oti/connection/file/FCInputStream.skipImpl.(JI)J", function(count, fd) {
2014-09-11 03:59:10 +04:00
var curpos = fs.getpos(fd);
var size = fs.getsize(fd);
2014-09-11 04:51:08 +04:00
if (curpos + count.toNumber() > size) {
2014-09-11 03:59:10 +04:00
fs.setpos(fd, size);
return Long.fromNumber(size - curpos);
2014-09-11 03:59:10 +04:00
}
fs.setpos(fd, curpos + count.toNumber());
return count;
});
2014-09-11 21:10:49 +04:00
Native.create("com/ibm/oti/connection/file/FCInputStream.readImpl.([BIII)I", function(buffer, offset, count, fd) {
2014-09-11 21:10:49 +04:00
if (offset < 0 || count < 0 || offset > buffer.byteLength || (buffer.byteLength - offset) < count) {
throw $.newIndexOutOfBoundsException();
2014-09-11 21:12:29 +04:00
}
2014-09-11 21:10:49 +04:00
if (buffer.byteLength == 0 || count == 0) {
return 0;
2014-09-11 21:10:49 +04:00
}
var curpos = fs.getpos(fd);
var data = fs.read(fd, curpos, curpos + count);
2014-09-11 21:45:27 +04:00
buffer.set(data, offset);
2014-09-11 21:10:49 +04:00
return (data.byteLength > 0) ? data.byteLength : -1;
});
Native.create("com/ibm/oti/connection/file/FCInputStream.readByteImpl.(I)I", function(fd) {
var curpos = fs.getpos(fd);
var data = fs.read(fd, curpos, curpos+1);
return (data.byteLength > 0) ? data[0] : -1;
});
Native.create("com/ibm/oti/connection/file/FCInputStream.closeImpl.(I)V", function(fd) {
if (fd >= 0) {
fs.close(fd);
}
});
Native.create("com/ibm/oti/connection/file/FCOutputStream.closeImpl.(I)V", function(fd) {
fs.close(fd);
});
Native.create("com/ibm/oti/connection/file/FCOutputStream.openImpl.([B)I", function(jPath) {
2014-10-17 02:04:31 +04:00
var path = util.decodeUtf8(jPath);
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
fs.exists(path, function(exists) {
if (exists) {
fs.truncate(path, function(truncated) {
if (truncated) {
fs.open(path, resolve);
} else {
resolve(-1);
}
});
} else {
fs.create(path, new Blob(), function(created) {
if (created) {
fs.open(path, resolve);
} else {
resolve(-1);
}
});
}
});
});
}, true);
Native.create("com/ibm/oti/connection/file/FCOutputStream.openOffsetImpl.([BJ)I", function(jPath, offset) {
2014-10-17 02:04:31 +04:00
var path = util.decodeUtf8(jPath);
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
function open() {
fs.open(path, function(fd) {
fs.setpos(fd, offset.toNumber());
resolve(fd);
});
}
2014-10-17 02:04:31 +04:00
fs.exists(path, function(exists) {
if (exists) {
open();
} else {
fs.create(path, new Blob(), function(created) {
if (created) {
open();
} else {
resolve(-1);
}
});
}
});
});
}, true);
Native.create("com/ibm/oti/connection/file/FCOutputStream.syncImpl.(I)V", function(fd) {
2014-11-24 12:49:56 +03:00
fs.flush(fd);
});
Native.create("com/ibm/oti/connection/file/FCOutputStream.writeByteImpl.(II)V", function(val, fd) {
var buf = new Uint8Array(1);
2014-09-12 21:29:41 +04:00
buf[0] = val;
fs.write(fd, buf);
});
Native.create("com/ibm/oti/connection/file/FCOutputStream.writeImpl.([BIII)V",
function(byteArray, offset, count, fd) {
fs.write(fd, byteArray.subarray(offset, offset+count));
});
Native.create("com/sun/midp/io/j2me/storage/RandomAccessStream.open.(Ljava/lang/String;I)I", function(fileName, mode) {
2014-10-17 02:04:31 +04:00
var path = "/" + util.fromJavaString(fileName);
var ctx = $.ctx;
2014-10-17 02:04:31 +04:00
return new Promise(function(resolve, reject) {
function open() {
fs.open(path, function(fd) {
ctx.setAsCurrentContext();
2014-10-17 02:04:31 +04:00
if (fd == -1) {
reject($.newIOException("RandomAccessStream::open(" + path + ") failed opening the file"));
} else {
2014-10-17 02:04:31 +04:00
resolve(fd);
}
});
}
2014-10-17 02:04:31 +04:00
fs.exists(path, function(exists) {
if (exists) {
open();
} else {
fs.create(path, new Blob(), function(created) {
ctx.setAsCurrentContext();
2014-10-17 02:04:31 +04:00
if (created) {
open();
} else {
reject($.newIOException("RandomAccessStream::open(" + path + ") failed creating the file"));
2014-10-17 02:04:31 +04:00
}
});
}
});
});
}, true);
Native.create("com/sun/midp/io/j2me/storage/RandomAccessStream.read.(I[BII)I",
function(handle, buffer, offset, length) {
var from = fs.getpos(handle);
var to = from + length;
var readBytes = fs.read(handle, from, to);
if (readBytes.byteLength <= 0) {
return -1;
}
var subBuffer = buffer.subarray(offset, offset + readBytes.byteLength);
for (var i = 0; i < readBytes.byteLength; i++) {
subBuffer[i] = readBytes[i];
}
return readBytes.byteLength;
});
Native.create("com/sun/midp/io/j2me/storage/RandomAccessStream.write.(I[BII)V",
function(handle, buffer, offset, length) {
fs.write(handle, buffer.subarray(offset, offset + length));
});
Native.create("com/sun/midp/io/j2me/storage/RandomAccessStream.commitWrite.(I)V", function(handle) {
2014-11-24 12:49:56 +03:00
fs.flush(handle);
});
Native.create("com/sun/midp/io/j2me/storage/RandomAccessStream.position.(II)V", function(handle, position) {
fs.setpos(handle, position);
});
Native.create("com/sun/midp/io/j2me/storage/RandomAccessStream.sizeOf.(I)I", function(handle) {
var size = fs.getsize(handle);
if (size == -1) {
throw $.newIOException("RandomAccessStream::sizeOf(" + handle + ") failed");
}
return size;
});
Native.create("com/sun/midp/io/j2me/storage/RandomAccessStream.close.(I)V", function(handle) {
2014-11-24 12:49:56 +03:00
fs.close(handle);
});
Native.create("javax/microedition/io/file/FileSystemRegistry.getRootsImpl.()[Ljava/lang/String;", function() {
var array = J2ME.newStringArray(1);
array[0] = J2ME.newString("");
return array;
});