summaryrefslogtreecommitdiff
path: root/protocol/usb_hid/USB_Host_Shield_2.0/parsetools.h
blob: 66e9531c398b7067233fc112968b1fdfbe3ad38a (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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.

This software may be distributed and modified under the terms of the GNU
General Public License version 2 (GPL2) as published by the Free Software
Foundation and appearing in the file GPL2.TXT included in the packaging of
this file. Please note that GPL2 Section 2[b] requires that all works based
on this software must also be made publicly available under the terms of
the GPL2 ("Copyleft").

Contact information
-------------------

Circuits At Home, LTD
Web      :  http://www.circuitsathome.com
e-mail   :  support@circuitsathome.com
 */

#if !defined(_usb_h_) || defined(__PARSETOOLS_H__)
#error "Never include parsetools.h directly; include Usb.h instead"
#else
#define __PARSETOOLS_H__

struct MultiValueBuffer {
        uint8_t valueSize;
        void *pValue;
} __attribute__((packed));

class MultiByteValueParser {
        uint8_t * pBuf;
        uint8_t countDown;
        uint8_t valueSize;

public:

        MultiByteValueParser() : pBuf(NULL), countDown(0), valueSize(0) {
        };

        const uint8_t* GetBuffer() {
                return pBuf;
        };

        void Initialize(MultiValueBuffer * const pbuf) {
                pBuf = (uint8_t*)pbuf->pValue;
                countDown = valueSize = pbuf->valueSize;
        };

        bool Parse(uint8_t **pp, uint16_t *pcntdn);
};

class ByteSkipper {
        uint8_t *pBuf;
        uint8_t nStage;
        uint16_t countDown;

public:

        ByteSkipper() : pBuf(NULL), nStage(0), countDown(0) {
        };

        void Initialize(MultiValueBuffer *pbuf) {
                pBuf = (uint8_t*)pbuf->pValue;
                countDown = 0;
        };

        bool Skip(uint8_t **pp, uint16_t *pcntdn, uint16_t bytes_to_skip) {
                switch(nStage) {
                        case 0:
                                countDown = bytes_to_skip;
                                nStage++;
                        case 1:
                                for(; countDown && (*pcntdn); countDown--, (*pp)++, (*pcntdn)--);

                                if(!countDown)
                                        nStage = 0;
                };
                return (!countDown);
        };
};

// Pointer to a callback function triggered for each element of PTP array when used with PTPArrayParser
typedef void (*PTP_ARRAY_EL_FUNC)(const MultiValueBuffer * const p, uint32_t count, const void *me);

class PTPListParser {
public:

        enum ParseMode {
                modeArray, modeRange/*, modeEnum*/
        };

private:
        uint8_t nStage;
        uint8_t enStage;

        uint32_t arLen;
        uint32_t arLenCntdn;

        uint8_t lenSize; // size of the array length field in bytes
        uint8_t valSize; // size of the array element in bytes

        MultiValueBuffer *pBuf;

        // The only parser for both size and array element parsing
        MultiByteValueParser theParser;

        uint8_t /*ParseMode*/ prsMode;

public:

        PTPListParser() :
        nStage(0),
        enStage(0),
        arLen(0),
        arLenCntdn(0),
        lenSize(0),
        valSize(0),
        pBuf(NULL),
        prsMode(modeArray) {
        };

        void Initialize(const uint8_t len_size, const uint8_t val_size, MultiValueBuffer * const p, const uint8_t mode = modeArray) {
                pBuf = p;
                lenSize = len_size;
                valSize = val_size;
                prsMode = mode;

                if(prsMode == modeRange) {
                        arLenCntdn = arLen = 3;
                        nStage = 2;
                } else {
                        arLenCntdn = arLen = 0;
                        nStage = 0;
                }
                enStage = 0;
                theParser.Initialize(p);
        };

        bool Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me = NULL);
};

#endif // __PARSETOOLS_H__