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 struct data
data_copy_escape_string(const char *s
, int len
)
77 d
= data_add_marker(empty_data
, TYPE_STRING
, NULL
);
78 d
= data_grow_for(d
, len
+ 1);
85 c
= get_escape_char(s
, &i
);
94 struct data
data_copy_file(FILE *f
, size_t maxlen
)
96 struct data d
= empty_data
;
98 d
= data_add_marker(d
, TYPE_NONE
, NULL
);
99 while (!feof(f
) && (d
.len
< maxlen
)) {
100 size_t chunksize
, ret
;
105 chunksize
= maxlen
- d
.len
;
107 d
= data_grow_for(d
, chunksize
);
108 ret
= fread(d
.val
+ d
.len
, 1, chunksize
, f
);
111 die("Error reading file into data: %s", strerror(errno
));
113 if (d
.len
+ ret
< d
.len
)
114 die("Overflow reading file into data\n");
122 struct data
data_append_data(struct data d
, const void *p
, int len
)
124 d
= data_grow_for(d
, len
);
125 memcpy(d
.val
+ d
.len
, p
, len
);
130 struct data
data_insert_at_marker(struct data d
, struct marker
*m
,
131 const void *p
, int len
)
133 d
= data_grow_for(d
, len
);
134 memmove(d
.val
+ m
->offset
+ len
, d
.val
+ m
->offset
, d
.len
- m
->offset
);
135 memcpy(d
.val
+ m
->offset
, p
, len
);
138 /* Adjust all markers after the one we're inserting at */
145 static struct data
data_append_markers(struct data d
, struct marker
*m
)
147 struct marker
**mp
= &d
.markers
;
149 /* Find the end of the markerlist */
156 struct data
data_merge(struct data d1
, struct data d2
)
159 struct marker
*m2
= d2
.markers
;
161 d
= data_append_markers(data_append_data(d1
, d2
.val
, d2
.len
), m2
);
163 /* Adjust for the length of d1 */
165 m2
->offset
+= d1
.len
;
167 d2
.markers
= NULL
; /* So data_free() doesn't clobber them */
173 struct data
data_append_integer(struct data d
, uint64_t value
, int bits
)
183 return data_append_data(d
, &value_8
, 1);
186 value_16
= cpu_to_fdt16(value
);
187 return data_append_data(d
, &value_16
, 2);
190 value_32
= cpu_to_fdt32(value
);
191 return data_append_data(d
, &value_32
, 4);
194 value_64
= cpu_to_fdt64(value
);
195 return data_append_data(d
, &value_64
, 8);
198 die("Invalid literal size (%d)\n", bits
);
202 struct data
data_append_re(struct data d
, uint64_t address
, uint64_t size
)
204 struct fdt_reserve_entry re
;
206 re
.address
= cpu_to_fdt64(address
);
207 re
.size
= cpu_to_fdt64(size
);
209 return data_append_data(d
, &re
, sizeof(re
));
212 struct data
data_append_cell(struct data d
, cell_t word
)
214 return data_append_integer(d
, word
, sizeof(word
) * 8);
217 struct data
data_append_addr(struct data d
, uint64_t addr
)
219 return data_append_integer(d
, addr
, sizeof(addr
) * 8);
222 struct data
data_append_byte(struct data d
, uint8_t byte
)
224 return data_append_data(d
, &byte
, 1);
227 struct data
data_append_zeroes(struct data d
, int len
)
229 d
= data_grow_for(d
, len
);
231 memset(d
.val
+ d
.len
, 0, len
);
236 struct data
data_append_align(struct data d
, int align
)
238 int newlen
= ALIGN(d
.len
, align
);
239 return data_append_zeroes(d
, newlen
- d
.len
);
242 struct data
data_add_marker(struct data d
, enum markertype type
, char *ref
)
246 m
= xmalloc(sizeof(*m
));
252 return data_append_markers(d
, m
);
255 bool data_is_one_string(struct data d
)
263 for (i
= 0; i
< len
-1; i
++)
264 if (d
.val
[i
] == '\0')
267 if (d
.val
[len
-1] != '\0')