/[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 80 - (hide annotations)
Wed Dec 27 02:12:23 2000 UTC (23 years, 4 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 frodo 79 /*
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 frodo 80 typedef struct psiconv_relocation_s {
31     psiconv_u32 offset;
32     int id;
33     } *psiconv_relocation;
34    
35 frodo 79 struct psiconv_buffer_s {
36 frodo 80 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 frodo 79 };
40    
41 frodo 80 static psiconv_u32 unique_id = 1;
42    
43     psiconv_u32 psiconv_buffer_unique_id(void)
44 frodo 79 {
45 frodo 80 return unique_id ++;
46     }
47    
48     psiconv_buffer psiconv_buffer_new(void)
49     {
50 frodo 79 psiconv_buffer buf;
51     if (!(buf = malloc(sizeof(*buf))))
52 frodo 80 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 frodo 79 return buf;
62 frodo 80 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 frodo 79 }
71    
72     void psiconv_buffer_free(psiconv_buffer buf)
73     {
74 frodo 80 psiconv_list_free(buf->reloc_ref);
75     psiconv_list_free(buf->reloc_target);
76 frodo 79 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 frodo 80 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 frodo 79 return psiconv_list_concat(buf->data,extra->data);
133     }
134 frodo 80
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