-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwriter.c
89 lines (76 loc) · 2.03 KB
/
writer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "writer.h"
#define SIZE_BYTE 8
void write(FILE *out,FILE *in, simbolo* simbs, int size)
{
int i;
char simbInBits[SIZE_BYTE];
char lenInBits[SIZE_BYTE];
char chr, x;
buffer buffer;
buffer.size = buffer.b = 0;
putc(size, out);
for(i = 0; i <= size; i++)
{
/*Table*/
/*Write binary code of current symbol*/
chr = simbs[i]->simb;
mkCharBits(chr, simbInBits,SIZE_BYTE);
/*why do this? i thought if i wrote \n to out it would write a new line*/
/*Maybe not*/
writeSimbBin(&buffer, simbInBits, out, SIZE_BYTE);
/*Write the length of shannon-fano code for the current symbol*/
mkCharBits(simbs[i]->codeLen, lenInBits, SIZE_BYTE);
writeSimbBin(&buffer, lenInBits, out, SIZE_BYTE); /*yeah, i know, i should rename that func*/
/*Write shannon-fano code of current symbol*/
writeSimbBin(&buffer, simbs[i]->code, out, simbs[i]->codeLen);
}
/*Now we start writing the content*/
fseek(in, 0, SEEK_SET);
while((x = getc(in))!=EOF)
{
/*This is stupid simbs is a hashtable i should be calling directly simbs[x]->...*/
i = lookFor(x, simbs, size);
writeSimbBin(&buffer, simbs[i]->code, out, simbs[i]->codeLen);
}
}
int lookFor(char x, simbolo *simbs, int n)
{
int i;
for(i = 0; i <= n; i++)
if(simbs[i]->simb == x)
break;
return i;
}
void mkCharBits(char chr, char simbInBits[], int n)
{
int i;
for(i = n-1; i>=0; i--)
{
simbInBits[i] = chr % 2 == 1 ? '1' : '0';
chr /= 2;
}
}
void writeSimbBin(buffer *buffer, char simbInBits[], FILE* out, int n)
{
int i;
for(i = 0; i < n; i++)
{
if(buffer->size == SIZE_BYTE)
{
putc(buffer->b, out);
buffer->size = buffer->b = 0;
}
if(simbInBits[i] == '1')
buffer->b |= 1 << buffer->size;
else
{
/*Places 1 where 0 must go, nots and ands it with buffer*/
/*Basically what we'll get is a mask with every bit turned on*/
/*except the bit that we want to turn to 0*/
/*AND this mask with the buffer keeps everything the same but*/
/*that bit we wanted to be zero*/
buffer->b &= ~(1 << buffer->size);
}
(buffer->size)++;
}
}