1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
10 #include "../Value.hh"
15 // =================================
17 // =================================
19 Tag::Tag(tagplicit_t p_plicit
, tagclass_t p_tagclass
, Value
*p_tagvalue
)
21 plicit(p_plicit
), tagclass(p_tagclass
), tagvalue(p_tagvalue
),
25 FATAL_ERROR("NULL parameter: Asn::Tag::Tag()");
28 Tag::Tag(tagplicit_t p_plicit
, tagclass_t p_tagclass
, Int p_tagval
)
30 plicit(p_plicit
), tagclass(p_tagclass
), tagvalue(0),
31 tagval(p_tagval
), is_auto(false)
33 if(tagval
<0) FATAL_ERROR("Asn::Tag::Tag(): negative value");
36 Tag::Tag(const Tag
& p
)
37 : Node(p
), Location(p
),
38 plicit(p
.plicit
), tagclass(p
.tagclass
),
41 if (p
.tagvalue
) tagvalue
= p
.tagvalue
->clone();
53 Tag
& Tag::operator=(const Tag
& p
)
58 tagclass
= p
.tagclass
;
59 if (p
.tagvalue
) tagvalue
= p
.tagvalue
->clone();
69 bool Tag::operator==(const Tag
& p
) const
71 if (tagvalue
|| p
.tagvalue
) FATAL_ERROR("Comparison of unchecked tags.");
72 return tagclass
== p
.tagclass
&& tagval
== p
.tagval
;
75 bool Tag::operator<(const Tag
& p
) const
77 if (tagvalue
|| p
.tagvalue
) FATAL_ERROR("Comparison of unchecked tags.");
78 if (tagclass
< p
.tagclass
) return true;
79 else if (tagclass
> p
.tagclass
) return false;
80 else return tagval
< p
.tagval
;
83 const char *Tag::get_tagclass_str() const
87 return "ASN_TAG_UNIV";
89 return "ASN_TAG_APPL";
91 return "ASN_TAG_CONT";
93 return "ASN_TAG_PRIV";
95 FATAL_ERROR("Tag::get_tagclass_str()");
100 Int
Tag::get_tagvalue()
106 void Tag::set_tagvalue(const Int
& p_tagval
)
108 if(tagvalue
) {delete tagvalue
; tagvalue
=0;}
112 void Tag::set_my_scope(Scope
*p_scope
)
114 if (tagvalue
) tagvalue
->set_my_scope(p_scope
);
119 if (!tagvalue
) return;
120 Error_Context
cntxt(this, "In tag");
121 Value
*v
= tagvalue
->get_value_refd_last();
122 switch (v
->get_valuetype()) {
124 const int_val_t
*tagval_int
= tagvalue
->get_val_Int();
125 if (*tagval_int
< 0 || *tagval_int
> INT_MAX
) {
126 error("Integer value in range 0..%d was expected instead of `%s' "
127 "for tag value", INT_MAX
, (tagval_int
->t_str()).c_str());
130 tagval
= tagval_int
->get_val();
136 error("INTEGER value was expected for tag value");
148 void Tag::dump(unsigned level
) const
153 s
+="<ERROR> "; break;
159 s
+="UNIVERSAL "; break;
160 case TAG_APPLICATION
:
161 s
+="APPLICATION "; break;
165 s
+="PRIVATE "; break;
167 s
+=" <UNKNOWN CLASS>"; break;
169 if(!tagvalue
) s
+=Int2string(tagval
);
176 s
+=" EXPLICIT"; break;
178 s
+=" IMPLICIT"; break;
180 s
+=" <UNKNOWN PLICIT>"; break;
182 if(is_auto
) s
+=" (auto)";
183 DEBUG(level
, "Tag: %s", s
.c_str());
184 if(tagvalue
) tagvalue
->dump(level
+1);
187 // =================================
189 // =================================
191 Tags::Tags() : Node()
193 set_fullname(string("<tags>"));
197 Tags::Tags(const Tags
& p
) : Node(p
)
199 for(size_t i
=0; i
<p
.tags
.size(); i
++)
200 add_tag(p
.tags
[i
]->clone());
206 for(size_t i
=0; i
<tags
.size(); i
++) delete tags
[i
];
210 void Tags::set_fullname(const string
& p_fullname
)
212 Node::set_fullname(p_fullname
);
213 for(size_t i
=0; i
<tags
.size(); i
++)
214 tags
[i
]->set_fullname(get_fullname()+"."+Int2string(i
));
217 void Tags::set_my_scope(Scope
*p_scope
)
220 for(size_t i
=0; i
<tags
.size(); i
++)
221 tags
[i
]->set_my_scope(p_scope
);
224 void Tags::add_tag(Tag
*p_tag
)
227 FATAL_ERROR("NULL parameter: Asn::Tags::add_tag()");
229 p_tag
->set_fullname(get_fullname()+"."+Int2string(tags
.size()));
230 p_tag
->set_my_scope(my_scope
);
235 for(size_t i
=0; i
<tags
.size(); i
++)
239 void Tags::set_plicit(Type
*p_type
)
241 if (!p_type
) FATAL_ERROR("NULL parameter: Asn::Tags::set_plicit()");
242 Asn::Module
*m
= dynamic_cast<Asn::Module
*>
243 (p_type
->get_my_scope()->get_scope_mod());
244 if (!m
) FATAL_ERROR("Asn::Tags::set_plicit()");
245 bool type_needs_explicit
= p_type
->needs_explicit_tag();
246 bool module_uses_explicit
= (m
->get_tagdef() == TagDefault::EXPLICIT
);
247 Tag
*innermost
= tags
[0];
248 switch (innermost
->get_plicit()) {
249 case Tag::TAG_DEFPLICIT
:
250 if (module_uses_explicit
|| type_needs_explicit
)
251 innermost
->set_plicit(Tag::TAG_EXPLICIT
);
252 else innermost
->set_plicit(Tag::TAG_IMPLICIT
);
254 case Tag::TAG_IMPLICIT
:
255 if (type_needs_explicit
) {
256 p_type
->error("Type cannot have IMPLICIT tag");
257 innermost
->set_plicit(Tag::TAG_EXPLICIT
);
262 for (size_t i
= 1; i
< tags
.size(); i
++) {
264 if (tag
->get_plicit() == Tag::TAG_DEFPLICIT
) {
265 if (module_uses_explicit
) tag
->set_plicit(Tag::TAG_EXPLICIT
);
266 else tag
->set_plicit(Tag::TAG_IMPLICIT
);
271 void Tags::cut_auto_tags()
274 while (i
< tags
.size()) {
276 if (tag
->is_automatic()) {
278 tags
.replace(i
, 1, NULL
);
283 void Tags::dump(unsigned level
) const
285 for(size_t i
=0; i
<tags
.size(); i
++)
286 tags
[i
]->dump(level
);
289 // =================================
290 // ===== TagCollection
291 // =================================
293 TagCollection::TagCollection()
294 : has_all(NULL
), is_extensible(false)
298 TagCollection::TagCollection(const TagCollection
& p
)
299 : Node(p
), Location(p
),
300 has_all(p
.has_all
), is_extensible(p
.is_extensible
)
302 for (size_t i
= 0; i
< p
.tag_map
.size(); i
++)
303 tag_map
.add(p
.tag_map
.get_nth_key(i
), 0);
306 TagCollection::~TagCollection()
311 void TagCollection::addTag(const Tag
*p_tag
)
314 FATAL_ERROR("Asn::TagCollection::addTag()");
315 if (p_tag
->get_tagclass() == Tag::TAG_ALL
) {
317 FATAL_ERROR("Asn::TagCollection::addTag(): tag 'all'");
320 else if(p_tag
->get_tagclass() == Tag::TAG_ERROR
)
322 else if(!tag_map
.has_key(*p_tag
))
323 tag_map
.add(*p_tag
, 0);
325 FATAL_ERROR("Asn::TagCollection::addTag(): tag is already in collection");
328 bool TagCollection::hasTag(const Tag
*p_tag
) const
330 if (!p_tag
) FATAL_ERROR("NULL parameter: Asn::TagCollection::hasTag()");
331 if (has_all
) return true;
332 else if (p_tag
->get_tagclass() == Tag::TAG_ALL
) return !tag_map
.empty();
333 else if (p_tag
->get_tagclass() == Tag::TAG_ERROR
) return false;
334 else return tag_map
.has_key(*p_tag
);
337 void TagCollection::addTags(const TagCollection
*p_tags
)
339 if (!p_tags
) FATAL_ERROR("NULL parameter: Asn::TagCollection::addTags()");
340 if (p_tags
->is_extensible
) setExtensible();
341 if (p_tags
->has_all
) {
342 if (has_all
) FATAL_ERROR("Asn::TagCollection::addTags(): tag 'all'");
343 has_all
= p_tags
->has_all
;
345 for (size_t i
= 0; i
< p_tags
->tag_map
.size(); i
++) {
346 const Tag
& tag
= p_tags
->tag_map
.get_nth_key(i
);
347 if (!tag_map
.has_key(tag
)) tag_map
.add(tag
, 0);
348 else FATAL_ERROR("Asn::TagCollection::addTags(): tag is already in collection");
352 bool TagCollection::hasTags(const TagCollection
*p_tags
) const
354 if (!p_tags
) FATAL_ERROR("NULL parameter: Asn::TagCollection::hasTags()");
355 if (has_all
) return !p_tags
->isEmpty();
356 else if (p_tags
->has_all
) return !isEmpty();
357 for (size_t i
= 0; i
< p_tags
->tag_map
.size(); i
++)
358 if (tag_map
.has_key(p_tags
->tag_map
.get_nth_key(i
))) return true;
362 bool TagCollection::greaterTags(const TagCollection
*p_tags
) const
365 FATAL_ERROR("NULL parameter: Asn::TagCollection::greaterTags()");
366 if (has_all
) return !p_tags
->isEmpty();
367 else if (p_tags
->has_all
) return !isEmpty();
368 else if (tag_map
.empty() || p_tags
->tag_map
.empty()) return true;
369 else return tag_map
.get_nth_key(tag_map
.size() - 1) <
370 p_tags
->tag_map
.get_nth_key(0);
373 const Tag
*TagCollection::getSmallestTag() const
375 if (has_all
) return has_all
;
376 if (tag_map
.empty()) FATAL_ERROR("TagCollection::getSmallestTag()");
377 return &tag_map
.get_nth_key(0);
380 const Tag
*TagCollection::getGreatestTag() const
382 if (has_all
) return has_all
;
383 if (tag_map
.empty()) FATAL_ERROR("TagCollection::getGreatestTag()");
384 return &tag_map
.get_nth_key(tag_map
.size() - 1);
387 void TagCollection::setExtensible()
390 error("Illegal use of extensibility notation (possible tag conflict)");
391 else is_extensible
=true;
394 bool TagCollection::isEmpty() const
396 if (has_all
|| is_extensible
) return false;
397 else return tag_map
.empty();
400 void TagCollection::clear()
404 is_extensible
= false;
This page took 0.039749 seconds and 5 git commands to generate.