* 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(ZG* zg, char *dst, char src)
+size_t zg_group(ZG* zg, unsigned char *dst, unsigned char src)
{
- if (src == '\0')
+ if (src == 0)
{
if (zg->in_zero)
{
- zg->count++; /* FIXME verificar que no pase 255 */
+ if (++(zg->count) == 255u) /* si es 255, salgo de serie 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
{
zg->in_zero = 1; /* entramos en serie de ceros */
zg->count = 0; /* reiniciamos contador de ceros */
- *dst = '\0'; /* devuelvo el cero */
+ *dst = 0; /* devuelvo el cero */
return 1; /* indico que hay un caracter */
}
}
size_t ret = 1;
if (zg->in_zero)
{
- zg->in_zero = 0; /* saldo de serie de ceros */
+ 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 */
return ret; /* indico la cantidad de caracteres devueltos */
}
}
-/*
-size_t zg_ungroup(char* dst, char *src, size_t size)
+
+/** A lo sumo puede devolver un unsigned char */
+size_t zg_group_finish(ZG* zg, unsigned char *dst)
{
- return 0;
+ if (zg->in_zero) /* sólo me interesa si estaba en una serie 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; /* no había nada */
}
-*/
+
+/** 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)
+{
+ 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 */
+ }
+ }
+}
+