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 //------------------------------------------------------------------------------
10 //-------------------------------------------------------- included header files
11 //------------------------------------------------------------------------------
17 #include <anna/diameter/stack/AvpRule.hpp>
18 #include <anna/diameter/stack/Avp.hpp>
19 #include <anna/diameter/stack/Format.hpp>
20 #include <anna/diameter/functions.hpp>
21 #include <anna/diameter/stack/Dictionary.hpp>
23 #include <anna/config/defines.hpp>
24 #include <anna/core/RuntimeException.hpp>
25 #include <anna/xml/xml.hpp>
27 anna_assign_enum(anna::diameter::stack::AvpRule::Presence) = { "Fixed", "Mandatory", "Optional", NULL /* list end indicator */};
30 //------------------------------------------------------------------------------
31 //----------------------------------------------------------- AvpRule::setQual()
32 //------------------------------------------------------------------------------
33 void anna::diameter::stack::AvpRule::setQual(const std::string & q) throw(anna::RuntimeException) {
34 const char *asterisk = strstr(q.c_str(), "*");
36 if((q != "") && (asterisk == NULL))
37 throw anna::RuntimeException("Non-empty qualifier must contain '*'", ANNA_FILE_LOCATION);
43 //------------------------------------------------------------------------------
44 //-------------------------------------------------------- AvpRule::getAvpName()
45 //------------------------------------------------------------------------------
46 std::string anna::diameter::stack::AvpRule::getAvpName(void) const throw() {
47 const Avp * avp = a_dictionary->getAvp(a_avpId);
48 return avp->getName();
51 //------------------------------------------------------------------------------
52 //------------------------------------------------------------- AvpRule::isAny()
53 //------------------------------------------------------------------------------
54 bool anna::diameter::stack::AvpRule::isAny(void) const throw() {
55 const Avp * avp = a_dictionary->getAvp(a_avpId);
56 const Format * format = a_dictionary->getFormat(avp->getFormatName());
57 return format->isAny();
61 //------------------------------------------------------------------------------
62 //-------------------------------------------------------- AvpRule::getQualMin()
63 //------------------------------------------------------------------------------
64 int anna::diameter::stack::AvpRule::getQualMin(void) const throw() {
66 if(isFixed() || isMandatory()) return 1;
68 if(isOptional()) return 0;
72 const char * c_qual = a_qual.c_str();
73 int asterisk_pos = strstr(c_qual, "*") - c_qual;
76 if(asterisk_pos == 0) return 0;
79 std::string min = a_qual.substr(0, asterisk_pos); // 'x'
80 return (atoi(min.c_str()));
85 //------------------------------------------------------------------------------
86 //-------------------------------------------------------- AvpRule::getQualMax()
87 //------------------------------------------------------------------------------
88 int anna::diameter::stack::AvpRule::getQualMax(void) const throw() {
89 if(a_qual == "") return 1;
92 const char * c_qual = a_qual.c_str();
93 int asterisk_pos = strstr(c_qual, "*") - c_qual;
96 if(asterisk_pos == (a_qual.size() - 1)) return -1; // inf
99 std::string max = a_qual.substr(asterisk_pos + 1, a_qual.size() - asterisk_pos - 1); // 'y'
100 return (atoi(max.c_str()));
104 //------------------------------------------------------------------------------
105 //---------------------------------------------------------- AvpRule::asString()
106 //------------------------------------------------------------------------------
107 std::string anna::diameter::stack::AvpRule::asString(bool showPair) const throw() {
108 std::string trace = "No Avp rule defined";
109 const Avp * avp = a_dictionary->getAvp(a_avpId);
113 std::string s_open, s_close;
115 if(isFixed()) { s_open = "<"; s_close = ">"; }
117 if(isMandatory()) { s_open = "{"; s_close = "}"; }
119 if(isOptional()) { s_open = "["; s_close = "]"; }
122 trace += getAvpName(); // anna::diameter::functions::avpIdAsPairString(a_avpId);;
125 if(!showPair) return trace;
127 // Avoid ambiguous descriptions:
128 int qualSize = a_qual.size();
129 int tabSize = strlen(DICTIONARY_AVPRULE_TAB);
130 int NumberOfDots = /* qual add */ ((qualSize > tabSize) ? tabSize : qualSize) +
131 /* max expected avp description size */ 48 -
132 /* current trace length */ trace.size();
134 for(int k = 0; k < NumberOfDots; k++) trace += ".";
136 trace += anna::diameter::functions::avpIdAsPairString(avp->getId());
143 //------------------------------------------------------------------------------
144 //------------------------------------------------------------- AvpRule::asXML()
145 //------------------------------------------------------------------------------
146 anna::xml::Node* anna::diameter::stack::AvpRule::asXML(anna::xml::Node* parent) const throw() {
147 // <!ELEMENT avprule EMPTY>
148 // <!ATTLIST avprule id CDATA #REQUIRED type (Fixed | Mandatory | Optional) #REQUIRED qual CDATA #IMPLIED>
149 anna::xml::Node* result = parent->createChild("avprule");
150 result->createAttribute("id", getAvpName());
153 if(isFixed()) type = "Fixed";
154 else if(isMandatory()) type = "Mandatory";
155 else if(isOptional()) type = "Optional";
157 result->createAttribute("type", type);
159 if(a_qual != "") result->createAttribute("qual", a_qual);