1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
9 #ifndef anna_diameter_codec_basetypes_AvpData_hpp
10 #define anna_diameter_codec_basetypes_AvpData_hpp
13 #include <anna/core/RuntimeException.hpp>
14 #include <anna/core/DataBlock.hpp>
15 #include <anna/core/functions.hpp>
17 #include <anna/core/functions.hpp>
32 * Diameter avp abstract data container
34 * All diameter types inherit from this class. Basic types with one level, derived ones with two levels.
35 * Three or more inheritance levels have no sense. Each level has own private members and updateBasic()
36 * will be implemented at derived types to keep coherence towards parent ones. This coherence implies to
37 * call updateBasic when private members are updated.
40 * Basic diameter types are: OctetString, Integer32, Integer64, Unsigned32, Unsigned64, Float32, Float64
41 * Derived diameter types are: Address, Time, UTF8String, DiameterIdentity, DiameterURI, IPFilterRule, QoSFilterRule (derived from OctetString)
42 * Enumerated (derived from Integer32)
43 * Printable derived types are: UTF8String, DiameterIdentity, DiameterURI, IPFilterRule, QoSFilterRule
45 * User application could create new diameter types derived for any basic one, and reimplement the methods to adjust its behaviour.
49 * There are setters/getters at any level, and a lot of helpers to decode/interpret the stored data.
50 * Then, this class could be used as container and/or helper tool.
51 * Parent setters won't modify child members and vice versa, but helpers syncronizes both levels through parent 'code()' and child 'decode()' methods.
53 * Derived types with own members, must use protected or private inheritance, and export base class methods desired (using declaration).
54 * This mechanism guarantees private members coherence between different levels: a derived type instance couldn't directly manipulate base class own members.
59 * Encodes the avp data part over target buffer.
60 * THIS WILL BE IMPLEMENTED AT BASIC TYPES because works with parent members
62 * @param buffer Raw data to be encoded
63 * @param size Size of raw data to be encoded
65 virtual void codeBasic(char* buffer, int &size) throw(anna::RuntimeException) = 0;
68 * Updates parent members from child ones to keep coherence between levels.
69 * Neither of diameter basic types need to be checked and have no parents,
70 * then THIS WILL BE IMPLEMENTED AT DERIVED TYPES WITH NEW MEMBERS (not, i.e. at Enumerated)
71 * and will be called after child members modification (setters).
72 * Basic types implementation will be empty.
74 virtual void updateBasic() throw(anna::RuntimeException) {;}
77 * Sets own members from natural/smart string representation
78 * String argument is never provided NULL (internally checked)
80 * @param printableString avp data in natural/smart string representation (human-readable)
82 virtual void setPrintableString(const char * printableString) throw(anna::RuntimeException) = 0;
88 * Asserts printable nature for buffer provided and launch exception if not.
89 * Must be invoked from 'updateBasic() and decode()' at derived diameter types, when buffer should be printable
91 * @param buffer Raw avp data
92 * @param size Raw avp data length
94 * @return Printable string or <null> if not printable
96 std::string assertPrintable(const char* buffer, const int size) const throw(anna::RuntimeException) {
99 if(size == 0) return result;
102 result = anna::functions::asAsciiString(buffer, size, printable);
105 std::string ex = getFormatName();
106 ex += "::assertPrintable | Non-printable data provided";
107 throw anna::RuntimeException(ex, ANNA_FILE_LOCATION);
116 * Default constructor
124 * Gets the avp data format name
126 * @return avp data format name
128 virtual std::string getFormatName() const throw() = 0;
131 * Gets the avp data size based on basic container.
132 * The AVP Data field is zero or more octets.
134 * @return avp data size
136 virtual int getSize() const throw() = 0;
142 * Encodes avp data part over buffer externally allocated
144 * @param buffer Raw data to be encoded
145 * @param size Size of raw data to be encoded
147 void code(char* buffer, int &size) throw(anna::RuntimeException) {
148 codeBasic(buffer, size);
153 * Gets the natural/smart string representation for avp data (format-dependent content)
154 * Used in diameter message 'data' field
155 * Default implementation launch exception when data is not printable
157 * @return Natural/smart string representation for avp data
159 virtual std::string asPrintableString() throw(anna::RuntimeException) {
160 int size = getSize();
163 return (assertPrintable(buffer, size));
167 * Gets DataBlock binary block and ascii representation
169 * @return String with DataBlock representation
171 std::string asDataBlockString() throw(anna::RuntimeException) {
172 int size = getSize();
175 anna::DataBlock db(buffer, size);
176 return(db.asString());
180 * Class string representation
181 * Default implementation invokes raw DataBlock 'asString' method,
182 * but it should be different specially with complex application data types.
184 * @return String with class content
186 virtual std::string asString() throw(anna::RuntimeException) {
187 return(asDataBlockString());
191 * Gets the hexadecimal string representation for avp data
192 * Used in diameter message 'hex-data' field
194 * @return Hexadecimal string representation for avp data
196 std::string asHexString() throw(anna::RuntimeException) {
197 int size = getSize();
200 anna::DataBlock db(buffer, size);
201 return anna::functions::asHexString(db);
208 * Decodes provided buffer/size
210 * Derived types must invoke base class 'decode()' at the end in order to keep coherence with parent members.
211 * This base class decodification actually sets the base class members with the same buffer provided, being
212 * more comfortable than using base class setters.
214 * @param buffer Raw avp data
215 * @param size Raw avp data length
217 virtual void decode(const char* buffer, const int size) throw(anna::RuntimeException) = 0;
220 * Initializes members from natural/smart string representation
222 * @param printableString avp data in natural/smart string representation (human-readable)
224 void fromPrintableString(const char * printableString) throw(anna::RuntimeException) {
225 if(!printableString) {
226 std::string ex = getFormatName();
227 ex += "::fromPrintableString | Null printableString provided";
228 throw anna::RuntimeException(ex, ANNA_FILE_LOCATION);
231 /*std::string dummy =*/assertPrintable(printableString, strlen(printableString));
232 setPrintableString(printableString);
236 * Initializes members from hexadecimal string representation. I.e.: af1233fb01 (even number of digits).
238 * @param hexString Raw avp data in hexadecimal string representation
240 void fromHexString(const std::string& hexString) throw(anna::RuntimeException) {
241 anna::DataBlock db(true);
242 anna::functions::fromHexString(hexString, db);
243 decode(db.getData(), db.getSize());