/[public]/psiconv/trunk/lib/psiconv/buffer.c
ViewVC logotype

Diff of /psiconv/trunk/lib/psiconv/buffer.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 79 Revision 351
1/* 1/*
2 buffer.c - Part of psiconv, a PSION 5 file formats converter 2 buffer.c - Part of psiconv, a PSION 5 file formats converter
3 Copyright (c) 2000 Frodo Looijaard <frodol@dds.nl> 3 Copyright (c) 2000-2014 Frodo Looijaard <frodo@frodo.looijaard.name>
4 4
5 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version. 8 (at your option) any later version.
25 25
26#include "list.h" 26#include "list.h"
27#include "error.h" 27#include "error.h"
28#include "buffer.h" 28#include "buffer.h"
29 29
30#ifdef DMALLOC
31#include <dmalloc.h>
32#endif
33
34typedef struct psiconv_relocation_s {
35 psiconv_u32 offset;
36 int id;
37} *psiconv_relocation;
38
30struct psiconv_buffer_s { 39struct psiconv_buffer_s {
31 psiconv_u32 base_offset; 40 psiconv_list reloc_target; /* of struct relocation_s */
32 psiconv_list data; 41 psiconv_list reloc_ref; /* of struct relocation_s */
42 psiconv_list data; /* of psiconv_u8 */
33}; 43};
34 44
35psiconv_buffer psiconv_buffer_new(psiconv_u32 base_offset) 45static psiconv_u32 unique_id = 1;
46
47psiconv_u32 psiconv_buffer_unique_id(void)
48{
49 return unique_id ++;
50}
51
52psiconv_buffer psiconv_buffer_new(void)
36{ 53{
37 psiconv_buffer buf; 54 psiconv_buffer buf;
38 if (!(buf = malloc(sizeof(*buf)))) 55 if (!(buf = malloc(sizeof(*buf))))
39 return NULL; 56 goto ERROR1;
40 if (!(buf->data = psiconv_list_new(sizeof(psiconv_u8)))) { 57 if (!(buf->data = psiconv_list_new(sizeof(psiconv_u8))))
41 free(buf); 58 goto ERROR2;
42 return NULL; 59 if (!(buf->reloc_target = psiconv_list_new(
43 } 60 sizeof(struct psiconv_relocation_s))))
44 buf->base_offset = base_offset; 61 goto ERROR3;
62 if (!(buf->reloc_ref = psiconv_list_new(
63 sizeof(struct psiconv_relocation_s))))
64 goto ERROR4;
45 return buf; 65 return buf;
66ERROR4:
67 psiconv_list_free(buf->reloc_target);
68ERROR3:
69 psiconv_list_free(buf->data);
70ERROR2:
71 free(buf);
72ERROR1:
73 return NULL;
46} 74}
47 75
48void psiconv_buffer_free(psiconv_buffer buf) 76void psiconv_buffer_free(psiconv_buffer buf)
49{ 77{
78 psiconv_list_free(buf->reloc_ref);
79 psiconv_list_free(buf->reloc_target);
50 psiconv_list_free(buf->data); 80 psiconv_list_free(buf->data);
51 free(buf); 81 free(buf);
52} 82}
53 83
54psiconv_u32 psiconv_buffer_base_offset(const psiconv_buffer buf)
55{
56 return buf->base_offset;
57}
58
59psiconv_u32 psiconv_buffer_length(const psiconv_buffer buf) 84psiconv_u32 psiconv_buffer_length(const psiconv_buffer buf)
60{ 85{
61 return psiconv_list_length(buf->data); 86 return psiconv_list_length(buf->data);
62} 87}
63 88
64
65psiconv_u8 *psiconv_buffer_get(const psiconv_buffer buf, psiconv_u32 off) 89psiconv_u8 *psiconv_buffer_get(const psiconv_buffer buf, psiconv_u32 off)
66{ 90{
67 return psiconv_list_get(buf->data,off); 91 return psiconv_list_get(buf->data,off);
68} 92}
69 93
70int psiconv_buffer_add(psiconv_buffer buf,psiconv_u8 data) 94int psiconv_buffer_add(psiconv_buffer buf,psiconv_u8 data)
71{ 95{
72 return psiconv_list_add(buf->data,&data); 96 return psiconv_list_add(buf->data,&data);
73} 97}
74 98
75size_t psiconv_buffer_fread(psiconv_buffer buf,size_t size, FILE *f) 99size_t psiconv_buffer_fread(psiconv_buffer buf, size_t size, FILE *f)
76{ 100{
77 return psiconv_list_fread(buf->data,size,f); 101 return psiconv_list_fread(buf->data,size,f);
78} 102}
79 103
80int psiconv_buffer_fread_all(psiconv_buffer buf, FILE *f) 104int psiconv_buffer_fread_all(psiconv_buffer buf, FILE *f)
85int psiconv_buffer_fwrite_all(const psiconv_buffer buf, FILE *f) 109int psiconv_buffer_fwrite_all(const psiconv_buffer buf, FILE *f)
86{ 110{
87 return psiconv_list_fwrite_all(buf->data,f); 111 return psiconv_list_fwrite_all(buf->data,f);
88} 112}
89 113
114int psiconv_buffer_subbuffer(psiconv_buffer *buf, const psiconv_buffer org,
115 psiconv_u32 offset, psiconv_u32 length)
116{
117 int i;
118 int res;
119 psiconv_u8 *data;
120 if (! (*buf = psiconv_buffer_new())) {
121 res = PSICONV_E_NOMEM;
122 goto ERROR1;
123 }
124 for (i = 0; i < length; i++) {
125 if (!(data = psiconv_buffer_get(org,offset+i))) {
126 res = PSICONV_E_OTHER;
127 goto ERROR2;
128 }
129 if ((res = psiconv_buffer_add(*buf,*data))) {
130 goto ERROR2;
131 }
132 }
133 return 0;
134
135ERROR2:
136 psiconv_buffer_free(*buf);
137ERROR1:
138 return res;
139}
140
90int psiconv_buffer_concat(psiconv_buffer buf, const psiconv_buffer extra) 141int psiconv_buffer_concat(psiconv_buffer buf, const psiconv_buffer extra)
91{ 142{
143 int res;
144 psiconv_u32 i;
145 psiconv_relocation reloc;
146
147
148 for (i = 0; i < psiconv_list_length(extra->reloc_target); i++) {
149 if (!(reloc = psiconv_list_get(extra->reloc_target,i)))
150 return -PSICONV_E_OTHER;
151 reloc->offset += psiconv_list_length(buf->data);
152 if ((res=psiconv_list_add(buf->reloc_target,reloc)))
153 return res;
154 }
155 for (i = 0; i < psiconv_list_length(extra->reloc_ref); i++) {
156 if (!(reloc = psiconv_list_get(extra->reloc_ref,i)))
157 return -PSICONV_E_OTHER;
158 reloc->offset += psiconv_list_length(buf->data);
159 if ((res = psiconv_list_add(buf->reloc_ref,reloc)))
160 return res;
161 }
92 return psiconv_list_concat(buf->data,extra->data); 162 return psiconv_list_concat(buf->data,extra->data);
93} 163}
164
165int psiconv_buffer_resolve(psiconv_buffer buf)
166{
167 int res;
168 psiconv_u32 i,j,temp;
169 psiconv_relocation target,ref;
170
171 for (i = 0; i < psiconv_list_length(buf->reloc_ref);i++) {
172 if (!(ref = psiconv_list_get(buf->reloc_ref,i)))
173 return -PSICONV_E_OTHER;
174 for (j = 0; j < psiconv_list_length(buf->reloc_target);j++) {
175 if (!(target = psiconv_list_get(buf->reloc_target,j)))
176 return -PSICONV_E_OTHER;
177 if (ref->id == target->id) {
178 temp = target->offset & 0xff;
179 if ((res = psiconv_list_replace(buf->data,ref->offset,&temp)))
180 return -PSICONV_E_OTHER;
181 temp = (target->offset >> 8) & 0xff;
182 if ((res = psiconv_list_replace(buf->data,ref->offset + 1,&temp)))
183 return -PSICONV_E_OTHER;
184 temp = (target->offset >> 16) & 0xff;
185 if ((res = psiconv_list_replace(buf->data,ref->offset + 2,&temp)))
186 return -PSICONV_E_OTHER;
187 temp = (target->offset >> 24) & 0xff;
188 if ((res = psiconv_list_replace(buf->data,ref->offset + 3,&temp)))
189 return -PSICONV_E_OTHER;
190 break;
191 }
192 }
193 if (j == psiconv_list_length(buf->reloc_target))
194 return -PSICONV_E_OTHER;
195 }
196 psiconv_list_empty(buf->reloc_target);
197 psiconv_list_empty(buf->reloc_ref);
198 return -PSICONV_E_OK;
199}
200
201int psiconv_buffer_add_reference(psiconv_buffer buf,int id)
202{
203 struct psiconv_relocation_s reloc;
204 int res,i;
205 psiconv_u8 data;
206
207 reloc.offset = psiconv_list_length(buf->data);
208 reloc.id = id;
209 if ((res = psiconv_list_add(buf->reloc_ref,&reloc)))
210 return res;
211 data = 0x00;
212 for (i = 0; i < 4; i++)
213 if ((res = psiconv_list_add(buf->data,&data)))
214 return res;
215 return -PSICONV_E_OK;
216}
217
218int psiconv_buffer_add_target(psiconv_buffer buf, int id)
219{
220 struct psiconv_relocation_s reloc;
221
222 reloc.offset = psiconv_list_length(buf->data);
223 reloc.id = id;
224 return psiconv_list_add(buf->reloc_target,&reloc);
225}

Legend:
Removed from v.79  
changed lines
  Added in v.351

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26