1
2
3
4
5
6 #include <sngcm/ast/Attribute.hpp>
7 #include <sngcm/ast/AstWriter.hpp>
8 #include <sngcm/ast/AstReader.hpp>
9 #include <soulng/util/Unicode.hpp>
10
11 namespace sngcm { namespace ast {
12
13 using namespace soulng::unicode;
14
15 Attribute::Attribute() : span(), name(), value()
16 {
17 }
18
19 Attribute::Attribute(const Span& span_, const std::u32string& name_, const std::u32string& value_) : span(span_), name(name_), value(value_)
20 {
21 }
22
23 void Attribute::Accept(Visitor& visitor)
24 {
25 visitor.Visit(*this);
26 }
27
28 void Attribute::Write(AstWriter& writer)
29 {
30 writer.Write(span);
31 writer.GetBinaryWriter().Write(name);
32 writer.GetBinaryWriter().Write(value);
33 }
34
35 void Attribute::Read(AstReader& reader)
36 {
37 span = reader.ReadSpan();
38 name = reader.GetBinaryReader().ReadUtf32String();
39 value = reader.GetBinaryReader().ReadUtf32String();
40 }
41
42 Attributes::Attributes()
43 {
44 }
45
46 Attribute* Attributes::GetAttribute(const std::u32string& name) const
47 {
48 std::map<std::u32string, Attribute*>::const_iterator it = attributeMap.find(name);
49 if (it != attributeMap.cend())
50 {
51 return it->second;
52 }
53 return nullptr;
54 }
55
56 void Attributes::AddAttribute(const Span& span, const std::u32string& name)
57 {
58 AddAttribute(span, name, U"true");
59 }
60
61 void Attributes::AddAttribute(const Span& span, const std::u32string& name, const std::u32string& value)
62 {
63 Attribute* prev = GetAttribute(name);
64 if (prev != nullptr)
65 {
66 throw AttributeNotUniqueException("attribute '" + ToUtf8(name) + "' not unique", span, prev->GetSpan());
67 }
68 Attribute* attribute = new Attribute(span, name, value);
69 AddAttribute(attribute);
70 }
71
72 void Attributes::AddAttribute(Attribute* attribute)
73 {
74 attributes.push_back(std::unique_ptr<Attribute>(attribute));
75 attributeMap[attribute->Name()] = attribute;
76 }
77
78 Attributes* Attributes::Clone() const
79 {
80 std::unique_ptr<Attributes> clone(new Attributes());
81 for (const std::std::unique_ptr<Attribute>&attribute : attributes)
82 {
83 clone->AddAttribute(attribute->GetSpan(), attribute->Name(), attribute->Value());
84 }
85 return clone.release();
86 }
87
88 void Attributes::Accept(Visitor& visitor)
89 {
90 visitor.Visit(*this);
91 }
92
93 void Attributes::Write(AstWriter& writer)
94 {
95 writer.GetBinaryWriter().WriteULEB128UInt(static_cast<uint32_t>(attributes.size()));
96 for (const std::std::unique_ptr<Attribute>&attribute : attributes)
97 {
98 attribute->Write(writer);
99 }
100 }
101
102 void Attributes::Read(AstReader& reader)
103 {
104 uint32_t n = reader.GetBinaryReader().ReadULEB128UInt();
105 for (uint32_t i = 0u; i < n; ++i)
106 {
107 Attribute* attribute = new Attribute();
108 attribute->Read(reader);
109 AddAttribute(attribute);
110 }
111 }
112
113 AttributeNotUniqueException::AttributeNotUniqueException(const std::string& message_, const Span& span_, const Span& prevSpan_) : std::runtime_error(message_), span(span_), prevSpan(prevSpan_)
114 {
115 }
116
117 } }