1 /* vim: set noexpandtab tabstop=4 shiftwidth=4 wrap:
2 *----------------------------------------------------------------------------
4 *----------------------------------------------------------------------------
5 * This file is part of jacu.
7 * jacu is free software; you can redistribute it and/or modify it under the
8 * terms of the GNU General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option) any later
12 * jacu is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along
18 * with jacu; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
20 *----------------------------------------------------------------------------
21 * Creado: lun jun 21 05:40:38 ART 2004
22 * Autores: Leandro Lucarella <llucare@fi.uba.ar>
23 *----------------------------------------------------------------------------
29 #include "zerogrouping.h"
35 * Implementación del agrupador de ceros. TODO completar doc.
45 * El dst se asume que tiene al menos 2 bytes reservados para escribir,
46 * por si se llegara a expandir. src es el caracter a encodear. Se
47 * devuelve la cantidad de bytes escritos en dst. */
48 size_t zg_group(ZG* zg, unsigned char *dst, unsigned char src)
54 if (++(zg->count) == 255u) /* si es 255, salgo de serie de ceros */
56 zg->in_zero = 0; /* salgo de serie de ceros */
57 *dst = zg->count; /* devuelvo cantidad de ceros */
58 return 1; /* indico que hay un caracter */
60 return 0; /* indico que no hay nada */
64 zg->in_zero = 1; /* entramos en serie de ceros */
65 zg->count = 0; /* reiniciamos contador de ceros */
66 *dst = 0; /* devuelvo el cero */
67 return 1; /* indico que hay un caracter */
70 else /* no es un cero */
75 zg->in_zero = 0; /* salgo de serie de ceros */
76 *dst = zg->count; /* devuelvo cantidad de ceros */
77 dst++; /* me muevo al siguiente caracter */
78 ret++; /* indico que hay un caracter más */
80 *dst = src; /* devuelvo el caracter */
81 return ret; /* indico la cantidad de caracteres devueltos */
85 /** A lo sumo puede devolver un unsigned char */
86 size_t zg_group_finish(ZG* zg, unsigned char *dst)
88 if (zg->in_zero) /* sólo me interesa si estaba en una serie de ceros */
90 zg->in_zero = 0; /* salgo de serie de ceros */
91 *dst = zg->count; /* devuelvo cantidad de ceros */
92 return 1; /* indico que hay un caracter */
94 return 0; /* no había nada */
98 * dst debe tener reservado al menos 256 bytes, src es el caracter a desencodear
99 * y se devuelven la cantidad de bytes desencodeados en dst. */
100 size_t zg_ungroup(ZG* zg, unsigned char *dst, unsigned char src)
104 if (zg->in_zero) /* eran 2 ceros seguidos (1 cero orig. expandido) */
106 zg->in_zero = 0; /* saldo de serie de ceros */
107 return 0; /* indico que no hay nada */
109 else /* empieza serie de ceros */
111 zg->in_zero = 1; /* entramos en serie de ceros */
112 *dst = 0; /* devuelvo el cero */
113 return 1; /* indico que hay un caracter */
116 else /* no es un cero */
118 if (zg->in_zero) /* era una serie de ceros comprimida */
120 unsigned char ret = src;
121 zg->in_zero = 0; /* salgo de serie de ceros */
122 while (src--) dst[(size_t)src] = 0; /* devuelve src cantidad de ceros */
123 return ret; /* indica que se devolvieron src cantidad de ceros */
127 *dst = src; /* devuelvo el caracter */
128 return 1; /* indico que se devolvió un caracter */