]> git.llucax.com Git - z.facultad/75.06/jacu.git/blob - examples/rle/rle.c
algunos () para que se note mejor los caracteres que no se imprimen.
[z.facultad/75.06/jacu.git] / examples / rle / rle.c
1
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5
6 #define SIZE 10
7 #define BIT_SIZE 4
8 #define MIN_LEN 2
9
10 /* Insertar un char al final */
11 void push_end(char *s, char c);
12 int esta_en_memoria(char *memoria, char *pal, int *len);
13
14 void out_ini(char *f);
15 void out_bit(char b);
16 void out_char(char c);
17 void out_data(char len, char pos);
18 void out_end();
19
20 unsigned int out_buffer;
21 FILE *out;
22 int bit_count;
23
24 int main(int argc, char *argv[])
25 {
26         int mc, ic; /* Contadores */
27         char memoria[SIZE];
28         char inspeccion[SIZE];
29         char c, i; /* caracter leido */
30         FILE *fp;
31
32         /* inicio todo lindo */
33         memset(memoria, 1, SIZE);
34         memset(inspeccion, 1, SIZE);
35         mc = ic = 0;
36
37         fp = fopen(argv[1], "rt");
38
39         /* llego INSPECCION */
40         while (((c = fgetc(fp)) != EOF) && (ic < SIZE)) {
41                 push_end(inspeccion, c);
42                 ic++;
43         }
44
45         ungetc(c, fp);
46
47         out_ini(argv[2]);
48         /* Comienza el juevo */
49         while (c != EOF) {
50                 int pos, len;
51                 /* Busco */
52                 pos = esta_en_memoria(memoria, inspeccion, &len);
53                 if (pos != -1) {
54                         /* La cadena se repite! */
55                         printf("[0,%d,%d]\n", pos, len);
56                         out_bit(0);
57                         out_data(len, pos);
58
59                         /* Tengo que meter caracteres */
60                         for(i=0; i<len; i++) {
61                                 push_end(memoria, inspeccion[0]);
62                                 c=fgetc(fp);
63                                 if (c != EOF)
64                                         push_end(inspeccion, c);
65                         }
66                 } else {
67                         /* la cadena no se repite, saco un bit 1 y el codigo ascii*/
68                         printf("[1,%c]\n", inspeccion[0]);
69                         out_bit(0);
70                         out_char(inspeccion[0]);
71                         /* Desplazo */
72                         push_end(memoria, inspeccion[0]);
73                         push_end(inspeccion, c=fgetc(fp));
74                 }
75         }
76
77         /* llegue al eof, sigo hasta vaciar inspeccion */
78         while (ic > 0) {
79                 int pos, len;
80                 /* busco */
81                 pos = esta_en_memoria(memoria, inspeccion, &len);
82                 if (pos != -1) {
83                         /* La cadena se repite! */
84                         printf("[0,%d,%d]\n", pos, len);
85                         out_bit(0);
86                         out_data(len, pos);
87
88                         /* Tengo que meter caracteres */
89                         for(i=0; i<len; i++) {
90                                 push_end(memoria, inspeccion[0]);
91                                 push_end(inspeccion, '\0');
92                         }
93                         ic -= len;
94                 } else {
95                         /* la cadena no se repite, saco un bit 1 y el codigo ascii*/
96                         printf("[1,%c]\n", inspeccion[0]);
97                         out_bit(0);
98                         out_char(inspeccion[0]);
99                         /* Desplazo */
100                         push_end(memoria, inspeccion[0]);
101                         push_end(inspeccion, '\0');
102                         ic--;
103                 }
104         }
105
106         out_end();
107         fclose(fp);
108         printf("\n");
109         return 0;
110 }
111
112 void push_end(char *s, char c)
113 {
114         int i;
115         for(i=0; i<SIZE-1; i++)
116                 s[i] = s[i+1];
117         s[SIZE-1] = c;
118 }
119
120 int esta_en_memoria(char *memoria, char *pal, int *len)
121 {
122         int i,j,k;
123         int len_max, pos_max=-1;
124
125         i=j=0;
126         k=0;
127         len_max = -1;
128         while (i<SIZE) {
129                 if (memoria[i] == pal[j]) {
130                         k++;
131                         if (k>len_max) {
132                                 pos_max = i-k+1;
133                                 len_max = k;
134                         }
135                         
136                         j++;
137                 } else {
138                         j = 0;
139                         k = 0;
140                 }
141                 i++;
142         }
143
144         if (len_max >= MIN_LEN) {
145                 (*len) = len_max;
146                 return pos_max;
147         }
148         return -1;
149 }
150
151 void out_bit(char b)
152 {
153         char c;
154         if (bit_count+1 >= 32) {
155                 /* Tengo que hacer lugar! , saco 1 byte*/
156                 c = (out_buffer >> (bit_count-8));
157                 bit_count -= 8;
158                 /* lo grabo en el archivo */
159                 fwrite(&c, 1, 1, out);
160         }
161
162         bit_count++;
163         out_buffer <<= 1;
164         out_buffer |= (0x1&b);
165 }
166
167 void out_char(char c)
168 {
169         char cc;
170         if (bit_count+8 >= 32) {
171                 /* Tengo que hacer lugar! , saco 1 byte */
172                 cc = (out_buffer >> (bit_count-8));
173                 bit_count -= 8;
174                 /* lo grabo en el archivo */
175                 fwrite(&cc, 1, 1, out);
176         }
177
178         bit_count+=8;
179         out_buffer <<= 8;
180         out_buffer |= c;
181 }
182
183 void out_data(char len, char pos)
184 {
185         char cc;
186         char b;
187         while (bit_count+BIT_SIZE*2 >= 32) {
188                 /* Tengo que hacer lugar! , saco 1 byte */
189                 cc = (out_buffer >> (bit_count-8));
190                 bit_count -= 8;
191                 /* lo grabo en el archivo */
192                 fwrite(&cc, 1, 1, out);
193         }
194
195         b = 0x0;
196         b = ((0x3|pos)<<3) & ((0x3|len));
197         bit_count+=BIT_SIZE*2;
198         out_buffer <<= BIT_SIZE*2;
199         out_buffer |= b;
200 }
201
202 void out_ini(char *f)
203 {
204         out = fopen(f, "wb");
205         bit_count = 0;
206         out_buffer = 0;
207 }
208
209 void out_end()
210 {
211         char cc;
212         /* Saco lo que falte */
213         while (bit_count > 8) {
214                 cc = (out_buffer >> (bit_count-8));
215                 bit_count -= 8;
216                 fwrite(&cc, 1, 1, out);
217         }
218
219         if (bit_count > 0) {
220                 cc = (out_buffer >> bit_count);
221                 fwrite(&cc, 1, 1, out);
222         }
223         fclose(out);
224 }
225