int hcfg_serialize(char **buf, int *buflen, const hcfg_t *cfg) { int i, count, total; count = snprintf_serial(buf, buflen, "hcfg:%u %u ", cfg->count, cfg->logsize); if (count < 0) goto invalid; total = count; for (i = 0; i < (1 << cfg->logsize); ++i) { if (cfg->hash[i].key) { count = printstr_serial(buf, buflen, cfg->hash[i].key); if (count < 0) goto invalid; total += count; count = printstr_serial(buf, buflen, cfg->hash[i].val); if (count < 0) goto invalid; total += count; } } return total; invalid: errno = EINVAL; return -1; }
int hsignature_serialize(char **buf, int *buflen, const hsignature_t *sig) { int i, count, total; count = snprintf_serial(buf, buflen, "sig: "); if (count < 0) goto invalid; total = count; count = printstr_serial(buf, buflen, sig->name); if (count < 0) goto error; total += count; count = snprintf_serial(buf, buflen, "%d ", sig->range_len); if (count < 0) goto invalid; total += count; for (i = 0; i < sig->range_len; ++i) { count = hrange_serialize(buf, buflen, &sig->range[i]); if (count < 0) goto error; total += count; } return total; invalid: errno = EINVAL; error: return -1; }
int hrange_serialize(char **buf, int *buflen, const hrange_t *range) { int i, count, total; const char *type_str; count = snprintf_serial(buf, buflen, "range: "); if (count < 0) goto error; total = count; count = printstr_serial(buf, buflen, range->name); if (count < 0) goto error; total += count; switch (range->type) { case HVAL_INT: type_str = "INT"; break; case HVAL_REAL: type_str = "REL"; break; case HVAL_STR: type_str = "STR"; break; default: goto invalid; } count = snprintf_serial(buf, buflen, "%s ", type_str); if (count < 0) goto invalid; total += count; switch (range->type) { case HVAL_INT: count = snprintf_serial(buf, buflen, "%ld %ld %ld ", range->bounds.i.min, range->bounds.i.max, range->bounds.i.step); if (count < 0) goto invalid; total += count; break; case HVAL_REAL: count = snprintf_serial(buf, buflen, "%la %la %la ", range->bounds.r.min, range->bounds.r.max, range->bounds.r.step); if (count < 0) goto invalid; total += count; break; case HVAL_STR: count = snprintf_serial(buf, buflen, "%d ", range->bounds.s.set_len); if (count < 0) goto invalid; total += count; for (i = 0; i < range->bounds.s.set_len; ++i) { count = printstr_serial(buf, buflen, range->bounds.s.set[i]); if (count < 0) goto invalid; total += count; } break; default: goto invalid; } return total; invalid: errno = EINVAL; error: return -1; }
int hmesg_serialize(hmesg_t *mesg) { const char *type_str, *status_str; char hdr[HMESG_HDRLEN + 1]; char *buf; int buflen, count, total; top: buf = mesg->buf; buflen = mesg->buflen; /* Leave room for a header. */ buf += HMESG_HDRLEN; buflen -= HMESG_HDRLEN; if (buflen < 0) buflen = 0; total = HMESG_HDRLEN; switch (mesg->type) { case HMESG_UNKNOWN: type_str = "UNK"; break; case HMESG_SESSION: type_str = "SES"; break; case HMESG_JOIN: type_str = "JOI"; break; case HMESG_GETCFG: type_str = "QRY"; break; case HMESG_SETCFG: type_str = "INF"; break; case HMESG_FETCH: type_str = "FET"; break; case HMESG_REPORT: type_str = "REP"; break; default: goto invalid; } switch (mesg->status) { case HMESG_STATUS_REQ: status_str = "REQ"; break; case HMESG_STATUS_OK: status_str = "ACK"; break; case HMESG_STATUS_FAIL: status_str = "ERR"; break; case HMESG_STATUS_BUSY: status_str = "BSY"; break; default: goto invalid; } count = snprintf_serial(&buf, &buflen, ":%d:%s:%s:", mesg->dest, type_str, status_str); if (count < 0) goto error; total += count; count = printstr_serial(&buf, &buflen, mesg->src_id); if (count < 0) goto error; total += count; if (mesg->status == HMESG_STATUS_BUSY) { /* Busy messages contain no data. */ } else if (mesg->status == HMESG_STATUS_FAIL) { count = printstr_serial(&buf, &buflen, mesg->data.string); if (count < 0) goto error; total += count; } else { switch (mesg->type) { case HMESG_SESSION: if (mesg->status == HMESG_STATUS_REQ) { count = hsession_serialize(&buf, &buflen, &mesg->data.session); if (count < 0) goto error; total += count; } break; case HMESG_JOIN: count = hsignature_serialize(&buf, &buflen, &mesg->data.join); if (count < 0) goto error; total += count; break; case HMESG_GETCFG: case HMESG_SETCFG: count = printstr_serial(&buf, &buflen, mesg->data.string); if (count < 0) goto error; total += count; break; case HMESG_FETCH: if (mesg->status == HMESG_STATUS_REQ) { count = snprintf_serial(&buf, &buflen, "%d ", mesg->data.fetch.best.id); if (count < 0) goto error; total += count; } else if (mesg->status == HMESG_STATUS_OK) { count = hpoint_serialize(&buf, &buflen, &mesg->data.fetch.cand); if (count < 0) goto error; total += count; count = hpoint_serialize(&buf, &buflen, &mesg->data.fetch.best); if (count < 0) goto error; total += count; } break; case HMESG_REPORT: if (mesg->status == HMESG_STATUS_REQ) { count = hpoint_serialize(&buf, &buflen, &mesg->data.report.cand); if (count < 0) goto error; total += count; count = snprintf_serial(&buf, &buflen, "%la ", mesg->data.report.perf); if (count < 0) goto error; total += count; } break; default: goto invalid; } } if (total >= mesg->buflen) { buf = (char *) realloc(mesg->buf, total + 1); if (!buf) goto error; mesg->buf = buf; mesg->buflen = total + 1; goto top; } snprintf(hdr, sizeof(hdr), "XXXX%04d%02x", total, HMESG_VERSION); *(unsigned int *)(hdr) = htonl(HMESG_MAGIC); memcpy(mesg->buf, hdr, HMESG_HDRLEN); return total; invalid: errno = EINVAL; error: return -1; }