Skip to content

Commit

Permalink
move unpack_from_jar to its own class (#656)
Browse files Browse the repository at this point in the history
Signed-off-by: Andrey Parfenov <a1994ndrey@gmail.com>
  • Loading branch information
Andrey1994 authored Jul 30, 2023
1 parent 194cdfc commit 10a762b
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 100 deletions.
70 changes: 24 additions & 46 deletions java_package/brainflow/src/main/java/brainflow/BoardShim.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package brainflow;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -122,34 +119,34 @@ int get_current_board_data (int num_samples, int preset, double[] data_buf, int[
if (SystemUtils.IS_OS_WINDOWS)
{
lib_name = "BoardController.dll";
unpack_from_jar ("neurosdk-x64.dll");
unpack_from_jar ("Unicorn.dll");
unpack_from_jar ("gForceSDKWrapper.dll");
unpack_from_jar ("gforce64.dll");
unpack_from_jar ("simpleble-c.dll");
unpack_from_jar ("MuseLib.dll");
unpack_from_jar ("BrainBitLib.dll");
unpack_from_jar ("GanglionLib.dll");
unpack_from_jar ("BrainFlowBluetooth.dll");
unpack_from_jar ("eego-SDK.dll");
JarHelper.unpack_from_jar ("neurosdk-x64.dll");
JarHelper.unpack_from_jar ("Unicorn.dll");
JarHelper.unpack_from_jar ("gForceSDKWrapper.dll");
JarHelper.unpack_from_jar ("gforce64.dll");
JarHelper.unpack_from_jar ("simpleble-c.dll");
JarHelper.unpack_from_jar ("MuseLib.dll");
JarHelper.unpack_from_jar ("BrainBitLib.dll");
JarHelper.unpack_from_jar ("GanglionLib.dll");
JarHelper.unpack_from_jar ("BrainFlowBluetooth.dll");
JarHelper.unpack_from_jar ("eego-SDK.dll");
} else if (SystemUtils.IS_OS_MAC)
{
lib_name = "libBoardController.dylib";
unpack_from_jar ("libGanglionLib.dylib");
unpack_from_jar ("libneurosdk-shared.dylib");
unpack_from_jar ("libsimpleble-c.dylib");
unpack_from_jar ("libMuseLib.dylib");
unpack_from_jar ("libBrainBitLib.dylib");
unpack_from_jar ("libBrainFlowBluetooth.dylib");
JarHelper.unpack_from_jar ("libGanglionLib.dylib");
JarHelper.unpack_from_jar ("libneurosdk-shared.dylib");
JarHelper.unpack_from_jar ("libsimpleble-c.dylib");
JarHelper.unpack_from_jar ("libMuseLib.dylib");
JarHelper.unpack_from_jar ("libBrainBitLib.dylib");
JarHelper.unpack_from_jar ("libBrainFlowBluetooth.dylib");
} else if ((SystemUtils.IS_OS_LINUX) && (!is_os_android))
{
unpack_from_jar ("libunicorn.so");
unpack_from_jar ("libGanglionLib.so");
unpack_from_jar ("libsimpleble-c.so");
unpack_from_jar ("libMuseLib.so");
unpack_from_jar ("libBrainFlowBluetooth.so");
unpack_from_jar ("libBrainBitLib.so");
unpack_from_jar ("libeego-SDK.so");
JarHelper.unpack_from_jar ("libunicorn.so");
JarHelper.unpack_from_jar ("libGanglionLib.so");
JarHelper.unpack_from_jar ("libsimpleble-c.so");
JarHelper.unpack_from_jar ("libMuseLib.so");
JarHelper.unpack_from_jar ("libBrainFlowBluetooth.so");
JarHelper.unpack_from_jar ("libBrainBitLib.so");
JarHelper.unpack_from_jar ("libeego-SDK.so");
}

if (is_os_android)
Expand All @@ -160,7 +157,7 @@ int get_current_board_data (int num_samples, int preset, double[] data_buf, int[
} else
{
// need to extract libraries from jar
Path lib_path = unpack_from_jar (lib_name);
Path lib_path = JarHelper.unpack_from_jar (lib_name);
if (lib_path != null)
{
lib_name = lib_path.toString ();
Expand All @@ -172,25 +169,6 @@ int get_current_board_data (int num_samples, int preset, double[] data_buf, int[
instance.java_set_jnienv (JNIEnv.CURRENT);
}

private static Path unpack_from_jar (String lib_name)
{
try
{
File file = new File (lib_name);
System.err.println ("Unpacking to: " + file.getAbsolutePath ().toString ());
if (file.exists ())
file.delete ();
InputStream link = (BoardShim.class.getResourceAsStream (lib_name));
Files.copy (link, file.getAbsoluteFile ().toPath ());
return file.getAbsoluteFile ().toPath ();
} catch (Exception io)
{
io.printStackTrace ();
System.err.println ("file: " + lib_name + " is not found in jar file");
return null;
}
}

/**
* enable BrainFlow logger with level INFO
*/
Expand Down
24 changes: 1 addition & 23 deletions java_package/brainflow/src/main/java/brainflow/DataFilter.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package brainflow;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -134,7 +131,7 @@ int perform_ica (double[] data, int rows, int cols, int num_components, double[]
} else
{
// need to extract libraries from jar
Path lib_path = unpack_from_jar (lib_name);
Path lib_path = JarHelper.unpack_from_jar (lib_name);
if (lib_path != null)
{
lib_name = lib_path.toString ();
Expand All @@ -143,25 +140,6 @@ int perform_ica (double[] data, int rows, int cols, int num_components, double[]
instance = Native.loadLibrary (lib_name, DllInterface.class);
}

private static Path unpack_from_jar (String lib_name)
{
try
{
File file = new File (lib_name);
System.err.println ("Unpacking to: " + file.getAbsolutePath ().toString ());
if (file.exists ())
file.delete ();
InputStream link = (BoardShim.class.getResourceAsStream (lib_name));
Files.copy (link, file.getAbsoluteFile ().toPath ());
return file.getAbsoluteFile ().toPath ();
} catch (Exception io)
{
io.printStackTrace ();
System.err.println ("file: " + lib_name + " is not found in jar file");
return null;
}
}

/**
* enable Data logger with level INFO
*/
Expand Down
96 changes: 96 additions & 0 deletions java_package/brainflow/src/main/java/brainflow/JarHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package brainflow;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;

import com.sun.jna.Platform;

public class JarHelper
{
public static Path unpack_from_jar (String lib_name)
{
File file = new File (lib_name);
try
{
File temp_dir = get_temp_dir ();
file = new File (temp_dir, lib_name);
} catch (IOException io)
{
io.printStackTrace ();
}
try
{
System.err.println ("Unpacking to: " + file.getAbsolutePath ().toString ());
if (file.exists ())
file.delete ();
InputStream link = (JarHelper.class.getResourceAsStream (lib_name));
Files.copy (link, file.getAbsoluteFile ().toPath ());
return file.getAbsoluteFile ().toPath ();
} catch (Exception io)
{
io.printStackTrace ();
System.err.println ("file: " + lib_name + " is not found in jar file");
return null;
}
}

static File get_temp_dir () throws IOException
{
File jna_tmp;
String prop = System.getProperty ("jna.tmpdir");
if (prop != null)
{
jna_tmp = new File (prop);
jna_tmp.mkdirs ();
} else
{
File tmp = new File (System.getProperty ("java.io.tmpdir"));
if (Platform.isMac ())
{
// https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html
jna_tmp = new File (System.getProperty ("user.home"), "Library/Caches/JNA/temp");
} else if (
Platform.isLinux () || Platform.isSolaris () || Platform.isAIX () || Platform.isFreeBSD ()
|| Platform.isNetBSD () || Platform.isOpenBSD () || Platform.iskFreeBSD ()
)
{
// https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
// The XDG_CACHE_DIR is expected to be per user
String xdg_cache_environment = System.getenv ("XDG_CACHE_HOME");
File xdg_cache_file;
if (xdg_cache_environment == null || xdg_cache_environment.trim ().isEmpty ())
{
xdg_cache_file = new File (System.getProperty ("user.home"), ".cache");
} else
{
xdg_cache_file = new File (xdg_cache_environment);
}
jna_tmp = new File (xdg_cache_file, "JNA/temp");
} else
{
// Loading DLLs via System.load() under a directory with a unicode
// name will fail on windows, so use a hash code of the user's
// name in case the user's name contains non-ASCII characters
jna_tmp = new File (tmp, "jna-" + System.getProperty ("user.name").hashCode ());
}

jna_tmp.mkdirs ();
if (!jna_tmp.exists () || !jna_tmp.canWrite ())
{
jna_tmp = tmp;
}
}
if (!jna_tmp.exists ())
{
throw new IOException ("JNA temporary directory '" + jna_tmp + "' does not exist");
}
if (!jna_tmp.canWrite ())
{
throw new IOException ("JNA temporary directory '" + jna_tmp + "' is not writable");
}
return jna_tmp;
}
}
40 changes: 9 additions & 31 deletions java_package/brainflow/src/main/java/brainflow/MLModel.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package brainflow;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;

Expand Down Expand Up @@ -46,19 +43,19 @@ private interface DllInterface extends Library
if (SystemUtils.IS_OS_WINDOWS)
{
lib_name = "MLModule.dll";
unpack_from_jar ("onnxruntime_arm.dll");
unpack_from_jar ("onnxruntime_arm64.dll");
unpack_from_jar ("onnxruntime_x64.dll");
unpack_from_jar ("onnxruntime_x86.dll");
JarHelper.unpack_from_jar ("onnxruntime_arm.dll");
JarHelper.unpack_from_jar ("onnxruntime_arm64.dll");
JarHelper.unpack_from_jar ("onnxruntime_x64.dll");
JarHelper.unpack_from_jar ("onnxruntime_x86.dll");
} else if (SystemUtils.IS_OS_MAC)
{
lib_name = "libMLModule.dylib";
unpack_from_jar ("onnxruntime_x86.dll");
unpack_from_jar ("onnxruntime_x86.dll");
JarHelper.unpack_from_jar ("onnxruntime_x86.dll");
JarHelper.unpack_from_jar ("onnxruntime_x86.dll");
} else if ((SystemUtils.IS_OS_LINUX) && (!is_os_android))
{
unpack_from_jar ("libonnxruntime_x64.so");
unpack_from_jar ("libonnxruntime_arm64.so");
JarHelper.unpack_from_jar ("libonnxruntime_x64.so");
JarHelper.unpack_from_jar ("libonnxruntime_arm64.so");
}

if (is_os_android)
Expand All @@ -69,7 +66,7 @@ private interface DllInterface extends Library
} else
{
// need to extract libraries from jar
Path lib_path = unpack_from_jar (lib_name);
Path lib_path = JarHelper.unpack_from_jar (lib_name);
if (lib_path != null)
{
lib_name = lib_path.toString ();
Expand All @@ -79,25 +76,6 @@ private interface DllInterface extends Library
instance = Native.loadLibrary (lib_name, DllInterface.class);
}

private static Path unpack_from_jar (String lib_name)
{
try
{
File file = new File (lib_name);
System.err.println ("Unpacking to: " + file.getAbsolutePath ().toString ());
if (file.exists ())
file.delete ();
InputStream link = (BoardShim.class.getResourceAsStream (lib_name));
Files.copy (link, file.getAbsoluteFile ().toPath ());
return file.getAbsoluteFile ().toPath ();
} catch (Exception io)
{
io.printStackTrace ();
System.err.println ("file: " + lib_name + " is not found in jar file");
return null;
}
}

private String input_params;

private BrainFlowModelParams params;
Expand Down
63 changes: 63 additions & 0 deletions python_package/examples/tests/plotjuggler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import argparse
import time

from brainflow.board_shim import BoardShim, BrainFlowInputParams, BoardIds, BrainFlowPresets


def main():
BoardShim.enable_dev_board_logger()
parser = argparse.ArgumentParser()
# use docs to check which parameters are required for specific board, e.g. for Cyton - set serial port
parser.add_argument('--timeout', type=int, help='timeout for device discovery or connection', required=False,
default=0)
parser.add_argument('--ip-port', type=int, help='ip port', required=False, default=0)
parser.add_argument('--ip-protocol', type=int, help='ip protocol, check IpProtocolType enum', required=False,
default=0)
parser.add_argument('--ip-address', type=str, help='ip address', required=False, default='')
parser.add_argument('--serial-port', type=str, help='serial port', required=False, default='')
parser.add_argument('--mac-address', type=str, help='mac address', required=False, default='')
parser.add_argument('--other-info', type=str, help='other info', required=False, default='')
parser.add_argument('--serial-number', type=str, help='serial number', required=False, default='')
parser.add_argument('--board-id', type=int, help='board id, check docs to get a list of supported boards',
required=True)
parser.add_argument('--file', type=str, help='file', required=False, default='')
parser.add_argument('--master-board', type=int, help='master board id for streaming and playback boards',
required=False, default=BoardIds.NO_BOARD)
args = parser.parse_args()

params = BrainFlowInputParams()
params.ip_port = args.ip_port
params.serial_port = args.serial_port
params.mac_address = args.mac_address
params.other_info = args.other_info
params.serial_number = args.serial_number
params.ip_address = args.ip_address
params.ip_protocol = args.ip_protocol
params.timeout = args.timeout
params.file = args.file
params.master_board = args.master_board

board = BoardShim(args.board_id, params)
board_id = board.get_board_id()
presets = BoardShim.get_board_presets(board_id)
board.prepare_session()
for preset in presets:
# to stream to plotjuggler
board.add_streamer(
f'plotjuggler_udp://127.0.0.1:9870', preset)
# to store data in a file
board.add_streamer(f'file://data_{preset}.csv:w', preset)
board.start_stream ()

while True:
try:
time.sleep(1)
except KeyboardInterrupt:
break
except Exception as e:
print(e)
board.release_session()


if __name__ == "__main__":
main()

0 comments on commit 10a762b

Please sign in to comment.