1 // ANNA - Anna is Not 'N' Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // https://bitbucket.org/testillano/anna
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
37 #ifndef anna_diameter_codec_basetypes_AvpData_hpp
38 #define anna_diameter_codec_basetypes_AvpData_hpp
41 #include <anna/core/RuntimeException.hpp>
42 #include <anna/core/DataBlock.hpp>
43 #include <anna/core/functions.hpp>
45 #include <anna/core/functions.hpp>
60 * Diameter avp abstract data container
62 * All diameter types inherit from this class. Basic types with one level, derived ones with two levels.
63 * Three or more inheritance levels have no sense. Each level has own private members and updateBasic()
64 * will be implemented at derived types to keep coherence towards parent ones. This coherence implies to
65 * call updateBasic when private members are updated.
68 * Basic diameter types are: OctetString, Integer32, Integer64, Unsigned32, Unsigned64, Float32, Float64
69 * Derived diameter types are: Address, Time, UTF8String, DiameterIdentity, DiameterURI, IPFilterRule, QoSFilterRule (derived from OctetString)
70 * Enumerated (derived from Integer32)
71 * Printable derived types are: UTF8String, DiameterIdentity, DiameterURI, IPFilterRule, QoSFilterRule
73 * User application could create new diameter types derived for any basic one, and reimplement the methods to adjust its behaviour.
77 * There are setters/getters at any level, and a lot of helpers to decode/interpret the stored data.
78 * Then, this class could be used as container and/or helper tool.
79 * Parent setters won't modify child members and vice versa, but helpers syncronizes both levels through parent 'code()' and child 'decode()' methods.
81 * Derived types with own members, must use protected or private inheritance, and export base class methods desired (using declaration).
82 * This mechanism guarantees private members coherence between different levels: a derived type instance couldn't directly manipulate base class own members.
87 * Encodes the avp data part over target buffer.
88 * THIS WILL BE IMPLEMENTED AT BASIC TYPES because works with parent members
90 * @param buffer Raw data to be encoded
91 * @param size Size of raw data to be encoded
93 virtual void codeBasic(char* buffer, int &size) throw(anna::RuntimeException) = 0;
96 * Updates parent members from child ones to keep coherence between levels.
97 * Neither of diameter basic types need to be checked and have no parents,
98 * then THIS WILL BE IMPLEMENTED AT DERIVED TYPES WITH NEW MEMBERS (not, i.e. at Enumerated)
99 * and will be called after child members modification (setters).
100 * Basic types implementation will be empty.
102 virtual void updateBasic() throw(anna::RuntimeException) {;}
105 * Sets own members from natural/smart string representation
106 * String argument is never provided NULL (internally checked)
108 * @param printableString avp data in natural/smart string representation (human-readable)
110 virtual void setPrintableString(const char * printableString) throw(anna::RuntimeException) = 0;
116 * Asserts printable nature for buffer provided and launch exception if not.
117 * Must be invoked from 'updateBasic() and decode()' at derived diameter types, when buffer should be printable
119 * @param buffer Raw avp data
120 * @param size Raw avp data length
122 * @return Printable string or <null> if not printable
124 std::string assertPrintable(const char* buffer, const int size) const throw(anna::RuntimeException) {
127 if(size == 0) return result;
130 result = anna::functions::asAsciiString(buffer, size, printable);
133 std::string ex = getFormatName();
134 ex += "::assertPrintable | Non-printable data provided";
135 throw anna::RuntimeException(ex, ANNA_FILE_LOCATION);
144 * Default constructor
152 * Gets the avp data format name
154 * @return avp data format name
156 virtual std::string getFormatName() const throw() = 0;
159 * Gets the avp data size based on basic container.
160 * The AVP Data field is zero or more octets.
162 * @return avp data size
164 virtual int getSize() const throw() = 0;
170 * Encodes avp data part over buffer externally allocated
172 * @param buffer Raw data to be encoded
173 * @param size Size of raw data to be encoded
175 void code(char* buffer, int &size) throw(anna::RuntimeException) {
176 codeBasic(buffer, size);
181 * Gets the natural/smart string representation for avp data (format-dependent content)
182 * Used in diameter message 'data' field
183 * Default implementation launch exception when data is not printable
185 * @return Natural/smart string representation for avp data
187 virtual std::string asPrintableString() throw(anna::RuntimeException) {
188 int size = getSize();
191 return (assertPrintable(buffer, size));
195 * Gets DataBlock binary block and ascii representation
197 * @return String with DataBlock representation
199 std::string asDataBlockString() throw(anna::RuntimeException) {
200 int size = getSize();
203 anna::DataBlock db(buffer, size);
204 return(db.asString());
208 * Class string representation
209 * Default implementation invokes raw DataBlock 'asString' method,
210 * but it should be different specially with complex application data types.
212 * @return String with class content
214 virtual std::string asString() throw(anna::RuntimeException) {
215 return(asDataBlockString());
219 * Gets the hexadecimal string representation for avp data
220 * Used in diameter message 'hex-data' field
222 * @return Hexadecimal string representation for avp data
224 std::string asHexString() throw(anna::RuntimeException) {
225 int size = getSize();
228 anna::DataBlock db(buffer, size);
229 return anna::functions::asHexString(db);
236 * Decodes provided buffer/size
238 * Derived types must invoke base class 'decode()' at the end in order to keep coherence with parent members.
239 * This base class decodification actually sets the base class members with the same buffer provided, being
240 * more comfortable than using base class setters.
242 * @param buffer Raw avp data
243 * @param size Raw avp data length
245 virtual void decode(const char* buffer, const int size) throw(anna::RuntimeException) = 0;
248 * Initializes members from natural/smart string representation
250 * @param printableString avp data in natural/smart string representation (human-readable)
252 void fromPrintableString(const char * printableString) throw(anna::RuntimeException) {
253 if(!printableString) {
254 std::string ex = getFormatName();
255 ex += "::fromPrintableString | Null printableString provided";
256 throw anna::RuntimeException(ex, ANNA_FILE_LOCATION);
259 /*std::string dummy =*/assertPrintable(printableString, strlen(printableString));
260 setPrintableString(printableString);
264 * Initializes members from hexadecimal string representation. I.e.: af1233fb01 (even number of digits).
266 * @param hexString Raw avp data in hexadecimal string representation
268 void fromHexString(const std::string& hexString) throw(anna::RuntimeException) {
269 anna::DataBlock db(true);
270 anna::functions::fromHexString(hexString, db);
271 decode(db.getData(), db.getSize());