-
Notifications
You must be signed in to change notification settings - Fork 0
/
candidates.c
126 lines (108 loc) · 2.92 KB
/
candidates.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <stdlib.h>
#include <string.h>
#include "alphabet.h"
#include "candidates.h"
#include "cipher.h"
int candidates_init(Candidates *candidates, size_t n)
{
memset(candidates, 0, sizeof(*candidates));
candidates->n = n;
if (!(candidates->c = (Candidate**)malloc(sizeof(*candidates->c) * candidates->n)))
return 1;
memset(candidates->c, 0, sizeof(*candidates->c) * candidates->n);
return 0;
}
void candidates_free(Candidates *candidates)
{
for (int i = 0; i < candidates->n; i++) {
candidate_free(candidates->c[i]);
free(candidates->c[i]);
}
free(candidates->c);
}
int candidates_print(Candidates *candidates, FILE *f)
{
for (int i = 0; i < candidates->n; i++) {
if (candidate_print(candidates->c[i], f))
return 1;
if (fprintf(f, "\n") < 0)
return 1;
} return 0;
}
int candidates_copyInsert(Candidates *candidates, Candidate *candidate)
{
Candidate *last = candidates->c[candidates->n - 1];
/* Exit early if no insertion will be made */
if (last && last->score > candidate->score)
return 0;
/* Determine where the candidate should be inserted */
int i;
for (i = 0; i < candidates->n; i++) {
Candidate *contender = candidates->c[i];
if (!contender || candidate->score > contender->score)
break;
/* Don't insert the same candidate twice */
if (candidate_equal(candidate, contender))
return 0;
}
/* Shift elements to make space for new candidate */
for (int j = candidates->n - 2; j >= i; j--)
candidates->c[j+1] = candidates->c[j];
free(last);
/* Insert new element */
Candidate *c;
if (!(c = (Candidate*)malloc(sizeof(*c))))
return 1;
candidate_copy(c, candidate);
candidates->c[i] = c;
return 0;
}
int candidate_init(Candidate *candidate)
{
memset(candidate, 0, sizeof(*candidate));
return 0;
}
void candidate_free(Candidate *candidate)
{
if (!candidate)
return;
freeKey(candidate->key);
free(candidate->key);
free(candidate->text);
}
int candidate_print(Candidate *candidate, FILE *f)
{
if (!candidate)
return 0;
char strText[alphabetStrlen(candidate->text) + 1];
alphabetToString(candidate->text, strText);
if (fprintf(f, "(%s) ", strText) < 0)
return 1;
if (candidate->cipher->k->serializeKey(candidate->key, stdout))
return 1;
return 0;
}
int candidate_copy(Candidate *candidate, Candidate *other)
{
candidate_init(candidate);
if (!(candidate->key = (Key*)malloc(sizeof(candidate->key))))
return 1;
copyKey(candidate->key, other->key);
int textLen = alphabetStrlen(other->text) + 1;
if (!(candidate->text = (Alphabet*)malloc(sizeof(other->text) * textLen)))
return 1;
memcpy(candidate->text, other->text, sizeof(other->text) * textLen);
candidate->cipher = other->cipher;
candidate->score = other->score;
return 0;
}
int candidate_equal(Candidate *candidate, Candidate *other)
{
if (candidate->score != other->score)
return 0;
if (candidate->cipher != other->cipher)
return 0;
if (!candidate->cipher->k->equalKey(candidate->key, other->key))
return 0;
return 1;
}