2014-08-29 01:04:17 +04:00
|
|
|
/* -*- 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-08-29 01:04:17 +04:00
|
|
|
|
2014-09-30 20:17:16 +04:00
|
|
|
var RECORD_STORE_BASE = "/RecordStore";
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-29 12:47:53 +03:00
|
|
|
// The filesystem roots, which are used by both FileSystemRegistry.getRootsImpl
|
|
|
|
// and System.getProperty to provide inquiring midlets with the list. Each root
|
|
|
|
// must have a trailing slash. See FileSystemRegistry.listRoots for more info.
|
|
|
|
MIDP.fsRoots = [
|
2014-12-30 03:08:44 +03:00
|
|
|
"MemoryCard/",
|
|
|
|
"Phone/",
|
|
|
|
"Private/",
|
2014-12-29 12:47:53 +03:00
|
|
|
];
|
|
|
|
// The names here should be localized.
|
|
|
|
MIDP.fsRootNames = [
|
|
|
|
"Memory card",
|
2014-12-30 03:08:44 +03:00
|
|
|
"Phone memory",
|
|
|
|
"Private",
|
2014-12-29 12:47:53 +03:00
|
|
|
];
|
|
|
|
|
|
|
|
function getAbsolutePath(jPath) {
|
|
|
|
return "/" + util.decodeUtf8(jPath);
|
|
|
|
}
|
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/io/j2me/storage/File.initConfigRoot.(I)Ljava/lang/String;"] = function(storageId) {
|
2014-12-23 23:17:16 +03:00
|
|
|
return J2ME.newString("assets/" + storageId + "/");
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2015-01-16 00:08:45 +03:00
|
|
|
Native["com/sun/midp/io/j2me/storage/File.initStorageRoot.(I)Ljava/lang/String;"] = function(storageId) {
|
|
|
|
return J2ME.newString("assets/" + storageId + "/");
|
|
|
|
};
|
2014-12-30 02:41:22 +03:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/midletsuite/MIDletSuiteStorage.getSecureFilenameBase.(I)Ljava/lang/String;"] = function(id) {
|
2014-12-23 23:17:16 +03:00
|
|
|
return J2ME.newString("");
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreUtil.exists.(Ljava/lang/String;Ljava/lang/String;I)Z"] =
|
2014-10-27 14:37:53 +03:00
|
|
|
function(filenameBase, name, ext) {
|
2015-02-02 14:10:57 +03:00
|
|
|
var path = RECORD_STORE_BASE + "/" + util.fromJavaString(filenameBase) + "/" + util.fromJavaString(name) + "." + ext;
|
|
|
|
return fs.exists(path) ? 1 : 0;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreUtil.deleteFile.(Ljava/lang/String;Ljava/lang/String;I)V"] =
|
2014-10-27 14:37:53 +03:00
|
|
|
function(filenameBase, name, ext) {
|
2014-12-23 14:30:18 +03:00
|
|
|
var path = RECORD_STORE_BASE + "/" + util.fromJavaString(filenameBase) + "/" + util.fromJavaString(name) + "." + ext;
|
|
|
|
fs.remove(path);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreFile.spaceAvailableNewRecordStore0.(Ljava/lang/String;I)I"] = function(filenameBase, storageId) {
|
2014-08-29 01:04:17 +04:00
|
|
|
// 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.
|
2014-10-16 06:48:17 +04:00
|
|
|
return 50 * 1024 * 1024;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreFile.spaceAvailableRecordStore.(ILjava/lang/String;I)I"] = function(handle, filenameBase, storageId) {
|
2014-08-29 01:04:17 +04:00
|
|
|
// 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.
|
2014-10-16 06:48:17 +04:00
|
|
|
return 50 * 1024 * 1024;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreFile.openRecordStoreFile.(Ljava/lang/String;Ljava/lang/String;I)I"] =
|
2014-10-27 14:37:53 +03:00
|
|
|
function(filenameBase, name, ext) {
|
2014-12-18 05:12:21 +03:00
|
|
|
var ctx = $.ctx;
|
2014-12-19 00:03:59 +03:00
|
|
|
asyncImpl("I", new Promise(function(resolve, reject) {
|
2014-10-17 02:04:31 +04:00
|
|
|
var path = RECORD_STORE_BASE + "/" + util.fromJavaString(filenameBase) + "/" + util.fromJavaString(name) + "." + ext;
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-10-17 02:04:31 +04:00
|
|
|
function openCallback(fd) {
|
2014-12-18 05:12:21 +03:00
|
|
|
ctx.setAsCurrentContext();
|
2014-10-17 02:04:31 +04:00
|
|
|
if (fd == -1) {
|
2014-12-18 05:12:21 +03:00
|
|
|
reject($.newIOException("openRecordStoreFile: open failed"));
|
2014-10-17 02:04:31 +04:00
|
|
|
} else {
|
|
|
|
resolve(fd); // handle
|
|
|
|
}
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
|
|
|
|
2014-12-23 14:30:18 +03:00
|
|
|
|
|
|
|
if (fs.exists(path)) {
|
|
|
|
fs.open(path, openCallback);
|
|
|
|
} else {
|
|
|
|
// Per the reference impl, create the file if it doesn't exist.
|
|
|
|
var dirname = fs.dirname(path);
|
|
|
|
if (fs.mkdirp(dirname)) {
|
|
|
|
if (fs.create(path, new Blob())) {
|
|
|
|
fs.open(path, openCallback);
|
|
|
|
} else {
|
2015-01-26 07:14:44 +03:00
|
|
|
// TODO: determine if this is actually necessary, as I think
|
|
|
|
// we're still in synchronous execution of the native here.
|
|
|
|
ctx.setAsCurrentContext();
|
|
|
|
|
|
|
|
reject($.newIOException("openRecordStoreFile: create failed"));
|
2014-12-23 14:30:18 +03:00
|
|
|
}
|
2014-10-17 02:04:31 +04:00
|
|
|
} else {
|
2015-01-26 07:14:44 +03:00
|
|
|
// TODO: determine if this is actually necessary, as I think
|
|
|
|
// we're still in synchronous execution of the native here.
|
|
|
|
ctx.setAsCurrentContext();
|
|
|
|
|
|
|
|
reject($.newIOException("openRecordStoreFile: mkdirp failed"));
|
2014-10-17 02:04:31 +04:00
|
|
|
}
|
2014-12-23 14:30:18 +03:00
|
|
|
}
|
2014-12-19 00:03:59 +03:00
|
|
|
}));
|
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreFile.setPosition.(II)V"] = function(handle, pos) {
|
2014-08-29 01:04:17 +04:00
|
|
|
fs.setpos(handle, pos);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreFile.readBytes.(I[BII)I"] = function(handle, buf, offset, numBytes) {
|
2014-08-29 01:04:17 +04:00
|
|
|
var from = fs.getpos(handle);
|
|
|
|
var to = from + numBytes;
|
|
|
|
var readBytes = fs.read(handle, from, to);
|
|
|
|
|
|
|
|
if (readBytes.byteLength <= 0) {
|
2014-12-18 05:12:21 +03:00
|
|
|
throw $.newIOException("handle invalid or segment indices out of bounds");
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
var subBuffer = buf.subarray(offset, offset + readBytes.byteLength);
|
|
|
|
for (var i = 0; i < readBytes.byteLength; i++) {
|
|
|
|
subBuffer[i] = readBytes[i];
|
|
|
|
}
|
2014-10-16 06:48:17 +04:00
|
|
|
return readBytes.byteLength;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreFile.writeBytes.(I[BII)V"] = function(handle, buf, offset, numBytes) {
|
2014-08-29 01:04:17 +04:00
|
|
|
fs.write(handle, buf.subarray(offset, offset + numBytes));
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreFile.commitWrite.(I)V"] = function(handle) {
|
2015-02-02 14:10:57 +03:00
|
|
|
fs.flush(handle);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreFile.closeFile.(I)V"] = function(handle) {
|
2015-02-02 14:10:57 +03:00
|
|
|
fs.close(handle);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["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);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
|
|
|
MIDP.RecordStoreCache = [];
|
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreSharedDBHeader.getLookupId0.(ILjava/lang/String;I)I"] =
|
2014-10-27 14:37:53 +03:00
|
|
|
function(suiteId, jStoreName, headerDataSize) {
|
2014-10-16 06:48:17 +04:00
|
|
|
var storeName = util.fromJavaString(jStoreName);
|
2014-08-29 01:04:17 +04:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2014-10-16 06:48:17 +04:00
|
|
|
return sharedHeader.lookupId;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreSharedDBHeader.shareCachedData0.(I[BI)I"] = function(lookupId, headerData, headerDataSize) {
|
2014-08-29 01:04:17 +04:00
|
|
|
var sharedHeader = MIDP.RecordStoreCache[lookupId];
|
|
|
|
if (!sharedHeader) {
|
2014-12-18 05:12:21 +03:00
|
|
|
throw $.newIllegalStateException("invalid header lookup ID");
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!headerData) {
|
2014-12-18 05:12:21 +03:00
|
|
|
throw $.newIllegalArgumentException("header data is null");
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
var size = headerDataSize;
|
|
|
|
if (size > sharedHeader.headerDataSize) {
|
|
|
|
size = sharedHeader.headerDataSize;
|
|
|
|
}
|
|
|
|
sharedHeader.headerData = headerData.buffer.slice(0, size);
|
|
|
|
++sharedHeader.headerVersion;
|
|
|
|
|
2014-10-16 06:48:17 +04:00
|
|
|
return sharedHeader.headerVersion;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreSharedDBHeader.updateCachedData0.(I[BII)I"] =
|
2014-10-27 14:37:53 +03:00
|
|
|
function(lookupId, headerData, headerDataSize, headerVersion) {
|
2014-08-29 01:04:17 +04:00
|
|
|
var sharedHeader = MIDP.RecordStoreCache[lookupId];
|
|
|
|
if (!sharedHeader) {
|
2014-12-18 05:12:21 +03:00
|
|
|
throw $.newIllegalStateException("invalid header lookup ID");
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!headerData) {
|
2014-12-18 05:12:21 +03:00
|
|
|
throw $.newIllegalArgumentException("header data is null");
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (sharedHeader.headerVersion > headerVersion && sharedHeader.headerData) {
|
|
|
|
var size = sharedHeader.headerDataSize;
|
|
|
|
if (size > headerDataSize) {
|
|
|
|
size = headerDataSize;
|
|
|
|
}
|
2014-12-12 01:36:47 +03:00
|
|
|
var sharedHeaderData = new Int8Array(sharedHeader.headerData);
|
2014-08-29 01:04:17 +04:00
|
|
|
for (var i = 0; i < size; i++) {
|
2014-12-12 01:36:47 +03:00
|
|
|
headerData[i] = sharedHeaderData[i];
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
2014-10-16 06:48:17 +04:00
|
|
|
return sharedHeader.headerVersion;
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
|
|
|
|
2014-10-16 06:48:17 +04:00
|
|
|
return headerVersion;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreSharedDBHeader.getHeaderRefCount0.(I)I"] = function(lookupId) {
|
2014-08-29 01:04:17 +04:00
|
|
|
var sharedHeader = MIDP.RecordStoreCache[lookupId];
|
|
|
|
if (!sharedHeader) {
|
2014-12-18 05:12:21 +03:00
|
|
|
throw $.newIllegalStateException("invalid header lookup ID");
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
|
|
|
|
2014-10-16 06:48:17 +04:00
|
|
|
return sharedHeader.refCount;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["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;
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
|
|
|
// 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"];
|
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreRegistry.getRecordStoreListeners.(ILjava/lang/String;)[I"] =
|
2014-10-27 14:37:53 +03:00
|
|
|
function(suiteId, storeName) {
|
2014-08-29 01:04:17 +04:00
|
|
|
console.warn("RecordStoreRegistry.getRecordStoreListeners.(IL...String;)[I not implemented (" +
|
2014-10-16 06:48:17 +04:00
|
|
|
suiteId + ", " + util.fromJavaString(storeName) + ")");
|
|
|
|
return null;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreRegistry.sendRecordStoreChangeEvent.(ILjava/lang/String;II)V"] =
|
2014-10-27 14:37:53 +03:00
|
|
|
function(suiteId, storeName, changeType, recordId) {
|
2014-08-29 01:04:17 +04:00
|
|
|
console.warn("RecordStoreRegistry.sendRecordStoreChangeEvent.(IL...String;II)V not implemented (" +
|
2014-10-16 06:48:17 +04:00
|
|
|
suiteId + ", " + util.fromJavaString(storeName) + ", " + changeType + ", " + recordId + ")");
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreRegistry.startRecordStoreListening.(ILjava/lang/String;)V"] =
|
2014-10-27 14:37:53 +03:00
|
|
|
function(suiteId, storeName) {
|
2014-09-04 20:54:20 +04:00
|
|
|
console.warn("RecordStoreRegistry.startRecordStoreListening.(IL...String;)V not implemented (" +
|
2014-10-16 06:48:17 +04:00
|
|
|
suiteId + ", " + util.fromJavaString(storeName) + ")");
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-09-04 20:54:20 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreRegistry.stopRecordStoreListening.(ILjava/lang/String;)V"] =
|
2014-10-27 14:37:53 +03:00
|
|
|
function(suiteId, storeName) {
|
2014-08-29 01:04:17 +04:00
|
|
|
console.warn("RecordStoreRegistry.stopRecordStoreListening.(IL...String;)V not implemented (" +
|
2014-10-16 06:48:17 +04:00
|
|
|
suiteId + ", " + util.fromJavaString(storeName) + ")");
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/rms/RecordStoreRegistry.stopAllRecordStoreListeners.(I)V"] = function(taskId) {
|
2014-08-29 01:04:17 +04:00
|
|
|
console.warn("RecordStoreRegistry.stopAllRecordStoreListeners.(I)V not implemented (" + taskId + ")");
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-09-09 03:36:43 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["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) {
|
2014-12-19 00:03:59 +03:00
|
|
|
return 0;
|
2014-09-09 03:36:43 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
return 1;
|
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-30 07:59:01 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.totalSizeImpl.([B)J"] = function(root) {
|
2014-12-29 07:44:56 +03:00
|
|
|
console.warn("Connection.totalSizeImpl.([B)J not implemented (" + util.decodeUtf8(root) + ")");
|
|
|
|
return Long.fromNumber(-1);
|
2014-12-30 07:59:01 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2015-01-26 07:14:44 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.existsImpl.([B)Z"] = function(path) {
|
|
|
|
return fs.exists(getAbsolutePath(path)) ? 1 : 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/ibm/oti/connection/file/Connection.fileSizeImpl.([B)J"] = function(path) {
|
|
|
|
return Long.fromNumber(fs.size(getAbsolutePath(path)));
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/ibm/oti/connection/file/Connection.isDirectoryImpl.([B)Z"] = function(path) {
|
|
|
|
var stat = fs.stat(getAbsolutePath(path));
|
|
|
|
return !!stat && stat.isDir ? 1 : 0;
|
|
|
|
};
|
|
|
|
|
2014-12-30 07:59:01 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.usedSizeImpl.([B)J"] = function(root) {
|
2014-12-29 07:44:56 +03:00
|
|
|
console.warn("Connection.usedSizeImpl.([B)J not implemented (" + util.decodeUtf8(root) + ")");
|
|
|
|
return Long.fromNumber(-1);
|
2014-12-30 07:59:01 +03:00
|
|
|
};
|
2014-12-29 07:44:56 +03:00
|
|
|
|
2015-01-03 01:00:22 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.availableSizeImpl.([B)J"] = function(root) {
|
2014-12-29 07:44:56 +03:00
|
|
|
console.warn("Connection.availableSizeImpl.([B)J not implemented (" + util.decodeUtf8(root) + ")");
|
2014-09-04 03:31:27 +04:00
|
|
|
// Pretend there is 1 GB available
|
2014-10-16 06:48:17 +04:00
|
|
|
return Long.fromNumber(1024 * 1024 * 1024);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-09-04 03:31:27 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.setHiddenImpl.([BZ)V"] = function(path, value) {
|
2014-10-16 06:48:17 +04:00
|
|
|
console.warn("Connection.setHiddenImpl.([BZ)V not implemented (" + util.decodeUtf8(path) + ")");
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-09-04 03:31:27 +04:00
|
|
|
|
2015-01-07 04:29:40 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.setReadOnlyImpl.([BZ)V"] = function(path, value) {
|
|
|
|
console.warn("Connection.setReadOnlyImpl.([BZ)V not implemented (" + util.decodeUtf8(path) + ")");
|
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2015-01-07 04:29:40 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.setWriteOnlyImpl.([BZ)V"] = function(path, value) {
|
|
|
|
console.warn("Connection.setWriteOnlyImpl.([BZ)V not implemented (" + util.decodeUtf8(path) + ")");
|
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-30 07:59:01 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.directorySizeImpl.([BZ)J"] = function(path, includeSubDirs) {
|
2014-12-29 12:47:53 +03:00
|
|
|
console.warn("Connection.directorySizeImpl.([BZ)J not implemented (" + getAbsolutePath(path) + ", " + includeSubDirs + ")");
|
2014-12-29 07:44:56 +03:00
|
|
|
return Long.fromNumber(0);
|
2014-12-30 07:59:01 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2015-01-26 07:14:44 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.listImpl.([B[BZ)[[B"] = function(jPath, filterArray, includeHidden) {
|
|
|
|
var path = getAbsolutePath(jPath);
|
2014-12-23 14:30:18 +03:00
|
|
|
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-08-29 01:04:17 +04:00
|
|
|
|
2014-12-23 14:30:18 +03:00
|
|
|
// Translate the filter to a regular expression
|
2014-09-12 02:40:31 +04:00
|
|
|
|
2014-12-23 14:30:18 +03: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-09-12 21:37:33 +04:00
|
|
|
|
2015-01-26 07:14:44 +03:00
|
|
|
// Transform * to .*
|
|
|
|
filter = filter.replace(/\*/g, ".*");
|
2014-09-12 21:37:33 +04:00
|
|
|
|
2015-01-26 07:14:44 +03:00
|
|
|
// Require filter to match from the beginning to the end.
|
|
|
|
filter = "^" + filter + "$";
|
2014-12-23 14:30:18 +03:00
|
|
|
}
|
2014-09-12 21:37:33 +04:00
|
|
|
|
2014-12-23 14:30:18 +03:00
|
|
|
var files;
|
2014-12-22 12:04:18 +03:00
|
|
|
|
2014-12-23 14:30:18 +03:00
|
|
|
try {
|
|
|
|
files = fs.list(path);
|
|
|
|
} catch (ex) {
|
|
|
|
// For these exceptions, we append a URL representation of the path
|
|
|
|
// in Connection.listInternal, so we don't have to implement getURL
|
|
|
|
// in native code.
|
|
|
|
if (ex.message == "Path does not exist") {
|
2015-01-26 07:14:44 +03:00
|
|
|
throw $.newIOException("Directory does not exist: ");
|
2014-12-23 14:30:18 +03:00
|
|
|
}
|
|
|
|
if (ex.message == "Path is not a directory") {
|
2015-01-26 07:14:44 +03:00
|
|
|
throw $.newIOException("Connection is open on a file: ");
|
2014-12-23 14:30:18 +03:00
|
|
|
}
|
|
|
|
}
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-23 14:30:18 +03:00
|
|
|
var regexp = new RegExp(filter);
|
|
|
|
files = files.filter(regexp.test.bind(regexp));
|
2015-01-26 07:14:44 +03:00
|
|
|
var filesArray = J2ME.newArray(J2ME.PrimitiveArrayClassInfo.B.klass, files.length);
|
2014-12-23 14:30:18 +03:00
|
|
|
var encoder = new TextEncoder("utf-8");
|
2014-12-22 13:27:19 +03:00
|
|
|
|
2014-12-23 14:30:18 +03:00
|
|
|
files.forEach(function(file, i) {
|
|
|
|
var bytesFile = encoder.encode(file);
|
2015-01-28 06:02:07 +03:00
|
|
|
var fileArray = J2ME.newByteArray(bytesFile.byteLength);
|
2014-12-23 14:30:18 +03:00
|
|
|
fileArray.set(bytesFile);
|
|
|
|
filesArray[i] = fileArray;
|
2014-08-29 01:04:17 +04:00
|
|
|
});
|
2014-12-23 14:30:18 +03:00
|
|
|
|
|
|
|
return filesArray;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.mkdirImpl.([B)I"] = function(path) {
|
2014-12-23 14:30:18 +03:00
|
|
|
// IBM's implementation returns different error numbers, we don't care
|
2015-01-26 07:14:44 +03:00
|
|
|
return fs.mkdir(getAbsolutePath(path)) ? 0 : 42;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.newFileImpl.([B)I"] = function(jPath) {
|
2014-12-29 12:47:53 +03:00
|
|
|
var path = getAbsolutePath(jPath);
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2015-01-26 07:14:44 +03:00
|
|
|
var stat = fs.stat(path);
|
|
|
|
if (stat !== null) {
|
|
|
|
return stat.isDir ? 3 : 1;
|
2014-12-23 14:30:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return fs.create(path, new Blob()) ? 0 : 42;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.deleteFileImpl.([B)Z"] = function(path) {
|
2015-01-26 07:14:44 +03:00
|
|
|
return fs.remove(getAbsolutePath(path)) ? 1 : 0;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-10-17 02:04:31 +04:00
|
|
|
|
|
|
|
Native["com/ibm/oti/connection/file/Connection.deleteDirImpl.([B)Z"] =
|
2015-01-14 22:55:30 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.deleteFileImpl.([B)Z"];
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.isReadOnlyImpl.([B)Z"] = function(path) {
|
2014-12-29 12:47:53 +03:00
|
|
|
console.warn("Connection.isReadOnlyImpl.([B)Z not implemented (" + getAbsolutePath(path) + ")");
|
2014-12-19 00:03:59 +03:00
|
|
|
return 0;
|
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.isWriteOnlyImpl.([B)Z"] = function(path) {
|
2014-12-29 12:47:53 +03:00
|
|
|
console.warn("Connection.isWriteOnlyImpl.([B)Z not implemented (" + getAbsolutePath(path) + ")");
|
2014-12-19 00:03:59 +03:00
|
|
|
return 0;
|
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.lastModifiedImpl.([B)J"] = function(path) {
|
2015-01-26 07:14:44 +03:00
|
|
|
var stat = fs.stat(getAbsolutePath(path));
|
2014-12-23 14:30:18 +03:00
|
|
|
return Long.fromNumber(stat != null ? stat.mtime : 0);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-09-11 03:42:44 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.renameImpl.([B[B)V"] = function(oldPath, newPath) {
|
2015-01-26 07:14:44 +03:00
|
|
|
if (!fs.rename(getAbsolutePath(oldPath), getAbsolutePath(newPath))) {
|
|
|
|
throw $.newIOException("Rename failed");
|
2014-12-23 14:30:18 +03:00
|
|
|
}
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/Connection.truncateImpl.([BJ)V"] = function(path, newLength) {
|
2014-12-18 05:12:21 +03:00
|
|
|
var ctx = $.ctx;
|
2014-12-19 00:03:59 +03:00
|
|
|
asyncImpl("V", new Promise(function(resolve, reject) {
|
2014-12-29 12:47:53 +03:00
|
|
|
fs.open(getAbsolutePath(path), function(fd) {
|
2014-12-18 05:12:21 +03:00
|
|
|
ctx.setAsCurrentContext();
|
2014-11-07 20:34:18 +03:00
|
|
|
if (fd == -1) {
|
2014-12-18 05:12:21 +03:00
|
|
|
reject($.newIOException("truncate failed"));
|
2014-11-07 20:34:18 +03:00
|
|
|
return;
|
2014-10-17 02:04:31 +04:00
|
|
|
}
|
2014-11-07 20:34:18 +03:00
|
|
|
|
|
|
|
fs.ftruncate(fd, newLength.toNumber());
|
2014-11-24 12:49:56 +03:00
|
|
|
fs.close(fd);
|
|
|
|
resolve();
|
2014-08-29 01:04:17 +04:00
|
|
|
});
|
2014-12-19 00:03:59 +03:00
|
|
|
}));
|
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/FCInputStream.openImpl.([B)I"] = function(path) {
|
|
|
|
asyncImpl("I", new Promise(function(resolve, reject) {
|
2014-12-29 12:47:53 +03:00
|
|
|
fs.open(getAbsolutePath(path), resolve);
|
2014-12-19 00:03:59 +03:00
|
|
|
}));
|
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/FCInputStream.availableImpl.(I)I"] = function(fd) {
|
2014-10-16 06:48:17 +04:00
|
|
|
return fs.getsize(fd) - fs.getpos(fd);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-09-11 03:59:10 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["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);
|
2014-10-16 06:48:17 +04:00
|
|
|
return Long.fromNumber(size - curpos);
|
2014-09-11 03:59:10 +04:00
|
|
|
}
|
|
|
|
|
2014-10-16 06:48:17 +04:00
|
|
|
fs.setpos(fd, curpos + count.toNumber());
|
|
|
|
return count;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-09-11 21:10:49 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["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) {
|
2014-12-18 05:12:21 +03:00
|
|
|
throw $.newIndexOutOfBoundsException();
|
2014-09-11 21:12:29 +04:00
|
|
|
}
|
2014-09-11 21:10:49 +04:00
|
|
|
|
|
|
|
if (buffer.byteLength == 0 || count == 0) {
|
2014-10-16 06:48:17 +04:00
|
|
|
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
|
|
|
|
2014-10-16 06:48:17 +04:00
|
|
|
return (data.byteLength > 0) ? data.byteLength : -1;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/FCInputStream.readByteImpl.(I)I"] = function(fd) {
|
2014-08-29 01:04:17 +04:00
|
|
|
var curpos = fs.getpos(fd);
|
|
|
|
|
|
|
|
var data = fs.read(fd, curpos, curpos+1);
|
|
|
|
|
2015-02-04 08:38:00 +03:00
|
|
|
return (data.byteLength > 0) ? (data[0] & 0xFF) : -1;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-09-12 04:58:29 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/FCInputStream.closeImpl.(I)V"] = function(fd) {
|
2014-09-12 04:58:29 +04:00
|
|
|
if (fd >= 0) {
|
|
|
|
fs.close(fd);
|
|
|
|
}
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/FCOutputStream.closeImpl.(I)V"] = function(fd) {
|
2014-11-24 03:59:08 +03:00
|
|
|
fs.close(fd);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/FCOutputStream.openImpl.([B)I"] = function(jPath) {
|
2014-12-29 12:47:53 +03:00
|
|
|
var path = getAbsolutePath(jPath);
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
asyncImpl("I", new Promise(function(resolve, reject) {
|
2014-12-23 14:30:18 +03:00
|
|
|
if (fs.exists(path)) {
|
|
|
|
fs.open(path, function(fd) {
|
|
|
|
if (fd != -1) {
|
|
|
|
fs.ftruncate(fd, 0);
|
|
|
|
}
|
|
|
|
resolve(fd);
|
|
|
|
});
|
|
|
|
} else if (fs.create(path, new Blob())) {
|
|
|
|
fs.open(path, resolve);
|
|
|
|
} else {
|
|
|
|
resolve(-1);
|
|
|
|
}
|
2014-12-19 00:03:59 +03:00
|
|
|
}));
|
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/FCOutputStream.openOffsetImpl.([BJ)I"] = function(jPath, offset) {
|
2014-12-29 12:47:53 +03:00
|
|
|
var path = getAbsolutePath(jPath);
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
asyncImpl("I", new Promise(function(resolve, reject) {
|
2014-10-17 02:04:31 +04:00
|
|
|
function open() {
|
|
|
|
fs.open(path, function(fd) {
|
|
|
|
fs.setpos(fd, offset.toNumber());
|
|
|
|
resolve(fd);
|
2014-08-29 01:04:17 +04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-12-23 14:30:18 +03:00
|
|
|
if (fs.exists(path)) {
|
|
|
|
open();
|
|
|
|
} else if (fs.create(path, new Blob())) {
|
|
|
|
open();
|
|
|
|
} else {
|
|
|
|
resolve(-1);
|
|
|
|
}
|
2014-12-19 00:03:59 +03:00
|
|
|
}));
|
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/FCOutputStream.syncImpl.(I)V"] = function(fd) {
|
2014-11-24 12:49:56 +03:00
|
|
|
fs.flush(fd);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/FCOutputStream.writeByteImpl.(II)V"] = function(val, fd) {
|
2015-02-04 08:38:00 +03:00
|
|
|
var buf = new Int8Array(1);
|
2014-09-12 21:29:41 +04:00
|
|
|
buf[0] = val;
|
2014-09-11 23:35:07 +04:00
|
|
|
fs.write(fd, buf);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/ibm/oti/connection/file/FCOutputStream.writeImpl.([BIII)V"] =
|
2014-10-27 14:37:53 +03:00
|
|
|
function(byteArray, offset, count, fd) {
|
2014-08-29 01:04:17 +04:00
|
|
|
fs.write(fd, byteArray.subarray(offset, offset+count));
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["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);
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-18 05:12:21 +03:00
|
|
|
var ctx = $.ctx;
|
2014-12-19 00:03:59 +03:00
|
|
|
asyncImpl("I", new Promise(function(resolve, reject) {
|
2014-10-17 02:04:31 +04:00
|
|
|
function open() {
|
|
|
|
fs.open(path, function(fd) {
|
2014-12-18 05:12:21 +03:00
|
|
|
ctx.setAsCurrentContext();
|
2014-10-17 02:04:31 +04:00
|
|
|
if (fd == -1) {
|
2014-12-18 05:12:21 +03:00
|
|
|
reject($.newIOException("RandomAccessStream::open(" + path + ") failed opening the file"));
|
2014-08-29 01:04:17 +04:00
|
|
|
} else {
|
2014-10-17 02:04:31 +04:00
|
|
|
resolve(fd);
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-12-23 14:30:18 +03:00
|
|
|
if (fs.exists(path)) {
|
|
|
|
open();
|
2015-01-26 07:14:44 +03:00
|
|
|
} else if (mode == 1) {
|
2015-01-02 20:13:34 +03:00
|
|
|
ctx.setAsCurrentContext();
|
2015-01-26 07:14:44 +03:00
|
|
|
reject($.newIOException("RandomAccessStream::open(" + path + ") file doesn't exist"));
|
2014-12-23 14:30:18 +03:00
|
|
|
} else if (fs.create(path, new Blob())) {
|
|
|
|
open();
|
|
|
|
} else {
|
2015-01-26 07:14:44 +03:00
|
|
|
ctx.setAsCurrentContext();
|
|
|
|
reject($.newIOException("RandomAccessStream::open(" + path + ") failed creating the file"));
|
2014-12-23 14:30:18 +03:00
|
|
|
}
|
2014-12-19 00:03:59 +03:00
|
|
|
}));
|
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/io/j2me/storage/RandomAccessStream.read.(I[BII)I"] =
|
2014-10-27 14:37:53 +03:00
|
|
|
function(handle, buffer, offset, length) {
|
2014-08-29 01:04:17 +04:00
|
|
|
var from = fs.getpos(handle);
|
|
|
|
var to = from + length;
|
|
|
|
var readBytes = fs.read(handle, from, to);
|
|
|
|
|
|
|
|
if (readBytes.byteLength <= 0) {
|
2014-10-16 06:48:17 +04:00
|
|
|
return -1;
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
var subBuffer = buffer.subarray(offset, offset + readBytes.byteLength);
|
|
|
|
for (var i = 0; i < readBytes.byteLength; i++) {
|
|
|
|
subBuffer[i] = readBytes[i];
|
|
|
|
}
|
2014-10-16 06:48:17 +04:00
|
|
|
return readBytes.byteLength;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/io/j2me/storage/RandomAccessStream.write.(I[BII)V"] =
|
2014-10-27 14:37:53 +03:00
|
|
|
function(handle, buffer, offset, length) {
|
2014-08-29 01:04:17 +04:00
|
|
|
fs.write(handle, buffer.subarray(offset, offset + length));
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/io/j2me/storage/RandomAccessStream.commitWrite.(I)V"] = function(handle) {
|
2014-11-24 12:49:56 +03:00
|
|
|
fs.flush(handle);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/io/j2me/storage/RandomAccessStream.position.(II)V"] = function(handle, position) {
|
2014-08-29 01:04:17 +04:00
|
|
|
fs.setpos(handle, position);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/io/j2me/storage/RandomAccessStream.sizeOf.(I)I"] = function(handle) {
|
2014-08-29 01:04:17 +04:00
|
|
|
var size = fs.getsize(handle);
|
|
|
|
|
|
|
|
if (size == -1) {
|
2014-12-18 05:12:21 +03:00
|
|
|
throw $.newIOException("RandomAccessStream::sizeOf(" + handle + ") failed");
|
2014-08-29 01:04:17 +04:00
|
|
|
}
|
|
|
|
|
2014-10-16 06:48:17 +04:00
|
|
|
return size;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-08-29 01:04:17 +04:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["com/sun/midp/io/j2me/storage/RandomAccessStream.close.(I)V"] = function(handle) {
|
2014-12-23 14:30:18 +03:00
|
|
|
fs.close(handle);
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2014-11-19 17:45:21 +03:00
|
|
|
|
2014-12-30 07:59:01 +03:00
|
|
|
Native["javax/microedition/io/file/FileSystemRegistry.initImpl.()V"] = function() {
|
2014-12-29 07:44:56 +03:00
|
|
|
console.warn("javax/microedition/io/file/FileSystemRegistry.initImpl.()V not implemented");
|
2014-12-30 07:59:01 +03:00
|
|
|
};
|
2014-12-29 07:44:56 +03:00
|
|
|
|
2014-12-19 00:03:59 +03:00
|
|
|
Native["javax/microedition/io/file/FileSystemRegistry.getRootsImpl.()[Ljava/lang/String;"] = function() {
|
2014-12-30 07:59:01 +03:00
|
|
|
var array = J2ME.newStringArray(MIDP.fsRoots.length);
|
2014-12-29 12:47:53 +03:00
|
|
|
|
|
|
|
for (var i = 0; i < MIDP.fsRoots.length; i++) {
|
2014-12-30 07:59:01 +03:00
|
|
|
array[i] = J2ME.newString(MIDP.fsRoots[i]);
|
2014-12-29 12:47:53 +03:00
|
|
|
}
|
2014-11-19 17:45:21 +03:00
|
|
|
|
|
|
|
return array;
|
2014-12-19 00:03:59 +03:00
|
|
|
};
|
2015-02-05 23:34:32 +03:00
|
|
|
|
|
|
|
addUnimplementedNative("com/sun/cdc/io/j2me/file/DefaultFileHandler.initialize.()V");
|
|
|
|
|
2015-02-06 03:34:27 +03:00
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.illegalFileNameChars0.()Ljava/lang/String;"] = function() {
|
|
|
|
return J2ME.newString('<>:"\\|?');
|
|
|
|
};
|
2015-02-05 23:34:32 +03:00
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.getFileSeparator.()C"] = function() {
|
|
|
|
return "/".charCodeAt(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.getNativePathForRoot.(Ljava/lang/String;)Ljava/lang/String;"] =
|
|
|
|
function(root) {
|
|
|
|
// XXX Ensure root is in MIDP.fsRoots?
|
|
|
|
console.log("getNativePathForRoot: " + util.fromJavaString(root));
|
|
|
|
var nativePath = J2ME.newString("/" + util.fromJavaString(root));
|
|
|
|
return nativePath;
|
|
|
|
};
|
|
|
|
|
|
|
|
MIDP.nativeFileNameToPointer = new Map();
|
|
|
|
MIDP.nativeFilePointerToName = new Map();
|
|
|
|
MIDP.lastNativeFilePointer = 0;
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.getNativeName.(Ljava/lang/String;J)J"] = function(name, oldName) {
|
|
|
|
name = fs.normalize(util.fromJavaString(name));
|
|
|
|
var pointer;
|
|
|
|
if (MIDP.nativeFileNameToPointer.has(name)) {
|
|
|
|
pointer = MIDP.nativeFileNameToPointer.get(name);
|
|
|
|
} else {
|
|
|
|
pointer = ++MIDP.lastNativeFilePointer;
|
|
|
|
MIDP.nativeFileNameToPointer.set(name, pointer);
|
|
|
|
MIDP.nativeFilePointerToName.set(pointer, name);
|
|
|
|
}
|
|
|
|
console.log(name + " has pointer " + pointer);
|
|
|
|
return Long.fromNumber(pointer);
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.getSuiteIdString.(I)Ljava/lang/String;"] = function(id) {
|
|
|
|
console.log("getSuiteIdString: " + id);
|
|
|
|
// return J2ME.newString(id.toString());
|
|
|
|
// The implementation adds this to the path of the file, presumably
|
|
|
|
// to segregate files by midlet, but we only run a single midlet
|
|
|
|
// per installation, so presumably we don't have to do that.
|
|
|
|
return J2ME.newString("");
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.exists.()Z"] = function() {
|
|
|
|
// console.log("exists: " + [p for (p in this)].join(","));
|
|
|
|
// console.log("exists: " + (this["$fileName"].toNumber()));
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
var exists = fs.exists(pathname);
|
|
|
|
console.log("DefaultFileHandler.exists: " + pathname + " " + exists);
|
|
|
|
return exists ? 1 : 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.mkdir.()V"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.mkdir: " + pathname);
|
|
|
|
|
|
|
|
if (!fs.mkdir(pathname)) {
|
|
|
|
throw $.newIOException("error creating " + pathname);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.getMountedRoots.()Ljava/lang/String;"] = function() {
|
|
|
|
return J2ME.newString(MIDP.fsRoots.join("\n"));
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.isDirectory.()Z"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
var stat = fs.stat(pathname);
|
|
|
|
var isDirectory = !!stat && stat.isDir;
|
|
|
|
console.log("DefaultFileHandler.isDirectory: " + pathname + " " + (isDirectory));
|
|
|
|
return isDirectory ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
MIDP.openDirs = new Map();
|
|
|
|
MIDP.openDirHandle = 0;
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.openDir.()J"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.openDir: " + pathname);
|
|
|
|
|
|
|
|
try {
|
|
|
|
var files = fs.list(pathname);
|
|
|
|
} catch(ex) {
|
|
|
|
if (ex.message == "Path does not exist") {
|
|
|
|
throw $.newIOException("Directory does not exist: file://" + pathname);
|
|
|
|
}
|
|
|
|
if (ex.message == "Path is not a directory") {
|
|
|
|
throw $.newIOException("Connection is open on a file: file://" + pathname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var openDirHandle = ++MIDP.openDirHandle;
|
|
|
|
|
|
|
|
MIDP.openDirs.set(openDirHandle, {
|
|
|
|
files: files,
|
|
|
|
index: -1,
|
|
|
|
});
|
|
|
|
|
|
|
|
return Long.fromNumber(openDirHandle);
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.closeDir.(J)V"] = function(dirHandle) {
|
|
|
|
MIDP.openDirs.delete(dirHandle.toNumber());
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.dirGetNextFile.(JZ)Ljava/lang/String;"] =
|
|
|
|
function(dirHandle, includeHidden) {
|
|
|
|
var iterator = MIDP.openDirs.get(dirHandle.toNumber());
|
|
|
|
var nextFile = iterator.files[++iterator.index];
|
|
|
|
console.log(iterator.index + " " + nextFile);
|
|
|
|
return nextFile ? J2ME.newString(nextFile) : null;
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.create.()V"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.create: " + pathname);
|
|
|
|
|
|
|
|
var stat = fs.stat(pathname);
|
|
|
|
|
|
|
|
if (stat !== null || !fs.create(pathname, new Blob())) {
|
|
|
|
throw $.newIOException("error creating " + pathname);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.fileSize.()J"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.fileSize: " + pathname);
|
|
|
|
|
|
|
|
return Long.fromNumber(fs.size(pathname));
|
|
|
|
};
|
|
|
|
|
|
|
|
addUnimplementedNative("com/sun/cdc/io/j2me/file/DefaultFileHandler.canWrite.()Z", 1);
|
|
|
|
|
|
|
|
MIDP.openFiles = new Map();
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.openForWrite.()V"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.openForWrite: " + pathname);
|
|
|
|
var fileNumber = this.$fileName;
|
|
|
|
asyncImpl("I", new Promise(function(resolve, reject) {
|
|
|
|
fs.open(pathname, function(fd) {
|
|
|
|
// The key is the $fileName Long, not the primitive number
|
|
|
|
// it represents, so a file can be opened by multiple handlers.
|
|
|
|
MIDP.openFiles.set(fileNumber, fd);
|
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.positionForWrite.(J)V"] = function(offset) {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.positionForWrite: " + pathname);
|
|
|
|
var fd = MIDP.openFiles.get(this.$fileName);
|
|
|
|
fs.setpos(fd, offset.toNumber());
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.write.([BII)I"] = function(b, off, len) {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.write: " + pathname);
|
|
|
|
var fd = MIDP.openFiles.get(this.$fileName);
|
|
|
|
fs.write(fd, b.subarray(off, off + len));
|
|
|
|
// The "length of data really written," which is always the length requested
|
|
|
|
// in our implementation.
|
|
|
|
return len;
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.flush.()V"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.flush: " + pathname);
|
|
|
|
var fd = MIDP.openFiles.get(this.$fileName);
|
|
|
|
fs.flush(fd);
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.close.()V"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.close: " + pathname);
|
|
|
|
var fd = MIDP.openFiles.get(this.$fileName);
|
|
|
|
fs.close(fd);
|
|
|
|
MIDP.openFiles.delete(this.$fileName);
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.closeForWrite.()V"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.closeForWrite: " + pathname);
|
|
|
|
var fd = MIDP.openFiles.get(this.$fileName);
|
|
|
|
fs.close(fd);
|
|
|
|
MIDP.openFiles.delete(this.$fileName);
|
|
|
|
};
|
|
|
|
|
|
|
|
addUnimplementedNative("com/sun/cdc/io/j2me/file/DefaultFileHandler.canRead.()Z", 1);
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.openForRead.()V"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.openForRead: " + pathname);
|
|
|
|
var fileNumber = this.$fileName;
|
|
|
|
asyncImpl("I", new Promise(function(resolve, reject) {
|
|
|
|
fs.open(pathname, function(fd) {
|
|
|
|
// The key is the $fileName Long, not the primitive number
|
|
|
|
// it represents, so a file can be opened by multiple handlers.
|
|
|
|
MIDP.openFiles.set(fileNumber, fd);
|
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.read.([BII)I"] = function(b, off, len) {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.flush: " + pathname);
|
|
|
|
var fd = MIDP.openFiles.get(this.$fileName);
|
|
|
|
|
|
|
|
if (off < 0 || len < 0 || off > b.byteLength || (b.byteLength - off) < len) {
|
|
|
|
throw $.newIOException();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (b.byteLength == 0 || len == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
var curpos = fs.getpos(fd);
|
|
|
|
var data = fs.read(fd, curpos, curpos + len);
|
|
|
|
b.set(data, off);
|
|
|
|
|
|
|
|
return (data.byteLength > 0) ? data.byteLength : -1;
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.closeForRead.()V"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.closeForRead: " + pathname);
|
|
|
|
var fd = MIDP.openFiles.get(this.$fileName);
|
|
|
|
fs.close(fd);
|
|
|
|
MIDP.openFiles.delete(this.$fileName);
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.closeForReadWrite.()V"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.closeForReadWrite: " + pathname);
|
|
|
|
var fd = MIDP.openFiles.get(this.$fileName);
|
|
|
|
fs.close(fd);
|
|
|
|
MIDP.openFiles.delete(this.$fileName);
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.delete.()V"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.delete: " + pathname);
|
|
|
|
fs.remove(pathname);
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.lastModified.()J"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.lastModified: " + pathname);
|
|
|
|
var stat = fs.stat(pathname);
|
|
|
|
return Long.fromNumber(stat != null ? stat.mtime : 0);
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.truncate.(J)V"] = function(byteOffset) {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.lastModified: " + pathname);
|
2015-02-06 03:34:27 +03:00
|
|
|
|
|
|
|
// XXX If the file is open, flush it first.
|
|
|
|
|
2015-02-05 23:34:32 +03:00
|
|
|
fs.truncate(pathname, byteOffset.toNumber());
|
|
|
|
};
|
2015-02-06 03:34:27 +03:00
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/Protocol.available.()I"] = function() {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileHandler.$fileName.toNumber());
|
|
|
|
var fd = MIDP.openFiles.get(this.$fileHandler.$fileName);
|
|
|
|
var available = fs.getsize(fd) - fs.getpos(fd);
|
|
|
|
console.log("Protocol.available: " + pathname + ": " + available);
|
|
|
|
return available;
|
|
|
|
};
|
|
|
|
|
|
|
|
Native["com/sun/cdc/io/j2me/file/DefaultFileHandler.rename0.(Ljava/lang/String;)V"] = function(newName) {
|
|
|
|
var pathname = MIDP.nativeFilePointerToName.get(this.$fileName.toNumber());
|
|
|
|
console.log("DefaultFileHandler.rename0: " + pathname);
|
|
|
|
console.log("newName: " + util.fromJavaString(newName));
|
|
|
|
if (!fs.rename(pathname, util.fromJavaString(newName))) {
|
|
|
|
throw $.newIOException("Rename failed");
|
|
|
|
}
|
|
|
|
};
|