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