Skip to content

Instantly share code, notes, and snippets.

@hostmaster
Last active December 11, 2015 21:38
Show Gist options
  • Save hostmaster/4663577 to your computer and use it in GitHub Desktop.
Save hostmaster/4663577 to your computer and use it in GitHub Desktop.
bnull-transform.cc chunked
static int
handle_buffering(TSCont contp, MyData * data) {
TSVIO write_vio;
int towrite, towriteLeft, avail;
/* Create the output buffer and its associated reader */
if (!data->output_buffer) {
data->output_buffer = TSIOBufferCreate();
TSAssert(data->output_buffer);
data->output_reader = TSIOBufferReaderAlloc(data->output_buffer);
TSAssert(data->output_reader);
}
if (!data->postTransformBuffer) {
data->postTransformBuffer = TSIOBufferCreate();
TSAssert(data->postTransformBuffer);
data->postTransformBuffeReader =
TSIOBufferReaderAlloc(data->postTransformBuffer);
TSAssert(data->postTransformBuffeReader);
}
/* Get the write VIO for the write operation that was performed on ourself.
This VIO contains the buffer that we are to read from
as well as the continuation we are to call when the buffer is empty. */
write_vio = TSVConnWriteVIOGet(contp);
/* We also check to see if the write VIO's buffer is non-NULL. A NULL
buffer indicates that the write operation has been
shutdown and that the continuation does not want us to send any more
WRITE_READY or WRITE_COMPLETE events. For this buffered
transformation that means we're done buffering data. */
if (!TSVIOBufferGet(write_vio)) {
data->state = STATE_OUTPUT_DATA;
return 0;
}
/* Determine how much data we have left to read. For this bnull transform
plugin this is also
the amount of data we have left to write to the output connection. */
towrite = TSVIONTodoGet(write_vio);
avail = TSIOBufferReaderAvail(TSVIOReaderGet(write_vio));
/* +++ chunked data case */
if (towrite < 0 && avail > 0) {
towrite = avail;
}
/* --- chunked data case */
/* The amount of data left to read needs to be truncated by the amount of
data actually in the read buffer. */
if (towrite > 0 && towrite > avail) {
towrite = avail;
}
if (towrite > 0) {
/* Copy the data from the read buffer to the input buffer. */
if (TSIOBufferCopy(data->output_buffer, TSVIOReaderGet(write_vio), towrite,
0) == TS_ERROR) {
TSError("[bnull-transform] Unable to copy read buffer\n");
goto Lerror;
}
/* Tell the read buffer that we have read the data and are no longer
interested in it. */
TSIOBufferReaderConsume(TSVIOReaderGet(write_vio), towrite);
/* Modify the write VIO to reflect how much data we've completed. */
TSVIONDoneSet(write_vio, TSVIONDoneGet(write_vio) + towrite);
}
avail = TSIOBufferReaderAvail(TSVIOReaderGet(write_vio));
/* Now we check the write VIO to see if there is data left to read. */
towriteLeft = TSVIONTodoGet(write_vio);
if (towriteLeft != 0) { /* +++ chunked data case */
if (towrite > 0) {
/* Call back the write VIO continuation to let it know that we are ready
for more data. */
TSContCall(TSVIOContGet(write_vio), TS_EVENT_VCONN_WRITE_READY, write_vio);
}
} else {
data->state = STATE_OUTPUT_DATA;
/* Call back the write VIO continuation to let it know that we have
completed the write operation. */
TSContCall(TSVIOContGet(write_vio), TS_EVENT_VCONN_WRITE_COMPLETE,
write_vio);
}
return 1;
Lerror:
/* If we are in this code path then something is seriously wrong. */
TSError("[bnull-transform] Fatal error in plugin");
TSReleaseAssert(!"[bnull-transform] Fatal error in plugin\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment