PageRenderTime 59ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/0.3.2/libsecondlife/LLSD/NotationLLSD.cs

https://github.com/kow/gridsearch
C# | 346 lines | 250 code | 29 blank | 67 comment | 34 complexity | 3ed18012d71b559a38b666ec735b7a9b MD5 | raw file
Possible License(s): BSD-3-Clause
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace libsecondlife.LLSD
  5. {
  6. public static partial class LLSDParser
  7. {
  8. public static object DeserializeNotation(string notationData)
  9. {
  10. int unused;
  11. return ParseNotationElement(notationData, out unused);
  12. }
  13. private static object ParseNotationElement(string notationData, out int endPos)
  14. {
  15. if (notationData.Length == 0)
  16. {
  17. endPos = 0;
  18. return null;
  19. }
  20. // Identify what type of object this is
  21. switch (notationData[0])
  22. {
  23. case '!':
  24. endPos = 1;
  25. return null;
  26. case '1':
  27. endPos = 1;
  28. return true;
  29. case '0':
  30. endPos = 1;
  31. return false;
  32. case 'i':
  33. {
  34. if (notationData.Length < 2)
  35. {
  36. endPos = notationData.Length;
  37. return 0;
  38. }
  39. int value;
  40. endPos = FindEnd(notationData, 1);
  41. if (Int32.TryParse(notationData.Substring(1, endPos - 1), out value))
  42. return value;
  43. else
  44. return 0;
  45. }
  46. case 'r':
  47. {
  48. if (notationData.Length < 2)
  49. {
  50. endPos = notationData.Length;
  51. return 0d;
  52. }
  53. double value;
  54. endPos = FindEnd(notationData, 1);
  55. if (Double.TryParse(notationData.Substring(1, endPos - 1), System.Globalization.NumberStyles.Float,
  56. Helpers.EnUsCulture.NumberFormat, out value))
  57. return value;
  58. else
  59. return 0d;
  60. }
  61. case 'u':
  62. {
  63. if (notationData.Length < 17)
  64. {
  65. endPos = notationData.Length;
  66. return LLUUID.Zero;
  67. }
  68. LLUUID value;
  69. endPos = FindEnd(notationData, 1);
  70. if (LLUUID.TryParse(notationData.Substring(1, endPos - 1), out value))
  71. return value;
  72. else
  73. return LLUUID.Zero;
  74. }
  75. case 'b':
  76. throw new NotImplementedException("Notation binary type is unimplemented");
  77. case 's':
  78. case '"':
  79. case '\'':
  80. if (notationData.Length < 2)
  81. {
  82. endPos = notationData.Length;
  83. return String.Empty;
  84. }
  85. endPos = FindEnd(notationData, 1);
  86. return notationData.Substring(1, endPos - 1).Trim(new char[] { '"', '\'' });
  87. case 'l':
  88. throw new NotImplementedException("Notation URI type is unimplemented");
  89. case 'd':
  90. throw new NotImplementedException("Notation date type is unimplemented");
  91. case '[':
  92. {
  93. if (notationData.IndexOf(']') == -1)
  94. throw new LLSDException("Invalid notation array");
  95. int pos = 0;
  96. List<object> array = new List<object>();
  97. while (notationData[pos] != ']')
  98. {
  99. ++pos;
  100. // Advance past comma if need be
  101. if (notationData[pos] == ',') ++pos;
  102. // Allow a single whitespace character
  103. if (pos < notationData.Length && notationData[pos] == ' ') ++pos;
  104. int end;
  105. array.Add(ParseNotationElement(notationData.Substring(pos), out end));
  106. pos += end;
  107. }
  108. endPos = pos + 1;
  109. return array;
  110. }
  111. case '{':
  112. {
  113. if (notationData.IndexOf('}') == -1)
  114. throw new LLSDException("Invalid notation map");
  115. int pos = 0;
  116. Dictionary<string, object> hashtable = new Dictionary<string, object>();
  117. while (notationData[pos] != '}')
  118. {
  119. ++pos;
  120. // Advance past comma if need be
  121. if (notationData[pos] == ',') ++pos;
  122. // Allow a single whitespace character
  123. if (pos < notationData.Length && notationData[pos] == ' ') ++pos;
  124. if (notationData[pos] != '\'')
  125. throw new LLSDException("Expected a map key");
  126. int endquote = notationData.IndexOf('\'', pos + 1);
  127. if (endquote == -1 || (endquote + 1) >= notationData.Length || notationData[endquote + 1] != ':')
  128. throw new LLSDException("Invalid map format");
  129. string key = notationData.Substring(pos, endquote - pos);
  130. key = key.Trim(new char[] { '"', '\'' }); //key.Replace("'", String.Empty);
  131. pos += (endquote - pos) + 2;
  132. int end;
  133. hashtable[key] = ParseNotationElement(notationData.Substring(pos), out end);
  134. pos += end;
  135. }
  136. endPos = pos + 1;
  137. return hashtable;
  138. }
  139. default:
  140. throw new LLSDException("Unknown notation value type");
  141. }
  142. }
  143. private static int FindEnd(string llsd, int start)
  144. {
  145. int end = llsd.IndexOfAny(new char[] { ',', ']', '}' });
  146. if (end == -1) end = llsd.Length - 1;
  147. return end;
  148. }
  149. #region Deprecated
  150. //private static object DeserializeNotation(byte[] notationData, int startPos, out int endPos)
  151. //{
  152. // if (startPos >= notationData.Length)
  153. // {
  154. // endPos = notationData.Length;
  155. // return null;
  156. // }
  157. // switch ((char)notationData[startPos])
  158. // {
  159. // case '!':
  160. // endPos = 1;
  161. // return null;
  162. // case '1':
  163. // endPos = 1;
  164. // return true;
  165. // case '0':
  166. // endPos = 1;
  167. // return false;
  168. // case 'i':
  169. // {
  170. // if (notationData.Length - startPos < 2)
  171. // {
  172. // endPos = notationData.Length;
  173. // return 0;
  174. // }
  175. // int value;
  176. // endPos = FindEnd(notationData, startPos + 1);
  177. // if (Int32.TryParse(UTF8Encoding.UTF8.GetString(notationData, startPos + 1, endPos - (startPos + 1)), out value))
  178. // return value;
  179. // else
  180. // return 0;
  181. // }
  182. // case 'r':
  183. // {
  184. // if (notationData.Length - startPos < 2)
  185. // {
  186. // endPos = notationData.Length;
  187. // return 0d;
  188. // }
  189. // double value;
  190. // endPos = FindEnd(notationData, startPos + 1);
  191. // if (Double.TryParse(UTF8Encoding.UTF8.GetString(notationData, startPos + 1, endPos - (startPos + 1)),
  192. // System.Globalization.NumberStyles.Float, Helpers.EnUsCulture.NumberFormat, out value))
  193. // return value;
  194. // else
  195. // return 0d;
  196. // }
  197. // case 'u':
  198. // {
  199. // if (notationData.Length - startPos < 17)
  200. // {
  201. // endPos = notationData.Length;
  202. // return LLUUID.Zero;
  203. // }
  204. // LLUUID value;
  205. // endPos = FindEnd(notationData, startPos + 1);
  206. // if (LLUUID.TryParse(UTF8Encoding.UTF8.GetString(notationData, startPos + 1, endPos - (startPos + 1)), out value))
  207. // return value;
  208. // else
  209. // return LLUUID.Zero;
  210. // }
  211. // case 'b':
  212. // {
  213. // if (notationData.Length - startPos < 2)
  214. // {
  215. // endPos = notationData.Length;
  216. // return new byte[0];
  217. // }
  218. // byte[] value;
  219. // endPos = FindEnd(notationData, startPos + 1);
  220. // if ((char)notationData[startPos + 1] == '(')
  221. // {
  222. // // Format: b(8)........
  223. // int endParens = Array.FindIndex<byte>(notationData, startPos + 1,
  224. // delegate(byte b) { return (char)b == ')'; });
  225. // if (endParens == -1)
  226. // return new byte[0];
  227. // int len;
  228. // if (!Int32.TryParse(UTF8Encoding.UTF8.GetString(notationData, startPos + 2, endParens - (startPos + 2)), out len))
  229. // return new byte[0];
  230. // // Make sure the size of the binary data doesn't run past the end of the total amount of data we have
  231. // if (endParens + 2 + len >= notationData.Length)
  232. // return new byte[0];
  233. // if ((char)notationData[endParens + 1] == '"')
  234. // {
  235. // // Quoted binary data (I know, this makes no sense)
  236. // value = new byte[len - 2];
  237. // Buffer.BlockCopy(notationData, endParens + 2, value, 0, len - 2);
  238. // }
  239. // else
  240. // {
  241. // // Unquoted binary data (technically breaks the protocol spec but we parse it anyways)
  242. // value = new byte[len];
  243. // Buffer.BlockCopy(notationData, endParens + 1, value, 0, len);
  244. // }
  245. // return value;
  246. // }
  247. // else
  248. // {
  249. // // Format: b64...........==
  250. // if (notationData.Length - startPos < 4)
  251. // return new byte[0];
  252. // int baseVal;
  253. // if (!Int32.TryParse(UTF8Encoding.UTF8.GetString(notationData, startPos + 1, 2), out baseVal))
  254. // return new byte[0];
  255. // string str = UTF8Encoding.UTF8.GetString(notationData, startPos + 3, endPos - (startPos + 3));
  256. // switch (baseVal)
  257. // {
  258. // case 64:
  259. // return Convert.FromBase64String(str);
  260. // default:
  261. // throw new LLSDException("Unsupported encoding: base" + baseVal);
  262. // }
  263. // }
  264. // }
  265. // case '\'':
  266. // // Find the
  267. // break;
  268. // case '"':
  269. // break;
  270. // case 's':
  271. // break;
  272. // case 'l':
  273. // break;
  274. // case 'd':
  275. // break;
  276. // case '[':
  277. // break;
  278. // case '{':
  279. // break;
  280. // default:
  281. // throw new LLSDException("Unhandled notation type: " + (char)notationData[startPos]);
  282. // }
  283. //}
  284. //private static int FindEnd(byte[] llsd, int start)
  285. //{
  286. // int end = Array.FindIndex<byte>(llsd, start,
  287. // delegate(byte b)
  288. // {
  289. // char c = (char)b;
  290. // return (c == ',' || c == ']' || c == '}');
  291. // }
  292. // );
  293. // if (end == -1) end = llsd.Length - 1;
  294. // return end;
  295. //}
  296. #endregion Deprecated
  297. }
  298. }