2
2
// Use of this source code is governed by GNU General Public License (GPL-2.0) that can be found in the COPYING file.
3
3
4
4
using System ;
5
+ using System . Globalization ;
5
6
using System . IO ;
6
7
using System . Reflection ;
7
8
using System . Text ;
9
+ using System . Xml ;
8
10
using Svg ;
9
11
10
12
namespace SvgFileTypePlugin . Extensions ;
@@ -51,16 +53,29 @@ public static string GetXML_QuotedFuncIRIHack(this SvgElement svg)
51
53
{
52
54
ArgumentNullException . ThrowIfNull ( svg ) ;
53
55
54
- return svg . GetXML ( ) . Replace ( """ , string . Empty ) ;
56
+ using InvariantUtf8StringWriter writer = new InvariantUtf8StringWriter ( ) ;
57
+ XmlWriterSettings xmlWriterSettings = new ( ) { Encoding = Encoding . UTF8 } ;
58
+ using ( XmlWriter xmlWriter = new CustomXmlWriter ( XmlWriter . Create ( writer , xmlWriterSettings ) ) )
59
+ {
60
+ svg . Write ( xmlWriter ) ;
61
+ xmlWriter . Flush ( ) ;
62
+ }
63
+ writer . Flush ( ) ;
64
+ return writer . ToString ( ) ;
55
65
}
56
66
57
- public static Stream GetXMLAsStream ( this SvgElement svg )
67
+ public static void WriteXML_QuotedFuncIRIHack ( this SvgElement svg , Stream output )
58
68
{
59
69
ArgumentNullException . ThrowIfNull ( svg ) ;
60
70
61
- string xml = svg . GetXML_QuotedFuncIRIHack ( ) ;
62
- byte [ ] bytes = Encoding . UTF8 . GetBytes ( xml ) ;
63
- return new MemoryStream ( bytes ) ;
71
+ using InvariantUtf8StreamWriter writer = new InvariantUtf8StreamWriter ( output ) ;
72
+ XmlWriterSettings xmlWriterSettings = new ( ) { Encoding = Encoding . UTF8 } ;
73
+ using ( XmlWriter xmlWriter = new CustomXmlWriter ( XmlWriter . Create ( writer , xmlWriterSettings ) ) )
74
+ {
75
+ svg . Write ( xmlWriter ) ;
76
+ xmlWriter . Flush ( ) ;
77
+ }
78
+ writer . Flush ( ) ;
64
79
}
65
80
66
81
private static T CreateGetterDelegate < T > ( string propertyName ) where T : Delegate
@@ -71,4 +86,56 @@ private static T CreateGetterDelegate<T>(string propertyName) where T : Delegate
71
86
?? throw new MissingMemberException ( nameof ( SvgElement ) , propertyName ) ;
72
87
return getter . CreateDelegate < T > ( ) ;
73
88
}
89
+
90
+ private sealed class InvariantUtf8StreamWriter ( Stream stream ) : StreamWriter ( stream , Encoding . UTF8 , leaveOpen : true )
91
+ {
92
+ private readonly Stream stream = stream ;
93
+
94
+ public override Encoding Encoding => Encoding . UTF8 ;
95
+ public override IFormatProvider FormatProvider => CultureInfo . InvariantCulture ;
96
+
97
+ protected override void Dispose ( bool disposing )
98
+ {
99
+ base . Dispose ( disposing ) ;
100
+ if ( disposing )
101
+ stream . Position = 0 ;
102
+ }
103
+ }
104
+
105
+ private sealed class InvariantUtf8StringWriter ( ) : StringWriter ( CultureInfo . InvariantCulture )
106
+ {
107
+ public override Encoding Encoding => Encoding . UTF8 ;
108
+ }
109
+
110
+ private sealed class CustomXmlWriter ( XmlWriter writer ) : XmlWriter
111
+ {
112
+ private readonly XmlWriter writer = writer ;
113
+ public override WriteState WriteState => writer . WriteState ;
114
+ public override void Flush ( ) => writer . Flush ( ) ;
115
+ public override string ? LookupPrefix ( string ns ) => writer . LookupPrefix ( ns ) ;
116
+ public override void WriteBase64 ( byte [ ] buffer , int index , int count ) => writer . WriteBase64 ( buffer , index , count ) ;
117
+ public override void WriteCData ( string ? text ) => writer . WriteCData ( text ) ;
118
+ public override void WriteCharEntity ( char ch ) => writer . WriteCharEntity ( ch ) ;
119
+ public override void WriteChars ( char [ ] buffer , int index , int count ) => writer . WriteChars ( buffer , index , count ) ;
120
+ public override void WriteComment ( string ? text ) => writer . WriteComment ( text ) ;
121
+ public override void WriteDocType ( string name , string ? pubid , string ? sysid , string ? subset ) => writer . WriteDocType ( name , pubid , sysid , subset ) ;
122
+ public override void WriteEndAttribute ( ) => writer . WriteEndAttribute ( ) ;
123
+ public override void WriteEndDocument ( ) => writer . WriteEndDocument ( ) ;
124
+ public override void WriteEndElement ( ) => writer . WriteEndElement ( ) ;
125
+ public override void WriteEntityRef ( string name ) => writer . WriteEntityRef ( name ) ;
126
+ public override void WriteFullEndElement ( ) => writer . WriteFullEndElement ( ) ;
127
+ public override void WriteProcessingInstruction ( string name , string ? text ) => writer . WriteProcessingInstruction ( name , text ) ;
128
+ public override void WriteRaw ( char [ ] buffer , int index , int count ) => writer . WriteRaw ( buffer , index , count ) ;
129
+ public override void WriteRaw ( string data ) => writer . WriteRaw ( data ) ;
130
+ public override void WriteStartAttribute ( string ? prefix , string localName , string ? ns ) => writer . WriteStartAttribute ( prefix , localName , ns ) ;
131
+ public override void WriteStartDocument ( ) => writer . WriteStartDocument ( ) ;
132
+ public override void WriteStartDocument ( bool standalone ) => writer . WriteStartDocument ( standalone ) ;
133
+ public override void WriteStartElement ( string ? prefix , string localName , string ? ns ) => writer . WriteStartElement ( prefix , localName , ns ) ;
134
+ public override void WriteString ( string ? text )
135
+ {
136
+ writer . WriteString ( text ? . Replace ( "\" " , string . Empty ) . Replace ( "\' " , string . Empty ) ) ;
137
+ }
138
+ public override void WriteSurrogateCharEntity ( char lowChar , char highChar ) => writer . WriteSurrogateCharEntity ( lowChar , highChar ) ;
139
+ public override void WriteWhitespace ( string ? ws ) => writer . WriteWhitespace ( ws ) ;
140
+ }
74
141
}
0 commit comments