stew

a monorepo of some sort
git clone git://git.nsmpr.xyz/stew.git
Log | Files | Refs

list.c (1819B)


      1 #include <u.h>
      2 #include <libc.h>
      3 
      4 #include "list.h"
      5 
      6 int
      7 readnodeheader(int fd, Node *node)
      8 {
      9 	char buf[4];
     10 	if (read(fd, buf, sizeof(char) * 4) <= 0) return -1;
     11 	node->count = (buf[1] & 0xff) << 16;
     12 	node->count |= (buf[2] & 0xff) << 8;
     13 	node->count |= (buf[3] & 0xff);
     14 	node->type = buf[0];
     15 
     16 	return 0;
     17 }
     18 
     19 int
     20 writenodeheader(int fd, Node *node)
     21 {
     22 	char buf[4];
     23 	buf[0] = node->type;
     24 	buf[1] = node->count >> 16;
     25 	buf[2] = node->count >> 8;
     26 	buf[3] = node->count;
     27 	if (write(fd, buf, sizeof(char) * 4) <= 0) return -1;
     28 	return 0;
     29 }
     30 
     31 int
     32 readnode(int fd, Node *node)
     33 {
     34 	if (readnodeheader(fd, node) < 0) return -1;
     35 
     36 
     37 	if (node->count == 0) {
     38 		node->data = nil;
     39 		return 0;
     40 	};
     41 	char *buf = malloc(sizeof(node->count));
     42 	if (read(fd, buf, node->count) < node->count) {
     43 		free(buf);
     44 		return -1;
     45 	}
     46 	node->data = buf;
     47 
     48 	return 0;
     49 }
     50 
     51 int
     52 writenode(int fd, Node *node)
     53 {
     54 	if (writenodeheader(fd, node) < 0) return -1;
     55 	if (node->count == 0) return 0;
     56 	if (write(fd, node->data, node->count) < node->count) return -1;
     57 	return 0;
     58 }
     59 
     60 Node *
     61 readlist(int fd)
     62 {
     63 	int i = 0, len = 0;
     64 	Node *list = nil;
     65 	for (;; i++) {
     66 		if (i >= len) {
     67 			len += 256;
     68 			list = realloc(list, sizeof(Node) * len);
     69 		}
     70 		if (readnode(fd, list + i) < 0) {
     71 			free(list);
     72 			return nil;
     73 		}
     74 		switch (list[i].type) {
     75 		default:
     76 			break;
     77 		case CList:
     78 			list[i].data = readlist(fd);
     79 			if (list[i].data == nil) {
     80 				free(list);
     81 				return nil;
     82 			}
     83 			break;
     84 		case CNull:
     85 			list[i].count = 0;
     86 			list[i].data = nil;
     87 			return list;
     88 		}
     89 	}
     90 }
     91 
     92 int
     93 writelist(int fd, Node *node)
     94 {
     95 	Node lstart = {CList, 0, nil};
     96 	writenodeheader(fd, &lstart);
     97 	for (;; node++) {
     98 		switch (node->type) {
     99 		default:
    100 			writenode(fd, node);
    101 			break;
    102 		case CList:
    103 			writelist(fd, node->data);
    104 			break;
    105 		case CNull:
    106 			writenode(fd, node);
    107 			return 0;
    108 		}
    109 	}
    110 }