2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
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.
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.
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
23 void data_free(struct data d
)
25 struct marker
*m
, *nm
;
39 struct data
data_grow_for(struct data d
, int xlen
)
51 while ((d
.len
+ xlen
) > newsize
)
54 nd
.val
= xrealloc(d
.val
, newsize
);
59 struct data
data_copy_mem(const char *mem
, int len
)
63 d
= data_grow_for(empty_data
, len
);
66 memcpy(d
.val
, mem
, len
);
71 static char get_oct_char(const char *s
, int *i
)
78 strncpy(x
, s
+ *i
, 3);
80 val
= strtol(x
, &endx
, 8);
88 static char get_hex_char(const char *s
, int *i
)
95 strncpy(x
, s
+ *i
, 2);
97 val
= strtol(x
, &endx
, 16);
99 die("\\x used with no following hex digits\n");
105 struct data
data_copy_escape_string(const char *s
, int len
)
111 d
= data_grow_for(empty_data
, strlen(s
)+1);
154 i
--; /* need to re-read the first digit as
155 * part of the octal value */
156 q
[d
.len
++] = get_oct_char(s
, &i
);
159 q
[d
.len
++] = get_hex_char(s
, &i
);
170 struct data
data_copy_file(FILE *f
, size_t maxlen
)
172 struct data d
= empty_data
;
174 while (!feof(f
) && (d
.len
< maxlen
)) {
175 size_t chunksize
, ret
;
180 chunksize
= maxlen
- d
.len
;
182 d
= data_grow_for(d
, chunksize
);
183 ret
= fread(d
.val
+ d
.len
, 1, chunksize
, f
);
186 die("Error reading file into data: %s", strerror(errno
));
188 if (d
.len
+ ret
< d
.len
)
189 die("Overflow reading file into data\n");
197 struct data
data_append_data(struct data d
, const void *p
, int len
)
199 d
= data_grow_for(d
, len
);
200 memcpy(d
.val
+ d
.len
, p
, len
);
205 struct data
data_insert_at_marker(struct data d
, struct marker
*m
,
206 const void *p
, int len
)
208 d
= data_grow_for(d
, len
);
209 memmove(d
.val
+ m
->offset
+ len
, d
.val
+ m
->offset
, d
.len
- m
->offset
);
210 memcpy(d
.val
+ m
->offset
, p
, len
);
213 /* Adjust all markers after the one we're inserting at */
220 static struct data
data_append_markers(struct data d
, struct marker
*m
)
222 struct marker
**mp
= &d
.markers
;
224 /* Find the end of the markerlist */
231 struct data
data_merge(struct data d1
, struct data d2
)
234 struct marker
*m2
= d2
.markers
;
236 d
= data_append_markers(data_append_data(d1
, d2
.val
, d2
.len
), m2
);
238 /* Adjust for the length of d1 */
240 m2
->offset
+= d1
.len
;
242 d2
.markers
= NULL
; /* So data_free() doesn't clobber them */
248 struct data
data_append_cell(struct data d
, cell_t word
)
250 cell_t beword
= cpu_to_fdt32(word
);
252 return data_append_data(d
, &beword
, sizeof(beword
));
255 struct data
data_append_re(struct data d
, const struct fdt_reserve_entry
*re
)
257 struct fdt_reserve_entry bere
;
259 bere
.address
= cpu_to_fdt64(re
->address
);
260 bere
.size
= cpu_to_fdt64(re
->size
);
262 return data_append_data(d
, &bere
, sizeof(bere
));
265 struct data
data_append_addr(struct data d
, uint64_t addr
)
267 uint64_t beaddr
= cpu_to_fdt64(addr
);
269 return data_append_data(d
, &beaddr
, sizeof(beaddr
));
272 struct data
data_append_byte(struct data d
, uint8_t byte
)
274 return data_append_data(d
, &byte
, 1);
277 struct data
data_append_zeroes(struct data d
, int len
)
279 d
= data_grow_for(d
, len
);
281 memset(d
.val
+ d
.len
, 0, len
);
286 struct data
data_append_align(struct data d
, int align
)
288 int newlen
= ALIGN(d
.len
, align
);
289 return data_append_zeroes(d
, newlen
- d
.len
);
292 struct data
data_add_marker(struct data d
, enum markertype type
, char *ref
)
296 m
= xmalloc(sizeof(*m
));
302 return data_append_markers(d
, m
);
305 int data_is_one_string(struct data d
)
313 for (i
= 0; i
< len
-1; i
++)
314 if (d
.val
[i
] == '\0')
317 if (d
.val
[len
-1] != '\0')