LCOV - code coverage report
Current view: directory - ipc/chromium/src/third_party/libevent - event_tagging.c (source / functions) Found Hit Coverage
Test: app.info Lines: 184 0 0.0 %
Date: 2012-06-02 Functions: 20 0 0.0 %

       1                 : /*
       2                 :  * Copyright (c) 2003, 2004 Niels Provos <provos@citi.umich.edu>
       3                 :  * All rights reserved.
       4                 :  *
       5                 :  * Redistribution and use in source and binary forms, with or without
       6                 :  * modification, are permitted provided that the following conditions
       7                 :  * are met:
       8                 :  * 1. Redistributions of source code must retain the above copyright
       9                 :  *    notice, this list of conditions and the following disclaimer.
      10                 :  * 2. Redistributions in binary form must reproduce the above copyright
      11                 :  *    notice, this list of conditions and the following disclaimer in the
      12                 :  *    documentation and/or other materials provided with the distribution.
      13                 :  * 3. The name of the author may not be used to endorse or promote products
      14                 :  *    derived from this software without specific prior written permission.
      15                 :  *
      16                 :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      17                 :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      18                 :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      19                 :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      20                 :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      21                 :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      22                 :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      23                 :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      24                 :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      25                 :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26                 :  */
      27                 : 
      28                 : #ifdef HAVE_CONFIG_H
      29                 : #include "config.h"
      30                 : #endif
      31                 : 
      32                 : #ifdef HAVE_SYS_TYPES_H
      33                 : #include <sys/types.h>
      34                 : #endif
      35                 : #ifdef HAVE_SYS_PARAM_H
      36                 : #include <sys/param.h>
      37                 : #endif
      38                 : 
      39                 : #ifdef WIN32
      40                 : #define WIN32_LEAN_AND_MEAN
      41                 : #include <winsock2.h>
      42                 : #include <windows.h>
      43                 : #undef WIN32_LEAN_AND_MEAN
      44                 : #else
      45                 : #include <sys/ioctl.h>
      46                 : #endif
      47                 : 
      48                 : #include <sys/queue.h>
      49                 : #ifdef HAVE_SYS_TIME_H
      50                 : #include <sys/time.h>
      51                 : #endif
      52                 : 
      53                 : #include <errno.h>
      54                 : #include <stdio.h>
      55                 : #include <stdlib.h>
      56                 : #include <string.h>
      57                 : #ifndef WIN32
      58                 : #include <syslog.h>
      59                 : #endif
      60                 : #ifdef HAVE_UNISTD_H
      61                 : #include <unistd.h>
      62                 : #endif
      63                 : 
      64                 : #include "event.h"
      65                 : #include "evutil.h"
      66                 : #include "log.h"
      67                 : 
      68                 : int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf);
      69                 : int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag);
      70                 : int evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf);
      71                 : 
      72                 : static struct evbuffer *_buf;   /* not thread safe */
      73                 : 
      74                 : void
      75               0 : evtag_init(void)
      76                 : {
      77               0 :         if (_buf != NULL)
      78               0 :                 return;
      79                 : 
      80               0 :         if ((_buf = evbuffer_new()) == NULL)
      81               0 :                 event_err(1, "%s: malloc", __func__);
      82                 : }
      83                 : 
      84                 : /* 
      85                 :  * We encode integer's by nibbles; the first nibble contains the number
      86                 :  * of significant nibbles - 1;  this allows us to encode up to 64-bit
      87                 :  * integers.  This function is byte-order independent.
      88                 :  */
      89                 : 
      90                 : void
      91               0 : encode_int(struct evbuffer *evbuf, ev_uint32_t number)
      92                 : {
      93               0 :         int off = 1, nibbles = 0;
      94                 :         ev_uint8_t data[5];
      95                 : 
      96               0 :         memset(data, 0, sizeof(ev_uint32_t)+1);
      97               0 :         while (number) {
      98               0 :                 if (off & 0x1)
      99               0 :                         data[off/2] = (data[off/2] & 0xf0) | (number & 0x0f);
     100                 :                 else
     101               0 :                         data[off/2] = (data[off/2] & 0x0f) |
     102                 :                             ((number & 0x0f) << 4);
     103               0 :                 number >>= 4;
     104               0 :                 off++;
     105                 :         }
     106                 : 
     107               0 :         if (off > 2)
     108               0 :                 nibbles = off - 2;
     109                 : 
     110                 :         /* Off - 1 is the number of encoded nibbles */
     111               0 :         data[0] = (data[0] & 0x0f) | ((nibbles & 0x0f) << 4);
     112                 : 
     113               0 :         evbuffer_add(evbuf, data, (off + 1) / 2);
     114               0 : }
     115                 : 
     116                 : /*
     117                 :  * Support variable length encoding of tags; we use the high bit in each
     118                 :  * octet as a continuation signal.
     119                 :  */
     120                 : 
     121                 : int
     122               0 : evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag)
     123                 : {
     124               0 :         int bytes = 0;
     125                 :         ev_uint8_t data[5];
     126                 : 
     127               0 :         memset(data, 0, sizeof(data));
     128                 :         do {
     129               0 :                 ev_uint8_t lower = tag & 0x7f;
     130               0 :                 tag >>= 7;
     131                 : 
     132               0 :                 if (tag)
     133               0 :                         lower |= 0x80;
     134                 : 
     135               0 :                 data[bytes++] = lower;
     136               0 :         } while (tag);
     137                 : 
     138               0 :         if (evbuf != NULL)
     139               0 :                 evbuffer_add(evbuf, data, bytes);
     140                 : 
     141               0 :         return (bytes);
     142                 : }
     143                 : 
     144                 : static int
     145               0 : decode_tag_internal(ev_uint32_t *ptag, struct evbuffer *evbuf, int dodrain)
     146                 : {
     147               0 :         ev_uint32_t number = 0;
     148               0 :         ev_uint8_t *data = EVBUFFER_DATA(evbuf);
     149               0 :         int len = EVBUFFER_LENGTH(evbuf);
     150               0 :         int count = 0, shift = 0, done = 0;
     151                 : 
     152               0 :         while (count++ < len) {
     153               0 :                 ev_uint8_t lower = *data++;
     154               0 :                 number |= (lower & 0x7f) << shift;
     155               0 :                 shift += 7;
     156                 : 
     157               0 :                 if (!(lower & 0x80)) {
     158               0 :                         done = 1;
     159               0 :                         break;
     160                 :                 }
     161                 :         }
     162                 : 
     163               0 :         if (!done)
     164               0 :                 return (-1);
     165                 : 
     166               0 :         if (dodrain)
     167               0 :                 evbuffer_drain(evbuf, count);
     168                 : 
     169               0 :         if (ptag != NULL)
     170               0 :                 *ptag = number;
     171                 : 
     172               0 :         return (count);
     173                 : }
     174                 : 
     175                 : int
     176               0 : evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf)
     177                 : {
     178               0 :         return (decode_tag_internal(ptag, evbuf, 1 /* dodrain */));
     179                 : }
     180                 : 
     181                 : /*
     182                 :  * Marshal a data type, the general format is as follows:
     183                 :  *
     184                 :  * tag number: one byte; length: var bytes; payload: var bytes
     185                 :  */
     186                 : 
     187                 : void
     188               0 : evtag_marshal(struct evbuffer *evbuf, ev_uint32_t tag,
     189                 :     const void *data, ev_uint32_t len)
     190                 : {
     191               0 :         evtag_encode_tag(evbuf, tag);
     192               0 :         encode_int(evbuf, len);
     193               0 :         evbuffer_add(evbuf, (void *)data, len);
     194               0 : }
     195                 : 
     196                 : /* Marshaling for integers */
     197                 : void
     198               0 : evtag_marshal_int(struct evbuffer *evbuf, ev_uint32_t tag, ev_uint32_t integer)
     199                 : {
     200               0 :         evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
     201               0 :         encode_int(_buf, integer);
     202                 : 
     203               0 :         evtag_encode_tag(evbuf, tag);
     204               0 :         encode_int(evbuf, EVBUFFER_LENGTH(_buf));
     205               0 :         evbuffer_add_buffer(evbuf, _buf);
     206               0 : }
     207                 : 
     208                 : void
     209               0 : evtag_marshal_string(struct evbuffer *buf, ev_uint32_t tag, const char *string)
     210                 : {
     211               0 :         evtag_marshal(buf, tag, string, strlen(string));
     212               0 : }
     213                 : 
     214                 : void
     215               0 : evtag_marshal_timeval(struct evbuffer *evbuf, ev_uint32_t tag, struct timeval *tv)
     216                 : {
     217               0 :         evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
     218                 : 
     219               0 :         encode_int(_buf, tv->tv_sec);
     220               0 :         encode_int(_buf, tv->tv_usec);
     221                 : 
     222               0 :         evtag_marshal(evbuf, tag, EVBUFFER_DATA(_buf),
     223               0 :             EVBUFFER_LENGTH(_buf));
     224               0 : }
     225                 : 
     226                 : static int
     227               0 : decode_int_internal(ev_uint32_t *pnumber, struct evbuffer *evbuf, int dodrain)
     228                 : {
     229               0 :         ev_uint32_t number = 0;
     230               0 :         ev_uint8_t *data = EVBUFFER_DATA(evbuf);
     231               0 :         int len = EVBUFFER_LENGTH(evbuf);
     232               0 :         int nibbles = 0;
     233                 : 
     234               0 :         if (!len)
     235               0 :                 return (-1);
     236                 : 
     237               0 :         nibbles = ((data[0] & 0xf0) >> 4) + 1;
     238               0 :         if (nibbles > 8 || (nibbles >> 1) + 1 > len)
     239               0 :                 return (-1);
     240               0 :         len = (nibbles >> 1) + 1;
     241                 : 
     242               0 :         while (nibbles > 0) {
     243               0 :                 number <<= 4;
     244               0 :                 if (nibbles & 0x1)
     245               0 :                         number |= data[nibbles >> 1] & 0x0f;
     246                 :                 else
     247               0 :                         number |= (data[nibbles >> 1] & 0xf0) >> 4;
     248               0 :                 nibbles--;
     249                 :         }
     250                 : 
     251               0 :         if (dodrain)
     252               0 :                 evbuffer_drain(evbuf, len);
     253                 : 
     254               0 :         *pnumber = number;
     255                 : 
     256               0 :         return (len);
     257                 : }
     258                 : 
     259                 : int
     260               0 : evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf)
     261                 : {
     262               0 :         return (decode_int_internal(pnumber, evbuf, 1) == -1 ? -1 : 0);
     263                 : }
     264                 : 
     265                 : int
     266               0 : evtag_peek(struct evbuffer *evbuf, ev_uint32_t *ptag)
     267                 : {
     268               0 :         return (decode_tag_internal(ptag, evbuf, 0 /* dodrain */));
     269                 : }
     270                 : 
     271                 : int
     272               0 : evtag_peek_length(struct evbuffer *evbuf, ev_uint32_t *plength)
     273                 : {
     274                 :         struct evbuffer tmp;
     275                 :         int res, len;
     276                 : 
     277               0 :         len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */);
     278               0 :         if (len == -1)
     279               0 :                 return (-1);
     280                 : 
     281               0 :         tmp = *evbuf;
     282               0 :         tmp.buffer += len;
     283               0 :         tmp.off -= len;
     284                 : 
     285               0 :         res = decode_int_internal(plength, &tmp, 0);
     286               0 :         if (res == -1)
     287               0 :                 return (-1);
     288                 : 
     289               0 :         *plength += res + len;
     290                 : 
     291               0 :         return (0);
     292                 : }
     293                 : 
     294                 : int
     295               0 : evtag_payload_length(struct evbuffer *evbuf, ev_uint32_t *plength)
     296                 : {
     297                 :         struct evbuffer tmp;
     298                 :         int res, len;
     299                 : 
     300               0 :         len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */);
     301               0 :         if (len == -1)
     302               0 :                 return (-1);
     303                 : 
     304               0 :         tmp = *evbuf;
     305               0 :         tmp.buffer += len;
     306               0 :         tmp.off -= len;
     307                 : 
     308               0 :         res = decode_int_internal(plength, &tmp, 0);
     309               0 :         if (res == -1)
     310               0 :                 return (-1);
     311                 : 
     312               0 :         return (0);
     313                 : }
     314                 : 
     315                 : int
     316               0 : evtag_consume(struct evbuffer *evbuf)
     317                 : {
     318                 :         ev_uint32_t len;
     319               0 :         if (decode_tag_internal(NULL, evbuf, 1 /* dodrain */) == -1)
     320               0 :                 return (-1);
     321               0 :         if (evtag_decode_int(&len, evbuf) == -1)
     322               0 :                 return (-1);
     323               0 :         evbuffer_drain(evbuf, len);
     324                 : 
     325               0 :         return (0);
     326                 : }
     327                 : 
     328                 : /* Reads the data type from an event buffer */
     329                 : 
     330                 : int
     331               0 : evtag_unmarshal(struct evbuffer *src, ev_uint32_t *ptag, struct evbuffer *dst)
     332                 : {
     333                 :         ev_uint32_t len;
     334                 :         ev_uint32_t integer;
     335                 : 
     336               0 :         if (decode_tag_internal(ptag, src, 1 /* dodrain */) == -1)
     337               0 :                 return (-1);
     338               0 :         if (evtag_decode_int(&integer, src) == -1)
     339               0 :                 return (-1);
     340               0 :         len = integer;
     341                 : 
     342               0 :         if (EVBUFFER_LENGTH(src) < len)
     343               0 :                 return (-1);
     344                 : 
     345               0 :         if (evbuffer_add(dst, EVBUFFER_DATA(src), len) == -1)
     346               0 :                 return (-1);
     347                 : 
     348               0 :         evbuffer_drain(src, len);
     349                 : 
     350               0 :         return (len);
     351                 : }
     352                 : 
     353                 : /* Marshaling for integers */
     354                 : 
     355                 : int
     356               0 : evtag_unmarshal_int(struct evbuffer *evbuf, ev_uint32_t need_tag,
     357                 :     ev_uint32_t *pinteger)
     358                 : {
     359                 :         ev_uint32_t tag;
     360                 :         ev_uint32_t len;
     361                 :         ev_uint32_t integer;
     362                 : 
     363               0 :         if (decode_tag_internal(&tag, evbuf, 1 /* dodrain */) == -1)
     364               0 :                 return (-1);
     365               0 :         if (need_tag != tag)
     366               0 :                 return (-1);
     367               0 :         if (evtag_decode_int(&integer, evbuf) == -1)
     368               0 :                 return (-1);
     369               0 :         len = integer;
     370                 : 
     371               0 :         if (EVBUFFER_LENGTH(evbuf) < len)
     372               0 :                 return (-1);
     373                 :         
     374               0 :         evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
     375               0 :         if (evbuffer_add(_buf, EVBUFFER_DATA(evbuf), len) == -1)
     376               0 :                 return (-1);
     377                 : 
     378               0 :         evbuffer_drain(evbuf, len);
     379                 : 
     380               0 :         return (evtag_decode_int(pinteger, _buf));
     381                 : }
     382                 : 
     383                 : /* Unmarshal a fixed length tag */
     384                 : 
     385                 : int
     386               0 : evtag_unmarshal_fixed(struct evbuffer *src, ev_uint32_t need_tag, void *data,
     387                 :     size_t len)
     388                 : {
     389                 :         ev_uint32_t tag;
     390                 : 
     391                 :         /* Initialize this event buffer so that we can read into it */
     392               0 :         evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
     393                 : 
     394                 :         /* Now unmarshal a tag and check that it matches the tag we want */
     395               0 :         if (evtag_unmarshal(src, &tag, _buf) == -1 || tag != need_tag)
     396               0 :                 return (-1);
     397                 : 
     398               0 :         if (EVBUFFER_LENGTH(_buf) != len)
     399               0 :                 return (-1);
     400                 : 
     401               0 :         memcpy(data, EVBUFFER_DATA(_buf), len);
     402               0 :         return (0);
     403                 : }
     404                 : 
     405                 : int
     406               0 : evtag_unmarshal_string(struct evbuffer *evbuf, ev_uint32_t need_tag,
     407                 :     char **pstring)
     408                 : {
     409                 :         ev_uint32_t tag;
     410                 : 
     411               0 :         evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
     412                 : 
     413               0 :         if (evtag_unmarshal(evbuf, &tag, _buf) == -1 || tag != need_tag)
     414               0 :                 return (-1);
     415                 : 
     416               0 :         *pstring = calloc(EVBUFFER_LENGTH(_buf) + 1, 1);
     417               0 :         if (*pstring == NULL)
     418               0 :                 event_err(1, "%s: calloc", __func__);
     419               0 :         evbuffer_remove(_buf, *pstring, EVBUFFER_LENGTH(_buf));
     420                 : 
     421               0 :         return (0);
     422                 : }
     423                 : 
     424                 : int
     425               0 : evtag_unmarshal_timeval(struct evbuffer *evbuf, ev_uint32_t need_tag,
     426                 :     struct timeval *ptv)
     427                 : {
     428                 :         ev_uint32_t tag;
     429                 :         ev_uint32_t integer;
     430                 : 
     431               0 :         evbuffer_drain(_buf, EVBUFFER_LENGTH(_buf));
     432               0 :         if (evtag_unmarshal(evbuf, &tag, _buf) == -1 || tag != need_tag)
     433               0 :                 return (-1);
     434                 : 
     435               0 :         if (evtag_decode_int(&integer, _buf) == -1)
     436               0 :                 return (-1);
     437               0 :         ptv->tv_sec = integer;
     438               0 :         if (evtag_decode_int(&integer, _buf) == -1)
     439               0 :                 return (-1);
     440               0 :         ptv->tv_usec = integer;
     441                 : 
     442               0 :         return (0);
     443                 : }

Generated by: LCOV version 1.7