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 }