SecurityTools.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /**
  2. * @brief convert xml data to binary
  3. */
  4. using System;
  5. using System.IO;
  6. using System.Security;
  7. using System.Collections;
  8. using System.Runtime.InteropServices;
  9. #if UNITY_EDITOR
  10. // 只允许编辑器环境下测试用
  11. // 不要随意打开 否则ios执行档又要增加很多了
  12. using System.Xml; // ignore
  13. #endif
  14. namespace Mono.Xml
  15. {
  16. public static class SecurityTools
  17. {
  18. enum ESecurityElementType
  19. {
  20. Root,
  21. Children
  22. }
  23. public static bool ConvertXmlFileToBinaryFile(string InXmlPath, string InBinaryPath)
  24. {
  25. string XmlText = File.ReadAllText(InXmlPath, System.Text.Encoding.UTF8);
  26. if (string.IsNullOrEmpty(XmlText))
  27. {
  28. DebugHelper.Assert(false, "{0} is not an valid xml file.", InXmlPath);
  29. return false;
  30. }
  31. return ConvertXmlTextToBinaryFile(XmlText, InBinaryPath);
  32. }
  33. public static bool ConvertXmlTextToBinaryFile(string InXmlText, string InBinaryPath)
  34. {
  35. SecurityParser Parser = new SecurityParser();
  36. Parser.LoadXml(InXmlText);
  37. SecurityElement Root = Parser.root;
  38. return ConvertSecurityElementToBinaryFile(Root, InBinaryPath);
  39. }
  40. public static bool ConvertSecurityElementToBinaryFile(SecurityElement InRoot, string InBinaryPath)
  41. {
  42. using (FileStream fs = File.OpenWrite(InBinaryPath))
  43. {
  44. using (BinaryWriter Writer = new BinaryWriter(fs))
  45. {
  46. Write(Writer, InRoot, (byte)ESecurityElementType.Root);
  47. }
  48. }
  49. return true;
  50. }
  51. private static void WriteString( this BinaryWriter InWriter, string InText )
  52. {
  53. if( InText != null )
  54. {
  55. InWriter.Write(InText);
  56. }
  57. else
  58. {
  59. InWriter.Write("");
  60. }
  61. }
  62. private static void Write(
  63. BinaryWriter InWriterRef,
  64. SecurityElement InElement,
  65. byte InType)
  66. {
  67. InWriterRef.Write(InType);
  68. // base information
  69. InWriterRef.WriteString(InElement.Tag);
  70. InWriterRef.WriteString(InElement.Text);
  71. // attributes
  72. Hashtable Attributes = InElement.Attributes;
  73. int AttributesCount = Attributes != null ? Attributes.Count : 0;
  74. InWriterRef.Write(AttributesCount);
  75. if (Attributes != null)
  76. {
  77. var AttIter = Attributes.GetEnumerator();
  78. while (AttIter.MoveNext())
  79. {
  80. string Key = AttIter.Key as string;
  81. string Value = AttIter.Value as string;
  82. DebugHelper.Assert(
  83. Key != null && Value != null,
  84. "Invalid Attributes"
  85. );
  86. InWriterRef.WriteString(Key);
  87. InWriterRef.WriteString(Value);
  88. }
  89. }
  90. // childrens.
  91. ArrayList Children = InElement.Children;
  92. int ChildrenCount = Children != null ? Children.Count : 0;
  93. InWriterRef.Write(ChildrenCount);
  94. if( Children != null )
  95. {
  96. var ChildIter = Children.GetEnumerator();
  97. while (ChildIter.MoveNext())
  98. {
  99. SecurityElement Child = ChildIter.Current as SecurityElement;
  100. DebugHelper.Assert(Child != null, "Invalid Security Element.");
  101. Write(InWriterRef, Child, (byte)ESecurityElementType.Children);
  102. }
  103. }
  104. }
  105. /////////////////////////////////////////////////////////
  106. // loading
  107. public static SecurityParser LoadXmlFromBinaryFile( string InPath )
  108. {
  109. SecurityParser Parser = new SecurityParser();
  110. if( !LoadXmlFromBinaryFile(Parser, InPath) )
  111. {
  112. return null;
  113. }
  114. return Parser;
  115. }
  116. public static bool LoadXmlFromBinaryFile( SecurityParser InParser, string InPath )
  117. {
  118. byte[] FileBytes = File.ReadAllBytes(InPath);
  119. return LoadXmlFromBinaryBuffer(InParser, FileBytes, InPath);
  120. }
  121. public static bool LoadXmlFromBinaryBuffer(SecurityParser InParser, byte[] InFileBytes, string InPath = "" )
  122. {
  123. if (InFileBytes == null || InFileBytes.Length < 4)
  124. {
  125. return false;
  126. }
  127. using (MemoryStream ms = new MemoryStream(InFileBytes))
  128. {
  129. using (BinaryReader Reader = new BinaryReader(ms))
  130. {
  131. SecurityElement Root = LoadRootSecurityElement(Reader);
  132. DebugHelper.Assert(Root != null, "Failed load root Security Element in file: {0}", InPath);
  133. if (Root != null)
  134. {
  135. InParser.root = Root;
  136. return true;
  137. }
  138. }
  139. }
  140. return false;
  141. }
  142. private static SecurityElement LoadRootSecurityElement(BinaryReader InReader)
  143. {
  144. try
  145. {
  146. SecurityElement Root = LoadSecurityElementChecked(InReader, (byte)ESecurityElementType.Root, null);
  147. return Root;
  148. }
  149. catch(Exception e)
  150. {
  151. DebugHelper.Assert(false, e.Message);
  152. return null;
  153. }
  154. }
  155. private static SecurityElement LoadSecurityElementChecked(BinaryReader InReader, byte InType, SecurityElement InParent )
  156. {
  157. byte ReadedType = InReader.ReadByte();
  158. if( ReadedType != InType )
  159. {
  160. return null;
  161. }
  162. string Tag = InReader.ReadString();
  163. string Text = InReader.ReadString();
  164. SecurityElement Element = new SecurityElement(Tag, Text);
  165. int AttributesCount = InReader.ReadInt32();
  166. DebugHelper.Assert(AttributesCount < 512, "too many attributes.");
  167. for( int i=0; i<AttributesCount; ++i )
  168. {
  169. string Key = InReader.ReadString();
  170. string Value = InReader.ReadString();
  171. Element.AddAttribute(Key, Value);
  172. }
  173. int ChildrenCount = InReader.ReadInt32();
  174. DebugHelper.Assert(ChildrenCount < 515, "too many children");
  175. for( int i=0; i<ChildrenCount; ++i )
  176. {
  177. SecurityElement ChildElement = LoadSecurityElementChecked(InReader, (byte)ESecurityElementType.Children, Element);
  178. DebugHelper.Assert(ChildElement != null, "invalid child element");
  179. }
  180. if( InParent != null )
  181. {
  182. InParent.AddChild(Element);
  183. }
  184. return Element;
  185. }
  186. #if UNITY_EDITOR
  187. // 只允许编辑器环境下测试用
  188. // 不要随意打开 否则ios执行档又要增加很多了
  189. // 写完了之后发现直接ToString就可以了,艹,先留着吧
  190. public static void DumpSecurityElementToXml(SecurityElement InRoot, string InPath)
  191. {
  192. XmlDocument doc = new XmlDocument();
  193. XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
  194. doc.AppendChild(docNode);
  195. DumpSecurityElement(doc, null, InRoot);
  196. doc.Save(InPath);
  197. }
  198. private static void DumpSecurityElement(XmlDocument InDocument, XmlNode InParent, SecurityElement InElement)
  199. {
  200. XmlNode node = InDocument.CreateElement(InElement.Tag);
  201. node.InnerText = InElement.Text;
  202. if( InParent != null )
  203. {
  204. InParent.AppendChild(node);
  205. }
  206. else
  207. {
  208. InDocument.AppendChild(node);
  209. }
  210. if (InElement.Attributes != null)
  211. {
  212. var Iter = InElement.Attributes.GetEnumerator();
  213. while( Iter.MoveNext() )
  214. {
  215. XmlAttribute XmlAttr = InDocument.CreateAttribute(Iter.Key as string);
  216. XmlAttr.Value = Iter.Value as string;
  217. node.Attributes.Append(XmlAttr);
  218. }
  219. }
  220. if (InElement.Children != null )
  221. {
  222. foreach (SecurityElement Element in InElement.Children)
  223. {
  224. DumpSecurityElement(InDocument, node, Element);
  225. }
  226. }
  227. }
  228. #endif
  229. }
  230. }