]> git.llucax.com Git - z.facultad/75.06/jacu.git/blobdiff - src/zerogrouping/zerogrouping.c
Se completa descripción de ZG y se hacen correcciones varias.
[z.facultad/75.06/jacu.git] / src / zerogrouping / zerogrouping.c
index b7e8c2cf6f4bec9c83dea7bf3b264cb49839d70c..569b9ad0c35e2cda72d3f22a83be0144d5e87383 100644 (file)
@@ -22,7 +22,7 @@
  * Autores: Leandro Lucarella <llucare@fi.uba.ar>
  *----------------------------------------------------------------------------
  *
  * Autores: Leandro Lucarella <llucare@fi.uba.ar>
  *----------------------------------------------------------------------------
  *
- * $Id: vfile.c 748 2004-06-21 00:46:08Z llucare $
+ * $Id$
  *
  */
 
  *
  */
 
  *
  */
 
  *
  */
 
+void zg_init(ZG* zg)
+{
+       zg->in_zero = 0;
+}
+
 /** FIXME
 /** FIXME
- * El dst se asume que tiene reservada al menos ceil(size/2.0)+size bytes de
- * memoria por si se llegara a expandir. size es el tamaño a leer de src. Se
+ * El dst se asume que tiene al menos 2 bytes reservados para escribir,
+ * por si se llegara a expandir. src es el caracter a encodear. Se
  * devuelve la cantidad de bytes escritos en dst. */
  * devuelve la cantidad de bytes escritos en dst. */
-size_t zg_group(char* dst, char *src, size_t size)
+size_t zg_group(ZG* zg, unsigned char *dst, unsigned char src)
 {
 {
-       char count;
-       size_t i;
-       size_t total = 0;
-       int in_zero = 0;
-       for (i = 0; i < size; ++i)
+       if (src == 0)
        {
        {
-               if (src[i] == '\0')
+               if (zg->in_zero)
                {
                {
-                       if (in_zero)
+                       if (++(zg->count) == 255u) /* si es 255, salgo de serie de ceros */
                        {
                        {
-                               ++count; /* FIXME verificar que no pase 255 */
-                       }
-                       else
-                       {
-                               in_zero = 1; /* entramos en serie de ceros */
-                               count = 0; /* reiniciamos contador de ceros */
+                               zg->in_zero = 0; /* salgo de serie de ceros */
+                               *dst = zg->count; /* devuelvo cantidad de ceros */
+                               return 1; /* indico que hay un caracter */
                        }
                        }
+                       return 0; /* indico que no hay nada */
                }
                else
                {
                }
                else
                {
-                       if (in_zero)
-                       {
-                               in_zero = 0;
-                               dst[total++] = '\0';
-                               dst[total++] = count;
-                       }
-                       dst[total++] = src[i];
+                       zg->in_zero = 1; /* entramos en serie de ceros */
+                       zg->count = 0; /* reiniciamos contador de ceros */
+                       *dst = 0; /* devuelvo el cero */
+                       return 1; /* indico que hay un caracter */
                }
        }
                }
        }
-       if (in_zero) /* si estaba en una serie de ceros, terminamos de escribir. */
+       else /* no es un cero */
+       {
+               size_t ret = 1;
+               if (zg->in_zero)
+               {
+                       zg->in_zero = 0; /* salgo de serie de ceros */
+                       *dst = zg->count; /* devuelvo cantidad de ceros */
+                       dst++; /* me muevo al siguiente caracter */
+                       ret++; /* indico que hay un caracter más */
+               }
+               *dst = src; /* devuelvo el caracter */
+               return ret; /* indico la cantidad de caracteres devueltos */
+       }
+}
+
+/** A lo sumo puede devolver un unsigned char */
+size_t zg_group_finish(ZG* zg, unsigned char *dst)
+{
+       if (zg->in_zero) /* sólo me interesa si estaba en una serie de ceros */
        {
        {
-               dst[total++] = '\0';
-               dst[total++] = count;
+               zg->in_zero = 0; /* salgo de serie de ceros */
+               *dst = zg->count; /* devuelvo cantidad de ceros */
+               return 1; /* indico que hay un caracter */
        }
        }
-       return total;
+       return 0; /* no había nada */
 }
 
 }
 
-size_t zg_ungroup(char* dst, char *src, size_t size)
+/** FIXME
+ * dst debe tener reservado al menos 256 bytes, src es el caracter a desencodear
+ * y se devuelven la cantidad de bytes desencodeados en dst. */
+size_t zg_ungroup(ZG* zg, unsigned char *dst, unsigned char src)
 {
 {
-       return 0;
+       if (src == 0)
+       {
+               if (zg->in_zero) /* eran 2 ceros seguidos (1 cero orig. expandido) */
+               {
+                       zg->in_zero = 0; /* saldo de serie de ceros */
+                       return 0; /* indico que no hay nada */
+               }
+               else /* empieza serie de ceros */
+               {
+                       zg->in_zero = 1; /* entramos en serie de ceros */
+                       *dst = 0; /* devuelvo el cero */
+                       return 1; /* indico que hay un caracter */
+               }
+       }
+       else /* no es un cero */
+       {
+               if (zg->in_zero) /* era una serie de ceros comprimida */
+               {
+                       unsigned char ret = src;
+                       zg->in_zero = 0; /* salgo de serie de ceros */
+                       while (src--) dst[(size_t)src] = 0; /* devuelve src cantidad de ceros */
+                       return ret; /* indica que se devolvieron src cantidad de ceros */
+               }
+               else
+               {
+                       *dst = src; /* devuelvo el caracter */
+                       return 1; /* indico que se devolvió un caracter */
+               }
+       }
 }
 
 }