home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Archived / Updates / Flash / writeflash / !MakeFlash / c / bucket < prev    next >
Text File  |  2000-04-19  |  5KB  |  323 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. //
  5. #include "proto.h"
  6. #include "bucket.h"
  7.  
  8.  
  9. static U8 *buf;
  10. static U32 bufsize, bucket, bits, ptr, writing;
  11.  
  12. static int extend_buffer(void);
  13.  
  14.  
  15.  
  16. int init_bucket(U8 *buffer, U32 size) {
  17.  
  18.   if (buffer == NULL) {       // writing
  19.     buf = malloc(32*1024);
  20.     if (!buf)       return 1;
  21.     writing = 32*1024;
  22.   } else {                    // reading
  23.     buf = buffer;
  24.     writing = 0;
  25.   }
  26.   bufsize = size;
  27.   bits = 0;
  28.   ptr = 0;
  29.  
  30.   return 0;
  31. }
  32.  
  33.  
  34. int close_bucket(U8 **out, U32 *size) {
  35.  
  36.   if (!buf)         return 1;
  37.  
  38.   if (!writing)     return 0;
  39.  
  40.   flush_bucket();
  41.  
  42.   *out = buf;
  43.   *size = ptr;
  44.   return 0;
  45. }
  46.  
  47.  
  48.  
  49. int flush_bucket() {
  50.  
  51.   if (writing) {
  52.     if (bits) {
  53.       if (bits &7)   write_ubits(8 - (bits &7), 0);
  54.       while (bits > 0) {
  55.         buf[ptr++] = bucket>>24;
  56.         bits -= 8;
  57.         bucket <<= 8;
  58.       }
  59.     }
  60.     bucket = 0;
  61.  
  62.   } else {
  63.     bits = 0;
  64.     bucket = 0;
  65.   }
  66.  
  67.   return 0;
  68. }
  69.  
  70.  
  71. // -------------------------------------------------------------------
  72.  
  73. U32 read_position(U8 **p) {
  74.  
  75.   if (p)  *p = buf;
  76.   return ptr;
  77. }
  78.  
  79.  
  80. int read_ushort(U16 *output) {
  81.  
  82.   if (ptr+2 > bufsize)  return 1;
  83.   *output = buf[ptr+0] | (buf[ptr+1]<<8);
  84.   ptr += 2;
  85.   bits = 0;
  86.   return 0;
  87. }
  88.  
  89.  
  90. int read_short(S16 *output) {
  91.  
  92.   return read_ushort((U16 *)output);
  93. }
  94.  
  95.  
  96. int read_uint(U32 *output) {
  97.  
  98.   if (ptr+4 > bufsize)  return 1;
  99.   *output = buf[ptr+0] | (buf[ptr+1]<<8) | (buf[ptr+2]<<16) | (buf[ptr+3]<<24);
  100.   ptr += 4;
  101.   bits = 0;
  102.   return 0;
  103. }
  104.  
  105.  
  106. int read_int(S32 *output) {
  107.  
  108.   return read_uint((U32 *)output);
  109. }
  110.  
  111.  
  112. int read_ubyte(U8 *output) {
  113.  
  114.   if (ptr+1 > bufsize)  return 1;
  115.   *output = buf[ptr+0];
  116.   ptr += 1;
  117.   bits = 0;
  118.   return 0;
  119. }
  120.  
  121.  
  122. int read_byte(S8 *output) {
  123.  
  124.   if (ptr+1 > bufsize)  return 1;
  125.   *output = (S8)buf[ptr+0];
  126.   ptr += 1;
  127.   bits = 0;
  128.   return 0;
  129. }
  130.  
  131.  
  132.  
  133. int read_bits(int n, S32 *output) {
  134.  
  135.   if (read_ubits(n, (U32 *)output))  return 1;
  136.   if (n == 32)  return 0;
  137.   n = 32-n;
  138.   *output = (*output<<n)>>n;
  139.   return 0;
  140. }
  141.  
  142.  
  143. int read_ubits(int n, U32 *output) {
  144.  
  145.   U32 v;
  146.  
  147.   if (n == 0) {
  148.     *output = 0;
  149.     return 0;
  150.   }
  151.  
  152.   if (ptr+(n>>3) > bufsize)  return 1;
  153.  
  154.   if (bits == 0)  bucket = buf[ptr++], bits = 8;
  155.  
  156.   v = 0;
  157.   while (1) {
  158.     if (n > bits) {
  159.       v |= bucket<<(n-bits);
  160.       n -= bits;
  161.       bucket = buf[ptr++];
  162.       bits = 8;
  163.  
  164.     } else {
  165.       v |= bucket>>(bits-n);
  166.       bits -= n;
  167.       bucket &= 0xff>>(8-bits);
  168.       *output = v;
  169.       return 0;
  170.     }
  171.   }
  172.  
  173.   return 1;
  174. }
  175.  
  176. // -------------------------------------------------------------------
  177.  
  178. int bucket_insert(int start, U8 *data, int bytes) {
  179.  
  180.   if (!writing)               return 1;
  181.   if (bytes <= 0)             return 1;
  182.  
  183.   if (ptr + 4 + bytes > writing-4) {
  184.     U8 *newbuf;
  185.     int add;
  186.  
  187.     add = (bytes+8191) & ~8191;
  188.     newbuf = realloc(buf, writing+add);
  189.     if (!newbuf)   return 1;
  190.     buf = newbuf;
  191.     writing += add;
  192.   }
  193.  
  194.   memmove(buf+start+bytes, buf+start, writing-(start+bytes));
  195.   memcpy(buf+start, data, bytes);
  196.   ptr += bytes;
  197.  
  198.   return 0;
  199. }
  200.  
  201.  
  202. int write_ushort(U16 input) {
  203.  
  204.   return write_short((S16)input);
  205. }
  206.  
  207.  
  208. int write_short(S16 input) {
  209.  
  210.   if (extend_buffer())        return 1;
  211.   flush_bucket();
  212.  
  213.   buf[ptr++] = input & 0xff;
  214.   buf[ptr++] = (input>>8) & 0xff;
  215.  
  216.   return 0;
  217. }
  218.  
  219.  
  220. int write_uint(U32 input) {
  221.  
  222.   return write_int((S32)input);
  223. }
  224.  
  225.  
  226. int write_int(S32 input) {
  227.  
  228.   if (extend_buffer())        return 1;
  229.   flush_bucket();
  230.  
  231.   buf[ptr++] = input       & 0xff;
  232.   buf[ptr++] = (input>>8)  & 0xff;
  233.   buf[ptr++] = (input>>16) & 0xff;
  234.   buf[ptr++] = (input>>24) & 0xff;
  235.  
  236.   return 0;
  237. }
  238.  
  239.  
  240. int write_ubyte(U8 input) {
  241.  
  242.   return write_byte((S8)input);
  243. }
  244.  
  245.  
  246. int write_byte(S8 input) {
  247.  
  248.   if (extend_buffer())        return 1;
  249.   flush_bucket();
  250.  
  251.   buf[ptr++] = input;
  252.  
  253.   return 0;
  254. }
  255.  
  256.  
  257. int write_ubits(int n, U32 input) {
  258.  
  259.   return write_bits(n, (S32)input);
  260. }
  261.  
  262.  
  263. int write_bits(int n, S32 input) {
  264.  
  265.   if (n == 0)                 return 0;
  266.   if (extend_buffer())        return 1;
  267.  
  268.   if (n < 32)  input = input & ~(0xffffffff<<n);
  269.  
  270.   while (1) {
  271.     if (n == 0)
  272.       return 0;
  273.  
  274.     else if (bits + n > 32) {
  275.       int thistime;
  276.  
  277.       thistime = 32-bits;
  278.       bucket |= input>>(n-thistime);
  279.       input &= ~(0xffffffff<<(n-thistime));
  280.       n -= thistime;
  281.  
  282.       buf[ptr++] = (bucket>>24) & 0xff;
  283.       buf[ptr++] = (bucket>>16) & 0xff;
  284.       buf[ptr++] = (bucket>>8 ) & 0xff;
  285.       buf[ptr++] =  bucket      & 0xff;
  286.       bits = 0;
  287.       bucket = 0;
  288.  
  289.     } else {
  290.       bucket |= input<<(32-bits-n);
  291.       bits += n;
  292.       return 0;
  293.     }
  294.   }
  295.  
  296.   return 1;
  297. }
  298.  
  299.  
  300. int write_position(U32 newpos, U32 *oldpos) {
  301.  
  302.   flush_bucket();
  303.   *oldpos = ptr;
  304.   ptr = newpos;
  305.  
  306.   return 0;
  307. }
  308.  
  309. // -------------------------------------------------------------------
  310.  
  311. int extend_buffer() {
  312.  
  313.   if (ptr >= writing-4) {
  314.     U8 *newbuf;
  315.     newbuf = realloc(buf, writing+32*1024);
  316.     if (!newbuf)   return 1;
  317.     buf = newbuf;
  318.     writing += 32*1024;
  319.   }
  320.  
  321.   return 0;
  322. }
  323.