|
|
@@ -419,6 +419,59 @@ extra_data_on_line: |
|
|
|
ERR_OTHER, "extra data on line"); |
|
|
|
} |
|
|
|
|
|
|
|
/**** |
|
|
|
* Append from binary data |
|
|
|
*/ |
|
|
|
|
|
|
|
/* .append_binary(self, data, start, end, last_timestamp) */ |
|
|
|
static PyObject *Rocket_append_binary(Rocket *self, PyObject *args) |
|
|
|
{ |
|
|
|
const uint8_t *data; |
|
|
|
int data_len; |
|
|
|
timestamp_t start; |
|
|
|
timestamp_t end; |
|
|
|
timestamp_t last_timestamp; |
|
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "t#lll:append_binary", |
|
|
|
&data, &data_len, |
|
|
|
&start, &end, &last_timestamp)) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
/* Check data length */ |
|
|
|
if (data_len % self->binary_size != 0) |
|
|
|
return raise_str(0, 0, ERR_OTHER, "data size must be a " |
|
|
|
"multiple of binary record size"); |
|
|
|
|
|
|
|
/* Check timestamps */ |
|
|
|
timestamp_t ts; |
|
|
|
int i; |
|
|
|
int rows = data_len / self->binary_size; |
|
|
|
for (i = 0; i < rows; i++) { |
|
|
|
/* Read raw timestamp, byteswap if needed */ |
|
|
|
memcpy(&ts, &data[i * self->binary_size], 8); |
|
|
|
ts = le64toh(ts); |
|
|
|
|
|
|
|
/* Check limits */ |
|
|
|
if (ts <= last_timestamp) |
|
|
|
return raise_int(i, 0, ERR_NON_MONOTONIC, ts); |
|
|
|
last_timestamp = ts; |
|
|
|
if (ts < start || ts >= end) |
|
|
|
return raise_int(i, 0, ERR_OUT_OF_INTERVAL, ts); |
|
|
|
} |
|
|
|
|
|
|
|
/* Write binary data */ |
|
|
|
if (fwrite(data, data_len, 1, self->file) != 1) { |
|
|
|
PyErr_SetFromErrno(PyExc_OSError); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
fflush(self->file); |
|
|
|
|
|
|
|
/* Build return value and return */ |
|
|
|
PyObject *o; |
|
|
|
o = Py_BuildValue("(il)", rows, last_timestamp); |
|
|
|
return o; |
|
|
|
} |
|
|
|
|
|
|
|
/**** |
|
|
|
* Extract to string |
|
|
|
*/ |
|
|
@@ -611,11 +664,13 @@ static PyMemberDef Rocket_members[] = { |
|
|
|
}; |
|
|
|
|
|
|
|
static PyMethodDef Rocket_methods[] = { |
|
|
|
{ "close", (PyCFunction)Rocket_close, METH_NOARGS, |
|
|
|
{ "close", |
|
|
|
(PyCFunction)Rocket_close, METH_NOARGS, |
|
|
|
"close(self)\n\n" |
|
|
|
"Close file handle" }, |
|
|
|
|
|
|
|
{ "append_string", (PyCFunction)Rocket_append_string, METH_VARARGS, |
|
|
|
{ "append_string", |
|
|
|
(PyCFunction)Rocket_append_string, METH_VARARGS, |
|
|
|
"append_string(self, count, data, offset, line, start, end, ts)\n\n" |
|
|
|
"Parse string and append data.\n" |
|
|
|
"\n" |
|
|
@@ -635,7 +690,25 @@ static PyMethodDef Rocket_methods[] = { |
|
|
|
" data_offset: current offset into the data string\n" |
|
|
|
" last_timestamp: last timestamp we parsed" }, |
|
|
|
|
|
|
|
{ "extract_string", (PyCFunction)Rocket_extract_string, METH_VARARGS, |
|
|
|
{ "append_binary", |
|
|
|
(PyCFunction)Rocket_append_binary, METH_VARARGS, |
|
|
|
"append_binary(self, data, start, end, ts)\n\n" |
|
|
|
"Append binary data, which must match the data layout.\n" |
|
|
|
"\n" |
|
|
|
" data: binary data\n" |
|
|
|
" start: starting timestamp for interval\n" |
|
|
|
" end: end timestamp for interval\n" |
|
|
|
" ts: last timestamp that was previously parsed\n" |
|
|
|
"\n" |
|
|
|
"Raises ParseError if timestamps are non-monotonic, outside\n" |
|
|
|
"the start/end interval etc.\n" |
|
|
|
"\n" |
|
|
|
"On success, return a tuple with two values:\n" |
|
|
|
" added_rows: how many rows were added from the file\n" |
|
|
|
" last_timestamp: last timestamp we parsed" }, |
|
|
|
|
|
|
|
{ "extract_string", |
|
|
|
(PyCFunction)Rocket_extract_string, METH_VARARGS, |
|
|
|
"extract_string(self, offset, count)\n\n" |
|
|
|
"Extract count rows of data from the file at offset offset.\n" |
|
|
|
"Return an ascii formatted string according to the layout" }, |
|
|
|