Skip to content

Commit

Permalink
Merge pull request #175 from henrypinkard/master
Browse files Browse the repository at this point in the history
Change encodings of bridge to fix problems passing arrays
  • Loading branch information
henrypinkard authored Oct 28, 2020
2 parents 7cafdd7 + db2eec3 commit dd155b6
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 34 deletions.
2 changes: 1 addition & 1 deletion java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.micro-manager.pycro-manager</groupId>
<artifactId>PycroManagerJava</artifactId>
<version>0.9.5</version>
<version>0.10.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
Expand Down
19 changes: 10 additions & 9 deletions java/src/main/java/org/micromanager/internal/zmq/ZMQServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
Expand All @@ -33,7 +34,7 @@ public class ZMQServer extends ZMQSocketWrapper {
private static Set<String> packages_;
private static ZMQUtil util_;

public static final String VERSION = "2.7.0";
public static final String VERSION = "3.0.0";

private static Function<Class, Object> classMapper_;
private static ZMQServer masterServer_;
Expand Down Expand Up @@ -110,7 +111,7 @@ public void initialize(int port) {
String exceptionAsString = sw.toString();
json.put("value", exceptionAsString);

reply = json.toString().getBytes();
reply = json.toString().getBytes( StandardCharsets.ISO_8859_1);
e.printStackTrace();

} catch (JSONException ex) {
Expand Down Expand Up @@ -141,7 +142,7 @@ protected byte[] getField(Object obj, JSONObject json) throws JSONException, NoS
Object field = obj.getClass().getField(fieldName).get(obj);
JSONObject serialized = new JSONObject();
util_.serialize(field, serialized, port_);
return serialized.toString().getBytes();
return serialized.toString().getBytes(StandardCharsets.ISO_8859_1);
}

protected void setField(Object obj, JSONObject json) throws JSONException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Expand Down Expand Up @@ -342,7 +343,7 @@ private byte[] runMethod(Object obj, JSONObject message) throws NoSuchMethodExce

JSONObject serialized = new JSONObject();
util_.serialize(result, serialized, port_);
return serialized.toString().getBytes();
return serialized.toString().getBytes( StandardCharsets.ISO_8859_1);
}

