-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.c
149 lines (122 loc) · 4.13 KB
/
index.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include "index.h"
uint8_t getMinDataBits(FILE* wordlist)
{
uint64_t wordlistSize = getFileSize(wordlist);
return MIN_DATA_BITS + (uint8_t) ceil(log2((double) wordlistSize));
}
int isDataSizeValid(FILE* wordlist, uint8_t bits)
{
return (bits >= getMinDataBits(wordlist)) && (bits <= MAX_DATA_BITS);
}
uint8_t getIndexEntrySize(IndexHeader* header)
{
return INDEX_HASH_SIZE + header->dataBytes;
}
int64_t getIndexesCount(IndexHeader* header)
{
uint8_t indexSize = getIndexEntrySize(header);
uint64_t indexesSize = header->wordlistOffset;
// Malformed index
if(indexesSize % indexSize)
{
return 0;
}
return (int64_t) (indexesSize / indexSize);
}
uint64_t getPointerFromData(uint8_t* data, uint8_t dataBytes)
{
uint64_t pointer;
if (dataBytes > 8)
{
pointer = *(uint64_t *) data;
}
else if (dataBytes == 8)
{
pointer = (*((uint64_t *) data));
((uint8_t*) &pointer)[dataBytes - 1] >>= TAG_BITS; // TODO: Check me
}
else
{
memcpy(&pointer, data, dataBytes);
((uint8_t*) &pointer)[dataBytes - 1] >>= TAG_BITS; // TODO: Check me
}
return pointer;
}
int readIndexHeader(FILE* in, IndexHeader* header)
{
fread(header, sizeof(IndexHeader), 1, in);
if(header->magic != INDEX_MAGIC)
{
return 1;
}
return getIndexesCount(header) == 0;
}
int writeIndexHeader(FILE* out, char* hashName, uint8_t dataBytes, uint64_t wordlistOffset)
{
uint32_t magic = INDEX_MAGIC;
uint8_t hashNameLength = strlen(hashName);
uint8_t hashNameBuf[MAX_HASH_NAME_SIZE] = {0};
if(hashNameLength > MAX_HASH_NAME_SIZE)
{
return 1;
}
memcpy(hashNameBuf, hashName, hashNameLength);
fwrite(&magic, sizeof(uint32_t), 1, out);
fwrite(hashNameBuf, sizeof(uint8_t), MAX_HASH_NAME_SIZE, out);
fwrite(&dataBytes, sizeof(uint8_t), 1, out);
fwrite(&wordlistOffset, sizeof(uint64_t), 1, out);
}
void writeIndexEntryInline(const uint8_t* hash, const uint8_t* data, size_t compressedDataBits, size_t dataBytes, WordType wordType, FILE* output)
{
size_t compressedDataBytes = BYTES_SIZE(compressedDataBits);
size_t paddingBytes = dataBytes - compressedDataBytes;
uint8_t lastByte = (wordType << 1) | 1;
uint64_t padding = 0L;
fwrite(hash, sizeof(uint8_t), INDEX_HASH_SIZE, output);
if(paddingBytes > 1)
{
fwrite(data, sizeof(uint8_t), compressedDataBytes, output);
fwrite((uint8_t*) &padding, sizeof(uint8_t), paddingBytes - 1, output);
fwrite(&lastByte, sizeof(uint8_t), 1, output);
}
else if(paddingBytes == 1)
{
fwrite(data, sizeof(uint8_t), compressedDataBytes, output);
fwrite(&lastByte, sizeof(uint8_t), 1, output);
}
else
{
// In this case the last data byte must have at least 3 bits set to 0
lastByte |= data[dataBytes - 1];
fwrite(data, sizeof(uint8_t), compressedDataBytes - 1, output);
fwrite(&lastByte, sizeof(uint8_t), 1, output);
}
}
void writeIndexEntryPointer(const uint8_t* hash, uint64_t wordPointer, size_t dataBytes, WordType wordType, FILE* output)
{
uint8_t i, lastByte = wordType << 1;
size_t compressedDataBytes, paddingBytes;
uint64_t padding = 0L;
for(i=0 ; (wordPointer >> i) != 0 ; i++);
compressedDataBytes = BYTES_SIZE(i);
paddingBytes = dataBytes - compressedDataBytes;
fwrite(hash, sizeof(uint8_t), INDEX_HASH_SIZE, output);
if(paddingBytes > 1)
{
fwrite(&wordPointer, sizeof(uint8_t), compressedDataBytes, output);
fwrite((uint8_t*) &padding, sizeof(uint8_t), paddingBytes - 1, output);
fwrite(&lastByte, sizeof(uint8_t), 1, output);
}
else if(paddingBytes == 1)
{
fwrite(&wordPointer, sizeof(uint8_t), compressedDataBytes, output);
fwrite(&lastByte, sizeof(uint8_t), 1, output);
}
else
{
// In this case the last data byte must have at least 3 bits set to 0
lastByte |= (wordPointer >> ((compressedDataBytes - 1) << 3));
fwrite(&wordPointer, sizeof(uint8_t), compressedDataBytes - 1, output);
fwrite(&lastByte, sizeof(uint8_t), 1, output);
}
}