"Fossies" - the Fresh Open Source Software Archive

Member "memcached-1.6.15/bipbuffer.c" (16 Jul 2020, 3764 Bytes) of package /linux/www/memcached-1.6.15.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "bipbuffer.c" see the Fossies "Dox" file reference documentation.

    1 /**
    2  * Copyright (c) 2011, Willem-Hendrik Thiart
    3  * Use of this source code is governed by a BSD-style license that can be
    4  * found in the LICENSE.bipbuffer file.
    5  *
    6  * @file
    7  * @author  Willem Thiart himself@willemthiart.com
    8  */
    9 
   10 #include "stdio.h"
   11 #include <stdlib.h>
   12 
   13 /* for memcpy */
   14 #include <string.h>
   15 
   16 #include "bipbuffer.h"
   17 
   18 static size_t bipbuf_sizeof(const unsigned int size)
   19 {
   20     return sizeof(bipbuf_t) + size;
   21 }
   22 
   23 int bipbuf_unused(const bipbuf_t* me)
   24 {
   25     if (1 == me->b_inuse)
   26         /* distance between region B and region A */
   27         return me->a_start - me->b_end;
   28     else
   29         return me->size - me->a_end;
   30 }
   31 
   32 int bipbuf_size(const bipbuf_t* me)
   33 {
   34     return me->size;
   35 }
   36 
   37 int bipbuf_used(const bipbuf_t* me)
   38 {
   39     return (me->a_end - me->a_start) + me->b_end;
   40 }
   41 
   42 void bipbuf_init(bipbuf_t* me, const unsigned int size)
   43 {
   44     me->a_start = me->a_end = me->b_end = 0;
   45     me->size = size;
   46     me->b_inuse = 0;
   47 }
   48 
   49 bipbuf_t *bipbuf_new(const unsigned int size)
   50 {
   51     bipbuf_t *me = malloc(bipbuf_sizeof(size));
   52     if (!me)
   53         return NULL;
   54     bipbuf_init(me, size);
   55     return me;
   56 }
   57 
   58 void bipbuf_free(bipbuf_t* me)
   59 {
   60     free(me);
   61 }
   62 
   63 int bipbuf_is_empty(const bipbuf_t* me)
   64 {
   65     return me->a_start == me->a_end;
   66 }
   67 
   68 /* find out if we should turn on region B
   69  * ie. is the distance from A to buffer's end less than B to A? */
   70 static void __check_for_switch_to_b(bipbuf_t* me)
   71 {
   72     if (me->size - me->a_end < me->a_start - me->b_end)
   73         me->b_inuse = 1;
   74 }
   75 
   76 /* TODO: DOCUMENT THESE TWO FUNCTIONS */
   77 unsigned char *bipbuf_request(bipbuf_t* me, const int size)
   78 {
   79     if (bipbuf_unused(me) < size)
   80         return 0;
   81     if (1 == me->b_inuse)
   82     {
   83         return (unsigned char *)me->data + me->b_end;
   84     }
   85     else
   86     {
   87         return (unsigned char *)me->data + me->a_end;
   88     }
   89 }
   90 
   91 int bipbuf_push(bipbuf_t* me, const int size)
   92 {
   93     if (bipbuf_unused(me) < size)
   94         return 0;
   95 
   96     if (1 == me->b_inuse)
   97     {
   98         me->b_end += size;
   99     }
  100     else
  101     {
  102         me->a_end += size;
  103     }
  104 
  105     __check_for_switch_to_b(me);
  106     return size;
  107 }
  108 
  109 int bipbuf_offer(bipbuf_t* me, const unsigned char *data, const int size)
  110 {
  111     /* not enough space */
  112     if (bipbuf_unused(me) < size)
  113         return 0;
  114 
  115     if (1 == me->b_inuse)
  116     {
  117         memcpy(me->data + me->b_end, data, size);
  118         me->b_end += size;
  119     }
  120     else
  121     {
  122         memcpy(me->data + me->a_end, data, size);
  123         me->a_end += size;
  124     }
  125 
  126     __check_for_switch_to_b(me);
  127     return size;
  128 }
  129 
  130 unsigned char *bipbuf_peek(const bipbuf_t* me, const unsigned int size)
  131 {
  132     /* make sure we can actually peek at this data */
  133     if (me->size < me->a_start + size)
  134         return NULL;
  135 
  136     if (bipbuf_is_empty(me))
  137         return NULL;
  138 
  139     return (unsigned char *)me->data + me->a_start;
  140 }
  141 
  142 unsigned char *bipbuf_peek_all(const bipbuf_t* me, unsigned int *size)
  143 {
  144     if (bipbuf_is_empty(me))
  145         return NULL;
  146 
  147     *size = me->a_end - me->a_start;
  148     return (unsigned char*)me->data + me->a_start;
  149 }
  150 
  151 unsigned char *bipbuf_poll(bipbuf_t* me, const unsigned int size)
  152 {
  153     if (bipbuf_is_empty(me))
  154         return NULL;
  155 
  156     /* make sure we can actually poll this data */
  157     if (me->size < me->a_start + size)
  158         return NULL;
  159 
  160     void *end = me->data + me->a_start;
  161     me->a_start += size;
  162 
  163     /* we seem to be empty.. */
  164     if (me->a_start == me->a_end)
  165     {
  166         /* replace a with region b */
  167         if (1 == me->b_inuse)
  168         {
  169             me->a_start = 0;
  170             me->a_end = me->b_end;
  171             me->b_end = me->b_inuse = 0;
  172         }
  173         else
  174             /* safely move cursor back to the start because we are empty */
  175             me->a_start = me->a_end = 0;
  176     }
  177 
  178     __check_for_switch_to_b(me);
  179     return end;
  180 }