1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <sngxml/dom/CharacterData.hpp>
  7 #include <soulng/util/Unicode.hpp>
  8 
  9 namespace sngxml { namespace dom {
 10 
 11 using namespace soulng::unicode;
 12 
 13 std::u32string XmlCharDataEscape(const std::u32string& charData)
 14 {
 15     std::u32string result;
 16     for (char32_t c : charData)
 17     {
 18         switch (c)
 19         {
 20         case '<': result.append(U"&lt;"); break;
 21         case '&': result.append(U"&amp;"); break;
 22         default: result.append(1c); break;
 23         }
 24     }
 25     return result;
 26 }
 27 
 28 CharacterData::CharacterData(NodeType nodeType_const std::u32string& name_) : Node(nodeType_name_)
 29 {
 30 }
 31 
 32 CharacterData::CharacterData(NodeType nodeType_const std::u32string& name_const std::u32string& data_) : Node(nodeType_name_)data(data_)
 33 {
 34 }
 35 
 36 void CharacterData::Write(CodeFormatter& formatter)
 37 {
 38     formatter.Write(ToUtf8(XmlCharDataEscape(data)));
 39 }
 40 
 41 bool CharacterData::ValueContainsNewLine() const
 42 {
 43     return data.find('\n') != std::u32string::npos;
 44 }
 45 
 46 Text::Text() : CharacterData(NodeType::textNodeU"text")
 47 {
 48 }
 49 
 50 Text::Text(const std::u32string& data_) : CharacterData(NodeType::textNodeU"text"data_)
 51 {
 52 }
 53 
 54 Text::Text(NodeType nodeType_const std::u32string& name_) : CharacterData(nodeType_name_)
 55 {
 56 }
 57 
 58 Text::Text(NodeType nodeType_const std::u32string& name_const std::u32string& data_) : CharacterData(nodeType_name_data_)
 59 {
 60 }
 61 
 62 std::std::unique_ptr<Node>Text::CloneNode(booldeep)
 63 {
 64     return std::unique_ptr<Node>(new Text(Data()));
 65 }
 66 
 67 void Text::Accept(Visitor& visitor)
 68 {
 69     visitor.Visit(this);
 70 }
 71 
 72 EntityReference::EntityReference() : CharacterData(NodeType::entityReferenceNodeU"entity_refefrence")
 73 {
 74 }
 75 
 76 EntityReference::EntityReference(const std::u32string& entityRef_) : CharacterData(NodeType::entityReferenceNodeU"entity_refefrence"entityRef_)
 77 {
 78 }
 79 
 80 void EntityReference::Write(CodeFormatter& formatter)
 81 {
 82     formatter.Write("&");
 83     formatter.Write(ToUtf8(Data()));
 84     formatter.Write(";");
 85 }
 86 
 87 std::std::unique_ptr<Node>EntityReference::CloneNode(booldeep)
 88 {
 89     return std::unique_ptr<Node>(new EntityReference(Data()));
 90 }
 91 
 92 void EntityReference::Accept(Visitor& visitor)
 93 {
 94     visitor.Visit(this);
 95 }
 96 
 97 CDataSection::CDataSection() : Text(NodeType::cdataSectionNodeU"cdata_section")
 98 {
 99 }
100 
101 CDataSection::CDataSection(const std::u32string& data_) : Text(NodeType::cdataSectionNodeU"cdata_section"data_)
102 {
103 }
104 
105 void CDataSection::Write(CodeFormatter& formatter)
106 {
107     formatter.Write("<![CDATA[");
108     formatter.Write(ToUtf8(Data()));
109     formatter.Write("]]>");
110 }
111 
112 std::std::unique_ptr<Node>CDataSection::CloneNode(booldeep)
113 {
114     return std::unique_ptr<Node>(new CDataSection(Data()));
115 }
116 
117 void CDataSection::Accept(Visitor& visitor)
118 {
119     visitor.Visit(this);
120 }
121 
122 Comment::Comment() : CharacterData(NodeType::commentNodeU"comment")
123 {
124 }
125 
126 Comment::Comment(const std::u32string& data_) : CharacterData(NodeType::commentNodeU"comment"data_)
127 {
128 }
129 
130 void Comment::Write(CodeFormatter& formatter)
131 {
132     formatter.Write("<!-- ");
133     formatter.Write(ToUtf8(Data()));
134     formatter.Write(" -->");
135 }
136 
137 std::std::unique_ptr<Node>Comment::CloneNode(booldeep)
138 {
139     return std::unique_ptr<Node>(new Comment(Data()));
140 }
141 
142 void Comment::Accept(Visitor& visitor)
143 {
144     visitor.Visit(this);
145 }
146 
147 ProcessingInstruction::ProcessingInstruction(const std::u32string& target_const std::u32string& data_) : Node(NodeType::processingInstructionNodeU"processing_instruction")target(target_)data(data_)
148 {
149 }
150 
151 void ProcessingInstruction::Write(CodeFormatter& formatter)
152 {
153     formatter.WriteLine("<?" + ToUtf8(target) + " " + ToUtf8(data) + "?>");
154 }
155 
156 std::std::unique_ptr<Node>ProcessingInstruction::CloneNode(booldeep)
157 {
158     return std::unique_ptr<Node>(new ProcessingInstruction(targetdata));
159 }
160 
161 void ProcessingInstruction::Accept(Visitor& visitor)
162 {
163     visitor.Visit(this);
164 }
165 
166 } } // namespace sngxml::dom