Util.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. #########
  3. ############
  4. #############
  5. ## ###########
  6. ### ###### #####
  7. ### ####### ####
  8. ### ########## ####
  9. #### ########### ####
  10. #### ########### #####
  11. ##### ### ######## #####
  12. ##### ### ######## ######
  13. ###### ### ########### ######
  14. ###### #### ############## ######
  15. ####### ##################### ######
  16. ####### ###################### ######
  17. ####### ###### ################# ######
  18. ####### ###### ###### ######### ######
  19. ####### ## ###### ###### ######
  20. ####### ###### ##### #####
  21. ###### ##### ##### ####
  22. ##### #### ##### ###
  23. ##### ### ### #
  24. ### ### ###
  25. ## ### ###
  26. __________#_______####_______####______________
  27. 我们的未来没有BUG
  28. * ==============================================================================
  29. * Filename: Utl
  30. * Created: 2018/7/2 11:36:16
  31. * Author: エル・プサイ・コングリィ
  32. * Purpose:
  33. * ==============================================================================
  34. */
  35. #if UNITY_EDITOR || USE_LUA_PROFILER
  36. #define API_CHECK
  37. #define UNILUA_ASSERT
  38. using System;
  39. namespace MikuLuaProfiler
  40. {
  41. using DebugS = System.Diagnostics.Debug;
  42. using NumberStyles = System.Globalization.NumberStyles;
  43. internal static class Utl
  44. {
  45. private static void Throw(params string[] msgs)
  46. {
  47. throw new Exception(String.Join("", msgs));
  48. }
  49. public static void Assert(bool condition)
  50. {
  51. #if UNILUA_ASSERT
  52. if (!condition)
  53. Throw("assert failed!");
  54. DebugS.Assert(condition);
  55. #endif
  56. }
  57. private static bool IsNegative(string s, ref int pos)
  58. {
  59. if (pos >= s.Length)
  60. return false;
  61. char c = s[pos];
  62. if (c == '-')
  63. {
  64. ++pos;
  65. return true;
  66. }
  67. else if (c == '+')
  68. {
  69. ++pos;
  70. }
  71. return false;
  72. }
  73. private static bool IsXDigit(char c)
  74. {
  75. if (Char.IsDigit(c))
  76. return true;
  77. if ('a' <= c && c <= 'f')
  78. return true;
  79. if ('A' <= c && c <= 'F')
  80. return true;
  81. return false;
  82. }
  83. private static double ReadHexa(string s, ref int pos, double r, out int count)
  84. {
  85. count = 0;
  86. while (pos < s.Length && IsXDigit(s[pos]))
  87. {
  88. r = (r * 16.0) + Int32.Parse(s[pos].ToString(), NumberStyles.HexNumber);
  89. ++pos;
  90. ++count;
  91. }
  92. return r;
  93. }
  94. private static double ReadDecimal(string s, ref int pos, double r, out int count)
  95. {
  96. count = 0;
  97. while (pos < s.Length && Char.IsDigit(s[pos]))
  98. {
  99. r = (r * 10.0) + Int32.Parse(s[pos].ToString());
  100. ++pos;
  101. ++count;
  102. }
  103. return r;
  104. }
  105. // following C99 specification for 'strtod'
  106. public static double StrX2Number(string s, ref int curpos)
  107. {
  108. int pos = curpos;
  109. while (pos < s.Length && Char.IsWhiteSpace(s[pos])) ++pos;
  110. bool negative = IsNegative(s, ref pos);
  111. // check `0x'
  112. if (pos >= s.Length || !(s[pos] == '0' && (s[pos + 1] == 'x' || s[pos + 1] == 'X')))
  113. return 0.0;
  114. pos += 2; // skip `0x'
  115. double r = 0.0;
  116. int i = 0;
  117. int e = 0;
  118. r = ReadHexa(s, ref pos, r, out i);
  119. if (pos < s.Length && s[pos] == '.')
  120. {
  121. ++pos; // skip `.'
  122. r = ReadHexa(s, ref pos, r, out e);
  123. }
  124. if (i == 0 && e == 0)
  125. return 0.0; // invalid format (no digit)
  126. // each fractional digit divides value by 2^-4
  127. e *= -4;
  128. curpos = pos;
  129. // exponent part
  130. if (pos < s.Length && (s[pos] == 'p' || s[pos] == 'P'))
  131. {
  132. ++pos; // skip `p'
  133. bool expNegative = IsNegative(s, ref pos);
  134. if (pos >= s.Length || !Char.IsDigit(s[pos]))
  135. goto ret;
  136. int exp1 = 0;
  137. while (pos < s.Length && Char.IsDigit(s[pos]))
  138. {
  139. exp1 = exp1 * 10 + Int32.Parse(s[pos].ToString());
  140. ++pos;
  141. }
  142. if (expNegative)
  143. exp1 = -exp1;
  144. e += exp1;
  145. }
  146. curpos = pos;
  147. ret:
  148. if (negative) r = -r;
  149. return r * Math.Pow(2.0, e);
  150. }
  151. public static double Str2Number(string s, ref int curpos)
  152. {
  153. int pos = curpos;
  154. while (pos < s.Length && Char.IsWhiteSpace(s[pos])) ++pos;
  155. bool negative = IsNegative(s, ref pos);
  156. double r = 0.0;
  157. int i = 0;
  158. int f = 0;
  159. r = ReadDecimal(s, ref pos, r, out i);
  160. if (pos < s.Length && s[pos] == '.')
  161. {
  162. ++pos;
  163. r = ReadDecimal(s, ref pos, r, out f);
  164. }
  165. if (i == 0 && f == 0)
  166. return 0.0;
  167. f = -f;
  168. curpos = pos;
  169. // exponent part
  170. double e = 0.0;
  171. if (pos < s.Length && (s[pos] == 'e' || s[pos] == 'E'))
  172. {
  173. ++pos;
  174. bool expNegative = IsNegative(s, ref pos);
  175. if (pos >= s.Length || !Char.IsDigit(s[pos]))
  176. goto ret;
  177. int n;
  178. e = ReadDecimal(s, ref pos, e, out n);
  179. if (expNegative)
  180. e = -e;
  181. f += (int)e;
  182. }
  183. curpos = pos;
  184. ret:
  185. if (negative) r = -r;
  186. return r * Math.Pow(10, f);
  187. }
  188. }
  189. }
  190. #endif