fsa_impl.hpp
2.74 KB
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
/*
* File: _simple_fsa_impl.hpp
* Author: mlenart
*
* Created on October 20, 2013, 12:25 PM
*/
#ifndef _SIMPLE_FSA_IMPL_HPP
#define _SIMPLE_FSA_IMPL_HPP
#include <cstring>
#include <algorithm>
#include <utility>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include "const.hpp"
#include "../utils.hpp"
#include "../endianness.hpp"
//using namespace std;
//static const unsigned int FSA_OFFSET = 6;
template <class T>
bool FSA<T>::tryToRecognize(const char* input, T& value) const {
State<T> currState = this->getInitialState();
int i = 0;
while (!currState.isSink() && input[i] != '\0') {
#ifdef DEBUG_BUILD
cerr << "proceed to next " << input[i] << endl;
#endif
currState.proceedToNext(input[i]);
i++;
}
// input[i] == '\0'
// currState.proceedToNext(0);
if (currState.isAccepting()) {
value = currState.getValue();
// DEBUG(string("recognized: ")+input);
return true;
} else {
return false;
}
}
template <class T>
FSA<T>::FSA(const unsigned char* initialStatePtr, const Deserializer<T>& deserializer)
: initialStatePtr(initialStatePtr), deserializer(deserializer) {
}
template <class T>
State<T> FSA<T>::getInitialState() const {
return State<T>(*this);
}
template <class T>
FSA<T>* FSA<T>::getFSA(const std::string& filename, const Deserializer<T>& deserializer) {
return getFSA(readFile<unsigned char>(filename.c_str()), deserializer);
}
template <class T>
FSA<T>* FSA<T>::getFSA(const unsigned char* ptr, const Deserializer<T>& deserializer) {
uint32_t magicNumber = ntohl(*((const uint32_t*) ptr));
if (magicNumber != MAGIC_NUMBER) {
throw FSAException("Invalid magic number");
}
uint8_t versionNum = *(ptr + VERSION_NUM_OFFSET);
if (versionNum != VERSION_NUM) {
std::ostringstream oss;
oss << "Invalid version number: " << versionNum << ", should be: " << VERSION_NUM;
throw FSAException(oss.str());
}
uint8_t implementationNum = *(ptr + IMPLEMENTATION_NUM_OFFSET);
// uint32_t additionalDataSize = ntohl(*(reinterpret_cast<const uint32_t*>(ptr + ADDITIONAL_DATA_SIZE_OFFSET)));
const unsigned char* startPtr = ptr + FSA_DATA_OFFSET;
switch (implementationNum) {
case 0:
return new SimpleFSA<T>(startPtr, deserializer);
case 1:
return new CompressedFSA1<T>(startPtr, deserializer);
case 2:
return new CompressedFSA2<T>(startPtr, deserializer);
default:
std::ostringstream oss;
oss << "Invalid implementation number: " << versionNum << ", should be: " << VERSION_NUM;
throw FSAException(oss.str());
}
}
#endif /* _SIMPLE_FSA_IMPL_HPP */