data.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  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. #include "dtc.h"
  21. void data_free(struct data d)
  22. {
  23. struct marker *m, *nm;
  24. m = d.markers;
  25. while (m) {
  26. nm = m->next;
  27. free(m->ref);
  28. free(m);
  29. m = nm;
  30. }
  31. assert(!d.val || d.asize);
  32. if (d.val)
  33. free(d.val);
  34. }
  35. struct data data_grow_for(struct data d, int xlen)
  36. {
  37. struct data nd;
  38. int newsize;
  39. /* we must start with an allocated datum */
  40. assert(!d.val || d.asize);
  41. if (xlen == 0)
  42. return d;
  43. nd = d;
  44. newsize = xlen;
  45. while ((d.len + xlen) > newsize)
  46. newsize *= 2;
  47. nd.asize = newsize;
  48. nd.val = xrealloc(d.val, newsize);
  49. assert(nd.asize >= (d.len + xlen));
  50. return nd;
  51. }
  52. struct data data_copy_mem(const char *mem, int len)
  53. {
  54. struct data d;
  55. d = data_grow_for(empty_data, len);
  56. d.len = len;
  57. memcpy(d.val, mem, len);
  58. return d;
  59. }
  60. static char get_oct_char(const char *s, int *i)
  61. {
  62. char x[4];
  63. char *endx;
  64. long val;
  65. x[3] = '\0';
  66. x[0] = s[(*i)];
  67. if (x[0]) {
  68. x[1] = s[(*i)+1];
  69. if (x[1])
  70. x[2] = s[(*i)+2];
  71. }
  72. val = strtol(x, &endx, 8);
  73. if ((endx - x) == 0)
  74. fprintf(stderr, "Empty \\nnn escape\n");
  75. (*i) += endx - x;
  76. return val;
  77. }
  78. static char get_hex_char(const char *s, int *i)
  79. {
  80. char x[3];
  81. char *endx;
  82. long val;
  83. x[2] = '\0';
  84. x[0] = s[(*i)];
  85. if (x[0])
  86. x[1] = s[(*i)+1];
  87. val = strtol(x, &endx, 16);
  88. if ((endx - x) == 0)
  89. fprintf(stderr, "Empty \\x escape\n");
  90. (*i) += endx - x;
  91. return val;
  92. }
  93. struct data data_copy_escape_string(const char *s, int len)
  94. {
  95. int i = 0;
  96. struct data d;
  97. char *q;
  98. d = data_grow_for(empty_data, strlen(s)+1);
  99. q = d.val;
  100. while (i < len) {
  101. char c = s[i++];
  102. if (c != '\\') {
  103. q[d.len++] = c;
  104. continue;
  105. }
  106. c = s[i++];
  107. assert(c);
  108. switch (c) {
  109. case 'a':
  110. q[d.len++] = '\a';
  111. break;
  112. case 'b':
  113. q[d.len++] = '\b';
  114. break;
  115. case 't':
  116. q[d.len++] = '\t';
  117. break;
  118. case 'n':
  119. q[d.len++] = '\n';
  120. break;
  121. case 'v':
  122. q[d.len++] = '\v';
  123. break;
  124. case 'f':
  125. q[d.len++] = '\f';
  126. break;
  127. case 'r':
  128. q[d.len++] = '\r';
  129. break;
  130. case '0':
  131. case '1':
  132. case '2':
  133. case '3':
  134. case '4':
  135. case '5':
  136. case '6':
  137. case '7':
  138. i--; /* need to re-read the first digit as
  139. * part of the octal value */
  140. q[d.len++] = get_oct_char(s, &i);
  141. break;
  142. case 'x':
  143. q[d.len++] = get_hex_char(s, &i);
  144. break;
  145. default:
  146. q[d.len++] = c;
  147. }
  148. }
  149. q[d.len++] = '\0';
  150. return d;
  151. }
  152. struct data data_copy_file(FILE *f, size_t len)
  153. {
  154. struct data d;
  155. d = data_grow_for(empty_data, len);
  156. d.len = len;
  157. fread(d.val, len, 1, f);
  158. return d;
  159. }
  160. struct data data_append_data(struct data d, const void *p, int len)
  161. {
  162. d = data_grow_for(d, len);
  163. memcpy(d.val + d.len, p, len);
  164. d.len += len;
  165. return d;
  166. }
  167. struct data data_insert_at_marker(struct data d, struct marker *m,
  168. const void *p, int len)
  169. {
  170. d = data_grow_for(d, len);
  171. memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset);
  172. memcpy(d.val + m->offset, p, len);
  173. d.len += len;
  174. /* Adjust all markers after the one we're inserting at */
  175. m = m->next;
  176. for_each_marker(m)
  177. m->offset += len;
  178. return d;
  179. }
  180. struct data data_append_markers(struct data d, struct marker *m)
  181. {
  182. struct marker **mp = &d.markers;
  183. /* Find the end of the markerlist */
  184. while (*mp)
  185. mp = &((*mp)->next);
  186. *mp = m;
  187. return d;
  188. }
  189. struct data data_merge(struct data d1, struct data d2)
  190. {
  191. struct data d;
  192. struct marker *m2 = d2.markers;
  193. d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
  194. /* Adjust for the length of d1 */
  195. for_each_marker(m2)
  196. m2->offset += d1.len;
  197. d2.markers = NULL; /* So data_free() doesn't clobber them */
  198. data_free(d2);
  199. return d;
  200. }
  201. struct data data_append_cell(struct data d, cell_t word)
  202. {
  203. cell_t beword = cpu_to_be32(word);
  204. return data_append_data(d, &beword, sizeof(beword));
  205. }
  206. struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
  207. {
  208. struct fdt_reserve_entry bere;
  209. bere.address = cpu_to_be64(re->address);
  210. bere.size = cpu_to_be64(re->size);
  211. return data_append_data(d, &bere, sizeof(bere));
  212. }
  213. struct data data_append_addr(struct data d, u64 addr)
  214. {
  215. u64 beaddr = cpu_to_be64(addr);
  216. return data_append_data(d, &beaddr, sizeof(beaddr));
  217. }
  218. struct data data_append_byte(struct data d, uint8_t byte)
  219. {
  220. return data_append_data(d, &byte, 1);
  221. }
  222. struct data data_append_zeroes(struct data d, int len)
  223. {
  224. d = data_grow_for(d, len);
  225. memset(d.val + d.len, 0, len);
  226. d.len += len;
  227. return d;
  228. }
  229. struct data data_append_align(struct data d, int align)
  230. {
  231. int newlen = ALIGN(d.len, align);
  232. return data_append_zeroes(d, newlen - d.len);
  233. }
  234. struct data data_add_marker(struct data d, enum markertype type, char *ref)
  235. {
  236. struct marker *m;
  237. m = xmalloc(sizeof(*m));
  238. m->offset = d.len;
  239. m->type = type;
  240. m->ref = ref;
  241. m->next = NULL;
  242. return data_append_markers(d, m);
  243. }
  244. int data_is_one_string(struct data d)
  245. {
  246. int i;
  247. int len = d.len;
  248. if (len == 0)
  249. return 0;
  250. for (i = 0; i < len-1; i++)
  251. if (d.val[i] == '\0')
  252. return 0;
  253. if (d.val[len-1] != '\0')
  254. return 0;
  255. return 1;
  256. }