• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "buffer"
18 
19 #include <assert.h>
20 #include <errno.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 
24 #include "buffer.h"
25 #include "loghack.h"
26 
bufferCreate(size_t capacity)27 Buffer* bufferCreate(size_t capacity) {
28     Buffer* buffer = malloc(sizeof(Buffer));
29     if (buffer == NULL) {
30         return NULL;
31     }
32     buffer->capacity = capacity;
33     buffer->expected = 0;
34     buffer->data = malloc(capacity);
35     if (buffer->data == NULL) {
36         free(buffer);
37         return NULL;
38     }
39     return buffer;
40 }
41 
bufferFree(Buffer * buffer)42 void bufferFree(Buffer* buffer) {
43     free(buffer->data);
44     free(buffer);
45 }
46 
bufferWrap(char * data,size_t capacity,size_t size)47 Buffer* bufferWrap(char* data, size_t capacity, size_t size) {
48     Buffer* buffer = malloc(sizeof(Buffer));
49     if (buffer == NULL) {
50         return NULL;
51     }
52 
53     buffer->data = data;
54     buffer->capacity = capacity;
55     buffer->size = size;
56     buffer->expected = 0;
57     return buffer;
58 }
59 
bufferPrepareForRead(Buffer * buffer,size_t expected)60 int bufferPrepareForRead(Buffer* buffer, size_t expected) {
61     if (expected > buffer->capacity) {
62         // Expand buffer.
63         char* expanded = realloc(buffer->data, expected);
64         if (expanded == NULL) {
65             errno = ENOMEM;
66             return -1;
67         }
68         buffer->capacity = expected;
69         buffer->data = expanded;
70     }
71 
72     buffer->size = 0;
73     buffer->expected = expected;
74     return 0;
75 }
76 
bufferRead(Buffer * buffer,int fd)77 ssize_t bufferRead(Buffer* buffer, int fd) {
78     assert(buffer->size < buffer->expected);
79 
80     ssize_t bytesRead = read(fd,
81             buffer->data + buffer->size,
82             buffer->expected - buffer->size);
83 
84     if (bytesRead > 0) {
85         buffer->size += bytesRead;
86         return buffer->size;
87     }
88 
89     return bytesRead;
90 }
91 
bufferPrepareForWrite(Buffer * buffer)92 void bufferPrepareForWrite(Buffer* buffer) {
93     buffer->remaining = buffer->size;
94 }
95 
bufferWrite(Buffer * buffer,int fd)96 ssize_t bufferWrite(Buffer* buffer, int fd) {
97     assert(buffer->remaining > 0);
98     assert(buffer->remaining <= buffer->size);
99 
100     ssize_t bytesWritten = write(fd,
101             buffer->data + buffer->size - buffer->remaining,
102             buffer->remaining);
103 
104     if (bytesWritten >= 0) {
105         buffer->remaining -= bytesWritten;
106 
107         LOGD("Buffer bytes written: %d", (int) bytesWritten);
108         LOGD("Buffer size: %d", (int) buffer->size);
109         LOGD("Buffer remaining: %d", (int) buffer->remaining);
110 
111         return buffer->remaining;
112     }
113 
114     return bytesWritten;
115 }
116 
117