|
|
|
@ -6,10 +6,98 @@ using System.Xml; |
|
|
|
|
using System.Xml.Linq; |
|
|
|
|
using System.Xml.Xsl; |
|
|
|
|
using System.IO; |
|
|
|
|
using System.Globalization; |
|
|
|
|
using FLocal.Core; |
|
|
|
|
|
|
|
|
|
namespace FLocal.IISHandler { |
|
|
|
|
class TemplateEngine { |
|
|
|
|
|
|
|
|
|
public static class EncodingInfo { |
|
|
|
|
|
|
|
|
|
public class XmlEncoderReplacementFallback : EncoderFallback { |
|
|
|
|
|
|
|
|
|
private readonly Encoding originalEncoding; |
|
|
|
|
|
|
|
|
|
public XmlEncoderReplacementFallback(Encoding encoding) { |
|
|
|
|
this.originalEncoding = encoding; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override EncoderFallbackBuffer CreateFallbackBuffer() { |
|
|
|
|
return new XmlEncoderReplacementFallbackBuffer(this.originalEncoding); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override int MaxCharCount { |
|
|
|
|
get { |
|
|
|
|
return 20; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private class XmlEncoderReplacementFallbackBuffer : EncoderFallbackBuffer { |
|
|
|
|
|
|
|
|
|
const int SurHighStart = 0xd800; |
|
|
|
|
const int SurHighEnd = 0xdbff; |
|
|
|
|
const int SurLowStart = 0xdc00; |
|
|
|
|
const int SurLowEnd = 0xdfff; |
|
|
|
|
|
|
|
|
|
int fallbackIndex = -1; |
|
|
|
|
string currentReplacement = ""; |
|
|
|
|
|
|
|
|
|
private readonly Encoding originalEncoding; |
|
|
|
|
|
|
|
|
|
public XmlEncoderReplacementFallbackBuffer(Encoding originalEncoding) { |
|
|
|
|
this.originalEncoding = originalEncoding; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private bool Fallback(int ch) { |
|
|
|
|
this.currentReplacement = string.Format(CultureInfo.InvariantCulture, "&#x{0:X};", ch); |
|
|
|
|
return this.currentReplacement.Length > 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override bool Fallback(char highChar, char lowChar, int index) { |
|
|
|
|
if (!char.IsSurrogatePair(highChar, lowChar)) { |
|
|
|
|
throw new CriticalException("Invalid surrogate pair: " + (int)lowChar + (int)highChar); |
|
|
|
|
} |
|
|
|
|
return this.Fallback(char.ConvertToUtf32(highChar, lowChar)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override bool Fallback(char ch, int index) { |
|
|
|
|
if (char.IsSurrogate(ch)) { |
|
|
|
|
throw new FLocalException("Wrong char: " + (int)ch); |
|
|
|
|
} |
|
|
|
|
return this.Fallback(ch); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override char GetNextChar() { |
|
|
|
|
this.fallbackIndex++; |
|
|
|
|
return this.currentReplacement[this.fallbackIndex]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override bool MovePrevious() { |
|
|
|
|
if(this.fallbackIndex > 0) { |
|
|
|
|
this.fallbackIndex--; |
|
|
|
|
return true; |
|
|
|
|
} else { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override int Remaining { |
|
|
|
|
get { |
|
|
|
|
return this.currentReplacement.Length - this.fallbackIndex - 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override void Reset() { |
|
|
|
|
this.fallbackIndex = -1; |
|
|
|
|
this.currentReplacement = ""; |
|
|
|
|
base.Reset(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private class TemplateCacher { |
|
|
|
|
|
|
|
|
|
public static TemplateCacher instance = new TemplateCacher(); |
|
|
|
@ -33,8 +121,9 @@ namespace FLocal.IISHandler { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static void WriteCompiled(string templateName, XDocument data, Encoding encoding, TextWriter outStream) { |
|
|
|
|
using(XmlWriter writer = XmlWriter.Create(outStream, new XmlWriterSettings { Indent = false, Encoding = encoding })) { |
|
|
|
|
public static void WriteCompiled(string templateName, XDocument data, TextWriter outStream) { |
|
|
|
|
//var fallback = new EncodingInfo.XmlEncoderReplacementFallback(outStream.Encoding); |
|
|
|
|
using(XmlWriter writer = XmlWriter.Create(outStream, new XmlWriterSettings { Indent = false })) { |
|
|
|
|
using(XmlReader reader = data.CreateReader()) { |
|
|
|
|
TemplateCacher.instance.getCompiledTransform(templateName).Transform(reader, writer); |
|
|
|
|
} |
|
|
|
|