aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxutil/xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/libxutil/xdr.c')
-rw-r--r--tools/libxutil/xdr.c246
1 files changed, 246 insertions, 0 deletions
diff --git a/tools/libxutil/xdr.c b/tools/libxutil/xdr.c
new file mode 100644
index 0000000000..dfb91f23c4
--- /dev/null
+++ b/tools/libxutil/xdr.c
@@ -0,0 +1,246 @@
+/* $Id: xdr.c,v 1.3 2003/09/29 13:40:00 mjw Exp $ */
+#include "xdr.h"
+#include <errno.h>
+/** @file
+ * XDR packer/unpacker for elements.
+ *
+ * string -> [T_STRING] [len:u32] <len bytes>
+ * atom -> [T_ATOM] [len:u32] <len bytes>
+ * uint -> [T_UINT] [value]
+ * cons -> [T_CONS] <car> <cdr>
+ * null -> [T_NULL]
+ * none -> [T_NONE]
+ * bool -> [T_BOOL] { 0:u8 | 1:u8 }
+ *
+ * types packed as u16.
+ *
+ * So (a b c) -> [T_CONS] a [T_CONS] b [T_CONS] c [T_NULL]
+ * () -> [T_NULL]
+ */
+
+int pack_bool(IOStream *io, int x){
+ int err=0;
+ err = IOStream_print(io, "%c", 0xff & x);
+ if(err > 0) err = 0;
+ return err;
+}
+
+int unpack_bool(IOStream *io, int *x){
+ int err = 0;
+ int c;
+ c = IOStream_getc(io);
+ *x = (c < 0 ? 0 : c);
+ err = IOStream_error(io);
+ if(c < 0 && !err) err = -EIO;
+ return err;
+}
+
+int pack_ushort(IOStream *io, unsigned short x){
+ int err=0;
+ err = IOStream_print(io, "%c%c",
+ 0xff & (x >> 8),
+ 0xff & (x ));
+ if(err > 0) err = 0;
+ return err;
+}
+
+int unpack_ushort(IOStream *io, unsigned short *x){
+ int err = 0;
+ int i, c = 0;
+ *x = 0;
+ for(i = 0; i< 2; i++){
+ c = IOStream_getc(io);
+ if(c < 0) break;
+ *x <<= 8;
+ *x |= (0xff & c);
+ }
+ err = IOStream_error(io);
+ if(c < 0 && !err) err = -EIO;
+ return err;
+}
+
+int pack_uint(IOStream *io, unsigned int x){
+ int err=0;
+ err = IOStream_print(io, "%c%c%c%c",
+ 0xff & (x >> 24),
+ 0xff & (x >> 16),
+ 0xff & (x >> 8),
+ 0xff & (x ));
+ if(err > 0) err = 0;
+ return err;
+}
+
+int unpack_uint(IOStream *io, unsigned int *x){
+ int err = 0;
+ int i, c = 0;
+ *x = 0;
+ for(i = 0; i< 4; i++){
+ c = IOStream_getc(io);
+ if(c < 0) break;
+ *x <<= 8;
+ *x |= (0xff & c);
+ }
+ err = IOStream_error(io);
+ if(c < 0 && !err) err = -EIO;
+ return err;
+}
+
+int pack_string(IOStream *io, Sxpr x){
+ int err = 0;
+ int n = string_length(x);
+ char *s = string_string(x);
+ int i;
+ err = pack_uint(io, n);
+ if(err) goto exit;
+ for(i = 0; i < n; i++){
+ err = IOStream_print(io, "%c", s[i]);
+ if(err < 0) break;
+ }
+ if(err > 0) err = 0;
+ exit:
+ return err;
+}
+
+int unpack_string(IOStream *io, Sxpr *x){
+ int err;
+ unsigned int n;
+ int i, c = 0;
+ char *s;
+ Sxpr val = ONONE;
+
+ err = unpack_uint(io, &n);
+ if(err) goto exit;
+ val = halloc(n+1, T_STRING);
+ if(NOMEMP(val)){
+ err = -ENOMEM;
+ goto exit;
+ }
+ s = string_string(val);
+ for(i=0; i<n; i++){
+ c = IOStream_getc(io);
+ if(c < 0) break;
+ s[i] = (char)c;
+ }
+ s[n] = '\0';
+ exit:
+ err = IOStream_error(io);
+ if(c < 0 && !err) err = -EIO;
+ if(err){
+ objfree(val);
+ val = ONONE;
+ }
+ *x = val;
+ return err;
+}
+
+int pack_cons(IOStream *io, Sxpr x){
+ int err = 0;
+ err = pack_sxpr(io, CAR(x));
+ if(err) goto exit;
+ err = pack_sxpr(io, CDR(x));
+ exit:
+ return err;
+}
+
+int unpack_cons(IOStream *io, Sxpr *x){
+ int err = 0;
+ Sxpr u = ONONE, v = ONONE, val = ONONE;
+ err = unpack_sxpr(io, &u);
+ if(err) goto exit;
+ err = unpack_sxpr(io, &v);
+ if(err) goto exit;
+ val = cons_new(u, v);
+ if(NOMEMP(val)){
+ err = -ENOMEM;
+ }
+ exit:
+ if(err){
+ objfree(u);
+ objfree(v);
+ val = ONONE;
+ }
+ *x = val;
+ return err;
+}
+
+int pack_sxpr(IOStream *io, Sxpr x){
+ int err = 0;
+ unsigned short type = get_type(x);
+ err = pack_ushort(io, type);
+ if(err) goto exit;
+ switch(type){
+ case T_NULL:
+ break;
+ case T_NONE:
+ break;
+ break;
+ case T_BOOL:
+ err = pack_bool(io, get_ul(x));
+ break;
+ case T_CONS:
+ err = pack_cons(io, x);
+ break;
+ case T_ATOM:
+ err = pack_string(io, OBJ_ATOM(x)->name);
+ break;
+ case T_STRING:
+ err = pack_string(io, x);
+ break;
+ case T_UINT:
+ err = pack_uint(io, get_ul(x));
+ break;
+ default:
+ err = -EINVAL;
+ IOStream_print(iostderr, "%s> invalid type %d\n", __FUNCTION__, type);
+ break;
+ }
+ exit:
+ return err;
+}
+
+int unpack_sxpr(IOStream *io, Sxpr *x){
+ int err = 0;
+ unsigned short type;
+ unsigned int u;
+ Sxpr val = ONONE, y;
+
+ err = unpack_ushort(io, &type);
+ if(err) goto exit;
+ switch(type){
+ case T_NULL:
+ val = ONULL;
+ break;
+ case T_NONE:
+ val = ONONE;
+ break;
+ case T_CONS:
+ err = unpack_cons(io, &val);
+ break;
+ case T_BOOL:
+ err = unpack_bool(io, &u);
+ if(err) goto exit;
+ val = (u ? OTRUE : OFALSE);
+ break;
+ case T_ATOM:
+ err = unpack_string(io, &y);
+ if(err) goto exit;
+ val = intern(string_string(y));
+ objfree(y);
+ break;
+ case T_STRING:
+ err = unpack_string(io, &val);
+ break;
+ case T_UINT:
+ err = unpack_uint(io, &u);
+ if(err) goto exit;
+ val = OBJI(type, u);
+ break;
+ default:
+ err = -EINVAL;
+ IOStream_print(iostderr, "%s> invalid type %d\n", __FUNCTION__, type);
+ break;
+ }
+ exit:
+ *x = (err ? ONONE : val);
+ return err;
+}