Home

Traffic Server Software Developers Kit

INKIOBufferBlockReadStart

Starts reading an IO buffer block.

Prototype

const char* INKIOBufferBlockReadStart (INKIOBufferBlock blockp, INKIOBufferReader readerp, int *avail)

Description

Gets the start point for reading from the IO buffer block blockp. The readerp parameter is needed because each IO buffer reader maintains its own current offset. INKIOBufferBlockReadStart stores the amount of data available for reading in the parameter avail. This is the same value that INKIOBufferBlockReadAvail returns. If avail is NULL, then no attempt is made to dereference it.

[Note] Note

The avail parameter stores the amount of data available for reading on the specified INKIOBufferBlock. If you need to read all available data in an INKIOBuffer, then make sure that your code keeps checking INKIOBufferBlocks until all the available data is read.

Returns

A pointer to the starting point for reading from the specified IO buffer block.

INK_ERROR_PTR if there is an error.

Example

Below is a sample routine, transform_read_status_event (modified from server-transform.c), that attempts to read a certain number of bytes. It calls INKIOBufferBlockReadStart to determine the number of bytes available to read (and get the start point within the INKIOBufferBlock to start reading). However, INKIOBufferBlockReadStart returns the available bytes within the current block only. Because the INKIOBuffer data structure contains a linked list of INKIOBufferBlocks, the available data within the INKIOBuffer could span more than one INKIOBufferBlock. The correct way to code this subroutine is to keep checking INKIOBufferBlocks for available data until all of the available INKIOBuffer data is read.

static int
transform_read_status_event (INKCont contp, TransformData *data,
                             INKEvent event, void *edata)
{
    switch (event) {
    case INK_EVENT_ERROR:
    case INK_EVENT_VCONN_EOS:
        return transform_bypass (contp, data);
    case INK_EVENT_VCONN_READ_COMPLETE:
        if (INKIOBufferReaderAvail (data->output_reader) ==
            sizeof (int)) {
            INKIOBufferBlock blk;
       char *buf;
            void *buf_ptr;
            int avail;
       int read_nbytes = sizeof (int);
       int read_ndone = 0;
         
       buf_ptr = &data->content_length;
       while (read_nbytes > 0) {
      blk = INKIOBufferReaderStart (data->output_reader);
      buf = (char *)INKIOBufferBlockReadStart (blk,
                   data->output_reader, 
                   &avail);
      read_ndone = (avail >= read_nbytes)? read_nbytes : avail;
      memcpy (buf_ptr, buf, read_ndone);
      if (read_ndone > 0) {
          INKIOBufferReaderConsume (data->output_reader,
                     read_ndone);   
          read_nbytes -= read_ndone;
          /* move ptr frwd by read_ndone bytes */
          buf_ptr = (char*)buf_ptr + read_ndone;
      }      
       }
       data->content_length = ntohl (data->content_length);
       return transform_read (contp, data);
        } 
        return transform_bypass (contp, data);
    default:
        break;