5 /* Aggregate SAA components smaller than this */
6 #define SAA_BLKSHIFT 16
7 #define SAA_BLKLEN ((size_t)1 << SAA_BLKSHIFT)
9 struct SAA
*saa_init(size_t elem_len
)
14 s
= nasm_zalloc(sizeof(struct SAA
));
16 if (elem_len
>= SAA_BLKLEN
)
17 s
->blk_len
= elem_len
;
19 s
->blk_len
= SAA_BLKLEN
- (SAA_BLKLEN
% elem_len
);
21 s
->elem_len
= elem_len
;
22 s
->length
= s
->blk_len
;
23 data
= nasm_malloc(s
->blk_len
);
24 s
->nblkptrs
= s
->nblks
= 1;
25 s
->blk_ptrs
= nasm_malloc(sizeof(char *));
26 s
->blk_ptrs
[0] = data
;
27 s
->wblk
= s
->rblk
= &s
->blk_ptrs
[0];
32 void saa_free(struct SAA
*s
)
37 for (p
= s
->blk_ptrs
, n
= s
->nblks
; n
; p
++, n
--)
40 nasm_free(s
->blk_ptrs
);
44 /* Add one allocation block to an SAA */
45 static void saa_extend(struct SAA
*s
)
47 size_t blkn
= s
->nblks
++;
49 if (blkn
>= s
->nblkptrs
) {
50 size_t rindex
= s
->rblk
- s
->blk_ptrs
;
51 size_t windex
= s
->wblk
- s
->blk_ptrs
;
55 nasm_realloc(s
->blk_ptrs
, s
->nblkptrs
* sizeof(char *));
57 s
->rblk
= s
->blk_ptrs
+ rindex
;
58 s
->wblk
= s
->blk_ptrs
+ windex
;
61 s
->blk_ptrs
[blkn
] = nasm_malloc(s
->blk_len
);
62 s
->length
+= s
->blk_len
;
65 void *saa_wstruct(struct SAA
*s
)
69 if (s
->wpos
% s
->elem_len
)
70 nasm_malloc_error(ERR_PANIC
| ERR_NOFILE
,
71 "misaligned wpos in saa_wstruct");
73 if (s
->wpos
+ s
->elem_len
> s
->blk_len
) {
74 if (s
->wpos
!= s
->blk_len
)
75 nasm_malloc_error(ERR_PANIC
| ERR_NOFILE
,
76 "unfilled block in saa_wstruct");
78 if (s
->wptr
+ s
->elem_len
> s
->length
)
84 p
= *s
->wblk
+ s
->wpos
;
85 s
->wpos
+= s
->elem_len
;
86 s
->wptr
+= s
->elem_len
;
88 if (s
->wptr
> s
->datalen
)
94 void saa_wbytes(struct SAA
*s
, const void *data
, size_t len
)
99 size_t l
= s
->blk_len
- s
->wpos
;
104 memcpy(*s
->wblk
+ s
->wpos
, d
, l
);
107 memset(*s
->wblk
+ s
->wpos
, 0, l
);
112 if (s
->datalen
< s
->wptr
)
113 s
->datalen
= s
->wptr
;
116 if (s
->wptr
>= s
->length
)
124 void saa_rewind(struct SAA
*s
)
126 s
->rblk
= s
->blk_ptrs
;
127 s
->rpos
= s
->rptr
= 0;
130 void *saa_rstruct(struct SAA
*s
)
134 if (s
->rptr
+ s
->elem_len
> s
->datalen
)
137 if (s
->rpos
% s
->elem_len
)
138 nasm_malloc_error(ERR_PANIC
| ERR_NOFILE
,
139 "misaligned rpos in saa_rstruct");
141 if (s
->rpos
+ s
->elem_len
> s
->blk_len
) {
146 p
= *s
->rblk
+ s
->rpos
;
147 s
->rpos
+= s
->elem_len
;
148 s
->rptr
+= s
->elem_len
;
153 const void *saa_rbytes(struct SAA
*s
, size_t * lenp
)
158 if (s
->rptr
>= s
->datalen
) {
163 if (s
->rpos
>= s
->blk_len
) {
169 if (len
> s
->datalen
- s
->rptr
)
170 len
= s
->datalen
- s
->rptr
;
171 if (len
> s
->blk_len
- s
->rpos
)
172 len
= s
->blk_len
- s
->rpos
;
175 p
= *s
->rblk
+ s
->rpos
;
183 void saa_rnbytes(struct SAA
*s
, void *data
, size_t len
)
187 if (s
->rptr
+ len
> s
->datalen
) {
188 nasm_malloc_error(ERR_PANIC
| ERR_NOFILE
,
189 "overrun in saa_rnbytes");
198 p
= saa_rbytes(s
, &l
);
206 /* Same as saa_rnbytes, except position the counter first */
207 void saa_fread(struct SAA
*s
, size_t posn
, void *data
, size_t len
)
211 if (posn
+ len
> s
->datalen
) {
212 nasm_malloc_error(ERR_PANIC
| ERR_NOFILE
, "overrun in saa_fread");
216 if (likely(s
->blk_len
== SAA_BLKLEN
)) {
217 ix
= posn
>> SAA_BLKSHIFT
;
218 s
->rpos
= posn
& (SAA_BLKLEN
- 1);
220 ix
= posn
/ s
->blk_len
;
221 s
->rpos
= posn
% s
->blk_len
;
224 s
->rblk
= &s
->blk_ptrs
[ix
];
226 saa_rnbytes(s
, data
, len
);
229 /* Same as saa_wbytes, except position the counter first */
230 void saa_fwrite(struct SAA
*s
, size_t posn
, const void *data
, size_t len
)
234 if (posn
> s
->datalen
) {
235 /* Seek beyond the end of the existing array not supported */
236 nasm_malloc_error(ERR_PANIC
| ERR_NOFILE
, "overrun in saa_fwrite");
240 if (likely(s
->blk_len
== SAA_BLKLEN
)) {
241 ix
= posn
>> SAA_BLKSHIFT
;
242 s
->wpos
= posn
& (SAA_BLKLEN
- 1);
244 ix
= posn
/ s
->blk_len
;
245 s
->wpos
= posn
% s
->blk_len
;
248 s
->wblk
= &s
->blk_ptrs
[ix
];
251 s
->wpos
= s
->blk_len
;
255 saa_wbytes(s
, data
, len
);
258 void saa_fpwrite(struct SAA
*s
, FILE * fp
)
264 while (len
= s
->datalen
, (data
= saa_rbytes(s
, &len
)) != NULL
)
265 fwrite(data
, 1, len
, fp
);
268 void saa_write8(struct SAA
*s
, uint8_t v
)
270 saa_wbytes(s
, &v
, 1);
273 #ifdef WORDS_LITTEENDIAN
275 void saa_write16(struct SAA
*s
, uint16_t v
)
277 saa_wbytes(s
, &v
, 2);
280 void saa_write32(struct SAA
*s
, uint32_t v
)
282 saa_wbytes(s
, &v
, 4);
285 void saa_write64(struct SAA
*s
, uint64_t v
)
287 saa_wbytes(s
, &v
, 8);
290 void saa_writeaddr(struct SAA
*s
, uint64_t v
, size_t len
)
292 saa_wbytes(s
, &v
, len
);
295 #else /* not WORDS_LITTLEENDIAN */
297 void saa_write16(struct SAA
*s
, uint16_t v
)
306 void saa_write32(struct SAA
*s
, uint32_t v
)
317 void saa_write64(struct SAA
*s
, uint64_t v
)
332 void saa_writeaddr(struct SAA
*s
, uint64_t v
, size_t len
)
345 saa_wbytes(s
, &v
, len
);
348 #endif /* WORDS_LITTLEENDIAN */
350 /* write unsigned LEB128 value to SAA */
351 void saa_wleb128u(struct SAA
*psaa
, int value
)
353 char temp
[64], *ptemp
;
362 if (value
!= 0) /* more bytes to come */
367 } while (value
!= 0);
368 saa_wbytes(psaa
, temp
, len
);
371 /* write signed LEB128 value to SAA */
372 void saa_wleb128s(struct SAA
*psaa
, int value
)
374 char temp
[64], *ptemp
;
381 negative
= (value
< 0);
382 size
= sizeof(int) * 8;
389 value
|= -(1 << (size
- 7));
390 /* sign bit of byte is second high order bit (0x40) */
391 if ((value
== 0 && !(byte
& 0x40)) ||
392 ((value
== -1) && (byte
& 0x40)))
400 saa_wbytes(psaa
, temp
, len
);