Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
data.c
Go to the documentation of this file.
1 /*
2  * (C) Copyright David Gibson <[email protected]>, 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 
23 void data_free(struct data d)
24 {
25  struct marker *m, *nm;
26 
27  m = d.markers;
28  while (m) {
29  nm = m->next;
30  free(m->ref);
31  free(m);
32  m = nm;
33  }
34 
35  if (d.val)
36  free(d.val);
37 }
38 
40 {
41  struct data nd;
42  int newsize;
43 
44  if (xlen == 0)
45  return d;
46 
47  nd = d;
48 
49  newsize = xlen;
50 
51  while ((d.len + xlen) > newsize)
52  newsize *= 2;
53 
54  nd.val = xrealloc(d.val, newsize);
55 
56  return nd;
57 }
58 
60 {
61  struct data d;
62 
64 
65  d.len = len;
66  memcpy(d.val, mem, len);
67 
68  return d;
69 }
70 
72 {
73  int i = 0;
74  struct data d;
75  char *q;
76 
77  d = data_grow_for(empty_data, strlen(s)+1);
78 
79  q = d.val;
80  while (i < len) {
81  char c = s[i++];
82 
83  if (c == '\\')
84  c = get_escape_char(s, &i);
85 
86  q[d.len++] = c;
87  }
88 
89  q[d.len++] = '\0';
90  return d;
91 }
92 
93 struct data data_copy_file(FILE *f, size_t maxlen)
94 {
95  struct data d = empty_data;
96 
97  while (!feof(f) && (d.len < maxlen)) {
98  size_t chunksize, ret;
99 
100  if (maxlen == -1)
101  chunksize = 4096;
102  else
103  chunksize = maxlen - d.len;
104 
105  d = data_grow_for(d, chunksize);
106  ret = fread(d.val + d.len, 1, chunksize, f);
107 
108  if (ferror(f))
109  die("Error reading file into data: %s", strerror(errno));
110 
111  if (d.len + ret < d.len)
112  die("Overflow reading file into data\n");
113 
114  d.len += ret;
115  }
116 
117  return d;
118 }
119 
121 {
122  d = data_grow_for(d, len);
123  memcpy(d.val + d.len, p, len);
124  d.len += len;
125  return d;
126 }
127 
129  const void *p, int len)
130 {
131  d = data_grow_for(d, len);
132  memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset);
133  memcpy(d.val + m->offset, p, len);
134  d.len += len;
135 
136  /* Adjust all markers after the one we're inserting at */
137  m = m->next;
138  for_each_marker(m)
139  m->offset += len;
140  return d;
141 }
142 
143 static struct data data_append_markers(struct data d, struct marker *m)
144 {
145  struct marker **mp = &d.markers;
146 
147  /* Find the end of the markerlist */
148  while (*mp)
149  mp = &((*mp)->next);
150  *mp = m;
151  return d;
152 }
153 
155 {
156  struct data d;
157  struct marker *m2 = d2.markers;
158 
159  d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
160 
161  /* Adjust for the length of d1 */
162  for_each_marker(m2)
163  m2->offset += d1.len;
164 
165  d2.markers = NULL; /* So data_free() doesn't clobber them */
166  data_free(d2);
167 
168  return d;
169 }
170 
172 {
173  uint8_t value_8;
174  uint16_t value_16;
175  uint32_t value_32;
176  uint64_t value_64;
177 
178  switch (bits) {
179  case 8:
180  value_8 = value;
181  return data_append_data(d, &value_8, 1);
182 
183  case 16:
184  value_16 = cpu_to_fdt16(value);
185  return data_append_data(d, &value_16, 2);
186 
187  case 32:
188  value_32 = cpu_to_fdt32(value);
189  return data_append_data(d, &value_32, 4);
190 
191  case 64:
192  value_64 = cpu_to_fdt64(value);
193  return data_append_data(d, &value_64, 8);
194 
195  default:
196  die("Invalid literal size (%d)\n", bits);
197  }
198 }
199 
201 {
202  struct fdt_reserve_entry bere;
203 
204  bere.address = cpu_to_fdt64(re->address);
205  bere.size = cpu_to_fdt64(re->size);
206 
207  return data_append_data(d, &bere, sizeof(bere));
208 }
209 
211 {
212  return data_append_integer(d, word, sizeof(word) * 8);
213 }
214 
216 {
217  return data_append_integer(d, addr, sizeof(addr) * 8);
218 }
219 
221 {
222  return data_append_data(d, &byte, 1);
223 }
224 
226 {
227  d = data_grow_for(d, len);
228 
229  memset(d.val + d.len, 0, len);
230  d.len += len;
231  return d;
232 }
233 
235 {
236  int newlen = ALIGN(d.len, align);
237  return data_append_zeroes(d, newlen - d.len);
238 }
239 
241 {
242  struct marker *m;
243 
244  m = xmalloc(sizeof(*m));
245  m->offset = d.len;
246  m->type = type;
247  m->ref = ref;
248  m->next = NULL;
249 
250  return data_append_markers(d, m);
251 }
252 
254 {
255  int i;
256  int len = d.len;
257 
258  if (len == 0)
259  return 0;
260 
261  for (i = 0; i < len-1; i++)
262  if (d.val[i] == '\0')
263  return 0;
264 
265  if (d.val[len-1] != '\0')
266  return 0;
267 
268  return 1;
269 }