]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/libdrm.git/blob - radeon/bof.c
radeon: fix unused-function warning
[glsdk/libdrm.git] / radeon / bof.c
1 /*
2  * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *      Jerome Glisse
25  */
26 #include <errno.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include "bof.h"
31 /*
32  * helpers
33  */
34 static int bof_entry_grow(bof_t *bof)
35 {
36         bof_t **array;
38         if (bof->array_size < bof->nentry)
39                 return 0;
40         array = realloc(bof->array, (bof->nentry + 16) * sizeof(void*));
41         if (array == NULL)
42                 return -ENOMEM;
43         bof->array = array;
44         bof->nentry += 16;
45         return 0;
46 }
48 /*
49  * object 
50  */
51 bof_t *bof_object(void)
52 {
53         bof_t *object;
55         object = calloc(1, sizeof(bof_t));
56         if (object == NULL)
57                 return NULL;
58         object->refcount = 1;
59         object->type = BOF_TYPE_OBJECT;
60         object->size = 12;
61         return object;
62 }
64 bof_t *bof_object_get(bof_t *object, const char *keyname)
65 {
66         unsigned i;
68         for (i = 0; i < object->array_size; i += 2) {
69                 if (!strcmp(object->array[i]->value, keyname)) {
70                         return object->array[i + 1];
71                 }
72         }
73         return NULL;
74 }
76 int bof_object_set(bof_t *object, const char *keyname, bof_t *value)
77 {
78         bof_t *key;
79         int r;
81         if (object->type != BOF_TYPE_OBJECT)
82                 return -EINVAL;
83         r = bof_entry_grow(object);
84         if (r)
85                 return r;
86         key = bof_string(keyname);
87         if (key == NULL)
88                 return -ENOMEM;
89         object->array[object->array_size++] = key;
90         object->array[object->array_size++] = value;
91         object->size += value->size;
92         object->size += key->size;
93         bof_incref(value);
94         return 0;
95 }
97 /*
98  * array
99  */
100 bof_t *bof_array(void)
102         bof_t *array = bof_object();
104         if (array == NULL)
105                 return NULL;
106         array->type = BOF_TYPE_ARRAY;
107         array->size = 12;
108         return array;
111 int bof_array_append(bof_t *array, bof_t *value)
113         int r;
114         if (array->type != BOF_TYPE_ARRAY)
115                 return -EINVAL;
116         r = bof_entry_grow(array);
117         if (r)
118                 return r;
119         array->array[array->array_size++] = value;
120         array->size += value->size;
121         bof_incref(value);
122         return 0;
125 bof_t *bof_array_get(bof_t *bof, unsigned i)
127         if (!bof_is_array(bof) || i >= bof->array_size)
128                 return NULL;
129         return bof->array[i];
132 unsigned bof_array_size(bof_t *bof)
134         if (!bof_is_array(bof))
135                 return 0;
136         return bof->array_size;
139 /*
140  * blob
141  */
142 bof_t *bof_blob(unsigned size, void *value)
144         bof_t *blob = bof_object();
146         if (blob == NULL)
147                 return NULL;
148         blob->type = BOF_TYPE_BLOB;
149         blob->value = calloc(1, size);
150         if (blob->value == NULL) {
151                 bof_decref(blob);
152                 return NULL;
153         }
154         blob->size = size;
155         memcpy(blob->value, value, size);
156         blob->size += 12;
157         return blob;
160 unsigned bof_blob_size(bof_t *bof)
162         if (!bof_is_blob(bof))
163                 return 0;
164         return bof->size - 12;
167 void *bof_blob_value(bof_t *bof)
169         if (!bof_is_blob(bof))
170                 return NULL;
171         return bof->value;
174 /*
175  * string
176  */
177 bof_t *bof_string(const char *value)
179         bof_t *string = bof_object();
181         if (string == NULL)
182                 return NULL;
183         string->type = BOF_TYPE_STRING;
184         string->size = strlen(value) + 1;
185         string->value = calloc(1, string->size);
186         if (string->value == NULL) {
187                 bof_decref(string);
188                 return NULL;
189         }
190         strcpy(string->value, value);
191         string->size += 12;
192         return string;
195 /*
196  *  int32
197  */
198 bof_t *bof_int32(int32_t value)
200         bof_t *int32 = bof_object();
202         if (int32 == NULL)
203                 return NULL;
204         int32->type = BOF_TYPE_INT32;
205         int32->size = 4;
206         int32->value = calloc(1, int32->size);
207         if (int32->value == NULL) {
208                 bof_decref(int32);
209                 return NULL;
210         }
211         memcpy(int32->value, &value, 4);
212         int32->size += 12;
213         return int32;
216 int32_t bof_int32_value(bof_t *bof)
218         return *((uint32_t*)bof->value);
221 /*
222  *  common
223  */
224 static void bof_indent(int level)
226         int i;
228         for (i = 0; i < level; i++)
229                 fprintf(stderr, " ");
232 static void bof_print_bof(bof_t *bof, int level, int entry)
234         bof_indent(level);
235         if (bof == NULL) {
236                 fprintf(stderr, "--NULL-- for entry %d\n", entry);
237                 return;
238         }
239         switch (bof->type) {
240         case BOF_TYPE_STRING:
241                 fprintf(stderr, "%p string [%s %d]\n", bof, (char*)bof->value, bof->size);
242                 break;
243         case BOF_TYPE_INT32:
244                 fprintf(stderr, "%p int32 [%d %d]\n", bof, *(int*)bof->value, bof->size);
245                 break;
246         case BOF_TYPE_BLOB:
247                 fprintf(stderr, "%p blob [%d]\n", bof, bof->size);
248                 break;
249         case BOF_TYPE_NULL:
250                 fprintf(stderr, "%p null [%d]\n", bof, bof->size);
251                 break;
252         case BOF_TYPE_OBJECT:
253                 fprintf(stderr, "%p object [%d %d]\n", bof, bof->array_size / 2, bof->size);
254                 break;
255         case BOF_TYPE_ARRAY:
256                 fprintf(stderr, "%p array [%d %d]\n", bof, bof->array_size, bof->size);
257                 break;
258         default:
259                 fprintf(stderr, "%p unknown [%d]\n", bof, bof->type);
260                 return;
261         }
264 static void bof_print_rec(bof_t *bof, int level, int entry)
266         unsigned i;
268         bof_print_bof(bof, level, entry);
269         for (i = 0; i < bof->array_size; i++) {
270                 bof_print_rec(bof->array[i], level + 2, i);
271         }
274 void bof_print(bof_t *bof)
276         bof_print_rec(bof, 0, 0);
279 static int bof_read(bof_t *root, FILE *file, long end, int level)
281         bof_t *bof = NULL;
282         int r;
284         if (ftell(file) >= end) {
285                 return 0;
286         }
287         r = bof_entry_grow(root);
288         if (r)
289                 return r;
290         bof = bof_object();
291         if (bof == NULL)
292                 return -ENOMEM;
293         bof->offset = ftell(file);
294         r = fread(&bof->type, 4, 1, file);
295         if (r != 1)
296                 goto out_err;
297         r = fread(&bof->size, 4, 1, file);
298         if (r != 1)
299                 goto out_err;
300         r = fread(&bof->array_size, 4, 1, file);
301         if (r != 1)
302                 goto out_err;
303         switch (bof->type) {
304         case BOF_TYPE_STRING:
305         case BOF_TYPE_INT32:
306         case BOF_TYPE_BLOB:
307                 bof->value = calloc(1, bof->size - 12);
308                 if (bof->value == NULL) {
309                         goto out_err;
310                 }
311                 r = fread(bof->value, bof->size - 12, 1, file);
312                 if (r != 1) {
313                         fprintf(stderr, "error reading %d\n", bof->size - 12);
314                         goto out_err;
315                 }
316                 break;
317         case BOF_TYPE_NULL:
318                 return 0;
319         case BOF_TYPE_OBJECT:
320         case BOF_TYPE_ARRAY:
321                 r = bof_read(bof, file, bof->offset + bof->size, level + 2);
322                 if (r)
323                         goto out_err;
324                 break;
325         default:
326                 fprintf(stderr, "invalid type %d\n", bof->type);
327                 goto out_err;
328         }
329         root->array[root->centry++] = bof;
330         return bof_read(root, file, end, level);
331 out_err:
332         bof_decref(bof);
333         return -EINVAL;
336 bof_t *bof_load_file(const char *filename)
338         bof_t *root = bof_object();
339         int r;
341         if (root == NULL) {
342                 fprintf(stderr, "%s failed to create root object\n", __func__);
343                 return NULL;
344         }
345         root->file = fopen(filename, "r");
346         if (root->file == NULL)
347                 goto out_err;
348         r = fseek(root->file, 0L, SEEK_SET);
349         if (r) {
350                 fprintf(stderr, "%s failed to seek into file %s\n", __func__, filename);
351                 goto out_err;
352         }
353         root->offset = ftell(root->file);
354         r = fread(&root->type, 4, 1, root->file);
355         if (r != 1)
356                 goto out_err;
357         r = fread(&root->size, 4, 1, root->file);
358         if (r != 1)
359                 goto out_err;
360         r = fread(&root->array_size, 4, 1, root->file);
361         if (r != 1)
362                 goto out_err;
363         r = bof_read(root, root->file, root->offset + root->size, 2);
364         if (r)
365                 goto out_err;
366         return root;
367 out_err:
368         bof_decref(root);
369         return NULL;
372 void bof_incref(bof_t *bof)
374         bof->refcount++;
377 void bof_decref(bof_t *bof)
379         unsigned i;
381         if (bof == NULL)
382                 return;
383         if (--bof->refcount > 0)
384                 return;
385         for (i = 0; i < bof->array_size; i++) {
386                 bof_decref(bof->array[i]);
387                 bof->array[i] = NULL;
388         }
389         bof->array_size = 0;
390         if (bof->file) {
391                 fclose(bof->file);
392                 bof->file = NULL;
393         }
394         free(bof->array);
395         free(bof->value);
396         free(bof);
399 static int bof_file_write(bof_t *bof, FILE *file)
401         unsigned i;
402         int r;
404         r = fwrite(&bof->type, 4, 1, file);
405         if (r != 1)
406                 return -EINVAL;
407         r = fwrite(&bof->size, 4, 1, file);
408         if (r != 1)
409                 return -EINVAL;
410         r = fwrite(&bof->array_size, 4, 1, file);
411         if (r != 1)
412                 return -EINVAL;
413         switch (bof->type) {
414         case BOF_TYPE_NULL:
415                 if (bof->size)
416                         return -EINVAL;
417                 break;
418         case BOF_TYPE_STRING:
419         case BOF_TYPE_INT32:
420         case BOF_TYPE_BLOB:
421                 r = fwrite(bof->value, bof->size - 12, 1, file);
422                 if (r != 1)
423                         return -EINVAL;
424                 break;
425         case BOF_TYPE_OBJECT:
426         case BOF_TYPE_ARRAY:
427                 for (i = 0; i < bof->array_size; i++) {
428                         r = bof_file_write(bof->array[i], file);
429                         if (r)
430                                 return r;
431                 }
432                 break;
433         default:
434                 return -EINVAL;
435         }
436         return 0;
439 int bof_dump_file(bof_t *bof, const char *filename)
441         unsigned i;
442         int r = 0;
444         if (bof->file) {
445                 fclose(bof->file);
446                 bof->file = NULL;
447         }
448         bof->file = fopen(filename, "w");
449         if (bof->file == NULL) {
450                 fprintf(stderr, "%s failed to open file %s\n", __func__, filename);
451                 r = -EINVAL;
452                 goto out_err;
453         }
454         r = fseek(bof->file, 0L, SEEK_SET);
455         if (r) {
456                 fprintf(stderr, "%s failed to seek into file %s\n", __func__, filename);
457                 goto out_err;
458         }
459         r = fwrite(&bof->type, 4, 1, bof->file);
460         if (r != 1)
461                 goto out_err;
462         r = fwrite(&bof->size, 4, 1, bof->file);
463         if (r != 1)
464                 goto out_err;
465         r = fwrite(&bof->array_size, 4, 1, bof->file);
466         if (r != 1)
467                 goto out_err;
468         for (i = 0; i < bof->array_size; i++) {
469                 r = bof_file_write(bof->array[i], bof->file);
470                 if (r)
471                         return r;
472         }
473 out_err:
474         fclose(bof->file);
475         bof->file = NULL;
476         return r;