示例#1
0
/**
 * This method is used to read and consume the input buffer
 * @arg conn The client connection
 * @arg bytes The number of bytes to read
 * @arg buf Output parameter, sets the start of the buffer.
 * @arg should_free Output parameter, should the buffer be freed by the caller.
 * @return 0 on success, -1 if there is insufficient data.
 */
int read_client_bytes(statsite_conn_info *conn, int bytes, char** buf, int* should_free) {
    if (unlikely(bytes > circbuf_used_buf(&conn->input))) return -1;

    // Handle the wrap around case
    if (unlikely(conn->input.write_cursor < conn->input.read_cursor)) {
        // Check if we can use a contiguous chunk
        int end_size = conn->input.buf_size - conn->input.read_cursor;
        if (end_size >= bytes) {
            *buf = conn->input.buffer + conn->input.read_cursor;
            *should_free = 0;

        // Otherwise, allocate a dynamic slab, and copy
        } else {
            *buf = malloc(bytes);
            memcpy(*buf, conn->input.buffer + conn->input.read_cursor, end_size);
            memcpy(*buf + end_size, conn->input.buffer, bytes - end_size);
            *should_free = 1;
        }

    // Handle the contiguous case
    } else {
        *buf = conn->input.buffer + conn->input.read_cursor;
        *should_free = 0;
    }

    // Advance the read cursor
    circbuf_advance_read(&conn->input, bytes);
    return 0;
}
/**
 * This method is used to peek into the input buffer without
 * causing input to be consumed.
 * @arg conn The client connection
 * @arg bytes The number of bytes to peek
 * @arg buf The output buffer to write to
 * @return 0 on success, -1 if there is insufficient data.
 */
int peek_client_bytes(statsite_proxy_conn_info *conn, int bytes, char* buf) {
    // Ensure we have sufficient data
    if (bytes > circbuf_used_buf(&conn->input)) return -1;

    // Copy the bytes
    int offset = conn->input.read_cursor;
    int buf_size = conn->input.buf_size;
    for (int i=0; i < bytes; i++) {
        buf[i] = conn->input.buffer[(offset + i) % buf_size];
    }

    return 0;
}
示例#3
0
/**
 * This method is used to seek the input buffer without
 * consuming input. It can be used in conjunction with
 * peek_client_bytes to conditionally seek.
 * @arg conn The client connection
 * @arg bytes The number of bytes to seek
 * @return 0 on success, -1 if there is insufficient data.
 */
int seek_client_bytes(statsite_conn_info *conn, int bytes) {
    if (unlikely(bytes > circbuf_used_buf(&conn->input))) return -1;
    circbuf_advance_read(&conn->input, bytes);
    return 0;
}
示例#4
0
/**
 * Lets the caller look at the next byte
 * @arg conn The client connectoin
 * @arg byte The output byte
 * @return 0 on success, -1 if there is no data.
 */
int peek_client_byte(statsite_conn_info *conn, unsigned char* byte) {
    if (unlikely(!circbuf_used_buf(&conn->input))) return -1;
    *byte = *(unsigned char*)(conn->input.buffer+conn->input.read_cursor);
    return 0;
}
示例#5
0
/**
 * This method is used to query how much data is available
 * to be read from the command buffer.
 * @arg conn The client connection
 * @return The bytes available
 */
uint64_t available_bytes(statsite_conn_info *conn) {
    // Query the circular buffer
    return circbuf_used_buf(&conn->input);
}