LCOV - code coverage report
Current view: directory - src/shared/gio - gio_mem.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 49 49 100.0 %
Date: 2012-02-16 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2011 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                 :   GioMemoryFileRead,
      28                 :   GioMemoryFileWrite,
      29                 :   GioMemoryFileSeek,
      30                 :   GioMemoryFileFlush,
      31                 :   GioMemoryFileClose,
      32                 :   GioMemoryFileDtor,
      33                 : };
      34                 : 
      35                 : 
      36                 : int GioMemoryFileCtor(struct GioMemoryFile  *self,
      37                 :                       char                  *buffer,
      38              14 :                       size_t                len) {
      39              14 :   self->buffer = buffer;
      40              14 :   self->len = len;
      41              14 :   self->curpos = 0;
      42                 : 
      43              14 :   self->base.vtbl = &kGioMemoryFileVtbl;
      44              14 :   return 1;
      45                 : }
      46                 : 
      47                 : 
      48                 : ssize_t GioMemoryFileRead(struct Gio  *vself,
      49                 :                           void        *buf,
      50              46 :                           size_t      count) {
      51              46 :   struct GioMemoryFile    *self = (struct GioMemoryFile *) vself;
      52                 :   size_t                  remain;
      53                 :   size_t                  newpos;
      54                 : 
      55                 :   /* 0 <= self->curpos && self->curpos <= self->len */
      56              46 :   remain = self->len - self->curpos;
      57                 :   /* 0 <= remain <= self->len */
      58              46 :   if (count > remain) {
      59               2 :     count = remain;
      60                 :   }
      61                 :   /* 0 <= count && count <= remain */
      62              46 :   if (0 == count) {
      63               1 :     return 0;
      64                 :   }
      65              45 :   newpos = self->curpos + count;
      66                 :   /* self->curpos <= newpos && newpos <= self->len */
      67                 : 
      68              45 :   memcpy(buf, self->buffer + self->curpos, count);
      69              45 :   self->curpos = newpos;
      70              45 :   return count;
      71                 : }
      72                 : 
      73                 : 
      74                 : ssize_t GioMemoryFileWrite(struct Gio *vself,
      75                 :                            const void *buf,
      76               4 :                            size_t     count) {
      77               4 :   struct GioMemoryFile  *self = (struct GioMemoryFile *) vself;
      78                 :   size_t                remain;
      79                 :   size_t                newpos;
      80                 : 
      81                 :   /* 0 <= self->curpos && self->curpos <= self->len */
      82               4 :   remain = self->len - self->curpos;
      83                 :   /* 0 <= remain <= self->len */
      84               4 :   if (count > remain) {
      85               2 :     count = remain;
      86                 :   }
      87                 :   /* 0 <= count && count <= remain */
      88               4 :   if (0 == count) {
      89               1 :     return 0;
      90                 :   }
      91               3 :   newpos = self->curpos + count;
      92                 :   /* self->curpos <= newpos && newpos <= self->len */
      93                 : 
      94               3 :   memcpy(self->buffer + self->curpos, buf, count);
      95               3 :   self->curpos = newpos;
      96                 :   /* we never extend a memory file */
      97               3 :   return count;
      98                 : }
      99                 : 
     100                 : 
     101                 : off_t GioMemoryFileSeek(struct Gio  *vself,
     102                 :                         off_t       offset,
     103              42 :                         int         whence) {
     104              42 :   struct GioMemoryFile  *self = (struct GioMemoryFile *) vself;
     105              42 :   size_t                 new_pos = (size_t) -1;
     106                 : 
     107              42 :   switch (whence) {
     108                 :     case SEEK_SET:
     109              34 :       new_pos = offset;
     110              34 :       break;
     111                 :     case SEEK_CUR:
     112               5 :       new_pos = self->curpos + offset;
     113               5 :       break;
     114                 :     case SEEK_END:
     115               2 :       new_pos = (size_t) (self->len + offset);
     116               2 :       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              42 :   if (new_pos > self->len) {
     127               3 :     errno = EINVAL;
     128               3 :     return (off_t) -1;
     129                 :   }
     130              39 :   self->curpos = new_pos;
     131              39 :   return (off_t) new_pos;
     132                 : }
     133                 : 
     134                 : 
     135              14 : int GioMemoryFileClose(struct Gio *vself) {
     136                 :   UNREFERENCED_PARAMETER(vself);
     137              14 :   return 0;
     138                 : }
     139                 : 
     140                 : 
     141               2 : int GioMemoryFileFlush(struct Gio   *vself) {
     142                 :   UNREFERENCED_PARAMETER(vself);
     143               2 :   return 0;
     144                 : }
     145                 : 
     146                 : 
     147              14 : void  GioMemoryFileDtor(struct Gio    *vself) {
     148                 :   UNREFERENCED_PARAMETER(vself);
     149                 :   return;
     150                 : }

Generated by: LCOV version 1.7