Packets/80221Bundle: more GenericTLVBase integration; removed GenericTLVPacket; some...
[senf.git] / senf / Packets / 80221Bundle / TLVParser.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Thorsten Horstmann <tho@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief TLVParser public header */
25
26 #ifndef HH_SENF_Packets_80221Bundle_TLVParser_
27 #define HH_SENF_Packets_80221Bundle_TLVParser_ 1
28
29 // Custom includes
30 #include <algorithm>
31 #include <senf/Packets/Packets.hh>
32 #include "MIHTypes.hh"
33
34 //#include "TLVParser.mpp"
35 ///////////////////////////////hh.p////////////////////////////////////////
36
37 namespace senf {
38
39     struct MIHTLVLengthException : public senf::Exception
40     { 
41         MIHTLVLengthException() 
42           : senf::Exception("MIHTLVLengthException") {} 
43     };
44
45     
46     class MIHTLVLengthParser 
47         : public detail::packet::IntParserOps<MIHTLVLengthParser, boost::uint32_t>,
48           public PacketParserBase
49     {
50     public:
51         MIHTLVLengthParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
52
53         typedef boost::uint32_t value_type;
54         static const size_type init_bytes = 1;
55         static value_type const min_value = 0;
56         static value_type const max_value = 4294967295u;
57
58         value_type value() const;
59         void value(value_type const & v);
60         
61         MIHTLVLengthParser const & operator= (value_type other);
62         size_type bytes() const;
63         void init() const;
64
65 #       include SENF_PARSER()
66         SENF_PARSER_PRIVATE_FIELD ( length_field, UInt8Parser );
67         SENF_PARSER_GOTO( length_field );
68         SENF_PARSER_PRIVATE_BITFIELD ( extended_length_flag, 1,  bool     );
69         SENF_PARSER_PRIVATE_BITFIELD ( underflow_flag,       1,  bool     );
70         SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field,   6,  unsigned );
71
72         void finalize();
73         void maxValue(value_type v);
74         value_type maxValue() const;
75         
76     private:
77         void resize_(size_type size);
78     };  
79         
80
81     /** \brief Base class for MIH TLV parsers
82      
83          MIHBaseTLVParser is the abstract base class for MIH TLV parsers. It defines the
84          \ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a 
85          MIHTLVLengthParser. The length field is read-only. 
86          
87          To create your own \c TLVParser you have to inherit from MIHBaseTLVParser (don't 
88          forget \ref SENF_PARSER_INHERIT) and define the \c value field. In the following example 
89          the value is a vector of MacAddresses: 
90          \code
91          struct MacAddressesTLVParser : public MIHBaseTLVParser {
92          #   include SENF_PARSER()        
93              SENF_PARSER_INHERIT ( MIHBaseTLVParser );
94              SENF_PARSER_VECTOR  ( value, bytes(length), senf::MACAddressParser );
95              SENF_PARSER_FINALIZE( MacAddressesTLVParser );
96          };
97          \endcode
98          
99          You have to adjust the maximum length value with the \ref maxLengthValue function 
100          before the length value is set. The default maximum value is 127. So, in the above
101          example adding more than 21 MACAddresses to the vector will throw a TLVLengthException
102          if you don't call \c macAddressesTLVPacket->maxLengthValue( \e some_value) before.
103          
104          \see MIHTLVLengthParser \n
105            MIHGenericTLVParser \n
106      */
107     class MIHBaseTLVParser : public PacketParserBase
108     {
109     public:
110 #       include SENF_PARSER()
111         SENF_PARSER_FIELD    ( type,   UInt8Parser        );
112         SENF_PARSER_FIELD_RO ( length, MIHTLVLengthParser );
113         SENF_PARSER_FINALIZE ( MIHBaseTLVParser           );
114         
115         /** \brief set maximum value of length field
116     
117             The size of the length field will be increased if necessary.
118             \param v maximum value of length field
119          */
120         void maxLengthValue(MIHTLVLengthParser::value_type v) const {
121             protect(), length_().maxValue(v);
122         }
123         
124         /** \brief shrink size of length field to minimum
125     
126             The size of the length field will be decreased to minimum necessary to hold
127             the current length value.
128          */
129         void finalizeLength() { 
130             protect(), length_().finalize(); 
131         };
132         
133     protected:
134         /// resize the packet after the length field to given size
135         senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size);
136     };
137
138         
139     /** \brief Parser for a generic TLV packet
140      */
141     struct MIHGenericTLVParser
142         : public GenericTLVParserBase<MIHBaseTLVParser>
143     {
144         typedef senf::GenericTLVParserBase<MIHBaseTLVParser> base;
145         MIHGenericTLVParser(data_iterator i, state_type s) : base(i,s) {}
146
147         void init() const {
148             defaultInit();
149             maxLengthValue( MIHTLVLengthParser::max_value);
150         }
151         
152         using base::init;
153     };
154         
155     /** \brief Parse a MIHF_ID
156
157          the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
158          we could set maxLengthValue in init(), but for the most MIHF_IDs the default
159          maximum length of 127 should be enough.
160          
161          \note you must call mihfIdPacket.maxLengthValue( 253) *before*
162          setting longer MIHF_IDs values.
163     */
164     class MIHFId_TLVParser : public MIHBaseTLVParser
165     {
166     #   include SENF_PARSER()
167         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
168         SENF_PARSER_SKIP     ( length(), 0      );
169         SENF_PARSER_FINALIZE ( MIHFId_TLVParser );
170         
171     public:
172         std::string asString() const;
173         void setString(std::string const &id);
174
175         senf::MACAddress asMACAddress() const;
176         void setMACAddress(senf::MACAddress const &mac);
177
178         senf::INet4Address asINet4Address() const;
179         void setINet4Address(senf::INet4Address const &addr);
180
181         senf::INet6Address asINet6Address() const;
182         void setINet6Address(senf::INet6Address const &addr);
183         
184         senf::EUI64 asEUI64() const;
185         void setEUI64(senf::EUI64 const &addr);
186
187         MIHFId valueAs(MIHFId::Type type) const;
188         
189     private:
190         template <class OutputIterator>
191         struct binaryNAIEncoder {
192             binaryNAIEncoder(OutputIterator &i) : i_(i) {}
193             void operator()(const boost::uint8_t &v) const {
194                 *i_++ = '\\';
195                 *i_++ = v;
196             }
197             OutputIterator &i_;
198         };
199         template <class OutputIterator>
200         static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> > getNAIEncodedOutputIterator(OutputIterator i) {
201             return boost::make_function_output_iterator(binaryNAIEncoder<OutputIterator>(i));
202         }
203
204         struct binaryNAIDecoder {
205             binaryNAIDecoder() : readNextByte_(true) {}
206             bool operator()(const boost::uint8_t &v) {
207                 readNextByte_ = readNextByte_ ? false : true;
208                 return readNextByte_;
209             }
210             bool readNextByte_;
211         };
212         template <class Iterator>
213         static boost::filter_iterator<binaryNAIDecoder, Iterator> getNAIDecodedIterator(Iterator begin, Iterator end) {
214             return boost::make_filter_iterator<binaryNAIDecoder>(begin, end);
215         }
216     };
217
218
219 }
220
221
222 ///////////////////////////////hh.e////////////////////////////////////////
223 #include "TLVParser.cci"
224 //#include "TLVParser.ct"
225 //#include "TLVParser.cti"
226 #endif
227
228 \f
229 // Local Variables:
230 // mode: c++
231 // fill-column: 100
232 // c-file-style: "senf"
233 // indent-tabs-mode: nil
234 // ispell-local-dictionary: "american"
235 // compile-command: "scons -u test"
236 // comment-column: 40
237 // End: