* 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
- * 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. */
-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
{
- 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 */
+ }
+ }
}