Remove dynamic exceptions
[anna.git] / include / anna / diameter / codec / basetypes / AvpData.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
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 //
7
8
9 #ifndef anna_diameter_codec_basetypes_AvpData_hpp
10 #define anna_diameter_codec_basetypes_AvpData_hpp
11
12
13 #include <anna/core/RuntimeException.hpp>
14 #include <anna/core/DataBlock.hpp>
15 #include <anna/core/functions.hpp>
16
17 #include <anna/core/functions.hpp>
18
19 // STL
20 #include <string>
21
22
23 namespace anna {
24
25 namespace diameter {
26
27 namespace codec {
28
29 namespace basetypes {
30
31 /**
32 * Diameter avp abstract data container
33 *
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.
38 *
39 *<pre>
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
44 *
45 * User application could create new diameter types derived for any basic one, and reimplement the methods to adjust its behaviour.
46 *
47 *</pre>
48 *
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.
52 *
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.
55 */
56 class AvpData {
57
58   /**
59   * Encodes the avp data part over target buffer.
60   * THIS WILL BE IMPLEMENTED AT BASIC TYPES because works with parent members
61   *
62   * @param buffer Raw data to be encoded
63   * @param size Size of raw data to be encoded
64   */
65   virtual void codeBasic(char* buffer, int &size) noexcept(false) = 0;
66
67   /**
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.
73   */
74   virtual void updateBasic() noexcept(false) {;}
75
76   /**
77   * Sets own members from natural/smart string representation
78   * String argument is never provided NULL (internally checked)
79   *
80   * @param printableString avp data in natural/smart string representation (human-readable)
81   */
82   virtual void setPrintableString(const char * printableString) noexcept(false) = 0;
83
84
85 protected:
86
87   /**
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
90   *
91   * @param buffer Raw avp data
92   * @param size Raw avp data length
93   *
94   * @return Printable string or <null> if not printable
95   */
96   std::string assertPrintable(const char* buffer, const int size) const noexcept(false) {
97     std::string result;
98
99     if(size == 0) return result;
100
101     bool printable;
102     result = anna::functions::asAsciiString(buffer, size, printable);
103
104     if(!printable) {
105       std::string ex = getFormatName();
106       ex += "::assertPrintable | Non-printable data provided";
107       throw anna::RuntimeException(ex, ANNA_FILE_LOCATION);
108     }
109
110     return result;
111   }
112
113 public:
114
115   /**
116   * Default constructor
117   */
118   AvpData() {};
119
120
121   // gets
122
123   /**
124   * Gets the avp data format name
125   *
126   * @return avp data format name
127   */
128   virtual std::string getFormatName() const  = 0;
129
130   /**
131   * Gets the avp data size based on basic container.
132   * The AVP Data field is zero or more octets.
133   *
134   * @return avp data size
135   */
136   virtual int getSize() const  = 0;
137
138
139   // helpers
140
141   /**
142   * Encodes avp data part over buffer externally allocated
143   *
144   * @param buffer Raw data to be encoded
145   * @param size Size of raw data to be encoded
146   */
147   void code(char* buffer, int &size) noexcept(false) {
148     codeBasic(buffer, size);
149   }
150
151
152   /**
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
156   *
157   * @return Natural/smart string representation for avp data
158   */
159   virtual std::string asPrintableString() noexcept(false) {
160     int size = getSize();
161     char buffer[size];
162     code(buffer, size);
163     return (assertPrintable(buffer, size));
164   }
165
166   /**
167   * Gets DataBlock binary block and ascii representation
168   *
169   * @return String with DataBlock representation
170   */
171   std::string asDataBlockString() noexcept(false) {
172     int size = getSize();
173     char buffer[size];
174     code(buffer, size);
175     anna::DataBlock db(buffer, size);
176     return(db.asString());
177   }
178
179   /**
180   * Class string representation
181   * Default implementation invokes raw DataBlock 'asString' method,
182   * but it should be different specially with complex application data types.
183   *
184   * @return String with class content
185   */
186   virtual std::string asString() noexcept(false) {
187     return(asDataBlockString());
188   }
189
190   /**
191   * Gets the hexadecimal string representation for avp data
192   * Used in diameter message 'hex-data' field
193   *
194   * @return Hexadecimal string representation for avp data
195   */
196   std::string asHexString() noexcept(false) {
197     int size = getSize();
198     char buffer[size];
199     code(buffer, size);
200     anna::DataBlock db(buffer, size);
201     return anna::functions::asHexString(db);
202   }
203
204
205   // sets
206
207   /**
208   * Decodes provided buffer/size
209   *
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.
213   *
214   * @param buffer Raw avp data
215   * @param size Raw avp data length
216   */
217   virtual void decode(const char* buffer, const int size) noexcept(false) = 0;
218
219   /**
220   * Initializes members from natural/smart string representation
221   *
222   * @param printableString avp data in natural/smart string representation (human-readable)
223   */
224   void fromPrintableString(const char * printableString) noexcept(false) {
225     if(!printableString) {
226       std::string ex = getFormatName();
227       ex += "::fromPrintableString | Null printableString provided";
228       throw anna::RuntimeException(ex, ANNA_FILE_LOCATION);
229     }
230
231     /*std::string dummy =*/assertPrintable(printableString, strlen(printableString));
232     setPrintableString(printableString);
233   }
234
235   /**
236   * Initializes members from hexadecimal string representation. I.e.: af1233fb01 (even number of digits).
237   *
238   * @param hexString Raw avp data in hexadecimal string representation
239   */
240   void fromHexString(const std::string& hexString) noexcept(false) {
241     anna::DataBlock db(true);
242     anna::functions::fromHexString(hexString, db);
243     decode(db.getData(), db.getSize());
244   }
245 };
246
247 }
248 }
249 }
250 }
251
252
253 #endif