#include "pqp.h"
#include <stdlib.h>
#include <string.h>
typedef _layout pq_array {
int32_t nonempty, nullable, ty, nelts, resv;
char body [];
} pq_array;
typedef _layout pq_array_elt {
uint32_t sz; /* -1 for null */
char body [];
} pq_array_elt;
#include <stdio.h>
struct pqp_array*
pqp_array_read(const void* pqary) {
const pq_array* pqa = pqary;
pqp_array* r = calloc(1, sizeof(pqp_array)
+ (sizeof(pqp_array_elt) * pqa -> nelts));
*r = (pqp_array) {
.ty = ntohl(pqa -> ty),
.nullable = ntohl(pqa -> nullable),
.sz = ntohl(pqa -> nelts),
};
const char* p = pqa -> body;
for(size_t i = 0; i < r -> sz; ++ i) {
const pq_array_elt* e = (void*)p;
r -> elts[i] = (pqp_array_elt) {
.sz = ntohl(e -> sz),
.data = (e -> sz == pq_null ? null : e -> body),
};
if (e -> sz == pq_null) p += 4; /* null */
else p += 4 + r->elts[i].sz;
}
return r;
}
bool pqp_inet_read(const void* pqinet, struct sockaddr* d) {
if(memcmp(pqinet,"\x02\x20\x00\x04",4) == 0) {
uint32_t ip = 0;
for(uint8_t i = 0; i<4; ++i) {
ip |= (uint32_t)(((uint8_t*)pqinet)[4 + i]) << 8*i;
}
struct sockaddr_in* dd = (void*)d;
_zero(*dd);
dd -> sin_family = AF_INET;
dd -> sin_port = 0;
dd -> sin_addr = (struct in_addr){ip};
} else if(memcmp(pqinet,"\x03\x80\x00\x10",4) == 0) {
struct sockaddr_in6* dd = (void*)d;
_zero(*dd);
dd -> sin6_family = AF_INET6;
dd -> sin6_port = 0;
memcpy(&(dd->sin6_addr), pqinet+4, 16);
} else return false;
return true;
}