00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <sys/types.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <errno.h>
00030
00031 #include "data_object.h"
00032 #include "data_object_internal.h"
00033 #include "data_object_memory.h"
00034 #include "type_limits.h"
00035 #include "debug.h"
00036 #include "util.h"
00037
00038
00039
00040 static int data_object_memory_get_size(data_object_t *obj, off_t *size);
00041 static int data_object_memory_free(data_object_t *obj);
00042 static int data_object_memory_get_data(data_object_t *obj, void **buf, off_t offset,
00043 off_t *length, data_object_flags flags);
00044 static int data_object_memory_compare(int *result, data_object_t *obj1,
00045 data_object_t *obj2);
00046
00047
00048 static struct data_object_funcs data_object_memory_funcs = {
00049 .get_data = data_object_memory_get_data,
00050 .free = data_object_memory_free,
00051 .get_size = data_object_memory_get_size,
00052 .compare = data_object_memory_compare
00053 };
00054
00055
00056 struct data_object_memory_impl {
00057 void *data;
00058 size_t size;
00059 data_object_memory_free_func *mem_free;
00060 };
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 int data_object_memory_new(data_object_t **obj, void *data, size_t size)
00077 {
00078 if (obj == NULL)
00079 return_error(EINVAL);
00080
00081
00082 if (__MAX(size_t) - (size_t)data < size - 1 * (size != 0))
00083 return_error(EOVERFLOW);
00084
00085
00086 struct data_object_memory_impl *impl =
00087 malloc (sizeof(struct data_object_memory_impl));
00088
00089 if (impl == NULL)
00090 return_error(ENOMEM);
00091
00092 impl->data = data;
00093
00094
00095 int err = data_object_create_impl(obj, impl, &data_object_memory_funcs);
00096
00097 if (err) {
00098 free(impl);
00099 return_error(err);
00100 }
00101
00102 impl->size = size;
00103
00104
00105 impl->mem_free = NULL;
00106
00107 return 0;
00108
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 int data_object_memory_set_free_func(data_object_t *obj,
00123 data_object_memory_free_func *mem_free)
00124 {
00125 if (obj == NULL)
00126 return_error(EINVAL);
00127
00128 struct data_object_memory_impl *impl =
00129 data_object_get_impl(obj);
00130
00131 impl->mem_free = mem_free;
00132
00133 return 0;
00134 }
00135
00136 static int data_object_memory_get_data(data_object_t *obj, void **buf,
00137 off_t offset, off_t *length, data_object_flags flags)
00138 {
00139 UNUSED_PARAM(flags);
00140
00141 if (obj == NULL || buf == NULL || length == NULL || offset < 0)
00142 return_error(EINVAL);
00143
00144 off_t len = *length;
00145
00146
00147 if (__MAX(off_t) - offset < len - 1 * (len != 0))
00148 return_error(EOVERFLOW);
00149
00150 struct data_object_memory_impl *impl =
00151 data_object_get_impl(obj);
00152
00153
00154 if (offset + len - 1 * (len != 0) >= impl->size)
00155 return_error(EINVAL);
00156
00157 *buf = (unsigned char *)impl->data + offset;
00158
00159
00160 if (len > __MAX(ssize_t))
00161 *length = __MAX(ssize_t);
00162
00163 return 0;
00164 }
00165
00166 static int data_object_memory_free(data_object_t *obj)
00167 {
00168 if (obj == NULL)
00169 return_error(EINVAL);
00170
00171 struct data_object_memory_impl *impl =
00172 data_object_get_impl(obj);
00173
00174
00175 data_object_memory_free_func *mem_free = impl->mem_free;
00176
00177 if (mem_free != NULL)
00178 mem_free(impl->data);
00179
00180 free(impl);
00181
00182 return 0;
00183 }
00184
00185 static int data_object_memory_get_size(data_object_t *obj, off_t *size)
00186 {
00187 if (obj == NULL)
00188 return_error(EINVAL);
00189
00190 struct data_object_memory_impl *impl =
00191 data_object_get_impl(obj);
00192
00193 *size = (off_t) impl->size;
00194
00195 return 0;
00196 }
00197
00198 static int data_object_memory_compare(int *result, data_object_t *obj1,
00199 data_object_t *obj2)
00200 {
00201 if (obj1 == NULL || obj2 == NULL || result == NULL)
00202 return_error(EINVAL);
00203
00204 struct data_object_memory_impl *impl1 =
00205 data_object_get_impl(obj1);
00206
00207 struct data_object_memory_impl *impl2 =
00208 data_object_get_impl(obj2);
00209
00210 *result = !((impl1->data == impl2->data) && (impl1->size == impl2->size));
00211
00212 return 0;
00213 }