1 package eu.javaexperience.electronic.uartbus.rpc.client.device;
3 import java.io.IOException;
4 import java.lang.reflect.Array;
5 import java.lang.reflect.Field;
6 import java.lang.reflect.Method;
7 import java.lang.reflect.ParameterizedType;
8 import java.lang.reflect.Type;
9 import java.math.BigInteger;
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.List;
34 public static Object extractOrThrowResult(Method method, byte[] bs)
throws PosixErrnoException
36 boolean posix =
false;
40 for(Class c:method.getExceptionTypes())
42 if(PosixErrnoException.class.isAssignableFrom(c))
51 short err = pr.readUByte();
54 throw new PosixErrnoException(ERRNO.ERRNOOfValue(err));
58 Class<?> retc = method.getReturnType();
60 if(Void.class == retc ||
void.class == retc)
65 Object ret = readType(pr, retc, method.getGenericReturnType());
71 throw new RuntimeException(
"Unknown, unextractable returning type: "+method);
74 protected static Object tryExtractStruct(Class c, Type t,
PacketReader pr)
76 String n = StringTools.getSubstringAfterFirstString(c.getName(),
"eu.javaexperience.struct.GenericStruct", null);
82 Integer p = Integer.parseInt(n);
86 ParameterizedType pt = (ParameterizedType) t;
87 Type[] ts = pt.getActualTypeArguments();
88 Object ret = c.newInstance();
92 Field f = Mirror.getClassFieldOrNull(c, String.valueOf(((
char)(
'a'+i))));
95 f.set(ret, readType(pr, Mirror.extracClass(ts[i])));
103 Mirror.propagateAnyway(e);
108 protected static Object[] extractStruct(Object o)
110 String n = StringTools.getSubstringAfterFirstString(o.getClass().getName(),
"eu.javaexperience.struct.GenericStruct", null);
116 Integer p = Integer.parseInt(n);
117 Object[] ret =
new Object[p];
122 Field f = Mirror.getClassFieldOrNull(o.getClass(), String.valueOf(((
char)(
'a'+i))));
130 Mirror.propagateAnyway(e);
135 public static Object readType(
PacketReader reader, Class reqType)
137 return readType(reader, reqType, null);
140 public static Object readType(
PacketReader reader, Class reqClass, Type reqType)
142 reqClass = PrimitiveTools.toObjectClassType(reqClass, reqClass);
144 if(reqClass == Boolean.class)
146 return 0 == reader.readSByte()? Boolean.FALSE:Boolean.TRUE;
148 else if(reqClass == Byte.class)
150 return reader.readSByte();
152 else if(reqClass == Character.class)
154 return (
char) reader.readSByte();
156 else if(reqClass == Short.class)
158 return reader.readSShort();
160 else if(reqClass == Integer.class)
162 return reader.readSInt();
164 else if(reqClass == Long.class)
166 return reader.readSLong();
168 else if(reqClass == Float.class)
170 return reader.readFloat();
172 else if(reqClass == Double.class)
174 return reader.readDouble();
176 else if(reqClass == String.class)
178 return reader.readString();
180 else if(reqClass == byte[].
class)
182 return reader.readBlobRemain();
184 else if(reqClass ==
VSigned.class)
186 return new VSigned(reader.readVsNumber());
190 return new VUnsigned(reader.readVuNumber());
192 else if(reqClass ==
uint8_t.class)
194 return new uint8_t(reader.readUByte());
198 return new uint16_t(reader.readUShort());
202 reqClass.getCanonicalName().startsWith(
"eu.javaexperience.struct.GenericStruct")
207 return tryExtractStruct(reqClass, reqType, reader);
209 else if(reqClass.isArray())
211 List ret =
new ArrayList();
212 while(reader.hasUnprocessedBytes())
214 ret.add(readType(reader, reqClass.getComponentType()));
217 return ret.toArray((Object[]) Array.newInstance(reqClass.getComponentType(), 1));
219 else if(reqClass.isEnum())
221 return reqClass.getEnumConstants()[(int) reader.readVuint()];
227 public static boolean isUartbusDataType(Class o)
230 Boolean.class.isAssignableFrom(o) ||
231 Byte.class.isAssignableFrom(o) ||
232 uint8_t.class.isAssignableFrom(o) ||
233 uint16_t.class.isAssignableFrom(o) ||
234 Short.class.isAssignableFrom(o) ||
235 byte[].class.isAssignableFrom(o) ||
236 Number.class.isAssignableFrom(o) ||
237 String.class.isAssignableFrom(o) ||
238 VSigned.class.isAssignableFrom(o) ||
241 o.getCanonicalName().startsWith(
"eu.javaexperience.struct.GenericStruct")||
242 (o.isArray() && isUartbusDataType(o.getComponentType()))
246 public static boolean isUartbusDataType(Object o)
248 return isUartbusDataType(o.getClass());
251 public static void appendElements(
PacketAssembler pa, Object... elements)
throws IOException
253 for(Object o:elements)
257 throw new NullPointerException(
"Can't serialize null");
259 else if(o instanceof Boolean)
261 pa.writeByte((byte)((Boolean.FALSE.equals(o))?0:1));
263 else if(o instanceof Byte)
265 pa.writeByte((Byte) o);
269 pa.writeByte((((uint8_t)o).value & 0xff));
273 pa.writeShort((((uint16_t)o).value));
276 else if(o instanceof Short)
278 pa.writeShort((Short)o);
280 else if(o instanceof byte[])
282 pa.write((byte[]) o);
284 else if(o instanceof String)
286 pa.writeString(o.toString());
290 pa.writePackedValue(
true, ((VSigned) o).value);
294 pa.writePackedValue(
true, ((VUnsigned) o).value);
298 else if(o instanceof Number)
300 pa.writePackedValue(
true, (Number) o);
302 else if(o.getClass().isEnum())
304 pa.write(
UartbusTools.packInt(
false, ((Enum)o).ordinal()));
308 o.getClass().getCanonicalName().startsWith(
"eu.javaexperience.struct.GenericStruct")
312 appendElements(pa, extractStruct(o));
314 else if(o.getClass().isArray())
316 int len = Array.getLength(o);
317 for(
int i=0;i<len;++i)
319 Object add = Array.get(o, i);
320 appendElements(pa, add);
325 throw new RuntimeException(
"Can't serialize packet component ("+(null == o?
"null":o.getClass())+
"): "+o);
330 protected static final TrackedLimitedResourcePool<PacketAssembler> PA_POOL =
new TrackedLimitedResourcePool<PacketAssembler>(()->
new PacketAssembler(), 1024);
332 public static byte[] toPacket(
int to,
int from, Object... elements)
334 try(IssuedResource<PacketAssembler> res = PA_POOL.acquireResource())
337 pa.writeAddressing(from, to);
338 appendElements(pa, elements);
345 Mirror.propagateAnyway(e);
350 public static GetBy1<Boolean, UartbusPacketDispatch> createRequestPacketAcceptor
352 Integer targetAddress,
360 null != targetAddress
362 !targetAddress.equals(p.getPacket().to)
375 byte[] pl = p.getPayload();
376 if(pl.length < path.length)
380 for(
int i=0;i<path.length;++i)
388 p.setDispatchByteIndex(path.length);
397 return loadString(str, 16);
400 public static String loadString(
UbRemoteString str,
int maxGetLength)
402 int len = str.getLength().value.intValue();
404 StringBuilder sb =
new StringBuilder();
408 while(sb.length() < len)
410 String app =
new String(str.getStringPart(
new VUnsigned(sb.length()), rlen));
411 if(0 == app.length() || sb.length() >= len)
418 if(sb.length() < len)
420 throw new RuntimeException(
"Can't load the whole string.");
423 return sb.toString();