From 9fa1bea2f68dd8cd661d29085e34fc217bddc6d5 Mon Sep 17 00:00:00 2001 From: usernameak Date: Sat, 16 Nov 2024 04:25:15 +0100 Subject: [PATCH] Extra APIs --- .idea/inspectionProfiles/Project_Default.xml | 6 + .../sun/midp/lcdui/InputMethodHandler.java | 19 +++ src/main/java/com/xce/jam/XBrowser.java | 7 ++ src/main/java/com/xce/lcdui/XTextField.java | 14 ++- src/main/java/com/xce/net/Socket.java | 7 ++ .../java/javax/microedition/lcdui/Font.java | 2 +- .../rms/InvalidRecordIDException.java | 6 + .../javax/microedition/rms/RecordStore.java | 12 +- .../net/sktemu/ams/skvm/SkvmSysProps.java | 4 +- src/main/java/net/sktemu/rms/RmsManager.java | 116 +++++++++++++++--- 10 files changed, 172 insertions(+), 21 deletions(-) create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 src/main/java/com/sun/midp/lcdui/InputMethodHandler.java create mode 100644 src/main/java/com/xce/jam/XBrowser.java create mode 100644 src/main/java/com/xce/net/Socket.java diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..1a79a9a --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/src/main/java/com/sun/midp/lcdui/InputMethodHandler.java b/src/main/java/com/sun/midp/lcdui/InputMethodHandler.java new file mode 100644 index 0000000..af28879 --- /dev/null +++ b/src/main/java/com/sun/midp/lcdui/InputMethodHandler.java @@ -0,0 +1,19 @@ +package com.sun.midp.lcdui; + +public class InputMethodHandler { + private static final InputMethodHandler instance = new InputMethodHandler(); + + private int inputMode = 1; + + public static InputMethodHandler getInputMethodHandler() { + return instance; + } + + public void switchInputMode(int mode) { + inputMode = mode; + } + + public int getInputMode() { + return inputMode; + } +} diff --git a/src/main/java/com/xce/jam/XBrowser.java b/src/main/java/com/xce/jam/XBrowser.java new file mode 100644 index 0000000..8d16075 --- /dev/null +++ b/src/main/java/com/xce/jam/XBrowser.java @@ -0,0 +1,7 @@ +package com.xce.jam; + +public class XBrowser { + public static void setNetworkMode(int mode) { + // do nothing, whatever this is + } +} diff --git a/src/main/java/com/xce/lcdui/XTextField.java b/src/main/java/com/xce/lcdui/XTextField.java index c9d451e..1542b85 100644 --- a/src/main/java/com/xce/lcdui/XTextField.java +++ b/src/main/java/com/xce/lcdui/XTextField.java @@ -9,6 +9,8 @@ public class XTextField { private int constraints; private boolean hasFocus; + private int x, y, width, height; + public XTextField(String text, int maxSize, int constraints, Canvas canvas) { if (text == null) { text = ""; @@ -55,15 +57,23 @@ public void keyRepeated(int keyCode) { } public void paint(Graphics g) { + g.setColor(0xFFFFFFFF); + g.fillRect(x, y, width, height); + g.setColor(0xFF000000); + g.drawRect(x, y, width, height); + g.drawString(text, x + 1, y + 1, Graphics.LEFT | Graphics.TOP); } public void repaint() { - + // TODO: } public void setBounds(int x, int y, int width, int height) { - + this.x = x; + this.y = y; + this.width = width; + this.height = height; } public void setText(String text) { diff --git a/src/main/java/com/xce/net/Socket.java b/src/main/java/com/xce/net/Socket.java new file mode 100644 index 0000000..97702f1 --- /dev/null +++ b/src/main/java/com/xce/net/Socket.java @@ -0,0 +1,7 @@ +package com.xce.net; + +public class Socket { + public void setPPPPreserveTime(int time) { + // do nothing, as we aren't on a mobile network + } +} diff --git a/src/main/java/javax/microedition/lcdui/Font.java b/src/main/java/javax/microedition/lcdui/Font.java index b56bfff..a0cb695 100644 --- a/src/main/java/javax/microedition/lcdui/Font.java +++ b/src/main/java/javax/microedition/lcdui/Font.java @@ -87,6 +87,6 @@ public int stringWidth(String str) { } public int substringWidth(String str, int offset, int len) { - throw new FeatureNotImplementedError("Font::substringWidth"); + return charsWidth(str.toCharArray(), offset, len); } } diff --git a/src/main/java/javax/microedition/rms/InvalidRecordIDException.java b/src/main/java/javax/microedition/rms/InvalidRecordIDException.java index 86fbb08..301ff31 100644 --- a/src/main/java/javax/microedition/rms/InvalidRecordIDException.java +++ b/src/main/java/javax/microedition/rms/InvalidRecordIDException.java @@ -1,4 +1,10 @@ package javax.microedition.rms; public class InvalidRecordIDException extends RecordStoreException { + public InvalidRecordIDException() { + } + + public InvalidRecordIDException(String message) { + super(message); + } } diff --git a/src/main/java/javax/microedition/rms/RecordStore.java b/src/main/java/javax/microedition/rms/RecordStore.java index 4dd4a5f..92ece3b 100644 --- a/src/main/java/javax/microedition/rms/RecordStore.java +++ b/src/main/java/javax/microedition/rms/RecordStore.java @@ -42,6 +42,16 @@ public byte[] getRecord(int recordID) throws RecordStoreException { throw new RecordStoreNotOpenException(); } - throw new RecordStoreException("RecordStore.getRecord() not implemented"); + SkvmAppInstance skvmAppInstance = (SkvmAppInstance) AppInstance.appInstance; + return skvmAppInstance.getRmsManager().getRecord(storeID, recordID); + } + + public int addRecord(byte[] data, int offset, int numBytes) throws RecordStoreException { + if (isClosed) { + throw new RecordStoreNotOpenException(); + } + + SkvmAppInstance skvmAppInstance = (SkvmAppInstance) AppInstance.appInstance; + return skvmAppInstance.getRmsManager().addRecord(storeID, data, offset, numBytes); } } diff --git a/src/main/java/net/sktemu/ams/skvm/SkvmSysProps.java b/src/main/java/net/sktemu/ams/skvm/SkvmSysProps.java index 6cca620..1c78a63 100644 --- a/src/main/java/net/sktemu/ams/skvm/SkvmSysProps.java +++ b/src/main/java/net/sktemu/ams/skvm/SkvmSysProps.java @@ -3,8 +3,8 @@ public class SkvmSysProps { public static void init() { System.setProperty("com.xce.wipi.version", "1.0.0"); - System.setProperty("m.SK_VM", "12"); - System.setProperty("m.VENDER", "HD"); + System.setProperty("m.SK_VM", "20"); + System.setProperty("m.VENDER", "LG"); System.setProperty("m.MODEL", "11"); System.setProperty("m.CARRIER", "SKT"); System.setProperty("m.COLOR", "5"); diff --git a/src/main/java/net/sktemu/rms/RmsManager.java b/src/main/java/net/sktemu/rms/RmsManager.java index f90c31e..2e2277d 100644 --- a/src/main/java/net/sktemu/rms/RmsManager.java +++ b/src/main/java/net/sktemu/rms/RmsManager.java @@ -1,7 +1,9 @@ package net.sktemu.rms; +import javax.microedition.rms.InvalidRecordIDException; import javax.microedition.rms.RecordStoreException; import javax.microedition.rms.RecordStoreNotFoundException; +import java.io.ByteArrayInputStream; import java.io.File; import java.sql.*; import java.util.ArrayList; @@ -10,11 +12,38 @@ public class RmsManager implements AutoCloseable { private Connection sqlConn; + private static final String SQL_INIT_1_SCHEMA = + "CREATE TABLE IF NOT EXISTS rms_stores (" + + " id INTEGER PRIMARY KEY AUTOINCREMENT," + + " name VARCHAR(32) NOT NULL," + + " next_record INTEGER NOT NULL DEFAULT 1," + + " UNIQUE(name));"; + + private static final String SQL_INIT_2_SCHEMA = + "CREATE TABLE IF NOT EXISTS rms_records (" + + " id INTEGER NOT NULL," + + " store_id INTEGER NOT NULL," + + " data BLOB NOT NULL," + + " PRIMARY KEY (id, store_id)," + + " FOREIGN KEY (store_id) REFERENCES rms_stores(id) ON DELETE CASCADE" + + ");"; + + private static final String SQL_GET_NEXT_RECORD_ID = + "SELECT next_record FROM rms_stores WHERE id = ?;"; + + private static final String SQL_INCREMENT_NEXT_RECORD = + "UPDATE rms_stores SET next_record = next_record + 1 WHERE id = ?;"; + public void initialize(File dataDir) throws RecordStoreException { File dbPath = new File(dataDir, "rms.db"); String url = "jdbc:sqlite:" + dbPath; try { sqlConn = DriverManager.getConnection(url); + + try (Statement stmt = sqlConn.createStatement()) { + stmt.execute("PRAGMA foreign_keys = ON;"); + } + sqlConn.setAutoCommit(false); initializeDBSchema(); @@ -36,12 +65,8 @@ public void close() throws RecordStoreException { private void initializeDBSchema() throws SQLException { try (Statement stmt = sqlConn.createStatement()) { - final String q = "CREATE TABLE IF NOT EXISTS rms_stores (" - + "id INTEGER PRIMARY KEY AUTOINCREMENT," - + "name VARCHAR(32) NOT NULL," - + "next_record INTEGER NOT NULL DEFAULT 0," - + "UNIQUE(name));"; - stmt.execute(q); + stmt.execute(SQL_INIT_1_SCHEMA); + stmt.execute(SQL_INIT_2_SCHEMA); sqlConn.commit(); } catch (SQLException e) { @@ -62,9 +87,13 @@ public int getRecordStoreID(String name, boolean createIfNeccessary) throws Reco try (PreparedStatement stmt = sqlConn.prepareStatement("SELECT id FROM rms_stores WHERE name = ?;")) { stmt.setString(1, name); - ResultSet res = stmt.executeQuery(); - res.next(); - id = res.getInt(1); + try (ResultSet res = stmt.executeQuery()) { + if (res.next()) { + id = res.getInt(1); + } else { + throw new RecordStoreNotFoundException("RecordStore " + name + " not found"); + } + } } sqlConn.commit(); @@ -82,15 +111,15 @@ public int getRecordStoreID(String name, boolean createIfNeccessary) throws Reco public String[] listRecordStores() throws RecordStoreException { try (Statement stmt = sqlConn.createStatement()) { - ResultSet res = stmt.executeQuery("SELECT name FROM rms_stores;"); + try (ResultSet res = stmt.executeQuery("SELECT name FROM rms_stores;")) { + List names = new ArrayList<>(); - List names = new ArrayList<>(); + while (res.next()) { + names.add(res.getString(1)); + } - while (res.next()) { - names.add(res.getString(1)); + return names.toArray(new String[0]); } - - return names.toArray(new String[0]); } catch (SQLException e) { throw new RecordStoreException("sql error occurred", e); } @@ -110,4 +139,61 @@ public void deleteRecordStore(String recordStoreName) throws RecordStoreExceptio throw new RecordStoreException("sql error occurred", e); } } + + public byte[] getRecord(int recordStoreId, int recordId) throws RecordStoreException { + try (PreparedStatement stmt = sqlConn.prepareStatement("SELECT data FROM rms_records WHERE id = ? AND store_id = ?;")) { + stmt.setInt(1, recordId); + stmt.setInt(2, recordStoreId); + try (ResultSet res = stmt.executeQuery()) { + if (res.next()) { + return res.getBytes(1); + } else { + throw new InvalidRecordIDException("Record " + recordId + " in RecordStore " + recordStoreId + " not found"); + } + } + } catch (SQLException e) { + throw new RecordStoreException("sql error occurred", e); + } + } + + public int addRecord(int recordStoreId, byte[] data, int off, int len) throws RecordStoreException { + int recordId; + + try (PreparedStatement stmt = sqlConn.prepareStatement(SQL_GET_NEXT_RECORD_ID)) { + stmt.setInt(1, recordStoreId); + try (ResultSet res = stmt.executeQuery()) { + if (res.next()) { + recordId = res.getInt(1); + addRecordNoCommit(recordStoreId, recordId, data, off, len); + + try (PreparedStatement updateStmt = sqlConn.prepareStatement(SQL_INCREMENT_NEXT_RECORD)) { + updateStmt.setInt(1, recordStoreId); + updateStmt.executeUpdate(); + } + } else { + throw new RecordStoreNotFoundException("RecordStore with id " + recordStoreId + " not found"); + } + } + + sqlConn.commit(); + } catch (SQLException e) { + throw new RecordStoreException("sql error occurred", e); + } + + return recordId; + } + + public int deleteRecord(int recordStoreId, int recordId) throws RecordStoreException { + // TODO: + throw new RecordStoreException("not implemented yet"); + } + + private void addRecordNoCommit(int recordStoreId, int recordId, byte[] data, int off, int len) throws SQLException { + try (PreparedStatement stmt = sqlConn.prepareStatement("INSERT INTO rms_records (id, store_id, data) VALUES (?, ?, ?);")) { + stmt.setInt(1, recordId); + stmt.setInt(2, recordStoreId); + stmt.setBinaryStream(3, new ByteArrayInputStream(data, off, len), len); + stmt.executeUpdate(); + } + } }