return TRUE;
}
+METHOD(bio_reader_t, read_uint64, bool,
+ private_bio_reader_t *this, u_int64_t *res)
+{
+ if (this->buf.len < 8)
+ {
+ DBG1(DBG_LIB, "%d bytes insufficient to parse u_int64 data",
+ this->buf.len);
+ return FALSE;
+ }
+ *res = untoh64(this->buf.ptr);
+ this->buf = chunk_skip(this->buf, 8);
+ return TRUE;
+}
+
METHOD(bio_reader_t, read_data, bool,
private_bio_reader_t *this, u_int32_t len, chunk_t *res)
{
.read_uint16 = _read_uint16,
.read_uint24 = _read_uint24,
.read_uint32 = _read_uint32,
+ .read_uint64 = _read_uint64,
.read_data = _read_data,
.read_data8 = _read_data8,
.read_data16 = _read_data16,
*/
bool (*read_uint32)(bio_reader_t *this, u_int32_t *res);
+ /**
+ * Read a 64-bit integer from the buffer, advance.
+ *
+ * @param res pointer to result
+ * @return TRUE if integer read successfully
+ */
+ bool (*read_uint64)(bio_reader_t *this, u_int64_t *res);
+
/**
* Read a chunk of len bytes, advance.
*
this->used += 4;
}
+METHOD(bio_writer_t, write_uint64, void,
+ private_bio_writer_t *this, u_int64_t value)
+{
+ if (this->used + 8 > this->buf.len)
+ {
+ increase(this);
+ }
+ htoun64(this->buf.ptr + this->used, value);
+ this->used += 8;
+}
+
METHOD(bio_writer_t, write_data, void,
private_bio_writer_t *this, chunk_t value)
{
.write_uint16 = _write_uint16,
.write_uint24 = _write_uint24,
.write_uint32 = _write_uint32,
+ .write_uint64 = _write_uint64,
.write_data = _write_data,
.write_data8 = _write_data8,
.write_data16 = _write_data16,
*/
void (*write_uint32)(bio_writer_t *this, u_int32_t value);
+ /**
+ * Append a 64-bit integer to the buffer.
+ *
+ * @param value value to append
+ */
+ void (*write_uint64)(bio_writer_t *this, u_int64_t value);
+
/**
* Append a chunk of data without a length header.
*
memcpy((char*)unaligned, &host, sizeof(host));
}
+/**
+ * Write a 64-bit host order value in network order to an unaligned address.
+ *
+ * @param host host order 32-bit value
+ * @param network unaligned address to write network order value to
+ */
+static inline void htoun64(void *network, u_int64_t host)
+{
+ char *unaligned = (char*)network;
+ u_int32_t high_part, low_part;
+
+ high_part = host >> 32;
+ high_part = htonl(high_part);
+ low_part = host & 0xFFFFFFFFLL;
+ low_part = htonl(low_part);
+
+ memcpy(unaligned, &high_part, sizeof(high_part));
+ unaligned += sizeof(high_part);
+ memcpy(unaligned, &low_part, sizeof(low_part));
+}
+
/**
* Read a 16-bit value in network order from an unaligned address to host order.
*
return ntohl(tmp);
}
+/**
+ * Read a 64-bit value in network order from an unaligned address to host order.
+ *
+ * @param network unaligned address to read network order value from
+ * @return host order value
+ */
+static inline u_int64_t untoh64(void *network)
+{
+ char *unaligned = (char*)network;
+ u_int32_t high_part, low_part;
+
+ memcpy(&high_part, unaligned, sizeof(high_part));
+ unaligned += sizeof(high_part);
+ memcpy(&low_part, unaligned, sizeof(low_part));
+
+ high_part = ntohl(high_part);
+ low_part = ntohl(low_part);
+
+ return (((u_int64_t)high_part) << 32) + low_part;
+}
+
/**
* Special type to count references
*/