summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-reader/Navigation.cpp
blob: 36e33b4190aad3e57887f85764a23fd22c2b5f09 (plain)
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
#ifdef _WINDOWS
#include <string.h>
#endif
#include "Navigation.h"
//#include <stdio.h>

/*
    void saveposn(size_t posn)
    save/push position to history buffer for future use of back() function
*/
void CNavigation::saveposn(size_t posn)
{
    //printf("saving position %u, depth %u\n",posn,historycurrent);
    history[historycurrent] = posn;
    historycurrent=(historycurrent+1)%NAVIGATION_HISTORY_SIZE;
    if (historycurrent==historystart)
        // circular buffer full, forget oldest record
        historystart=(historystart+1)%NAVIGATION_HISTORY_SIZE;
    // no forward possible after saveposn
    historyend = historycurrent;
}

/*
    void writeposn(size_t posn)
    overwrite current (unused) position
    useful for saving current position before using back button
*/
void CNavigation::writeposn(size_t posn)
{
    //printf("witing position %u, depth %u\n",posn,historycurrent);
    history[historycurrent] = posn;
}

/*
    bool back(size_t& posn)
    go back in history
    restore last position saved with saveposn() and return true
    return false if there is nothing saved in history
*/
bool CNavigation::back(size_t& posn)
{
    if (historycurrent!=historystart) {
        // buffer is not empty
        if (historycurrent==0)
            historycurrent=NAVIGATION_HISTORY_SIZE-1;
        else
            historycurrent--;
        posn=history[historycurrent];
        //printf("back(): going back to %u depth %u\n",posn,historycurrent);
        return true;

    } else {
        // circular buffer empty
        //printf("back(): empty history\n");
        return false;
    }
}

/*
    bool forward(size_t& posn)
    go forward in history, if possible
    undo calling of back()
*/
bool CNavigation::forward(size_t& posn)
{
    if (historycurrent!=historyend) {
        // [historycurrent] = current position
        // [historycurrent+1] = position we need
        historycurrent=(historycurrent+1)%NAVIGATION_HISTORY_SIZE;
        posn = history[historycurrent];
        //printf("forward(): going to position %d\n",posn);
        return true;
    } else {
        //printf("forward(): there is no future :)\n");
        return false;
    }
}

void CNavigation::setSaveData(unsigned char*& data, unsigned short& len, unsigned char* src, unsigned short srclen)
{
    len = srclen+sizeof(size_t)*(3+NAVIGATION_HISTORY_SIZE);
    data = new unsigned char[len];
    unsigned char* p = data;
    memcpy(p, src, srclen);
    p += srclen;
    memcpy(p, &historystart, sizeof(size_t));
    p += sizeof(size_t);
    memcpy(p, &historyend, sizeof(size_t));
    p += sizeof(size_t);
    memcpy(p, &historycurrent, sizeof(size_t));
    p += sizeof(size_t);
    memcpy(p, history, sizeof(size_t)*NAVIGATION_HISTORY_SIZE);
/*
    printf("<%u,%u,%u>\n", historystart, historyend, historycurrent);
    for (int i = historystart; i <= historyend; i++)
	printf("<%u> ", history[i]);
    printf("\n");
*/
}

void CNavigation::putSaveData(unsigned char*& src, unsigned short& srclen)
{
    if (srclen >= sizeof(size_t)*(3+NAVIGATION_HISTORY_SIZE))
    {
	unsigned char* p = src;
	memcpy(&historystart, p, sizeof(size_t));
	p += sizeof(size_t);
	memcpy(&historyend, p, sizeof(size_t));
	p += sizeof(size_t);
	memcpy(&historycurrent, p, sizeof(size_t));
	p += sizeof(size_t);
	memcpy(history, p, sizeof(size_t)*NAVIGATION_HISTORY_SIZE);
	src = p + sizeof(size_t)*NAVIGATION_HISTORY_SIZE;
	srclen -= sizeof(size_t)*(3+NAVIGATION_HISTORY_SIZE);
    }
/*
    printf("<%u,%u,%u>\n", historystart, historyend, historycurrent);
    for (int i = historystart; i <= historyend; i++)
	printf("<%u> ", history[i]);
    printf("\n");
*/
}