LCOV - code coverage report
Current view: directory - src/shared/gio - gio_mem.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 56 56 100.0 %
Date: 2014-09-25 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*
       8                 :  * NaCl Generic I/O interface implementation: memory buffer-based I/O.
       9                 :  */
      10                 : #include "native_client/src/include/portability.h"
      11                 : 
      12                 : #include <string.h>
      13                 : #include <errno.h>
      14                 : 
      15                 : #include "native_client/src/shared/gio/gio.h"
      16                 : 
      17                 : /*
      18                 :  * Memory file is just read/write from/to an in-memory buffer.  Once
      19                 :  * the buffer is consumed, there is no refilling/flushing.
      20                 :  */
      21                 : 
      22                 : #if !defined(SIZE_T_MAX)
      23                 : # define SIZE_T_MAX ((size_t) -1)
      24                 : #endif
      25                 : 
      26                 : struct GioVtbl const    kGioMemoryFileVtbl = {
      27                 :   GioMemoryFileDtor,
      28                 :   GioMemoryFileRead,
      29                 :   GioMemoryFileWrite,
      30                 :   GioMemoryFileSeek,
      31                 :   GioMemoryFileFlush,
      32                 :   GioMemoryFileClose,
      33                 : };
      34                 : 
      35                 : 
      36                 : int GioMemoryFileCtor(struct GioMemoryFile  *self,
      37                 :                       char                  *buffer,
      38               1 :                       size_t                len) {
      39               1 :   self->buffer = buffer;
      40               1 :   self->len = len;
      41               1 :   self->curpos = 0;
      42                 : 
      43               1 :   self->base.vtbl = &kGioMemoryFileVtbl;
      44               1 :   return 1;
      45               1 : }
      46                 : 
      47                 : 
      48                 : ssize_t GioMemoryFileRead(struct Gio  *vself,
      49                 :                           void        *buf,
      50               1 :                           size_t      count) {
      51               1 :   struct GioMemoryFile    *self = (struct GioMemoryFile *) vself;
      52                 :   size_t                  remain;
      53                 :   size_t                  newpos;
      54                 : 
      55                 :   /* 0 <= self->curpos && self->curpos <= self->len */
      56               1 :   remain = self->len - self->curpos;
      57                 :   /* 0 <= remain <= self->len */
      58               1 :   if (count > remain) {
      59               1 :     count = remain;
      60                 :   }
      61                 :   /* 0 <= count && count <= remain */
      62               1 :   if (0 == count) {
      63               1 :     return 0;
      64                 :   }
      65               1 :   newpos = self->curpos + count;
      66                 :   /* self->curpos <= newpos && newpos <= self->len */
      67                 : 
      68               1 :   memcpy(buf, self->buffer + self->curpos, count);
      69               1 :   self->curpos = newpos;
      70               1 :   return count;
      71               1 : }
      72                 : 
      73                 : 
      74                 : ssize_t GioMemoryFileWrite(struct Gio *vself,
      75                 :                            const void *buf,
      76               1 :                            size_t     count) {
      77               1 :   struct GioMemoryFile  *self = (struct GioMemoryFile *) vself;
      78                 :   size_t                remain;
      79                 :   size_t                newpos;
      80                 : 
      81                 :   /* 0 <= self->curpos && self->curpos <= self->len */
      82               1 :   remain = self->len - self->curpos;
      83                 :   /* 0 <= remain <= self->len */
      84               1 :   if (count > remain) {
      85               1 :     count = remain;
      86                 :   }
      87                 :   /* 0 <= count && count <= remain */
      88               1 :   if (0 == count) {
      89               1 :     return 0;
      90                 :   }
      91               1 :   newpos = self->curpos + count;
      92                 :   /* self->curpos <= newpos && newpos <= self->len */
      93                 : 
      94               1 :   memcpy(self->buffer + self->curpos, buf, count);
      95               1 :   self->curpos = newpos;
      96                 :   /* we never extend a memory file */
      97               1 :   return count;
      98               1 : }
      99                 : 
     100                 : 
     101                 : off_t GioMemoryFileSeek(struct Gio  *vself,
     102                 :                         off_t       offset,
     103               1 :                         int         whence) {
     104               1 :   struct GioMemoryFile  *self = (struct GioMemoryFile *) vself;
     105               1 :   size_t                 new_pos = (size_t) -1;
     106                 : 
     107               1 :   switch (whence) {
     108                 :     case SEEK_SET:
     109               1 :       new_pos = offset;
     110               1 :       break;
     111                 :     case SEEK_CUR:
     112               1 :       new_pos = self->curpos + offset;
     113               1 :       break;
     114                 :     case SEEK_END:
     115               1 :       new_pos = (size_t) (self->len + offset);
     116               1 :       break;
     117                 :     default:
     118               1 :       errno = EINVAL;
     119                 :       break;
     120                 :   }
     121                 :   /**
     122                 :    * on error, new_pos should be SIZE_T_MAX. On overflow it will either
     123                 :    * be greater than self->len, or will have wrapped around.
     124                 :    * TODO (ilewis): Detect wraparound and return an error.
     125                 :    */
     126               1 :   if (new_pos > self->len) {
     127               1 :     errno = EINVAL;
     128               1 :     return (off_t) -1;
     129                 :   }
     130               1 :   self->curpos = new_pos;
     131               1 :   return (off_t) new_pos;
     132               1 : }
     133                 : 
     134                 : 
     135               1 : int GioMemoryFileClose(struct Gio *vself) {
     136                 :   UNREFERENCED_PARAMETER(vself);
     137               1 :   return 0;
     138               1 : }
     139                 : 
     140                 : 
     141               1 : int GioMemoryFileFlush(struct Gio   *vself) {
     142                 :   UNREFERENCED_PARAMETER(vself);
     143               1 :   return 0;
     144               1 : }
     145                 : 
     146                 : 
     147               1 : void  GioMemoryFileDtor(struct Gio    *vself) {
     148                 :   UNREFERENCED_PARAMETER(vself);
     149                 :   return;
     150               1 : }

Generated by: LCOV version 1.7