protected byte[] parseAndExecuteCommand(String message) throws Exception {
Expand All @@ -356,14 +357,14 @@ protected byte[] parseAndExecuteCommand(String message) throws Exception {
reply = new JSONObject();
reply.put("type", "none");
reply.put("version", VERSION);
return reply.toString().getBytes();
return reply.toString().getBytes( StandardCharsets.ISO_8859_1);
}
case "get-constructors": {
String classpath = request.getString("classpath");
reply = new JSONObject();
reply.put("type", "none");
reply.put("api", ZMQUtil.parseConstructors(classpath, classMapper_));
return reply.toString().getBytes();
return reply.toString().getBytes( StandardCharsets.ISO_8859_1);
}
case "constructor": { //construct a new object (or grab an exisitng instance)
Class baseClass = util_.loadClass(request.getString("classpath"));
Expand All @@ -385,7 +386,7 @@ protected byte[] parseAndExecuteCommand(String message) throws Exception {
}
reply = new JSONObject();
util_.serialize(instance, reply, port_);
return reply.toString().getBytes();
return reply.toString().getBytes( StandardCharsets.ISO_8859_1);
}
case "run-method": {
String hashCode = request.getString("hash-code");
Expand All @@ -403,7 +404,7 @@ protected byte[] parseAndExecuteCommand(String message) throws Exception {
setField(target, request);
reply = new JSONObject();
reply.put("type", "none");
return reply.toString().getBytes();
return reply.toString().getBytes( StandardCharsets.ISO_8859_1);
}
case "destructor": {
String hashCode = request.getString("hash-code");
Expand All @@ -413,7 +414,7 @@ protected byte[] parseAndExecuteCommand(String message) throws Exception {
reply = new JSONObject();

reply.put("type", "none");
return reply.toString().getBytes();
return reply.toString().getBytes( StandardCharsets.ISO_8859_1);
}
default:
break;
Expand Down
10 changes: 6 additions & 4 deletions java/src/main/java/org/micromanager/internal/zmq/ZMQUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
Expand Down Expand Up @@ -314,11 +314,12 @@ public static String encodeArray(Object array) {
buffer.order(BYTE_ORDER).asFloatBuffer().put((float[]) array);
byteArray = buffer.array();
}
return Base64.getEncoder().encodeToString(byteArray);
return new String(byteArray, StandardCharsets.ISO_8859_1);
}

public static Object decodeArray(String serialized, Class arrayClass) {
byte[] byteArray = Base64.getDecoder().decode(serialized);
byte[] byteArray;
byteArray = serialized.getBytes(StandardCharsets.ISO_8859_1);
if (arrayClass.equals(byte[].class)) {
return byteArray;
} else if (arrayClass.equals(short[].class)) {
Expand Down Expand Up @@ -623,7 +624,8 @@ static Object convertToPrimitiveClass(Object primitive, Class argClass) {
}

public static Object convertToPrimitiveArray(Object argClass, String value) {
byte[] bytes = value.getBytes();
byte[] bytes = new byte[0];
bytes = value.getBytes( StandardCharsets.ISO_8859_1);
if (argClass.equals(byte[].class)) {
return bytes;
} else if (argClass.equals(short[].class)) {
Expand Down
2 changes: 1 addition & 1 deletion pycromanager/_version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version_info = (0, 5, 1)
version_info = (0, 6, 0)
__version__ = ".".join(map(str, version_info))
39 changes: 20 additions & 19 deletions pycromanager/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import time
import typing
import warnings
from base64 import standard_b64encode, standard_b64decode
import inspect
import numpy as np
import zmq
Expand Down Expand Up @@ -46,8 +45,8 @@ def __del__(self):

def _convert_np_to_python(self, d):
"""
recursive ply search dictionary and convert any values from numpy floats/ints to
python floats/ints so they can be hson serialized
recursively search dictionary and convert any values from numpy floats/ints to
python floats/ints so they can be json serialized
:return:
"""
if type(d) != dict:
Expand All @@ -72,12 +71,12 @@ def send(self, message, timeout=0):
if self._debug:
print("DEBUG, sending: {}".format(message))
if timeout == 0:
self._socket.send(bytes(message_string, "utf-8"))
self._socket.send(bytes(message_string, 'iso-8859-1'))
else:
start = time.time()
while 1000 * (time.time() - start) < timeout:
try:
self._socket.send(bytes(message_string, "utf-8"), flags=zmq.NOBLOCK)
self._socket.send(bytes(message_string, 'iso-8859-1'), flags=zmq.NOBLOCK)
return True
except zmq.ZMQError:
pass # ignore, keep trying
Expand All @@ -98,7 +97,7 @@ def receive(self, timeout=0):
pass # ignore, keep trying
if reply is None:
return reply
message = json.loads(reply.decode("utf-8"))
message = json.loads(reply.decode('iso-8859-1'))
if self._debug:
print("DEBUG, recieved: {}".format(message))
self._check_exception(message)
Expand All @@ -119,7 +118,7 @@ class Bridge:
"""

_DEFAULT_PORT = 4827
_EXPECTED_ZMQ_SERVER_VERSION = "2.7.0"
_EXPECTED_ZMQ_SERVER_VERSION = "3.0.0"

thread_local = threading.local()

Expand Down Expand Up @@ -470,8 +469,7 @@ def _deserialize(self, json_return):


def serialize_array(array):
return standard_b64encode(array.tobytes()).decode("utf-8")

return array.tobytes().decode('iso-8859-1')

def deserialize_array(json_return):
"""
Expand All @@ -480,16 +478,19 @@ def deserialize_array(json_return):
----------
json_return
"""
if json_return["type"] == "byte-array":
return np.frombuffer(standard_b64decode(json_return["value"]), dtype=">u1").copy()
elif json_return["type"] == "double-array":
return np.frombuffer(standard_b64decode(json_return["value"]), dtype=">f8").copy()
elif json_return["type"] == "int-array":
return np.frombuffer(standard_b64decode(json_return["value"]), dtype=">u4").copy()
elif json_return["type"] == "short-array":
return np.frombuffer(standard_b64decode(json_return["value"]), dtype=">u2").copy()
elif json_return["type"] == "float-array":
return np.frombuffer(standard_b64decode(json_return["value"]), dtype=">f4").copy()
if json_return['type'] in ['byte-array', 'int-array', 'short-array', 'float-array']:
decoded = bytes(json_return['value'], 'iso-8859-1')
if json_return['type'] == 'byte-array':
return np.frombuffer(decoded, dtype='>u1').copy()
elif json_return['type'] == 'double-array':
return np.frombuffer(decoded, dtype='>f8').copy()
elif json_return['type'] == 'int-array':
return np.frombuffer(decoded, dtype='>u4').copy()
elif json_return['type'] == 'short-array':
return np.frombuffer(decoded, dtype='>u2').copy()
elif json_return['type'] == 'float-array':
return np.frombuffer(decoded, dtype='>f4').copy()



def _package_arguments(valid_method_spec, fn_args):
Expand Down

0 comments on commit dd155b6

Please sign in to comment.