home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 10
/
AU_CD10.iso
/
Archived
/
Updates
/
Flash
/
writeflash
/
!MakeFlash
/
c
/
bucket
< prev
next >
Wrap
Text File
|
2000-04-19
|
5KB
|
323 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//
#include "proto.h"
#include "bucket.h"
static U8 *buf;
static U32 bufsize, bucket, bits, ptr, writing;
static int extend_buffer(void);
int init_bucket(U8 *buffer, U32 size) {
if (buffer == NULL) { // writing
buf = malloc(32*1024);
if (!buf) return 1;
writing = 32*1024;
} else { // reading
buf = buffer;
writing = 0;
}
bufsize = size;
bits = 0;
ptr = 0;
return 0;
}
int close_bucket(U8 **out, U32 *size) {
if (!buf) return 1;
if (!writing) return 0;
flush_bucket();
*out = buf;
*size = ptr;
return 0;
}
int flush_bucket() {
if (writing) {
if (bits) {
if (bits &7) write_ubits(8 - (bits &7), 0);
while (bits > 0) {
buf[ptr++] = bucket>>24;
bits -= 8;
bucket <<= 8;
}
}
bucket = 0;
} else {
bits = 0;
bucket = 0;
}
return 0;
}
// -------------------------------------------------------------------
U32 read_position(U8 **p) {
if (p) *p = buf;
return ptr;
}
int read_ushort(U16 *output) {
if (ptr+2 > bufsize) return 1;
*output = buf[ptr+0] | (buf[ptr+1]<<8);
ptr += 2;
bits = 0;
return 0;
}
int read_short(S16 *output) {
return read_ushort((U16 *)output);
}
int read_uint(U32 *output) {
if (ptr+4 > bufsize) return 1;
*output = buf[ptr+0] | (buf[ptr+1]<<8) | (buf[ptr+2]<<16) | (buf[ptr+3]<<24);
ptr += 4;
bits = 0;
return 0;
}
int read_int(S32 *output) {
return read_uint((U32 *)output);
}
int read_ubyte(U8 *output) {
if (ptr+1 > bufsize) return 1;
*output = buf[ptr+0];
ptr += 1;
bits = 0;
return 0;
}
int read_byte(S8 *output) {
if (ptr+1 > bufsize) return 1;
*output = (S8)buf[ptr+0];
ptr += 1;
bits = 0;
return 0;
}
int read_bits(int n, S32 *output) {
if (read_ubits(n, (U32 *)output)) return 1;
if (n == 32) return 0;
n = 32-n;
*output = (*output<<n)>>n;
return 0;
}
int read_ubits(int n, U32 *output) {
U32 v;
if (n == 0) {
*output = 0;
return 0;
}
if (ptr+(n>>3) > bufsize) return 1;
if (bits == 0) bucket = buf[ptr++], bits = 8;
v = 0;
while (1) {
if (n > bits) {
v |= bucket<<(n-bits);
n -= bits;
bucket = buf[ptr++];
bits = 8;
} else {
v |= bucket>>(bits-n);
bits -= n;
bucket &= 0xff>>(8-bits);
*output = v;
return 0;
}
}
return 1;
}
// -------------------------------------------------------------------
int bucket_insert(int start, U8 *data, int bytes) {
if (!writing) return 1;
if (bytes <= 0) return 1;
if (ptr + 4 + bytes > writing-4) {
U8 *newbuf;
int add;
add = (bytes+8191) & ~8191;
newbuf = realloc(buf, writing+add);
if (!newbuf) return 1;
buf = newbuf;
writing += add;
}
memmove(buf+start+bytes, buf+start, writing-(start+bytes));
memcpy(buf+start, data, bytes);
ptr += bytes;
return 0;
}
int write_ushort(U16 input) {
return write_short((S16)input);
}
int write_short(S16 input) {
if (extend_buffer()) return 1;
flush_bucket();
buf[ptr++] = input & 0xff;
buf[ptr++] = (input>>8) & 0xff;
return 0;
}
int write_uint(U32 input) {
return write_int((S32)input);
}
int write_int(S32 input) {
if (extend_buffer()) return 1;
flush_bucket();
buf[ptr++] = input & 0xff;
buf[ptr++] = (input>>8) & 0xff;
buf[ptr++] = (input>>16) & 0xff;
buf[ptr++] = (input>>24) & 0xff;
return 0;
}
int write_ubyte(U8 input) {
return write_byte((S8)input);
}
int write_byte(S8 input) {
if (extend_buffer()) return 1;
flush_bucket();
buf[ptr++] = input;
return 0;
}
int write_ubits(int n, U32 input) {
return write_bits(n, (S32)input);
}
int write_bits(int n, S32 input) {
if (n == 0) return 0;
if (extend_buffer()) return 1;
if (n < 32) input = input & ~(0xffffffff<<n);
while (1) {
if (n == 0)
return 0;
else if (bits + n > 32) {
int thistime;
thistime = 32-bits;
bucket |= input>>(n-thistime);
input &= ~(0xffffffff<<(n-thistime));
n -= thistime;
buf[ptr++] = (bucket>>24) & 0xff;
buf[ptr++] = (bucket>>16) & 0xff;
buf[ptr++] = (bucket>>8 ) & 0xff;
buf[ptr++] = bucket & 0xff;
bits = 0;
bucket = 0;
} else {
bucket |= input<<(32-bits-n);
bits += n;
return 0;
}
}
return 1;
}
int write_position(U32 newpos, U32 *oldpos) {
flush_bucket();
*oldpos = ptr;
ptr = newpos;
return 0;
}
// -------------------------------------------------------------------
int extend_buffer() {
if (ptr >= writing-4) {
U8 *newbuf;
newbuf = realloc(buf, writing+32*1024);
if (!newbuf) return 1;
buf = newbuf;
writing += 32*1024;
}
return 0;
}