PageRenderTime 57ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs

https://bitbucket.org/VirtualReality/taiga
C# | 2023 lines | 1582 code | 332 blank | 109 comment | 236 complexity | 5d3c11c1b4f99b6953b42e0df94742b6 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections;
  29. using System.Globalization;
  30. using System.Text.RegularExpressions;
  31. using OpenSim.Framework;
  32. namespace OpenSim.Region.ScriptEngine.Shared
  33. {
  34. [Serializable]
  35. public partial class LSL_Types
  36. {
  37. // Types are kept is separate .dll to avoid having to add whatever .dll it is in it to script AppDomain
  38. [Serializable]
  39. public struct Vector3
  40. {
  41. public double x;
  42. public double y;
  43. public double z;
  44. #region Constructors
  45. public Vector3(Vector3 vector)
  46. {
  47. x = (float)vector.x;
  48. y = (float)vector.y;
  49. z = (float)vector.z;
  50. }
  51. public Vector3(double X, double Y, double Z)
  52. {
  53. x = X;
  54. y = Y;
  55. z = Z;
  56. }
  57. public Vector3(string str)
  58. {
  59. str = str.Replace('<', ' ');
  60. str = str.Replace('>', ' ');
  61. string[] tmps = str.Split(new Char[] { ',', '<', '>' });
  62. if (tmps.Length < 3)
  63. {
  64. x=y=z=0;
  65. return;
  66. }
  67. bool res;
  68. res = Double.TryParse(tmps[0], NumberStyles.Float, Culture.NumberFormatInfo, out x);
  69. res = res & Double.TryParse(tmps[1], NumberStyles.Float, Culture.NumberFormatInfo, out y);
  70. res = res & Double.TryParse(tmps[2], NumberStyles.Float, Culture.NumberFormatInfo, out z);
  71. }
  72. #endregion
  73. #region Overriders
  74. public override string ToString()
  75. {
  76. string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z);
  77. return s;
  78. }
  79. public static explicit operator LSLString(Vector3 vec)
  80. {
  81. string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z);
  82. return new LSLString(s);
  83. }
  84. public static explicit operator string(Vector3 vec)
  85. {
  86. string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z);
  87. return s;
  88. }
  89. public static explicit operator Vector3(string s)
  90. {
  91. return new Vector3(s);
  92. }
  93. public static implicit operator list(Vector3 vec)
  94. {
  95. return new list(new object[] { vec });
  96. }
  97. public static bool operator ==(Vector3 lhs, Vector3 rhs)
  98. {
  99. return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
  100. }
  101. public static bool operator !=(Vector3 lhs, Vector3 rhs)
  102. {
  103. return !(lhs == rhs);
  104. }
  105. public override int GetHashCode()
  106. {
  107. return (x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode());
  108. }
  109. public override bool Equals(object o)
  110. {
  111. if (!(o is Vector3)) return false;
  112. Vector3 vector = (Vector3)o;
  113. return (x == vector.x && y == vector.y && z == vector.z);
  114. }
  115. public static Vector3 operator -(Vector3 vector)
  116. {
  117. return new Vector3(-vector.x, -vector.y, -vector.z);
  118. }
  119. #endregion
  120. #region Vector & Vector Math
  121. // Vector-Vector Math
  122. public static Vector3 operator +(Vector3 lhs, Vector3 rhs)
  123. {
  124. return new Vector3(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
  125. }
  126. public static Vector3 operator -(Vector3 lhs, Vector3 rhs)
  127. {
  128. return new Vector3(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
  129. }
  130. public static LSLFloat operator *(Vector3 lhs, Vector3 rhs)
  131. {
  132. return Dot(lhs, rhs);
  133. }
  134. public static Vector3 operator %(Vector3 v1, Vector3 v2)
  135. {
  136. //Cross product
  137. Vector3 tv;
  138. tv.x = (v1.y * v2.z) - (v1.z * v2.y);
  139. tv.y = (v1.z * v2.x) - (v1.x * v2.z);
  140. tv.z = (v1.x * v2.y) - (v1.y * v2.x);
  141. return tv;
  142. }
  143. #endregion
  144. #region Vector & Float Math
  145. // Vector-Float and Float-Vector Math
  146. public static Vector3 operator *(Vector3 vec, float val)
  147. {
  148. return new Vector3(vec.x * val, vec.y * val, vec.z * val);
  149. }
  150. public static Vector3 operator *(float val, Vector3 vec)
  151. {
  152. return new Vector3(vec.x * val, vec.y * val, vec.z * val);
  153. }
  154. public static Vector3 operator /(Vector3 v, float f)
  155. {
  156. v.x = v.x / f;
  157. v.y = v.y / f;
  158. v.z = v.z / f;
  159. return v;
  160. }
  161. #endregion
  162. #region Vector & Double Math
  163. public static Vector3 operator *(Vector3 vec, double val)
  164. {
  165. return new Vector3(vec.x * val, vec.y * val, vec.z * val);
  166. }
  167. public static Vector3 operator *(double val, Vector3 vec)
  168. {
  169. return new Vector3(vec.x * val, vec.y * val, vec.z * val);
  170. }
  171. public static Vector3 operator /(Vector3 v, double f)
  172. {
  173. v.x = v.x / f;
  174. v.y = v.y / f;
  175. v.z = v.z / f;
  176. return v;
  177. }
  178. #endregion
  179. #region Vector & Rotation Math
  180. // Vector-Rotation Math
  181. public static Vector3 operator *(Vector3 v, Quaternion r)
  182. {
  183. Quaternion vq = new Quaternion(v.x, v.y, v.z, 0);
  184. Quaternion nq = new Quaternion(-r.x, -r.y, -r.z, r.s);
  185. // adapted for operator * computing "b * a"
  186. Quaternion result = nq * (vq * r);
  187. return new Vector3(result.x, result.y, result.z);
  188. }
  189. public static Vector3 operator /(Vector3 v, Quaternion r)
  190. {
  191. r.s = -r.s;
  192. return v * r;
  193. }
  194. #endregion
  195. #region Static Helper Functions
  196. public static double Dot(Vector3 v1, Vector3 v2)
  197. {
  198. return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
  199. }
  200. public static Vector3 Cross(Vector3 v1, Vector3 v2)
  201. {
  202. return new Vector3
  203. (
  204. v1.y * v2.z - v1.z * v2.y,
  205. v1.z * v2.x - v1.x * v2.z,
  206. v1.x * v2.y - v1.y * v2.x
  207. );
  208. }
  209. public static double Mag(Vector3 v)
  210. {
  211. return Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
  212. }
  213. public static Vector3 Norm(Vector3 vector)
  214. {
  215. double mag = Mag(vector);
  216. return new Vector3(vector.x / mag, vector.y / mag, vector.z / mag);
  217. }
  218. #endregion
  219. }
  220. [Serializable]
  221. public struct Quaternion
  222. {
  223. public double x;
  224. public double y;
  225. public double z;
  226. public double s;
  227. #region Constructors
  228. public Quaternion(Quaternion Quat)
  229. {
  230. x = (float)Quat.x;
  231. y = (float)Quat.y;
  232. z = (float)Quat.z;
  233. s = (float)Quat.s;
  234. if (x == 0 && y == 0 && z == 0 && s == 0)
  235. s = 1;
  236. }
  237. public Quaternion(double X, double Y, double Z, double S)
  238. {
  239. x = X;
  240. y = Y;
  241. z = Z;
  242. s = S;
  243. if (x == 0 && y == 0 && z == 0 && s == 0)
  244. s = 1;
  245. }
  246. public Quaternion(string str)
  247. {
  248. str = str.Replace('<', ' ');
  249. str = str.Replace('>', ' ');
  250. string[] tmps = str.Split(new Char[] { ',', '<', '>' });
  251. if (tmps.Length < 4)
  252. {
  253. x=y=z=s=0;
  254. return;
  255. }
  256. bool res;
  257. res = Double.TryParse(tmps[0], NumberStyles.Float, Culture.NumberFormatInfo, out x);
  258. res = res & Double.TryParse(tmps[1], NumberStyles.Float, Culture.NumberFormatInfo, out y);
  259. res = res & Double.TryParse(tmps[2], NumberStyles.Float, Culture.NumberFormatInfo, out z);
  260. res = res & Double.TryParse(tmps[3], NumberStyles.Float, Culture.NumberFormatInfo, out s);
  261. if (x == 0 && y == 0 && z == 0 && s == 0)
  262. s = 1;
  263. }
  264. #endregion
  265. #region Overriders
  266. public override int GetHashCode()
  267. {
  268. return (x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode() ^ s.GetHashCode());
  269. }
  270. public override bool Equals(object o)
  271. {
  272. if (!(o is Quaternion)) return false;
  273. Quaternion quaternion = (Quaternion)o;
  274. return x == quaternion.x && y == quaternion.y && z == quaternion.z && s == quaternion.s;
  275. }
  276. public override string ToString()
  277. {
  278. string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s);
  279. return st;
  280. }
  281. public static explicit operator string(Quaternion r)
  282. {
  283. string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s);
  284. return s;
  285. }
  286. public static explicit operator LSLString(Quaternion r)
  287. {
  288. string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s);
  289. return new LSLString(s);
  290. }
  291. public static explicit operator Quaternion(string s)
  292. {
  293. return new Quaternion(s);
  294. }
  295. public static implicit operator list(Quaternion r)
  296. {
  297. return new list(new object[] { r });
  298. }
  299. public static bool operator ==(Quaternion lhs, Quaternion rhs)
  300. {
  301. // Return true if the fields match:
  302. return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.s == rhs.s;
  303. }
  304. public static bool operator !=(Quaternion lhs, Quaternion rhs)
  305. {
  306. return !(lhs == rhs);
  307. }
  308. public static double Mag(Quaternion q)
  309. {
  310. return Math.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.s * q.s);
  311. }
  312. #endregion
  313. public static Quaternion operator +(Quaternion a, Quaternion b)
  314. {
  315. return new Quaternion(a.x + b.x, a.y + b.y, a.z + b.z, a.s + b.s);
  316. }
  317. public static Quaternion operator /(Quaternion a, Quaternion b)
  318. {
  319. b.s = -b.s;
  320. return a * b;
  321. }
  322. public static Quaternion operator -(Quaternion a, Quaternion b)
  323. {
  324. return new Quaternion(a.x - b.x, a.y - b.y, a.z - b.z, a.s - b.s);
  325. }
  326. // using the equations below, we need to do "b * a" to be compatible with LSL
  327. public static Quaternion operator *(Quaternion b, Quaternion a)
  328. {
  329. Quaternion c;
  330. c.x = a.s * b.x + a.x * b.s + a.y * b.z - a.z * b.y;
  331. c.y = a.s * b.y + a.y * b.s + a.z * b.x - a.x * b.z;
  332. c.z = a.s * b.z + a.z * b.s + a.x * b.y - a.y * b.x;
  333. c.s = a.s * b.s - a.x * b.x - a.y * b.y - a.z * b.z;
  334. return c;
  335. }
  336. }
  337. [Serializable]
  338. public class list
  339. {
  340. private object[] m_data;
  341. public list(params object[] args)
  342. {
  343. m_data = args;
  344. }
  345. public int Length
  346. {
  347. get
  348. {
  349. if (m_data == null)
  350. m_data=new Object[0];
  351. return m_data.Length;
  352. }
  353. }
  354. public int Size
  355. {
  356. get
  357. {
  358. if (m_data == null)
  359. m_data=new Object[0];
  360. int size = 0;
  361. foreach (Object o in m_data)
  362. {
  363. if (o is LSL_Types.LSLInteger)
  364. size += 4;
  365. else if (o is LSL_Types.LSLFloat)
  366. size += 8;
  367. else if (o is LSL_Types.LSLString)
  368. size += ((LSL_Types.LSLString)o).m_string.Length;
  369. else if (o is LSL_Types.key)
  370. size += ((LSL_Types.key)o).value.Length;
  371. else if (o is LSL_Types.Vector3)
  372. size += 32;
  373. else if (o is LSL_Types.Quaternion)
  374. size += 64;
  375. else if (o is int)
  376. size += 4;
  377. else if (o is string)
  378. size += ((string)o).Length;
  379. else if (o is float)
  380. size += 8;
  381. else if (o is double)
  382. size += 16;
  383. else
  384. throw new Exception("Unknown type in List.Size: " + o.GetType().ToString());
  385. }
  386. return size;
  387. }
  388. }
  389. public object[] Data
  390. {
  391. get {
  392. if (m_data == null)
  393. m_data=new Object[0];
  394. return m_data;
  395. }
  396. set {m_data = value; }
  397. }
  398. // Function to obtain LSL type from an index. This is needed
  399. // because LSL lists allow for multiple types, and safely
  400. // iterating in them requires a type check.
  401. public Type GetLSLListItemType(int itemIndex)
  402. {
  403. return m_data[itemIndex].GetType();
  404. }
  405. // Member functions to obtain item as specific types.
  406. // For cases where implicit conversions would apply if items
  407. // were not in a list (e.g. integer to float, but not float
  408. // to integer) functions check for alternate types so as to
  409. // down-cast from Object to the correct type.
  410. // Note: no checks for item index being valid are performed
  411. public LSL_Types.LSLFloat GetLSLFloatItem(int itemIndex)
  412. {
  413. if (m_data[itemIndex] is LSL_Types.LSLInteger)
  414. {
  415. return (LSL_Types.LSLInteger)m_data[itemIndex];
  416. }
  417. else if (m_data[itemIndex] is Int32)
  418. {
  419. return new LSL_Types.LSLFloat((int)m_data[itemIndex]);
  420. }
  421. else if (m_data[itemIndex] is float)
  422. {
  423. return new LSL_Types.LSLFloat((float)m_data[itemIndex]);
  424. }
  425. else if (m_data[itemIndex] is Double)
  426. {
  427. return new LSL_Types.LSLFloat((Double)m_data[itemIndex]);
  428. }
  429. else if (m_data[itemIndex] is LSL_Types.LSLString)
  430. {
  431. return new LSL_Types.LSLFloat(m_data[itemIndex].ToString());
  432. }
  433. else
  434. {
  435. return (LSL_Types.LSLFloat)m_data[itemIndex];
  436. }
  437. }
  438. public LSL_Types.LSLString GetLSLStringItem(int itemIndex)
  439. {
  440. if (m_data[itemIndex] is LSL_Types.key)
  441. {
  442. return (LSL_Types.key)m_data[itemIndex];
  443. }
  444. else if (m_data[itemIndex] is String)
  445. {
  446. return new LSL_Types.LSLString((string)m_data[itemIndex]);
  447. }
  448. else if (m_data[itemIndex] is LSL_Types.LSLFloat)
  449. {
  450. return new LSL_Types.LSLString((LSLFloat)m_data[itemIndex]);
  451. }
  452. else if (m_data[itemIndex] is LSL_Types.LSLInteger)
  453. {
  454. return new LSL_Types.LSLString((LSLInteger)m_data[itemIndex]);
  455. }
  456. else
  457. {
  458. return (LSL_Types.LSLString)m_data[itemIndex];
  459. }
  460. }
  461. public LSL_Types.LSLInteger GetLSLIntegerItem(int itemIndex)
  462. {
  463. if (m_data[itemIndex] is LSL_Types.LSLInteger)
  464. return (LSL_Types.LSLInteger)m_data[itemIndex];
  465. if (m_data[itemIndex] is LSL_Types.LSLFloat)
  466. return new LSLInteger((int)m_data[itemIndex]);
  467. else if (m_data[itemIndex] is Int32)
  468. return new LSLInteger((int)m_data[itemIndex]);
  469. else if (m_data[itemIndex] is LSL_Types.LSLString)
  470. return new LSLInteger((string)m_data[itemIndex]);
  471. else
  472. throw new InvalidCastException();
  473. }
  474. public LSL_Types.Vector3 GetVector3Item(int itemIndex)
  475. {
  476. return (LSL_Types.Vector3)m_data[itemIndex];
  477. }
  478. public LSL_Types.Quaternion GetQuaternionItem(int itemIndex)
  479. {
  480. return (LSL_Types.Quaternion)m_data[itemIndex];
  481. }
  482. public LSL_Types.key GetKeyItem(int itemIndex)
  483. {
  484. return (LSL_Types.key)m_data[itemIndex];
  485. }
  486. public static list operator +(list a, list b)
  487. {
  488. object[] tmp;
  489. tmp = new object[a.Length + b.Length];
  490. a.Data.CopyTo(tmp, 0);
  491. b.Data.CopyTo(tmp, a.Length);
  492. return new list(tmp);
  493. }
  494. private void ExtendAndAdd(object o)
  495. {
  496. Array.Resize(ref m_data, Length + 1);
  497. m_data.SetValue(o, Length - 1);
  498. }
  499. public static list operator +(list a, LSLString s)
  500. {
  501. a.ExtendAndAdd(s);
  502. return a;
  503. }
  504. public static list operator +(list a, LSLInteger i)
  505. {
  506. a.ExtendAndAdd(i);
  507. return a;
  508. }
  509. public static list operator +(list a, LSLFloat d)
  510. {
  511. a.ExtendAndAdd(d);
  512. return a;
  513. }
  514. public static bool operator ==(list a, list b)
  515. {
  516. int la = -1;
  517. int lb = -1;
  518. try { la = a.Length; }
  519. catch (NullReferenceException) { }
  520. try { lb = b.Length; }
  521. catch (NullReferenceException) { }
  522. return la == lb;
  523. }
  524. public static bool operator !=(list a, list b)
  525. {
  526. int la = -1;
  527. int lb = -1;
  528. try { la = a.Length; }
  529. catch (NullReferenceException) { }
  530. try {lb = b.Length;}
  531. catch (NullReferenceException) { }
  532. return la != lb;
  533. }
  534. public void Add(object o)
  535. {
  536. object[] tmp;
  537. tmp = new object[m_data.Length + 1];
  538. m_data.CopyTo(tmp, 0);
  539. tmp[m_data.Length] = o;
  540. m_data = tmp;
  541. }
  542. public bool Contains(object o)
  543. {
  544. bool ret = false;
  545. foreach (object i in Data)
  546. {
  547. if (i == o)
  548. {
  549. ret = true;
  550. break;
  551. }
  552. }
  553. return ret;
  554. }
  555. public list DeleteSublist(int start, int end)
  556. {
  557. // Not an easy one
  558. // If start <= end, remove that part
  559. // if either is negative, count from the end of the array
  560. // if the resulting start > end, remove all BUT that part
  561. Object[] ret;
  562. if (start < 0)
  563. start=m_data.Length-start;
  564. if (start < 0)
  565. start=0;
  566. if (end < 0)
  567. end=m_data.Length-end;
  568. if (end < 0)
  569. end=0;
  570. if (start > end)
  571. {
  572. if (end >= m_data.Length)
  573. return new list(new Object[0]);
  574. if (start >= m_data.Length)
  575. start=m_data.Length-1;
  576. return GetSublist(end, start);
  577. }
  578. // start >= 0 && end >= 0 here
  579. if (start >= m_data.Length)
  580. {
  581. ret=new Object[m_data.Length];
  582. Array.Copy(m_data, 0, ret, 0, m_data.Length);
  583. return new list(ret);
  584. }
  585. if (end >= m_data.Length)
  586. end=m_data.Length-1;
  587. // now, this makes the math easier
  588. int remove=end+1-start;
  589. ret=new Object[m_data.Length-remove];
  590. if (ret.Length == 0)
  591. return new list(ret);
  592. int src;
  593. int dest=0;
  594. for (src = 0; src < m_data.Length; src++)
  595. {
  596. if (src < start || src > end)
  597. ret[dest++]=m_data[src];
  598. }
  599. return new list(ret);
  600. }
  601. public list GetSublist(int start, int end)
  602. {
  603. object[] ret;
  604. // Take care of neg start or end's
  605. // NOTE that either index may still be negative after
  606. // adding the length, so we must take additional
  607. // measures to protect against this. Note also that
  608. // after normalisation the negative indices are no
  609. // longer relative to the end of the list.
  610. if (start < 0)
  611. {
  612. start = m_data.Length + start;
  613. }
  614. if (end < 0)
  615. {
  616. end = m_data.Length + end;
  617. }
  618. // The conventional case is start <= end
  619. // NOTE that the case of an empty list is
  620. // dealt with by the initial test. Start
  621. // less than end is taken to be the most
  622. // common case.
  623. if (start <= end)
  624. {
  625. // Start sublist beyond length
  626. // Also deals with start AND end still negative
  627. if (start >= m_data.Length || end < 0)
  628. {
  629. return new list();
  630. }
  631. // Sublist extends beyond the end of the supplied list
  632. if (end >= m_data.Length)
  633. {
  634. end = m_data.Length - 1;
  635. }
  636. // Sublist still starts before the beginning of the list
  637. if (start < 0)
  638. {
  639. start = 0;
  640. }
  641. ret = new object[end - start + 1];
  642. Array.Copy(m_data, start, ret, 0, end - start + 1);
  643. return new list(ret);
  644. }
  645. // Deal with the segmented case: 0->end + start->EOL
  646. else
  647. {
  648. list result = null;
  649. // If end is negative, then prefix list is empty
  650. if (end < 0)
  651. {
  652. result = new list();
  653. // If start is still negative, then the whole of
  654. // the existing list is returned. This case is
  655. // only admitted if end is also still negative.
  656. if (start < 0)
  657. {
  658. return this;
  659. }
  660. }
  661. else
  662. {
  663. result = GetSublist(0,end);
  664. }
  665. // If start is outside of list, then just return
  666. // the prefix, whatever it is.
  667. if (start >= m_data.Length)
  668. {
  669. return result;
  670. }
  671. return result + GetSublist(start, Data.Length);
  672. }
  673. }
  674. private static int compare(object left, object right, int ascending)
  675. {
  676. if (!left.GetType().Equals(right.GetType()))
  677. {
  678. // unequal types are always "equal" for comparison purposes.
  679. // this way, the bubble sort will never swap them, and we'll
  680. // get that feathered effect we're looking for
  681. return 0;
  682. }
  683. int ret = 0;
  684. if (left is key)
  685. {
  686. key l = (key)left;
  687. key r = (key)right;
  688. ret = String.CompareOrdinal(l.value, r.value);
  689. }
  690. else if (left is LSLString)
  691. {
  692. LSLString l = (LSLString)left;
  693. LSLString r = (LSLString)right;
  694. ret = String.CompareOrdinal(l.m_string, r.m_string);
  695. }
  696. else if (left is LSLInteger)
  697. {
  698. LSLInteger l = (LSLInteger)left;
  699. LSLInteger r = (LSLInteger)right;
  700. ret = Math.Sign(l.value - r.value);
  701. }
  702. else if (left is LSLFloat)
  703. {
  704. LSLFloat l = (LSLFloat)left;
  705. LSLFloat r = (LSLFloat)right;
  706. ret = Math.Sign(l.value - r.value);
  707. }
  708. else if (left is Vector3)
  709. {
  710. Vector3 l = (Vector3)left;
  711. Vector3 r = (Vector3)right;
  712. ret = Math.Sign(Vector3.Mag(l) - Vector3.Mag(r));
  713. }
  714. else if (left is Quaternion)
  715. {
  716. Quaternion l = (Quaternion)left;
  717. Quaternion r = (Quaternion)right;
  718. ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
  719. }
  720. if (ascending == 0)
  721. {
  722. ret = 0 - ret;
  723. }
  724. return ret;
  725. }
  726. class HomogeneousComparer : IComparer
  727. {
  728. public HomogeneousComparer()
  729. {
  730. }
  731. public int Compare(object lhs, object rhs)
  732. {
  733. return compare(lhs, rhs, 1);
  734. }
  735. }
  736. public list Sort(int stride, int ascending)
  737. {
  738. if (Data.Length == 0)
  739. return new list(); // Don't even bother
  740. object[] ret = new object[Data.Length];
  741. Array.Copy(Data, 0, ret, 0, Data.Length);
  742. if (stride <= 0)
  743. {
  744. stride = 1;
  745. }
  746. // we can optimize here in the case where stride == 1 and the list
  747. // consists of homogeneous types
  748. if (stride == 1)
  749. {
  750. bool homogeneous = true;
  751. int index;
  752. for (index = 1; index < Data.Length; index++)
  753. {
  754. if (!Data[0].GetType().Equals(Data[index].GetType()))
  755. {
  756. homogeneous = false;
  757. break;
  758. }
  759. }
  760. if (homogeneous)
  761. {
  762. Array.Sort(ret, new HomogeneousComparer());
  763. if (ascending == 0)
  764. {
  765. Array.Reverse(ret);
  766. }
  767. return new list(ret);
  768. }
  769. }
  770. // Because of the desired type specific feathered sorting behavior
  771. // requried by the spec, we MUST use a non-optimized bubble sort here.
  772. // Anything else will give you the incorrect behavior.
  773. // begin bubble sort...
  774. int i;
  775. int j;
  776. int k;
  777. int n = Data.Length;
  778. for (i = 0; i < (n-stride); i += stride)
  779. {
  780. for (j = i + stride; j < n; j += stride)
  781. {
  782. if (compare(ret[i], ret[j], ascending) > 0)
  783. {
  784. for (k = 0; k < stride; k++)
  785. {
  786. object tmp = ret[i + k];
  787. ret[i + k] = ret[j + k];
  788. ret[j + k] = tmp;
  789. }
  790. }
  791. }
  792. }
  793. // end bubble sort
  794. return new list(ret);
  795. }
  796. #region CSV Methods
  797. public static list FromCSV(string csv)
  798. {
  799. return new list(csv.Split(','));
  800. }
  801. public string ToCSV()
  802. {
  803. string ret = "";
  804. foreach (object o in this.Data)
  805. {
  806. if (ret == "")
  807. {
  808. ret = o.ToString();
  809. }
  810. else
  811. {
  812. ret = ret + ", " + o.ToString();
  813. }
  814. }
  815. return ret;
  816. }
  817. private string ToSoup()
  818. {
  819. string output;
  820. output = String.Empty;
  821. if (m_data.Length == 0)
  822. {
  823. return String.Empty;
  824. }
  825. foreach (object o in m_data)
  826. {
  827. output = output + o.ToString();
  828. }
  829. return output;
  830. }
  831. public static explicit operator String(list l)
  832. {
  833. return l.ToSoup();
  834. }
  835. public static explicit operator LSLString(list l)
  836. {
  837. return new LSLString(l.ToSoup());
  838. }
  839. public override string ToString()
  840. {
  841. return ToSoup();
  842. }
  843. #endregion
  844. #region Statistic Methods
  845. public double Min()
  846. {
  847. double minimum = double.PositiveInfinity;
  848. double entry;
  849. for (int i = 0; i < Data.Length; i++)
  850. {
  851. if (double.TryParse(Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
  852. {
  853. if (entry < minimum) minimum = entry;
  854. }
  855. }
  856. return minimum;
  857. }
  858. public double Max()
  859. {
  860. double maximum = double.NegativeInfinity;
  861. double entry;
  862. for (int i = 0; i < Data.Length; i++)
  863. {
  864. if (double.TryParse(Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
  865. {
  866. if (entry > maximum) maximum = entry;
  867. }
  868. }
  869. return maximum;
  870. }
  871. public double Range()
  872. {
  873. return (this.Max() / this.Min());
  874. }
  875. public int NumericLength()
  876. {
  877. int count = 0;
  878. double entry;
  879. for (int i = 0; i < Data.Length; i++)
  880. {
  881. if (double.TryParse(Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
  882. {
  883. count++;
  884. }
  885. }
  886. return count;
  887. }
  888. public static list ToDoubleList(list src)
  889. {
  890. list ret = new list();
  891. double entry;
  892. for (int i = 0; i < src.Data.Length - 1; i++)
  893. {
  894. if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
  895. {
  896. ret.Add(entry);
  897. }
  898. }
  899. return ret;
  900. }
  901. public double Sum()
  902. {
  903. double sum = 0;
  904. double entry;
  905. for (int i = 0; i < Data.Length; i++)
  906. {
  907. if (double.TryParse(Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
  908. {
  909. sum = sum + entry;
  910. }
  911. }
  912. return sum;
  913. }
  914. public double SumSqrs()
  915. {
  916. double sum = 0;
  917. double entry;
  918. for (int i = 0; i < Data.Length; i++)
  919. {
  920. if (double.TryParse(Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
  921. {
  922. sum = sum + Math.Pow(entry, 2);
  923. }
  924. }
  925. return sum;
  926. }
  927. public double Mean()
  928. {
  929. return (this.Sum() / this.NumericLength());
  930. }
  931. public void NumericSort()
  932. {
  933. IComparer Numeric = new NumericComparer();
  934. Array.Sort(Data, Numeric);
  935. }
  936. public void AlphaSort()
  937. {
  938. IComparer Alpha = new AlphaCompare();
  939. Array.Sort(Data, Alpha);
  940. }
  941. public double Median()
  942. {
  943. return Qi(0.5);
  944. }
  945. public double GeometricMean()
  946. {
  947. double ret = 1.0;
  948. list nums = ToDoubleList(this);
  949. for (int i = 0; i < nums.Data.Length; i++)
  950. {
  951. ret *= (double)nums.Data[i];
  952. }
  953. return Math.Exp(Math.Log(ret) / (double)nums.Data.Length);
  954. }
  955. public double HarmonicMean()
  956. {
  957. double ret = 0.0;
  958. list nums = ToDoubleList(this);
  959. for (int i = 0; i < nums.Data.Length; i++)
  960. {
  961. ret += 1.0 / (double)nums.Data[i];
  962. }
  963. return ((double)nums.Data.Length / ret);
  964. }
  965. public double Variance()
  966. {
  967. double s = 0;
  968. list num = ToDoubleList(this);
  969. for (int i = 0; i < num.Data.Length; i++)
  970. {
  971. s += Math.Pow((double)num.Data[i], 2);
  972. }
  973. return (s - num.Data.Length * Math.Pow(num.Mean(), 2)) / (num.Data.Length - 1);
  974. }
  975. public double StdDev()
  976. {
  977. return Math.Sqrt(this.Variance());
  978. }
  979. public double Qi(double i)
  980. {
  981. list j = this;
  982. j.NumericSort();
  983. if (Math.Ceiling(this.Length * i) == this.Length * i)
  984. {
  985. return (double)((double)j.Data[(int)(this.Length * i - 1)] + (double)j.Data[(int)(this.Length * i)]) / 2;
  986. }
  987. else
  988. {
  989. return (double)j.Data[((int)(Math.Ceiling(this.Length * i))) - 1];
  990. }
  991. }
  992. #endregion
  993. public string ToPrettyString()
  994. {
  995. string output;
  996. if (m_data.Length == 0)
  997. {
  998. return "[]";
  999. }
  1000. output = "[";
  1001. foreach (object o in m_data)
  1002. {
  1003. if (o is String)
  1004. {
  1005. output = output + "\"" + o + "\", ";
  1006. }
  1007. else
  1008. {
  1009. output = output + o.ToString() + ", ";
  1010. }
  1011. }
  1012. output = output.Substring(0, output.Length - 2);
  1013. output = output + "]";
  1014. return output;
  1015. }
  1016. public class AlphaCompare : IComparer
  1017. {
  1018. int IComparer.Compare(object x, object y)
  1019. {
  1020. return string.Compare(x.ToString(), y.ToString());
  1021. }
  1022. }
  1023. public class NumericComparer : IComparer
  1024. {
  1025. int IComparer.Compare(object x, object y)
  1026. {
  1027. double a;
  1028. double b;
  1029. if (!double.TryParse(x.ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out a))
  1030. {
  1031. a = 0.0;
  1032. }
  1033. if (!double.TryParse(y.ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out b))
  1034. {
  1035. b = 0.0;
  1036. }
  1037. if (a < b)
  1038. {
  1039. return -1;
  1040. }
  1041. else if (a == b)
  1042. {
  1043. return 0;
  1044. }
  1045. else
  1046. {
  1047. return 1;
  1048. }
  1049. }
  1050. }
  1051. public override bool Equals(object o)
  1052. {
  1053. if (!(o is list))
  1054. return false;
  1055. return Data.Length == ((list)o).Data.Length;
  1056. }
  1057. public override int GetHashCode()
  1058. {
  1059. return Data.GetHashCode();
  1060. }
  1061. }
  1062. //
  1063. // BELOW IS WORK IN PROGRESS... IT WILL CHANGE, SO DON'T USE YET! :)
  1064. //
  1065. public struct StringTest
  1066. {
  1067. // Our own little string
  1068. internal string actualString;
  1069. public static implicit operator bool(StringTest mString)
  1070. {
  1071. if (mString.actualString.Length == 0)
  1072. return true;
  1073. return false;
  1074. }
  1075. public override string ToString()
  1076. {
  1077. return actualString;
  1078. }
  1079. }
  1080. [Serializable]
  1081. public struct key
  1082. {
  1083. public string value;
  1084. #region Constructors
  1085. public key(string s)
  1086. {
  1087. value = s;
  1088. }
  1089. #endregion
  1090. #region Methods
  1091. static public bool Parse2Key(string s)
  1092. {
  1093. Regex isuuid = new Regex(@"^[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}$", RegexOptions.Compiled);
  1094. if (isuuid.IsMatch(s))
  1095. {
  1096. return true;
  1097. }
  1098. else
  1099. {
  1100. return false;
  1101. }
  1102. }
  1103. #endregion
  1104. #region Operators
  1105. static public implicit operator Boolean(key k)
  1106. {
  1107. if (k.value.Length == 0)
  1108. {
  1109. return false;
  1110. }
  1111. if (k.value == "00000000-0000-0000-0000-000000000000")
  1112. {
  1113. return false;
  1114. }
  1115. Regex isuuid = new Regex(@"^[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}$", RegexOptions.Compiled);
  1116. if (isuuid.IsMatch(k.value))
  1117. {
  1118. return true;
  1119. }
  1120. else
  1121. {
  1122. return false;
  1123. }
  1124. }
  1125. static public implicit operator key(string s)
  1126. {
  1127. return new key(s);
  1128. }
  1129. static public implicit operator String(key k)
  1130. {
  1131. return k.value;
  1132. }
  1133. static public implicit operator LSLString(key k)
  1134. {
  1135. return k.value;
  1136. }
  1137. public static bool operator ==(key k1, key k2)
  1138. {
  1139. return k1.value == k2.value;
  1140. }
  1141. public static bool operator !=(key k1, key k2)
  1142. {
  1143. return k1.value != k2.value;
  1144. }
  1145. #endregion
  1146. #region Overriders
  1147. public override bool Equals(object o)
  1148. {
  1149. return o.ToString() == value;
  1150. }
  1151. public override int GetHashCode()
  1152. {
  1153. return value.GetHashCode();
  1154. }
  1155. public override string ToString()
  1156. {
  1157. return value;
  1158. }
  1159. #endregion
  1160. }
  1161. [Serializable]
  1162. public struct LSLString
  1163. {
  1164. public string m_string;
  1165. #region Constructors
  1166. public LSLString(string s)
  1167. {
  1168. m_string = s;
  1169. }
  1170. public LSLString(double d)
  1171. {
  1172. string s=String.Format(Culture.FormatProvider, "{0:0.000000}", d);
  1173. m_string=s;
  1174. }
  1175. public LSLString(LSLFloat f)
  1176. {
  1177. string s = String.Format(Culture.FormatProvider, "{0:0.000000}", f.value);
  1178. m_string=s;
  1179. }
  1180. public LSLString(LSLInteger i)
  1181. {
  1182. string s = String.Format("{0}", i);
  1183. m_string = s;
  1184. }
  1185. #endregion
  1186. #region Operators
  1187. static public implicit operator Boolean(LSLString s)
  1188. {
  1189. if (s.m_string.Length == 0)
  1190. {
  1191. return false;
  1192. }
  1193. else
  1194. {
  1195. return true;
  1196. }
  1197. }
  1198. static public implicit operator String(LSLString s)
  1199. {
  1200. return s.m_string;
  1201. }
  1202. static public implicit operator LSLString(string s)
  1203. {
  1204. return new LSLString(s);
  1205. }
  1206. public static string ToString(LSLString s)
  1207. {
  1208. return s.m_string;
  1209. }
  1210. public override string ToString()
  1211. {
  1212. return m_string;
  1213. }
  1214. public static bool operator ==(LSLString s1, string s2)
  1215. {
  1216. return s1.m_string == s2;
  1217. }
  1218. public static bool operator !=(LSLString s1, string s2)
  1219. {
  1220. return s1.m_string != s2;
  1221. }
  1222. public static LSLString operator +(LSLString s1, LSLString s2)
  1223. {
  1224. return new LSLString(s1.m_string + s2.m_string);
  1225. }
  1226. public static explicit operator double(LSLString s)
  1227. {
  1228. return new LSLFloat(s).value;
  1229. }
  1230. public static explicit operator LSLInteger(LSLString s)
  1231. {
  1232. return new LSLInteger(s.m_string);
  1233. }
  1234. public static explicit operator LSLString(double d)
  1235. {
  1236. return new LSLString(d);
  1237. }
  1238. public static explicit operator LSLString(LSLFloat f)
  1239. {
  1240. return new LSLString(f);
  1241. }
  1242. static public explicit operator LSLString(bool b)
  1243. {
  1244. if (b)
  1245. return new LSLString("1");
  1246. else
  1247. return new LSLString("0");
  1248. }
  1249. public static implicit operator Vector3(LSLString s)
  1250. {
  1251. return new Vector3(s.m_string);
  1252. }
  1253. public static implicit operator Quaternion(LSLString s)
  1254. {
  1255. return new Quaternion(s.m_string);
  1256. }
  1257. public static implicit operator LSLFloat(LSLString s)
  1258. {
  1259. return new LSLFloat(s);
  1260. }
  1261. public static implicit operator list(LSLString s)
  1262. {
  1263. return new list(new object[]{s});
  1264. }
  1265. #endregion
  1266. #region Overriders
  1267. public override bool Equals(object o)
  1268. {
  1269. return m_string == o.ToString();
  1270. }
  1271. public override int GetHashCode()
  1272. {
  1273. return m_string.GetHashCode();
  1274. }
  1275. #endregion
  1276. #region " Standard string functions "
  1277. //Clone,CompareTo,Contains
  1278. //CopyTo,EndsWith,Equals,GetEnumerator,GetHashCode,GetType,GetTypeCode
  1279. //IndexOf,IndexOfAny,Insert,IsNormalized,LastIndexOf,LastIndexOfAny
  1280. //Length,Normalize,PadLeft,PadRight,Remove,Replace,Split,StartsWith,Substring,ToCharArray,ToLowerInvariant
  1281. //ToString,ToUpper,ToUpperInvariant,Trim,TrimEnd,TrimStart
  1282. public bool Contains(string value) { return m_string.Contains(value); }
  1283. public int IndexOf(string value) { return m_string.IndexOf(value); }
  1284. public int Length { get { return m_string.Length; } }
  1285. #endregion
  1286. }
  1287. [Serializable]
  1288. public struct LSLInteger
  1289. {
  1290. public int value;
  1291. #region Constructors
  1292. public LSLInteger(int i)
  1293. {
  1294. value = i;
  1295. }
  1296. public LSLInteger(uint i)
  1297. {
  1298. value = (int)i;
  1299. }
  1300. public LSLInteger(double d)
  1301. {
  1302. value = (int)d;
  1303. }
  1304. public LSLInteger(string s)
  1305. {
  1306. Regex r = new Regex("(^[ ]*0[xX][0-9A-Fa-f][0-9A-Fa-f]*)|(^[ ]*-?[0-9][0-9]*)");
  1307. Match m = r.Match(s);
  1308. string v = m.Groups[0].Value;
  1309. if (v == String.Empty)
  1310. {
  1311. value = 0;
  1312. }
  1313. else
  1314. {
  1315. try
  1316. {
  1317. if (v.Contains("x") || v.Contains("X"))
  1318. {
  1319. value = int.Parse(v.Substring(2), System.Globalization.NumberStyles.HexNumber);
  1320. }
  1321. else
  1322. {
  1323. value = int.Parse(v, System.Globalization.NumberStyles.Integer);
  1324. }
  1325. }
  1326. catch (OverflowException)
  1327. {
  1328. value = -1;
  1329. }
  1330. }
  1331. }
  1332. #endregion
  1333. #region Operators
  1334. static public implicit operator int(LSLInteger i)
  1335. {
  1336. return i.value;
  1337. }
  1338. static public explicit operator uint(LSLInteger i)
  1339. {
  1340. return (uint)i.value;
  1341. }

Large files files are truncated, but you can click here to view the full file