runtime,comm_generic: improve and fix list encoding

This commit is contained in:
Sebastien Bourdeauducq 2015-04-28 01:31:55 +08:00
parent cae473e848
commit 8a19766278
2 changed files with 91 additions and 63 deletions

View File

@ -120,27 +120,34 @@ class CommGeneric:
self.write(bytes(kname, "ascii")) self.write(bytes(kname, "ascii"))
logger.debug("running kernel: %s", kname) logger.debug("running kernel: %s", kname)
def _receive_rpc_value(self, type_tag):
if type_tag == "n":
return None
if type_tag == "b":
return bool(struct.unpack("B", self.read(1))[0])
if type_tag == "i":
return struct.unpack(">l", self.read(4))[0]
if type_tag == "I":
return struct.unpack(">q", self.read(8))[0]
if type_tag == "f":
return struct.unpack(">d", self.read(8))[0]
if type_tag == "F":
n, d = struct.unpack(">qq", self.read(16))
return Fraction(n, d)
def _receive_rpc_values(self): def _receive_rpc_values(self):
r = [] r = []
while True: while True:
type_tag = chr(struct.unpack("B", self.read(1))[0]) type_tag = chr(struct.unpack("B", self.read(1))[0])
if type_tag == "\x00": if type_tag == "\x00":
return r return r
if type_tag == "n": elif type_tag == "l":
r.append(None) elt_type_tag = chr(struct.unpack("B", self.read(1))[0])
if type_tag == "b": length = struct.unpack(">l", self.read(4))[0]
r.append(bool(struct.unpack("B", self.read(1))[0])) r.append([self._receive_rpc_value(elt_type_tag)
if type_tag == "i": for i in range(length)])
r.append(struct.unpack(">l", self.read(4))[0]) else:
if type_tag == "I": r.append(self._receive_rpc_value(type_tag))
r.append(struct.unpack(">q", self.read(8))[0])
if type_tag == "f":
r.append(struct.unpack(">d", self.read(8))[0])
if type_tag == "F":
n, d = struct.unpack(">qq", self.read(16))
r.append(Fraction(n, d))
if type_tag == "l":
r.append(self._receive_rpc_values())
def _serve_rpc(self, rpc_wrapper, rpc_map, user_exception_map): def _serve_rpc(self, rpc_wrapper, rpc_map, user_exception_map):
rpc_num = struct.unpack(">l", self.read(4))[0] rpc_num = struct.unpack(">l", self.read(4))[0]

View File

@ -1,4 +1,5 @@
#include <string.h> #include <string.h>
#include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <generated/csr.h> #include <generated/csr.h>
@ -105,12 +106,44 @@ enum {
REMOTEMSG_TYPE_RPC_REQUEST, REMOTEMSG_TYPE_RPC_REQUEST,
}; };
static int add_base_rpc_value(char base_type, void *value, char *buffer_out, int available_space)
{
switch(base_type) {
case 'n':
return 0;
case 'b':
if(available_space < 1)
return -1;
if(*(char *)value)
buffer_out[0] = 1;
else
buffer_out[0] = 0;
return 1;
case 'i':
if(available_space < 4)
return -1;
memcpy(buffer_out, value, 4);
return 4;
case 'I':
case 'f':
if(available_space < 8)
return -1;
memcpy(buffer_out, value, 8);
return 8;
case 'F':
if(available_space < 16)
return -1;
memcpy(buffer_out, value, 16);
return 16;
default:
return -1;
}
}
static int add_rpc_value(int bi, int type_tag, void *value) static int add_rpc_value(int bi, int type_tag, void *value)
{ {
char base_type; char base_type;
int obi, r; int obi, r;
int i, p;
int len;
obi = bi; obi = bi;
base_type = type_tag; base_type = type_tag;
@ -119,52 +152,40 @@ static int add_rpc_value(int bi, int type_tag, void *value)
return -1; return -1;
buffer_out[bi++] = base_type; buffer_out[bi++] = base_type;
switch(base_type) { if(base_type == 'l') {
case 'n': char elt_type;
return bi - obi; int len;
case 'b': int i, p;
if((bi + 1) > BUFFER_OUT_SIZE)
return -1; elt_type = type_tag >> 8;
if(*(char *)value) if((bi + 1) > BUFFER_OUT_SIZE)
buffer_out[bi++] = 1; return -1;
else buffer_out[bi++] = elt_type;
buffer_out[bi++] = 0;
return bi - obi; len = *(int *)value;
case 'i': if((bi + 4) > BUFFER_OUT_SIZE)
if((bi + 4) > BUFFER_OUT_SIZE) return -1;
return -1; memcpy(&buffer_out[bi], &len, 4);
memcpy(&buffer_out[bi], value, 4); bi += 4;
bi += 4;
return bi - obi; p = 4;
case 'I': for(i=0;i<len;i++) {
case 'f': r = add_base_rpc_value(elt_type, (char *)value + p,
if((bi + 8) > BUFFER_OUT_SIZE) &buffer_out[bi], BUFFER_OUT_SIZE - bi);
return -1; if(r < 0)
memcpy(&buffer_out[bi], value, 8); return r;
bi += 8; bi += r;
return bi - obi; p += r;
case 'F': }
if((bi + 16) > BUFFER_OUT_SIZE) } else {
return -1; r = add_base_rpc_value(base_type, value,
memcpy(&buffer_out[bi], value, 16); &buffer_out[bi], BUFFER_OUT_SIZE - bi);
bi += 16; if(r < 0)
return bi - obi; return r;
case 'l': bi += r;
len = *(int *)value;
p = 4;
for(i=0;i<len;i++) {
r = add_rpc_value(bi, type_tag >> 8, (char *)value + p);
if(r < 0)
return r;
bi += r;
p += r;
}
if((bi + 1) > BUFFER_OUT_SIZE)
return -1;
buffer_out[bi++] = 0;
return bi - obi;
} }
return -1;
return bi - obi;
} }
static int send_rpc_request(int rpc_num, va_list args) static int send_rpc_request(int rpc_num, va_list args)
@ -181,7 +202,7 @@ static int send_rpc_request(int rpc_num, va_list args)
while((type_tag = va_arg(args, int))) { while((type_tag = va_arg(args, int))) {
r = add_rpc_value(bi, type_tag, r = add_rpc_value(bi, type_tag,
type_tag == 'n' ? NULL : va_arg(args, void *)); type_tag == 'n' ? NULL : va_arg(args, void *));
if(bi < 0) if(r < 0)
return 0; return 0;
bi += r; bi += r;
} }