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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 80 - (show annotations)
Wed Dec 27 02:12:23 2000 UTC (23 years, 3 months ago) by frodo
File MIME type: text/plain
File size: 5504 byte(s)
(Frodo) Many changes. Layout sections now work!

* Added list_empty, list_replace
* Added relocation to buffers, removed base address
* Added buffer_resolve, buffer_add_reference, buffer_add_target,
  psiconv_unique_id functions
* Modifified other buffer functions to work with references
* Added comments to buffer.h
* Added write_offset function
* Added reference support in functions where needed
* Corrected extra/rewrite error message
* Corrected numerous bugs to make layouts work.

1 /*
2 buffer.c - Part of psiconv, a PSION 5 file formats converter
3 Copyright (c) 2000 Frodo Looijaard <frodol@dds.nl>
4
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 typedef struct psiconv_relocation_s {
31 psiconv_u32 offset;
32 int id;
33 } *psiconv_relocation;
34
35 struct psiconv_buffer_s {
36 psiconv_list reloc_target; /* of struct relocation_s */
37 psiconv_list reloc_ref; /* of struct relocation_s */
38 psiconv_list data; /* of psiconv_u8 */
39 };
40
41 static psiconv_u32 unique_id = 1;
42
43 psiconv_u32 psiconv_buffer_unique_id(void)
44 {
45 return unique_id ++;
46 }
47
48 psiconv_buffer psiconv_buffer_new(void)
49 {
50 psiconv_buffer buf;
51 if (!(buf = malloc(sizeof(*buf))))
52 goto ERROR1;
53 if (!(buf->data = psiconv_list_new(sizeof(psiconv_u8))))
54 goto ERROR2;
55 if (!(buf->reloc_target = psiconv_list_new(
56 sizeof(struct psiconv_relocation_s))))
57 goto ERROR3;
58 if (!(buf->reloc_ref = psiconv_list_new(
59 sizeof(struct psiconv_relocation_s))))
60 goto ERROR4;
61 return buf;
62 ERROR4:
63 psiconv_list_free(buf->reloc_target);
64 ERROR3:
65 psiconv_list_free(buf->data);
66 ERROR2:
67 free(buf);
68 ERROR1:
69 return NULL;
70 }
71
72 void psiconv_buffer_free(psiconv_buffer buf)
73 {
74 psiconv_list_free(buf->reloc_ref);
75 psiconv_list_free(buf->reloc_target);
76 psiconv_list_free(buf->data);
77 free(buf);
78 }
79
80 psiconv_u32 psiconv_buffer_length(const psiconv_buffer buf)
81 {
82 return psiconv_list_length(buf->data);
83 }
84
85
86 psiconv_u8 *psiconv_buffer_get(const psiconv_buffer buf, psiconv_u32 off)
87 {
88 return psiconv_list_get(buf->data,off);
89 }
90
91 int psiconv_buffer_add(psiconv_buffer buf,psiconv_u8 data)
92 {
93 return psiconv_list_add(buf->data,&data);
94 }
95
96 size_t psiconv_buffer_fread(psiconv_buffer buf,size_t size, FILE *f)
97 {
98 return psiconv_list_fread(buf->data,size,f);
99 }
100
101 int psiconv_buffer_fread_all(psiconv_buffer buf, FILE *f)
102 {
103 return psiconv_list_fread_all(buf->data,f);
104 }
105
106 int psiconv_buffer_fwrite_all(const psiconv_buffer buf, FILE *f)
107 {
108 return psiconv_list_fwrite_all(buf->data,f);
109 }
110
111 int psiconv_buffer_concat(psiconv_buffer buf, const psiconv_buffer extra)
112 {
113 int res;
114 psiconv_u32 i;
115 psiconv_relocation reloc;
116
117
118 for (i = 0; i < psiconv_list_length(extra->reloc_target); i++) {
119 if (!(reloc = psiconv_list_get(extra->reloc_target,i)))
120 return -PSICONV_E_OTHER;
121 reloc->offset += psiconv_list_length(buf->data);
122 if ((res=psiconv_list_add(buf->reloc_target,reloc)))
123 return res;
124 }
125 for (i = 0; i < psiconv_list_length(extra->reloc_ref); i++) {
126 if (!(reloc = psiconv_list_get(extra->reloc_ref,i)))
127 return -PSICONV_E_OTHER;
128 reloc->offset += psiconv_list_length(buf->data);
129 if ((res = psiconv_list_add(buf->reloc_ref,reloc)))
130 return res;
131 }
132 return psiconv_list_concat(buf->data,extra->data);
133 }
134
135 int psiconv_buffer_resolve(psiconv_buffer buf)
136 {
137 int res;
138 psiconv_u32 i,j,temp;
139 psiconv_relocation target,ref;
140
141 for (i = 0; i < psiconv_list_length(buf->reloc_ref);i++) {
142 if (!(ref = psiconv_list_get(buf->reloc_ref,i)))
143 return -PSICONV_E_OTHER;
144 for (j = 0; j < psiconv_list_length(buf->reloc_target);j++) {
145 if (!(target = psiconv_list_get(buf->reloc_target,j)))
146 return -PSICONV_E_OTHER;
147 if (ref->id == target->id) {
148 temp = target->offset & 0xff;
149 if ((res = psiconv_list_replace(buf->data,ref->offset,&temp)))
150 return -PSICONV_E_OTHER;
151 temp = (target->offset >> 8) & 0xff;
152 if ((res = psiconv_list_replace(buf->data,ref->offset + 1,&temp)))
153 return -PSICONV_E_OTHER;
154 temp = (target->offset >> 16) & 0xff;
155 if ((res = psiconv_list_replace(buf->data,ref->offset + 2,&temp)))
156 return -PSICONV_E_OTHER;
157 temp = (target->offset >> 24) & 0xff;
158 if ((res = psiconv_list_replace(buf->data,ref->offset + 3,&temp)))
159 return -PSICONV_E_OTHER;
160 break;
161 }
162 }
163 if (j == psiconv_list_length(buf->reloc_target))
164 return -PSICONV_E_OTHER;
165 }
166 psiconv_list_empty(buf->reloc_target);
167 psiconv_list_empty(buf->reloc_ref);
168 return -PSICONV_E_OK;
169 }
170
171 int psiconv_buffer_add_reference(psiconv_buffer buf,int id)
172 {
173 struct psiconv_relocation_s reloc;
174 int res,i;
175 psiconv_u8 data;
176
177 reloc.offset = psiconv_list_length(buf->data);
178 reloc.id = id;
179 if ((res = psiconv_list_add(buf->reloc_ref,&reloc)))
180 return res;
181 data = 0x00;
182 for (i = 0; i < 4; i++)
183 if ((res = psiconv_list_add(buf->data,&data)))
184 return res;
185 return -PSICONV_E_OK;
186 }
187
188 int psiconv_buffer_add_target(psiconv_buffer buf, int id)
189 {
190 struct psiconv_relocation_s reloc;
191
192 reloc.offset = psiconv_list_length(buf->data);
193 reloc.id = id;
194 return psiconv_list_add(buf->reloc_target,&reloc);
195 }

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