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_grow_for(empty_data
, len
+ 1);
84 c
= get_escape_char(s
, &i
);
93 struct data
data_copy_file(FILE *f
, size_t maxlen
)
95 struct data d
= empty_data
;
97 while (!feof(f
) && (d
.len
< maxlen
)) {
98 size_t chunksize
, ret
;
103 chunksize
= maxlen
- d
.len
;
105 d
= data_grow_for(d
, chunksize
);
106 ret
= fread(d
.val
+ d
.len
, 1, chunksize
, f
);
109 die("Error reading file into data: %s", strerror(errno
));
111 if (d
.len
+ ret
< d
.len
)
112 die("Overflow reading file into data\n");
120 struct data
data_append_data(struct data d
, const void *p
, int len
)
122 d
= data_grow_for(d
, len
);
123 memcpy(d
.val
+ d
.len
, p
, len
);
128 struct data
data_insert_at_marker(struct data d
, struct marker
*m
,
129 const void *p
, int len
)
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
);
136 /* Adjust all markers after the one we're inserting at */
143 static struct data
data_append_markers(struct data d
, struct marker
*m
)
145 struct marker
**mp
= &d
.markers
;
147 /* Find the end of the markerlist */
154 struct data
data_merge(struct data d1
, struct data d2
)
157 struct marker
*m2
= d2
.markers
;
159 d
= data_append_markers(data_append_data(d1
, d2
.val
, d2
.len
), m2
);
161 /* Adjust for the length of d1 */
163 m2
->offset
+= d1
.len
;
165 d2
.markers
= NULL
; /* So data_free() doesn't clobber them */
171 struct data
data_append_integer(struct data d
, uint64_t value
, int bits
)
181 return data_append_data(d
, &value_8
, 1);
184 value_16
= cpu_to_fdt16(value
);
185 return data_append_data(d
, &value_16
, 2);
188 value_32
= cpu_to_fdt32(value
);
189 return data_append_data(d
, &value_32
, 4);
192 value_64
= cpu_to_fdt64(value
);
193 return data_append_data(d
, &value_64
, 8);
196 die("Invalid literal size (%d)\n", bits
);
200 struct data
data_append_re(struct data d
, const struct fdt_reserve_entry
*re
)
202 struct fdt_reserve_entry bere
;
204 bere
.address
= cpu_to_fdt64(re
->address
);
205 bere
.size
= cpu_to_fdt64(re
->size
);
207 return data_append_data(d
, &bere
, sizeof(bere
));
210 struct data
data_append_cell(struct data d
, cell_t word
)
212 return data_append_integer(d
, word
, sizeof(word
) * 8);
215 struct data
data_append_addr(struct data d
, uint64_t addr
)
217 return data_append_integer(d
, addr
, sizeof(addr
) * 8);
220 struct data
data_append_byte(struct data d
, uint8_t byte
)
222 return data_append_data(d
, &byte
, 1);
225 struct data
data_append_zeroes(struct data d
, int len
)
227 d
= data_grow_for(d
, len
);
229 memset(d
.val
+ d
.len
, 0, len
);
234 struct data
data_append_align(struct data d
, int align
)
236 int newlen
= ALIGN(d
.len
, align
);
237 return data_append_zeroes(d
, newlen
- d
.len
);
240 struct data
data_add_marker(struct data d
, enum markertype type
, char *ref
)
244 m
= xmalloc(sizeof(*m
));
250 return data_append_markers(d
, m
);
253 bool data_is_one_string(struct data d
)
261 for (i
= 0; i
< len
-1; i
++)
262 if (d
.val
[i
] == '\0')
265 if (d
.val
[len
-1] != '\0')