Blame view

morfeusz/fsa/simplefsa_impl.hpp 2.56 KB
Michał Lenart authored
1
2
3
4
5
6
7
8
9
10
/* 
 * File:   simplefsa_impl.hpp
 * Author: mlenart
 *
 * Created on November 4, 2013, 1:05 PM
 */

#ifndef SIMPLEFSA_IMPL_HPP
#define	SIMPLEFSA_IMPL_HPP
Michał Lenart authored
11
12
#include <iostream>
Michał Lenart authored
13
14
#include "fsa.hpp"
Michał Lenart authored
15
//#pragma pack(push, 1)  /* push current alignment to stack */
Michał Lenart authored
16
17

struct StateData {
Michał Lenart authored
18
19
    unsigned char transitionsNum;
    bool accepting;
Michał Lenart authored
20
21
};
Michał Lenart authored
22
//#pragma pack(pop)   /* restore original alignment from stack */
Michał Lenart authored
23
24

template <class T>
Michał Lenart authored
25
26
SimpleFSA<T>::SimpleFSA(const unsigned char* ptr, const Deserializer<T>& deserializer, bool isTransducer)
: FSA<T>(ptr, deserializer), isTransducer(isTransducer) {
Michał Lenart authored
27
28
29
30
31
32
33
}

template <class T>
SimpleFSA<T>::~SimpleFSA() {

}
Michał Lenart authored
34
static inline unsigned int decodeOffset(const unsigned char* ptr) {
Michał Lenart authored
35
36
37
38
39
    unsigned int res = 0;
    res = ptr[0] << 16 | ptr[1] << 8 | ptr[2];
    return res;
}
Michał Lenart authored
40
41
42
43
44
45
46
47
48
static inline StateData decodeStateData(const unsigned char* ptr) {
    static const unsigned char acceptingFlag = 128;
    static const unsigned char transitionsNumMask = 127;
    StateData res;
    res.transitionsNum = (*ptr) & transitionsNumMask;
    res.accepting = (*ptr) & acceptingFlag;
    return res;
}
Michał Lenart authored
49
50
51
template <class T>
void SimpleFSA<T>::proceedToNext(const char c, State<T>& state) const {
    const unsigned char* fromPointer = this->initialStatePtr + state.getOffset();
Michał Lenart authored
52
    long transitionsTableOffset = 1;
Michał Lenart authored
53
54
55
    if (state.isAccepting()) {
        transitionsTableOffset += state.getValueSize();
    }
Michał Lenart authored
56
    StateData stateData = decodeStateData(fromPointer);
Michał Lenart authored
57
58
    const unsigned char* foundTransition = fromPointer + transitionsTableOffset;
    bool found = false;
Michał Lenart authored
59
60
    unsigned int increment = this->isTransducer ? 5 : 4;
    for (unsigned int i = 0; i < stateData.transitionsNum; i++, foundTransition += increment) {
Michał Lenart authored
61
62
63
64
65
66
67
68
        if ((char) *foundTransition == c) {
            found = true;
            break;
        }
    }
    //    const_cast<Counter*>(&counter)->increment(foundTransition - transitionsStart + 1);
    if (!found) {
        state.setNextAsSink();
Michał Lenart authored
69
70
    }
    else {
Michał Lenart authored
71
72
        unsigned int offset = decodeOffset(foundTransition + 1);
        const unsigned char* nextStatePointer = this->initialStatePtr + offset;
Michał Lenart authored
73
74
        StateData nextStateData = decodeStateData(nextStatePointer);
        if (nextStateData.accepting) {
Michał Lenart authored
75
            T object;
Michał Lenart authored
76
            long size = this->deserializer.deserialize(nextStatePointer + 1, object);
Michał Lenart authored
77
            state.setNext(offset, object, size);
Michał Lenart authored
78
79
        }
        else {
Michał Lenart authored
80
81
            state.setNext(offset);
        }
Michał Lenart authored
82
83
84
        if (isTransducer) {
            state.setLastTransitionValue(*(foundTransition + 4));
        }
Michał Lenart authored
85
86
87
88
89
    }
}

#endif	/* SIMPLEFSA_IMPL_HPP */