1 /******************************************************************************
2 * Copyright (c) 2000-2016 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
15 * Szabo, Janos Zoltan – initial implementation
17 ******************************************************************************/
20 #include "../Value.hh"
25 // =================================
27 // =================================
29 Tag::Tag(tagplicit_t p_plicit
, tagclass_t p_tagclass
, Value
*p_tagvalue
)
31 plicit(p_plicit
), tagclass(p_tagclass
), tagvalue(p_tagvalue
),
35 FATAL_ERROR("NULL parameter: Asn::Tag::Tag()");
38 Tag::Tag(tagplicit_t p_plicit
, tagclass_t p_tagclass
, Int p_tagval
)
40 plicit(p_plicit
), tagclass(p_tagclass
), tagvalue(0),
41 tagval(p_tagval
), is_auto(false)
43 if(tagval
<0) FATAL_ERROR("Asn::Tag::Tag(): negative value");
46 Tag::Tag(const Tag
& p
)
47 : Node(p
), Location(p
),
48 plicit(p
.plicit
), tagclass(p
.tagclass
),
51 if (p
.tagvalue
) tagvalue
= p
.tagvalue
->clone();
63 Tag
& Tag::operator=(const Tag
& p
)
68 tagclass
= p
.tagclass
;
69 if (p
.tagvalue
) tagvalue
= p
.tagvalue
->clone();
79 bool Tag::operator==(const Tag
& p
) const
81 if (tagvalue
|| p
.tagvalue
) FATAL_ERROR("Comparison of unchecked tags.");
82 return tagclass
== p
.tagclass
&& tagval
== p
.tagval
;
85 bool Tag::operator<(const Tag
& p
) const
87 if (tagvalue
|| p
.tagvalue
) FATAL_ERROR("Comparison of unchecked tags.");
88 if (tagclass
< p
.tagclass
) return true;
89 else if (tagclass
> p
.tagclass
) return false;
90 else return tagval
< p
.tagval
;
93 const char *Tag::get_tagclass_str() const
97 return "ASN_TAG_UNIV";
99 return "ASN_TAG_APPL";
101 return "ASN_TAG_CONT";
103 return "ASN_TAG_PRIV";
105 FATAL_ERROR("Tag::get_tagclass_str()");
110 Int
Tag::get_tagvalue()
116 void Tag::set_tagvalue(const Int
& p_tagval
)
118 if(tagvalue
) {delete tagvalue
; tagvalue
=0;}
122 void Tag::set_my_scope(Scope
*p_scope
)
124 if (tagvalue
) tagvalue
->set_my_scope(p_scope
);
129 if (!tagvalue
) return;
130 Error_Context
cntxt(this, "In tag");
131 Value
*v
= tagvalue
->get_value_refd_last();
132 switch (v
->get_valuetype()) {
134 const int_val_t
*tagval_int
= tagvalue
->get_val_Int();
135 if (*tagval_int
< 0 || *tagval_int
> INT_MAX
) {
136 error("Integer value in range 0..%d was expected instead of `%s' "
137 "for tag value", INT_MAX
, (tagval_int
->t_str()).c_str());
140 tagval
= tagval_int
->get_val();
146 error("INTEGER value was expected for tag value");
158 void Tag::dump(unsigned level
) const
163 s
+="<ERROR> "; break;
169 s
+="UNIVERSAL "; break;
170 case TAG_APPLICATION
:
171 s
+="APPLICATION "; break;
175 s
+="PRIVATE "; break;
177 s
+=" <UNKNOWN CLASS>"; break;
179 if(!tagvalue
) s
+=Int2string(tagval
);
186 s
+=" EXPLICIT"; break;
188 s
+=" IMPLICIT"; break;
190 s
+=" <UNKNOWN PLICIT>"; break;
192 if(is_auto
) s
+=" (auto)";
193 DEBUG(level
, "Tag: %s", s
.c_str());
194 if(tagvalue
) tagvalue
->dump(level
+1);
197 // =================================
199 // =================================
201 Tags::Tags() : Node()
203 set_fullname(string("<tags>"));
207 Tags::Tags(const Tags
& p
) : Node(p
)
209 for(size_t i
=0; i
<p
.tags
.size(); i
++)
210 add_tag(p
.tags
[i
]->clone());
216 for(size_t i
=0; i
<tags
.size(); i
++) delete tags
[i
];
220 void Tags::set_fullname(const string
& p_fullname
)
222 Node::set_fullname(p_fullname
);
223 for(size_t i
=0; i
<tags
.size(); i
++)
224 tags
[i
]->set_fullname(get_fullname()+"."+Int2string(i
));
227 void Tags::set_my_scope(Scope
*p_scope
)
230 for(size_t i
=0; i
<tags
.size(); i
++)
231 tags
[i
]->set_my_scope(p_scope
);
234 void Tags::add_tag(Tag
*p_tag
)
237 FATAL_ERROR("NULL parameter: Asn::Tags::add_tag()");
239 p_tag
->set_fullname(get_fullname()+"."+Int2string(tags
.size()));
240 p_tag
->set_my_scope(my_scope
);
245 for(size_t i
=0; i
<tags
.size(); i
++)
249 void Tags::set_plicit(Type
*p_type
)
251 if (!p_type
) FATAL_ERROR("NULL parameter: Asn::Tags::set_plicit()");
252 Asn::Module
*m
= dynamic_cast<Asn::Module
*>
253 (p_type
->get_my_scope()->get_scope_mod());
254 if (!m
) FATAL_ERROR("Asn::Tags::set_plicit()");
255 bool type_needs_explicit
= p_type
->needs_explicit_tag();
256 bool module_uses_explicit
= (m
->get_tagdef() == TagDefault::EXPLICIT
);
257 Tag
*innermost
= tags
[0];
258 switch (innermost
->get_plicit()) {
259 case Tag::TAG_DEFPLICIT
:
260 if (module_uses_explicit
|| type_needs_explicit
)
261 innermost
->set_plicit(Tag::TAG_EXPLICIT
);
262 else innermost
->set_plicit(Tag::TAG_IMPLICIT
);
264 case Tag::TAG_IMPLICIT
:
265 if (type_needs_explicit
) {
266 p_type
->error("Type cannot have IMPLICIT tag");
267 innermost
->set_plicit(Tag::TAG_EXPLICIT
);
272 for (size_t i
= 1; i
< tags
.size(); i
++) {
274 if (tag
->get_plicit() == Tag::TAG_DEFPLICIT
) {
275 if (module_uses_explicit
) tag
->set_plicit(Tag::TAG_EXPLICIT
);
276 else tag
->set_plicit(Tag::TAG_IMPLICIT
);
281 void Tags::cut_auto_tags()
284 while (i
< tags
.size()) {
286 if (tag
->is_automatic()) {
288 tags
.replace(i
, 1, NULL
);
293 void Tags::dump(unsigned level
) const
295 for(size_t i
=0; i
<tags
.size(); i
++)
296 tags
[i
]->dump(level
);
299 // =================================
300 // ===== TagCollection
301 // =================================
303 TagCollection::TagCollection()
304 : has_all(NULL
), is_extensible(false)
308 TagCollection::TagCollection(const TagCollection
& p
)
309 : Node(p
), Location(p
),
310 has_all(p
.has_all
), is_extensible(p
.is_extensible
)
312 for (size_t i
= 0; i
< p
.tag_map
.size(); i
++)
313 tag_map
.add(p
.tag_map
.get_nth_key(i
), 0);
316 TagCollection::~TagCollection()
321 void TagCollection::addTag(const Tag
*p_tag
)
324 FATAL_ERROR("Asn::TagCollection::addTag()");
325 if (p_tag
->get_tagclass() == Tag::TAG_ALL
) {
327 FATAL_ERROR("Asn::TagCollection::addTag(): tag 'all'");
330 else if(p_tag
->get_tagclass() == Tag::TAG_ERROR
)
332 else if(!tag_map
.has_key(*p_tag
))
333 tag_map
.add(*p_tag
, 0);
335 FATAL_ERROR("Asn::TagCollection::addTag(): tag is already in collection");
338 bool TagCollection::hasTag(const Tag
*p_tag
) const
340 if (!p_tag
) FATAL_ERROR("NULL parameter: Asn::TagCollection::hasTag()");
341 if (has_all
) return true;
342 else if (p_tag
->get_tagclass() == Tag::TAG_ALL
) return !tag_map
.empty();
343 else if (p_tag
->get_tagclass() == Tag::TAG_ERROR
) return false;
344 else return tag_map
.has_key(*p_tag
);
347 void TagCollection::addTags(const TagCollection
*p_tags
)
349 if (!p_tags
) FATAL_ERROR("NULL parameter: Asn::TagCollection::addTags()");
350 if (p_tags
->is_extensible
) setExtensible();
351 if (p_tags
->has_all
) {
352 if (has_all
) FATAL_ERROR("Asn::TagCollection::addTags(): tag 'all'");
353 has_all
= p_tags
->has_all
;
355 for (size_t i
= 0; i
< p_tags
->tag_map
.size(); i
++) {
356 const Tag
& tag
= p_tags
->tag_map
.get_nth_key(i
);
357 if (!tag_map
.has_key(tag
)) tag_map
.add(tag
, 0);
358 else FATAL_ERROR("Asn::TagCollection::addTags(): tag is already in collection");
362 bool TagCollection::hasTags(const TagCollection
*p_tags
) const
364 if (!p_tags
) FATAL_ERROR("NULL parameter: Asn::TagCollection::hasTags()");
365 if (has_all
) return !p_tags
->isEmpty();
366 else if (p_tags
->has_all
) return !isEmpty();
367 for (size_t i
= 0; i
< p_tags
->tag_map
.size(); i
++)
368 if (tag_map
.has_key(p_tags
->tag_map
.get_nth_key(i
))) return true;
372 bool TagCollection::greaterTags(const TagCollection
*p_tags
) const
375 FATAL_ERROR("NULL parameter: Asn::TagCollection::greaterTags()");
376 if (has_all
) return !p_tags
->isEmpty();
377 else if (p_tags
->has_all
) return !isEmpty();
378 else if (tag_map
.empty() || p_tags
->tag_map
.empty()) return true;
379 else return tag_map
.get_nth_key(tag_map
.size() - 1) <
380 p_tags
->tag_map
.get_nth_key(0);
383 const Tag
*TagCollection::getSmallestTag() const
385 if (has_all
) return has_all
;
386 if (tag_map
.empty()) FATAL_ERROR("TagCollection::getSmallestTag()");
387 return &tag_map
.get_nth_key(0);
390 const Tag
*TagCollection::getGreatestTag() const
392 if (has_all
) return has_all
;
393 if (tag_map
.empty()) FATAL_ERROR("TagCollection::getGreatestTag()");
394 return &tag_map
.get_nth_key(tag_map
.size() - 1);
397 void TagCollection::setExtensible()
400 error("Illegal use of extensibility notation (possible tag conflict)");
401 else is_extensible
=true;
404 bool TagCollection::isEmpty() const
406 if (has_all
|| is_extensible
) return false;
407 else return tag_map
.empty();
410 void TagCollection::clear()
414 is_extensible
= false;
This page took 0.039398 seconds and 6 git commands to generate.