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"))
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):
r = []
while True:
type_tag = chr(struct.unpack("B", self.read(1))[0])
if type_tag == "\x00":
return r
if type_tag == "n":
r.append(None)
if type_tag == "b":
r.append(bool(struct.unpack("B", self.read(1))[0]))
if type_tag == "i":
r.append(struct.unpack(">l", self.read(4))[0])
if type_tag == "I":
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())
elif type_tag == "l":
elt_type_tag = chr(struct.unpack("B", self.read(1))[0])
length = struct.unpack(">l", self.read(4))[0]
r.append([self._receive_rpc_value(elt_type_tag)
for i in range(length)])
else:
r.append(self._receive_rpc_value(type_tag))
def _serve_rpc(self, rpc_wrapper, rpc_map, user_exception_map):
rpc_num = struct.unpack(">l", self.read(4))[0]

View File

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