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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 351 - (hide annotations)
Wed Oct 22 19:53:40 2014 UTC (9 years, 5 months ago) by frodo
File MIME type: text/plain
File size: 6135 byte(s)
(Frodo) Update copyright year in all source files

1 frodo 79 /*
2     buffer.c - Part of psiconv, a PSION 5 file formats converter
3 frodo 351 Copyright (c) 2000-2014 Frodo Looijaard <frodo@frodo.looijaard.name>
4 frodo 79
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
7     the Free Software Foundation; either version 2 of the License, or
8     (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
13     GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.
18     */
19    
20    
21     #include "config.h"
22     #include "compat.h"
23    
24     #include <stdlib.h>
25    
26     #include "list.h"
27     #include "error.h"
28     #include "buffer.h"
29    
30 frodo 142 #ifdef DMALLOC
31     #include <dmalloc.h>
32     #endif
33    
34 frodo 80 typedef struct psiconv_relocation_s {
35     psiconv_u32 offset;
36     int id;
37     } *psiconv_relocation;
38    
39 frodo 79 struct psiconv_buffer_s {
40 frodo 80 psiconv_list reloc_target; /* of struct relocation_s */
41     psiconv_list reloc_ref; /* of struct relocation_s */
42     psiconv_list data; /* of psiconv_u8 */
43 frodo 79 };
44    
45 frodo 80 static psiconv_u32 unique_id = 1;
46    
47     psiconv_u32 psiconv_buffer_unique_id(void)
48 frodo 79 {
49 frodo 80 return unique_id ++;
50     }
51    
52     psiconv_buffer psiconv_buffer_new(void)
53     {
54 frodo 79 psiconv_buffer buf;
55     if (!(buf = malloc(sizeof(*buf))))
56 frodo 80 goto ERROR1;
57     if (!(buf->data = psiconv_list_new(sizeof(psiconv_u8))))
58     goto ERROR2;
59     if (!(buf->reloc_target = psiconv_list_new(
60     sizeof(struct psiconv_relocation_s))))
61     goto ERROR3;
62     if (!(buf->reloc_ref = psiconv_list_new(
63     sizeof(struct psiconv_relocation_s))))
64     goto ERROR4;
65 frodo 79 return buf;
66 frodo 80 ERROR4:
67     psiconv_list_free(buf->reloc_target);
68     ERROR3:
69     psiconv_list_free(buf->data);
70     ERROR2:
71     free(buf);
72     ERROR1:
73     return NULL;
74 frodo 79 }
75    
76     void psiconv_buffer_free(psiconv_buffer buf)
77     {
78 frodo 80 psiconv_list_free(buf->reloc_ref);
79     psiconv_list_free(buf->reloc_target);
80 frodo 79 psiconv_list_free(buf->data);
81     free(buf);
82     }
83    
84     psiconv_u32 psiconv_buffer_length(const psiconv_buffer buf)
85     {
86     return psiconv_list_length(buf->data);
87     }
88    
89     psiconv_u8 *psiconv_buffer_get(const psiconv_buffer buf, psiconv_u32 off)
90     {
91     return psiconv_list_get(buf->data,off);
92     }
93    
94     int psiconv_buffer_add(psiconv_buffer buf,psiconv_u8 data)
95     {
96     return psiconv_list_add(buf->data,&data);
97     }
98    
99 frodo 158 size_t psiconv_buffer_fread(psiconv_buffer buf, size_t size, FILE *f)
100 frodo 79 {
101     return psiconv_list_fread(buf->data,size,f);
102     }
103    
104     int psiconv_buffer_fread_all(psiconv_buffer buf, FILE *f)
105     {
106     return psiconv_list_fread_all(buf->data,f);
107     }
108    
109     int psiconv_buffer_fwrite_all(const psiconv_buffer buf, FILE *f)
110     {
111     return psiconv_list_fwrite_all(buf->data,f);
112     }
113    
114 frodo 158 int 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 frodo 162 return 0;
134 frodo 158
135     ERROR2:
136     psiconv_buffer_free(*buf);
137     ERROR1:
138     return res;
139     }
140    
141 frodo 79 int psiconv_buffer_concat(psiconv_buffer buf, const psiconv_buffer extra)
142     {
143 frodo 80 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     }
162 frodo 79 return psiconv_list_concat(buf->data,extra->data);
163     }
164 frodo 80
165     int 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    
201     int 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    
218     int 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     }

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