coreboot-v3/util/dtc/data.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
   3 *
   4 * 
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License as
   7 * published by the Free Software Foundation; either version 2 of the
   8 * License, or (at your option) any later version.
   9 *
  10 *  This program is distributed in the hope that it will be useful,
  11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 *  General Public License for more details.
  14 *                                                                       
  15 *  You should have received a copy of the GNU General Public License    
  16 *  along with this program; if not, write to the Free Software          
  17 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 
  18 *                                                                   USA 
  19 */
  20
  21#include "dtc.h"
  22
  23void fixup_free(struct fixup *f)
  24{
  25        free(f->ref);
  26        free(f);
  27}
  28
  29void data_free(struct data d)
  30{
  31        struct fixup *f;
  32
  33        f = d.refs;
  34        while (f) {
  35                struct fixup *nf;
  36
  37                nf = f->next;
  38                fixup_free(f);
  39                f = nf;
  40        }
  41
  42        assert(!d.val || d.asize);
  43
  44        if (d.val)
  45                free(d.val);
  46}
  47
  48struct data data_grow_for(struct data d, int xlen)
  49{
  50        struct data nd;
  51        int newsize;
  52
  53        /* we must start with an allocated datum */
  54        assert(!d.val || d.asize);
  55
  56        if (xlen == 0)
  57                return d;
  58
  59        newsize = xlen;
  60
  61        while ((d.len + xlen) > newsize)
  62                newsize *= 2;
  63
  64        nd.asize = newsize;
  65        nd.val = xrealloc(d.val, newsize);
  66        nd.len = d.len;
  67        nd.type = d.type;
  68        nd.refs = d.refs;
  69
  70        assert(nd.asize >= (d.len + xlen));
  71
  72        return nd;
  73}
  74
  75struct data data_copy_mem(char *mem, int len)
  76{
  77        struct data d;
  78
  79        d = data_grow_for(empty_data, len);
  80
  81        d.len = len;
  82        memcpy(d.val, mem, len);
  83
  84        return d;
  85}
  86
  87static char get_oct_char(char *s, int *i)
  88{
  89        char x[4];
  90        char *endx;
  91        long val;
  92
  93        x[3] = '\0';
  94        x[0] = s[(*i)];
  95        if (x[0]) {
  96                x[1] = s[(*i)+1];
  97                if (x[1])
  98                        x[2] = s[(*i)+2];
  99        }
 100
 101        val = strtol(x, &endx, 8);
 102        if ((endx - x) == 0)
 103                fprintf(stderr, "Empty \\nnn escape\n");
 104                
 105        (*i) += endx - x;
 106        return val;
 107}
 108
 109static char get_hex_char(char *s, int *i)
 110{
 111        char x[3];
 112        char *endx;
 113        long val;
 114
 115        x[2] = '\0';
 116        x[0] = s[(*i)];
 117        if (x[0])
 118                x[1] = s[(*i)+1];
 119
 120        val = strtol(x, &endx, 16);
 121        if ((endx - x) == 0)
 122                fprintf(stderr, "Empty \\x escape\n");
 123                
 124        (*i) += endx - x;
 125        return val;
 126}
 127
 128struct data data_copy_escape_string(char *s, int len)
 129{
 130        int i = 0;
 131        struct data d;
 132        unsigned char *q;
 133
 134        d = data_grow_for(empty_data, strlen(s)+1);
 135
 136        q = d.val;
 137        while (i < len) {
 138                char c = s[i++];
 139
 140                if (c != '\\') {
 141                        q[d.len++] = c;
 142                        continue;
 143                }
 144
 145                c = s[i++];
 146                assert(c);
 147                switch (c) {
 148                case 't':
 149                        q[d.len++] = '\t';
 150                        break;
 151                case 'n':
 152                        q[d.len++] = '\n';
 153                        break;
 154                case 'r':
 155                        q[d.len++] = '\r';
 156                        break;
 157                case '0':
 158                case '1':
 159                case '2':
 160                case '3':
 161                case '4':
 162                case '5':
 163                case '6':
 164                case '7':
 165                        i--; /* need to re-read the first digit as
 166                              * part of the octal value */
 167                        q[d.len++] = get_oct_char(s, &i);
 168                        break;
 169                case 'x':
 170                        q[d.len++] = get_hex_char(s, &i);
 171                        break;
 172                default:
 173                        q[d.len++] = c;
 174                }
 175        }
 176
 177        q[d.len++] = '\0';
 178        return d;
 179}
 180
 181struct data data_copy_file(FILE *f, size_t len)
 182{
 183        struct data d;
 184
 185        d = data_grow_for(empty_data, len);
 186
 187        d.len = len;
 188        fread(d.val, len, 1, f);
 189
 190        return d;
 191}
 192
 193struct data data_append_data(struct data d, void *p, int len)
 194{
 195        d = data_grow_for(d, len);
 196        memcpy(d.val + d.len, p, len);
 197        d.len += len;
 198        return d;
 199}
 200
 201struct data data_append_cell(struct data d, cell_t word)
 202{
 203        // Don't do system/network order byte translation. We don't do it for scalars either.
 204        //cell_t beword = cpu_to_be32(word);
 205        cell_t beword = word;
 206        // Mark this property as being of the 'cell' type
 207        d.type = 'C';
 208
 209        return data_append_data(d, &beword, sizeof(beword));
 210}
 211
 212struct data data_append_re(struct data d, struct reserve_entry *re)
 213{
 214        struct reserve_entry bere;
 215
 216        bere.address = cpu_to_be64(re->address);
 217        bere.size = cpu_to_be64(re->size);
 218
 219        return data_append_data(d, &bere, sizeof(bere));
 220}
 221
 222struct data data_append_addr(struct data d, u64 addr)
 223{
 224        u64 beaddr = cpu_to_be64(addr);
 225
 226        return data_append_data(d, &beaddr, sizeof(beaddr));
 227}
 228
 229struct data data_append_byte(struct data d, uint8_t byte)
 230{
 231        // Mark this property as being of the 'byte' type
 232        d.type = 'B';
 233        return data_append_data(d, &byte, 1);
 234}
 235
 236struct data data_append_zeroes(struct data d, int len)
 237{
 238        d = data_grow_for(d, len);
 239
 240        memset(d.val + d.len, 0, len);
 241        d.len += len;
 242        return d;
 243}
 244
 245struct data data_append_align(struct data d, int align)
 246{
 247        int newlen = DALIGN(d.len, align);
 248        return data_append_zeroes(d, newlen - d.len);
 249}
 250
 251struct data data_add_fixup(struct data d, char *ref)
 252{
 253        struct fixup *f;
 254        struct data nd;
 255
 256        f = xmalloc(sizeof(*f));
 257        f->offset = d.len;
 258        f->ref = ref;
 259        f->next = d.refs;
 260
 261        nd = d;
 262        nd.refs = f;
 263
 264        return nd;
 265}
 266
 267int data_is_one_string(struct data d)
 268{
 269        int i;
 270        int len = d.len;
 271
 272        if (len == 0)
 273                return 0;
 274
 275        for (i = 0; i < len-1; i++)
 276                if (d.val[i] == '\0')
 277                        return 0;
 278
 279        if (d.val[len-1] != '\0')
 280                return 0;
 281
 282        return 1;
 283}
 284
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.