Cosmetic updates of GL code and working prototype of NXDT

This commit is contained in:
Dmitry Isaenko 2020-10-28 15:59:45 +03:00
parent 6e21c514a8
commit 0cb945a7f4
2 changed files with 83 additions and 76 deletions

View file

@ -45,7 +45,7 @@ class NxdtUsbAbi1 {
private final boolean isWindows; private final boolean isWindows;
private boolean isWindows10; private boolean isWindows10;
private static final int NXDT_MAX_DIRECTIVE_SIZE = 0x1000; private static final int NXDT_MAX_DIRECTIVE_SIZE = 0x800000;//0x1000;
private static final int NXDT_FILE_CHUNK_SIZE = 0x800000; private static final int NXDT_FILE_CHUNK_SIZE = 0x800000;
private static final int NXDT_FILE_PROPERTIES_MAX_NAME_LENGTH = 0x300; private static final int NXDT_FILE_PROPERTIES_MAX_NAME_LENGTH = 0x300;
@ -212,8 +212,6 @@ class NxdtUsbAbi1 {
String absoluteFilePath = getAbsoluteFilePath(filename); String absoluteFilePath = getAbsoluteFilePath(filename);
File fileToDump = new File(absoluteFilePath); File fileToDump = new File(absoluteFilePath);
boolean nspTransferMode = false;
if (checkSizes(fullSize, headerSize)) if (checkSizes(fullSize, headerSize))
return; return;
@ -225,14 +223,9 @@ class NxdtUsbAbi1 {
return; return;
if (headerSize > 0){ // if NSP if (headerSize > 0){ // if NSP
logPrinter.print("Receiving NSP file entry: '"+filename+"' ("+fullSize+" b)", EMsgType.INFO); logPrinter.print("Receiving NSP file: '"+filename+"' ("+formatByteSize(fullSize)+")", EMsgType.PASS);
if (filename.equals(nspFile.getName())){ createNewNsp(filename, headerSize, fullSize, fileToDump);
nspTransferMode = true; return;
}
else {
createNewNsp(filename, headerSize, fullSize, fileToDump);
return;
}
} }
else { else {
// TODO: Note, in case of a big amount of small files performance decreases dramatically. It's better to handle this only in case of 1-big-file-transfer // TODO: Note, in case of a big amount of small files performance decreases dramatically. It's better to handle this only in case of 1-big-file-transfer
@ -244,7 +237,7 @@ class NxdtUsbAbi1 {
if (fullSize == 0) if (fullSize == 0)
return; return;
if (nspTransferMode) if (isNspTransfer())
dumpNspFile(nspFile, fullSize); dumpNspFile(nspFile, fullSize);
else else
dumpFile(fileToDump, fullSize); dumpFile(fileToDump, fullSize);
@ -261,8 +254,8 @@ class NxdtUsbAbi1 {
return false; return false;
} }
private boolean checkSizes(long fileSize, int headerSize) throws Exception{ private boolean checkSizes(long fileSize, int headerSize) throws Exception{
if (fileSize >= headerSize){ if (headerSize >= fileSize){
logPrinter.print("File size should not be equal to header size for NSP files!", EMsgType.FAIL); logPrinter.print(String.format("File size (%d) should not be less or equal to header size (%d)!", fileSize, headerSize), EMsgType.FAIL);
resetNsp(); resetNsp();
writeUsb(USBSTATUS_MALFORMED_REQUEST); writeUsb(USBSTATUS_MALFORMED_REQUEST);
return true; return true;
@ -275,7 +268,6 @@ class NxdtUsbAbi1 {
} }
return false; return false;
} }
private boolean checkFileSystem(File fileToDump, long fileSize) throws Exception{ private boolean checkFileSystem(File fileToDump, long fileSize) throws Exception{
// Check if enough space // Check if enough space
if (fileToDump.getParentFile().getFreeSpace() <= fileSize){ if (fileToDump.getParentFile().getFreeSpace() <= fileSize){
@ -297,7 +289,8 @@ class NxdtUsbAbi1 {
nspFile = new NxdtNspFile(filename, headerSize, fileSize, fileToDump); nspFile = new NxdtNspFile(filename, headerSize, fileSize, fileToDump);
} }
catch (Exception e){ catch (Exception e){
logPrinter.print(e.getMessage(), EMsgType.FAIL); logPrinter.print("Unable to create new file for: "+filename+" :"+e.getMessage(), EMsgType.FAIL);
e.printStackTrace();
writeUsb(USBSTATUS_HOSTIOERROR); writeUsb(USBSTATUS_HOSTIOERROR);
return; return;
} }
@ -310,6 +303,9 @@ class NxdtUsbAbi1 {
private long getLElong(byte[] bytes, int fromOffset){ private long getLElong(byte[] bytes, int fromOffset){
return ByteBuffer.wrap(bytes, fromOffset, 0x8).order(ByteOrder.LITTLE_ENDIAN).getLong(); return ByteBuffer.wrap(bytes, fromOffset, 0x8).order(ByteOrder.LITTLE_ENDIAN).getLong();
} }
private boolean isNspTransfer(){
return nspFile != null;
}
private String getAbsoluteFilePath(String filename) throws Exception{ private String getAbsoluteFilePath(String filename) throws Exception{
if (isRomFs(filename) && isWindows) // Since RomFS entry starts from '/' it should be replaced to '\'. if (isRomFs(filename) && isWindows) // Since RomFS entry starts from '/' it should be replaced to '\'.
@ -367,9 +363,10 @@ class NxdtUsbAbi1 {
private void dumpNspFile(NxdtNspFile nsp, long size) throws Exception{ private void dumpNspFile(NxdtNspFile nsp, long size) throws Exception{
FileOutputStream fos = new FileOutputStream(nsp.getFile(), true); FileOutputStream fos = new FileOutputStream(nsp.getFile(), true);
long nspSize = nsp.getFullSize(); long nspSize = nsp.getFullSize();
long nspRemainingSize = nsp.getNspRemainingSize();
try (BufferedOutputStream bos = new BufferedOutputStream(fos)) { try (BufferedOutputStream bos = new BufferedOutputStream(fos)) {
long nspRemainingSize = nsp.getNspRemainingSize();
FileDescriptor fd = fos.getFD(); FileDescriptor fd = fos.getFD();
byte[] readBuffer; byte[] readBuffer;
long received = 0; long received = 0;
@ -393,8 +390,6 @@ class NxdtUsbAbi1 {
if (isWindows10) if (isWindows10)
fd.sync(); fd.sync();
nspRemainingSize -= (lastChunkSize - 1); nspRemainingSize -= (lastChunkSize - 1);
}
finally {
nsp.setNspRemainingSize(nspRemainingSize); nsp.setNspRemainingSize(nspRemainingSize);
} }
} }
@ -427,7 +422,8 @@ class NxdtUsbAbi1 {
raf.seek(0); raf.seek(0);
raf.write(headerData); raf.write(headerData);
} }
logPrinter.print("NSP file: '"+nsp.getName()+"' successfully received!", EMsgType.PASS);
logPrinter.updateProgress(1.0);
writeUsb(USBSTATUS_SUCCESS); writeUsb(USBSTATUS_SUCCESS);
} }
private void resetNsp(){ private void resetNsp(){
@ -534,4 +530,13 @@ class NxdtUsbAbi1 {
"\n Returned: " + UsbErrorCodes.getErrCode(result) + "\n Returned: " + UsbErrorCodes.getErrCode(result) +
"\n (execution stopped)"); "\n (execution stopped)");
} }
private String formatByteSize(double length) {
final String[] unitNames = { "bytes", "KiB", "MiB", "GiB", "TiB"};
int i;
for (i = 0; length > 1024 && i < unitNames.length - 1; i++) {
length = length / 1024;
}
return String.format("%,.2f %s", length, unitNames[i]);
}
} }

View file

@ -64,14 +64,19 @@ class GoldLeaf_08 extends TransferModule {
private long virtDriveSize; private long virtDriveSize;
private HashMap<String, Long> splitFileSize; private HashMap<String, Long> splitFileSize;
private boolean isWindows; private final boolean isWindows;
private String homePath; private final String homePath;
// For using in CMD_SelectFile with SPEC:/ prefix // For using in CMD_SelectFile with SPEC:/ prefix
private File selectedFile; private File selectedFile;
private CancellableRunnable task; private final CancellableRunnable task;
GoldLeaf_08(DeviceHandle handler, LinkedHashMap<String, File> nspMap, CancellableRunnable task, ILogPrinter logPrinter, boolean nspFilter){ GoldLeaf_08(DeviceHandle handler,
LinkedHashMap<String, File> nspMap,
CancellableRunnable task,
ILogPrinter logPrinter,
boolean nspFilter)
{
super(handler, nspMap, task, logPrinter); super(handler, nspMap, task, logPrinter);
this.task = task; this.task = task;
@ -890,43 +895,42 @@ class GoldLeaf_08 extends TransferModule {
if (fileName.startsWith("VIRT:/")){ if (fileName.startsWith("VIRT:/")){
return writeGL_FAIL("GL Handle 'WriteFile' command [not supported for virtual drive]"); return writeGL_FAIL("GL Handle 'WriteFile' command [not supported for virtual drive]");
} }
else {
fileName = updateHomePath(fileName);
// Check if we didn't see this (or any) file during this session
if (writeFilesMap.size() == 0 || (! writeFilesMap.containsKey(fileName))){
// Open what we have to open
File writeFile = new File(fileName);
// If this file exists GL will take care
// Otherwise, let's add it
try{
BufferedOutputStream writeFileBufOutStream = new BufferedOutputStream(new FileOutputStream(writeFile, true));
writeFilesMap.put(fileName, writeFileBufOutStream);
} catch (IOException ioe){
return writeGL_FAIL("GL Handle 'WriteFile' command [IOException]\n\t"+ioe.getMessage());
}
}
// Now we have stream
BufferedOutputStream myStream = writeFilesMap.get(fileName);
byte[] transferredData; fileName = updateHomePath(fileName);
// Check if we didn't see this (or any) file during this session
if ((transferredData = readGL_file()) == null){ if (writeFilesMap.size() == 0 || (! writeFilesMap.containsKey(fileName))){
logPrinter.print("GL Handle 'WriteFile' command [1/1]", EMsgType.FAIL); // Open what we have to open
return true; File writeFile = new File(fileName);
} // If this file exists GL will take care
// Otherwise, let's add it
try{ try{
myStream.write(transferredData, 0, transferredData.length); BufferedOutputStream writeFileBufOutStream = new BufferedOutputStream(new FileOutputStream(writeFile, true));
writeFilesMap.put(fileName, writeFileBufOutStream);
} catch (IOException ioe){
return writeGL_FAIL("GL Handle 'WriteFile' command [IOException]\n\t"+ioe.getMessage());
} }
catch (IOException ioe){
return writeGL_FAIL("GL Handle 'WriteFile' command [1/1]\n\t"+ioe.getMessage());
}
// Report we're good
if (writeGL_PASS()) {
logPrinter.print("GL Handle 'WriteFile' command", EMsgType.FAIL);
return true;
}
return false;
} }
// Now we have stream
BufferedOutputStream myStream = writeFilesMap.get(fileName);
byte[] transferredData;
if ((transferredData = readGL_file()) == null){
logPrinter.print("GL Handle 'WriteFile' command [1/1]", EMsgType.FAIL);
return true;
}
try{
myStream.write(transferredData, 0, transferredData.length);
}
catch (IOException ioe){
return writeGL_FAIL("GL Handle 'WriteFile' command [1/1]\n\t"+ioe.getMessage());
}
// Report we're good
if (writeGL_PASS()) {
logPrinter.print("GL Handle 'WriteFile' command", EMsgType.FAIL);
return true;
}
return false;
} }
/** /**
@ -938,27 +942,27 @@ class GoldLeaf_08 extends TransferModule {
File selectedFile = CompletableFuture.supplyAsync(() -> { File selectedFile = CompletableFuture.supplyAsync(() -> {
FileChooser fChooser = new FileChooser(); FileChooser fChooser = new FileChooser();
fChooser.setTitle(MediatorControl.getInstance().getContoller().getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION fChooser.setTitle(MediatorControl.getInstance().getContoller().getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION
fChooser.setInitialDirectory(new File(System.getProperty("user.home"))); // TODO: Consider fixing; not a prio. fChooser.setInitialDirectory(new File(System.getProperty("user.home")));// TODO: Consider fixing; not a prio.
fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*")); fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*"));
return fChooser.showOpenDialog(null); // Leave as is for now. return fChooser.showOpenDialog(null); // Leave as is for now.
}, Platform::runLater).join(); }, Platform::runLater).join();
if (selectedFile != null){ if (selectedFile == null){ // Nothing selected
List<byte[]> command = new LinkedList<>(); this.selectedFile = null;
byte[] selectedFileNameBytes = ("SPEC:/"+selectedFile.getName()).getBytes(StandardCharsets.UTF_16LE); return writeGL_FAIL("GL Handle 'SelectFile' command: Nothing selected");
command.add(intToArrLE(selectedFileNameBytes.length / 2)); // since GL 0.7
command.add(selectedFileNameBytes);
if (writeGL_PASS(command)) {
logPrinter.print("GL Handle 'SelectFile' command", EMsgType.FAIL);
this.selectedFile = null;
return true;
}
this.selectedFile = selectedFile;
return false;
} }
// Nothing selected; Report failure.
this.selectedFile = null; List<byte[]> command = new LinkedList<>();
return writeGL_FAIL("GL Handle 'SelectFile' command: Nothing selected"); byte[] selectedFileNameBytes = ("SPEC:/"+selectedFile.getName()).getBytes(StandardCharsets.UTF_16LE);
command.add(intToArrLE(selectedFileNameBytes.length / 2)); // since GL 0.7
command.add(selectedFileNameBytes);
if (writeGL_PASS(command)) {
logPrinter.print("GL Handle 'SelectFile' command", EMsgType.FAIL);
this.selectedFile = null;
return true;
}
this.selectedFile = selectedFile;
return false;
} }
/*----------------------------------------------------*/ /*----------------------------------------------------*/
@ -1039,9 +1043,7 @@ class GoldLeaf_08 extends TransferModule {
return null; return null;
} }
private byte[] readGL_file(){ private byte[] readGL_file(){
ByteBuffer readBuffer; ByteBuffer readBuffer = ByteBuffer.allocateDirect(8388608); // Just don't ask..
readBuffer = ByteBuffer.allocateDirect(8388608); // Just don't ask..
IntBuffer readBufTransferred = IntBuffer.allocate(1); IntBuffer readBufTransferred = IntBuffer.allocate(1);
int result; int result;