LSL_Types.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335
  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 OpenSim 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.Text.RegularExpressions;
  30. namespace OpenSim.Region.ScriptEngine.Common
  31. {
  32. [Serializable]
  33. public partial class LSL_Types
  34. {
  35. // Types are kept is separate .dll to avoid having to add whatever .dll it is in it to script AppDomain
  36. [Serializable]
  37. public struct Vector3
  38. {
  39. public double x;
  40. public double y;
  41. public double z;
  42. #region Constructors
  43. public Vector3(Vector3 vector)
  44. {
  45. x = (float)vector.x;
  46. y = (float)vector.y;
  47. z = (float)vector.z;
  48. }
  49. public Vector3(double X, double Y, double Z)
  50. {
  51. x = X;
  52. y = Y;
  53. z = Z;
  54. }
  55. public Vector3(string str)
  56. {
  57. str = str.Replace('<', ' ');
  58. str = str.Replace('>', ' ');
  59. string[] tmps = str.Split(new Char[] { ',', '<', '>' });
  60. if(tmps.Length < 3)
  61. {
  62. x=y=z=0;
  63. return;
  64. }
  65. bool res;
  66. res = Double.TryParse(tmps[0], out x);
  67. res = res & Double.TryParse(tmps[1], out y);
  68. res = res & Double.TryParse(tmps[2], out z);
  69. }
  70. #endregion
  71. #region Overriders
  72. public override string ToString()
  73. {
  74. string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z);
  75. return s;
  76. }
  77. public static explicit operator LSLString(Vector3 vec)
  78. {
  79. string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z);
  80. return new LSLString(s);
  81. }
  82. public static explicit operator string(Vector3 vec)
  83. {
  84. string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z);
  85. return s;
  86. }
  87. public static explicit operator Vector3(string s)
  88. {
  89. return new Vector3(s);
  90. }
  91. public static bool operator ==(Vector3 lhs, Vector3 rhs)
  92. {
  93. return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
  94. }
  95. public static bool operator !=(Vector3 lhs, Vector3 rhs)
  96. {
  97. return !(lhs == rhs);
  98. }
  99. public override int GetHashCode()
  100. {
  101. return (x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode());
  102. }
  103. public override bool Equals(object o)
  104. {
  105. if (!(o is Vector3)) return false;
  106. Vector3 vector = (Vector3)o;
  107. return (x == vector.x && x == vector.x && z == vector.z);
  108. }
  109. #endregion
  110. #region Vector & Vector Math
  111. // Vector-Vector Math
  112. public static Vector3 operator +(Vector3 lhs, Vector3 rhs)
  113. {
  114. return new Vector3(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
  115. }
  116. public static Vector3 operator -(Vector3 lhs, Vector3 rhs)
  117. {
  118. return new Vector3(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
  119. }
  120. public static Vector3 operator *(Vector3 lhs, Vector3 rhs)
  121. {
  122. return new Vector3(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z);
  123. }
  124. public static Vector3 operator %(Vector3 v1, Vector3 v2)
  125. {
  126. //Cross product
  127. Vector3 tv;
  128. tv.x = (v1.y * v2.z) - (v1.z * v2.y);
  129. tv.y = (v1.z * v2.x) - (v1.x * v2.z);
  130. tv.z = (v1.x * v2.y) - (v1.y * v2.x);
  131. return tv;
  132. }
  133. #endregion
  134. #region Vector & Float Math
  135. // Vector-Float and Float-Vector Math
  136. public static Vector3 operator *(Vector3 vec, float val)
  137. {
  138. return new Vector3(vec.x * val, vec.y * val, vec.z * val);
  139. }
  140. public static Vector3 operator *(float val, Vector3 vec)
  141. {
  142. return new Vector3(vec.x * val, vec.y * val, vec.z * val);
  143. }
  144. public static Vector3 operator /(Vector3 v, float f)
  145. {
  146. v.x = v.x / f;
  147. v.y = v.y / f;
  148. v.z = v.z / f;
  149. return v;
  150. }
  151. #endregion
  152. #region Vector & Double Math
  153. public static Vector3 operator *(Vector3 vec, double val)
  154. {
  155. return new Vector3(vec.x * val, vec.y * val, vec.z * val);
  156. }
  157. public static Vector3 operator *(double val, Vector3 vec)
  158. {
  159. return new Vector3(vec.x * val, vec.y * val, vec.z * val);
  160. }
  161. public static Vector3 operator /(Vector3 v, double f)
  162. {
  163. v.x = v.x / f;
  164. v.y = v.y / f;
  165. v.z = v.z / f;
  166. return v;
  167. }
  168. #endregion
  169. #region Vector & Rotation Math
  170. // Vector-Rotation Math
  171. public static Vector3 operator *(Vector3 v, Quaternion r)
  172. {
  173. Quaternion vq = new Quaternion(v.x, v.y, v.z, 0);
  174. Quaternion nq = new Quaternion(-r.x, -r.y, -r.z, r.s);
  175. Quaternion result = (r * vq) * nq;
  176. return new Vector3(result.x, result.y, result.z);
  177. }
  178. // I *think* this is how it works....
  179. public static Vector3 operator /(Vector3 vec, Quaternion quat)
  180. {
  181. quat.s = -quat.s;
  182. Quaternion vq = new Quaternion(vec.x, vec.y, vec.z, 0);
  183. Quaternion nq = new Quaternion(-quat.x, -quat.y, -quat.z, quat.s);
  184. Quaternion result = (quat * vq) * nq;
  185. return new Vector3(result.x, result.y, result.z);
  186. }
  187. #endregion
  188. #region Static Helper Functions
  189. public static double Dot(Vector3 v1, Vector3 v2)
  190. {
  191. return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
  192. }
  193. public static Vector3 Cross(Vector3 v1, Vector3 v2)
  194. {
  195. return new Vector3
  196. (
  197. v1.y * v2.z - v1.z * v2.y,
  198. v1.z * v2.x - v1.x * v2.z,
  199. v1.x * v2.y - v1.y * v2.x
  200. );
  201. }
  202. public static double Mag(Vector3 v)
  203. {
  204. return Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
  205. }
  206. public static Vector3 Norm(Vector3 vector)
  207. {
  208. double mag = Mag(vector);
  209. return new Vector3(vector.x / mag, vector.y / mag, vector.z / mag);
  210. }
  211. #endregion
  212. }
  213. [Serializable]
  214. public struct Quaternion
  215. {
  216. public double x;
  217. public double y;
  218. public double z;
  219. public double s;
  220. #region Constructors
  221. public Quaternion(Quaternion Quat)
  222. {
  223. x = (float)Quat.x;
  224. y = (float)Quat.y;
  225. z = (float)Quat.z;
  226. s = (float)Quat.s;
  227. if (x == 0 && y == 0 && z == 0 && s == 0)
  228. s = 1;
  229. }
  230. public Quaternion(double X, double Y, double Z, double S)
  231. {
  232. x = X;
  233. y = Y;
  234. z = Z;
  235. s = S;
  236. if (x == 0 && y == 0 && z == 0 && s == 0)
  237. s = 1;
  238. }
  239. public Quaternion(string str)
  240. {
  241. str = str.Replace('<', ' ');
  242. str = str.Replace('>', ' ');
  243. string[] tmps = str.Split(new Char[] { ',', '<', '>' });
  244. if(tmps.Length < 4)
  245. {
  246. x=y=z=s=0;
  247. return;
  248. }
  249. bool res;
  250. res = Double.TryParse(tmps[0], out x);
  251. res = res & Double.TryParse(tmps[1], out y);
  252. res = res & Double.TryParse(tmps[2], out z);
  253. res = res & Double.TryParse(tmps[3], out s);
  254. if (x == 0 && y == 0 && z == 0 && s == 0)
  255. s = 1;
  256. }
  257. #endregion
  258. #region Overriders
  259. public override int GetHashCode()
  260. {
  261. return (x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode() ^ s.GetHashCode());
  262. }
  263. public override bool Equals(object o)
  264. {
  265. if (!(o is Quaternion)) return false;
  266. Quaternion quaternion = (Quaternion)o;
  267. return x == quaternion.x && y == quaternion.y && z == quaternion.z && s == quaternion.s;
  268. }
  269. public override string ToString()
  270. {
  271. string st=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s);
  272. return st;
  273. }
  274. public static explicit operator string(Quaternion r)
  275. {
  276. string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s);
  277. return s;
  278. }
  279. public static explicit operator LSLString(Quaternion r)
  280. {
  281. string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s);
  282. return new LSLString(s);
  283. }
  284. public static explicit operator Quaternion(string s)
  285. {
  286. return new Quaternion(s);
  287. }
  288. public static bool operator ==(Quaternion lhs, Quaternion rhs)
  289. {
  290. // Return true if the fields match:
  291. return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.s == rhs.s;
  292. }
  293. public static bool operator !=(Quaternion lhs, Quaternion rhs)
  294. {
  295. return !(lhs == rhs);
  296. }
  297. #endregion
  298. public static Quaternion operator +(Quaternion a, Quaternion b)
  299. {
  300. return new Quaternion(a.x + b.x, a.y + b.y, a.z + b.z, a.s + b.s);
  301. }
  302. public static Quaternion operator /(Quaternion a, Quaternion b)
  303. {
  304. Quaternion c = a * b;
  305. c.s = c.s * -1;
  306. return c;
  307. }
  308. public static Quaternion operator -(Quaternion a, Quaternion b)
  309. {
  310. return new Quaternion(a.x - b.x, a.y - b.y, a.z - b.z, a.s - b.s);
  311. }
  312. public static Quaternion operator *(Quaternion a, Quaternion b)
  313. {
  314. Quaternion c;
  315. c.x = a.s * b.x + a.x * b.s + a.y * b.z - a.z * b.y;
  316. c.y = a.s * b.y + a.y * b.s + a.z * b.x - a.x * b.z;
  317. c.z = a.s * b.z + a.z * b.s + a.x * b.y - a.y * b.x;
  318. c.s = a.s * b.s - a.x * b.x - a.y * b.y - a.z * b.z;
  319. return c;
  320. }
  321. }
  322. [Serializable]
  323. public class list
  324. {
  325. private object[] m_data;
  326. public list(params object[] args)
  327. {
  328. m_data = new object[args.Length];
  329. m_data = args;
  330. }
  331. public int Length
  332. {
  333. get {
  334. if(m_data == null)
  335. m_data=new Object[0];
  336. return m_data.Length;
  337. }
  338. }
  339. public object[] Data
  340. {
  341. get {
  342. if(m_data == null)
  343. m_data=new Object[0];
  344. return m_data;
  345. }
  346. }
  347. public static list operator +(list a, list b)
  348. {
  349. object[] tmp;
  350. tmp = new object[a.Length + b.Length];
  351. a.Data.CopyTo(tmp, 0);
  352. b.Data.CopyTo(tmp, a.Length);
  353. return new list(tmp);
  354. }
  355. public void Add(object o)
  356. {
  357. object[] tmp;
  358. tmp = new object[m_data.Length + 1];
  359. m_data.CopyTo(tmp, 0);
  360. tmp[m_data.Length] = o;
  361. m_data = tmp;
  362. }
  363. public bool Contains(object o)
  364. {
  365. bool ret = false;
  366. foreach (object i in Data)
  367. {
  368. if (i == o)
  369. {
  370. ret = true;
  371. break;
  372. }
  373. }
  374. return ret;
  375. }
  376. public list DeleteSublist(int start, int end)
  377. {
  378. // Not an easy one
  379. // If start <= end, remove that part
  380. // if either is negative, count from the end of the array
  381. // if the resulting start > end, remove all BUT that part
  382. Object[] ret;
  383. if(start < 0)
  384. start=m_data.Length-start;
  385. if(start < 0)
  386. start=0;
  387. if(end < 0)
  388. end=m_data.Length-end;
  389. if(end < 0)
  390. end=0;
  391. if(start > end)
  392. {
  393. if(end >= m_data.Length)
  394. return new list(new Object[0]);
  395. if(start >= m_data.Length)
  396. start=m_data.Length-1;
  397. return GetSublist(end, start);
  398. }
  399. // start >= 0 && end >= 0 here
  400. if(start >= m_data.Length)
  401. {
  402. ret=new Object[m_data.Length];
  403. Array.Copy(m_data, 0, ret, 0, m_data.Length);
  404. return new list(ret);
  405. }
  406. if(end >= m_data.Length)
  407. end=m_data.Length-1;
  408. // now, this makes the math easier
  409. int remove=end+1-start;
  410. ret=new Object[m_data.Length-remove];
  411. if(ret.Length == 0)
  412. return new list(ret);
  413. int src;
  414. int dest=0;
  415. for(src = 0 ; src < m_data.Length ; src++)
  416. {
  417. if(src < start || src > end)
  418. ret[dest++]=m_data[src];
  419. }
  420. return new list(ret);
  421. }
  422. public list GetSublist(int start, int end)
  423. {
  424. object[] ret;
  425. // Take care of neg start or end's
  426. // NOTE that either index may still be negative after
  427. // adding the length, so we must take additional
  428. // measures to protect against this. Note also that
  429. // after normalisation the negative indices are no
  430. // longer relative to the end of the list.
  431. if (start < 0)
  432. {
  433. start = m_data.Length + start;
  434. }
  435. if (end < 0)
  436. {
  437. end = m_data.Length + end;
  438. }
  439. // The conventional case is start <= end
  440. // NOTE that the case of an empty list is
  441. // dealt with by the initial test. Start
  442. // less than end is taken to be the most
  443. // common case.
  444. if (start <= end)
  445. {
  446. // Start sublist beyond length
  447. // Also deals with start AND end still negative
  448. if (start >= m_data.Length || end < 0)
  449. {
  450. return new list();
  451. }
  452. // Sublist extends beyond the end of the supplied list
  453. if (end >= m_data.Length)
  454. {
  455. end = m_data.Length - 1;
  456. }
  457. // Sublist still starts before the beginning of the list
  458. if (start < 0)
  459. {
  460. start = 0;
  461. }
  462. ret = new object[end - start + 1];
  463. Array.Copy(m_data, start, ret, 0, end - start + 1);
  464. return new list(ret);
  465. }
  466. // Deal with the segmented case: 0->end + start->EOL
  467. else
  468. {
  469. list result = null;
  470. // If end is negative, then prefix list is empty
  471. if(end < 0)
  472. {
  473. result = new list();
  474. // If start is still negative, then the whole of
  475. // the existing list is returned. This case is
  476. // only admitted if end is also still negative.
  477. if(start < 0)
  478. {
  479. return this;
  480. }
  481. }
  482. else
  483. {
  484. result = GetSublist(0,end);
  485. }
  486. // If start is outside of list, then just return
  487. // the prefix, whatever it is.
  488. if(start >= m_data.Length)
  489. {
  490. return result;
  491. }
  492. return result + GetSublist(start, Data.Length);
  493. }
  494. }
  495. public list Sort(int stride, int ascending)
  496. {
  497. if(Data.Length == 0)
  498. return new list(); // Don't even bother
  499. string[] keys;
  500. if(stride == 1) // The simple case
  501. {
  502. Object[] ret=new Object[Data.Length];
  503. Array.Copy(Data, 0, ret, 0, Data.Length);
  504. keys=new string[Data.Length];
  505. int k;
  506. for(k=0;k<Data.Length;k++)
  507. keys[k]=Data[k].ToString();
  508. Array.Sort(keys, ret);
  509. if(ascending == 0)
  510. Array.Reverse(ret);
  511. return new list(ret);
  512. }
  513. int src=0;
  514. int len=(Data.Length+stride-1)/stride;
  515. keys=new string[len];
  516. Object[][] vals=new Object[len][];
  517. int i;
  518. while(src < Data.Length)
  519. {
  520. Object[] o=new Object[stride];
  521. for(i=0;i<stride;i++)
  522. {
  523. if(src < Data.Length)
  524. o[i]=Data[src++];
  525. else
  526. {
  527. o[i]=new Object();
  528. src++;
  529. }
  530. }
  531. int idx=src/stride-1;
  532. keys[idx]=o[0].ToString();
  533. vals[idx]=o;
  534. }
  535. Array.Sort(keys, vals);
  536. if(ascending == 0)
  537. {
  538. Array.Reverse(vals);
  539. }
  540. Object[] sorted=new Object[stride*vals.Length];
  541. int j;
  542. for(i=0;i<vals.Length;i++)
  543. for(j=0;j<stride;j++)
  544. sorted[i*stride+j]=vals[i][j];
  545. return new list(sorted);
  546. }
  547. #region CSV Methods
  548. public static list FromCSV(string csv)
  549. {
  550. return new list(csv.Split(','));
  551. }
  552. public string ToCSV()
  553. {
  554. string ret = "";
  555. foreach(object o in this.Data)
  556. {
  557. if(ret == "")
  558. {
  559. ret = o.ToString();
  560. }
  561. else
  562. {
  563. ret = ret + ", " + o.ToString();
  564. }
  565. }
  566. return ret;
  567. }
  568. #endregion
  569. #region Statistic Methods
  570. public double Min()
  571. {
  572. double minimum = double.PositiveInfinity;
  573. double entry;
  574. for (int i = 0; i < Data.Length; i++)
  575. {
  576. if (double.TryParse(Data[i].ToString(), out entry))
  577. {
  578. if (entry < minimum) minimum = entry;
  579. }
  580. }
  581. return minimum;
  582. }
  583. public double Max()
  584. {
  585. double maximum = double.NegativeInfinity;
  586. double entry;
  587. for (int i = 0; i < Data.Length; i++)
  588. {
  589. if (double.TryParse(Data[i].ToString(), out entry))
  590. {
  591. if (entry > maximum) maximum = entry;
  592. }
  593. }
  594. return maximum;
  595. }
  596. public double Range()
  597. {
  598. return (this.Max() / this.Min());
  599. }
  600. public int NumericLength()
  601. {
  602. int count = 0;
  603. double entry;
  604. for (int i = 0; i < Data.Length; i++)
  605. {
  606. if (double.TryParse(Data[i].ToString(), out entry))
  607. {
  608. count++;
  609. }
  610. }
  611. return count;
  612. }
  613. public static list ToDoubleList(list src)
  614. {
  615. list ret = new list();
  616. double entry;
  617. for (int i = 0; i < src.Data.Length - 1; i++)
  618. {
  619. if (double.TryParse(src.Data[i].ToString(), out entry))
  620. {
  621. ret.Add(entry);
  622. }
  623. }
  624. return ret;
  625. }
  626. public double Sum()
  627. {
  628. double sum = 0;
  629. double entry;
  630. for (int i = 0; i < Data.Length; i++)
  631. {
  632. if (double.TryParse(Data[i].ToString(), out entry))
  633. {
  634. sum = sum + entry;
  635. }
  636. }
  637. return sum;
  638. }
  639. public double SumSqrs()
  640. {
  641. double sum = 0;
  642. double entry;
  643. for (int i = 0; i < Data.Length; i++)
  644. {
  645. if (double.TryParse(Data[i].ToString(), out entry))
  646. {
  647. sum = sum + Math.Pow(entry, 2);
  648. }
  649. }
  650. return sum;
  651. }
  652. public double Mean()
  653. {
  654. return (this.Sum() / this.NumericLength());
  655. }
  656. public void NumericSort()
  657. {
  658. IComparer Numeric = new NumericComparer();
  659. Array.Sort(Data, Numeric);
  660. }
  661. public void AlphaSort()
  662. {
  663. IComparer Alpha = new AlphaCompare();
  664. Array.Sort(Data, Alpha);
  665. }
  666. public double Median()
  667. {
  668. return Qi(0.5);
  669. }
  670. public double GeometricMean()
  671. {
  672. double ret = 1.0;
  673. list nums = ToDoubleList(this);
  674. for (int i = 0; i < nums.Data.Length; i++)
  675. {
  676. ret *= (double)nums.Data[i];
  677. }
  678. return Math.Exp(Math.Log(ret) / (double)nums.Data.Length);
  679. }
  680. public double HarmonicMean()
  681. {
  682. double ret = 0.0;
  683. list nums = ToDoubleList(this);
  684. for (int i = 0; i < nums.Data.Length; i++)
  685. {
  686. ret += 1.0 / (double)nums.Data[i];
  687. }
  688. return ((double)nums.Data.Length / ret);
  689. }
  690. public double Variance()
  691. {
  692. double s = 0;
  693. list num = ToDoubleList(this);
  694. for (int i = 0; i < num.Data.Length; i++)
  695. {
  696. s += Math.Pow((double)num.Data[i], 2);
  697. }
  698. return (s - num.Data.Length * Math.Pow(num.Mean(), 2)) / (num.Data.Length - 1);
  699. }
  700. public double StdDev()
  701. {
  702. return Math.Sqrt(this.Variance());
  703. }
  704. public double Qi(double i)
  705. {
  706. list j = this;
  707. j.NumericSort();
  708. if (Math.Ceiling(this.Length * i) == this.Length * i)
  709. {
  710. return (double)((double)j.Data[(int)(this.Length * i - 1)] + (double)j.Data[(int)(this.Length * i)]) / 2;
  711. }
  712. else
  713. {
  714. return (double)j.Data[((int)(Math.Ceiling(this.Length * i))) - 1];
  715. }
  716. }
  717. #endregion
  718. public string ToPrettyString()
  719. {
  720. string output;
  721. if (m_data.Length == 0)
  722. {
  723. return "[]";
  724. }
  725. output = "[";
  726. foreach (object o in m_data)
  727. {
  728. if (o is String)
  729. {
  730. output = output + "\"" + o + "\", ";
  731. }
  732. else
  733. {
  734. output = output + o.ToString() + ", ";
  735. }
  736. }
  737. output = output.Substring(0, output.Length - 2);
  738. output = output + "]";
  739. return output;
  740. }
  741. public class AlphaCompare : IComparer
  742. {
  743. int IComparer.Compare(object x, object y)
  744. {
  745. return string.Compare(x.ToString(), y.ToString());
  746. }
  747. }
  748. public class NumericComparer : IComparer
  749. {
  750. int IComparer.Compare(object x, object y)
  751. {
  752. double a;
  753. double b;
  754. if (!double.TryParse(x.ToString(), out a))
  755. {
  756. a = 0.0;
  757. }
  758. if (!double.TryParse(y.ToString(), out b))
  759. {
  760. b = 0.0;
  761. }
  762. if (a < b)
  763. {
  764. return -1;
  765. }
  766. else if (a == b)
  767. {
  768. return 0;
  769. }
  770. else
  771. {
  772. return 1;
  773. }
  774. }
  775. }
  776. public override string ToString()
  777. {
  778. string output;
  779. output = String.Empty;
  780. if (m_data.Length == 0)
  781. {
  782. return String.Empty;
  783. }
  784. foreach (object o in m_data)
  785. {
  786. output = output + o.ToString();
  787. }
  788. return output;
  789. }
  790. public static explicit operator string(list l)
  791. {
  792. string output;
  793. output = String.Empty;
  794. if (l.m_data.Length == 0)
  795. {
  796. return String.Empty;
  797. }
  798. foreach (object o in l.m_data)
  799. {
  800. output = output + o.ToString();
  801. }
  802. return output;
  803. }
  804. }
  805. //
  806. // BELOW IS WORK IN PROGRESS... IT WILL CHANGE, SO DON'T USE YET! :)
  807. //
  808. public struct StringTest
  809. {
  810. // Our own little string
  811. internal string actualString;
  812. public static implicit operator bool(StringTest mString)
  813. {
  814. if (mString.actualString.Length == 0)
  815. return true;
  816. return false;
  817. }
  818. public override string ToString()
  819. {
  820. return actualString;
  821. }
  822. }
  823. [Serializable]
  824. public struct key
  825. {
  826. public string value;
  827. #region Constructors
  828. public key(string s)
  829. {
  830. value = s;
  831. }
  832. #endregion
  833. #region Methods
  834. static public bool Parse2Key(string s)
  835. {
  836. 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);
  837. if (isuuid.IsMatch(s))
  838. {
  839. return true;
  840. }
  841. else
  842. {
  843. return false;
  844. }
  845. }
  846. #endregion
  847. #region Operators
  848. static public implicit operator Boolean(key k)
  849. {
  850. if (k.value.Length == 0)
  851. {
  852. return false;
  853. }
  854. if (k.value == "00000000-0000-0000-0000-000000000000")
  855. {
  856. return false;
  857. }
  858. 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);
  859. if (isuuid.IsMatch(k.value))
  860. {
  861. return true;
  862. }
  863. else
  864. {
  865. return false;
  866. }
  867. }
  868. static public implicit operator key(string s)
  869. {
  870. return new key(s);
  871. }
  872. static public implicit operator String(key k)
  873. {
  874. return k.value;
  875. }
  876. public static bool operator ==(key k1, key k2)
  877. {
  878. return k1.value == k2.value;
  879. }
  880. public static bool operator !=(key k1, key k2)
  881. {
  882. return k1.value != k2.value;
  883. }
  884. #endregion
  885. #region Overriders
  886. public override bool Equals(object o)
  887. {
  888. return o.ToString() == value;
  889. }
  890. public override int GetHashCode()
  891. {
  892. return value.GetHashCode();
  893. }
  894. #endregion
  895. }
  896. [Serializable]
  897. public struct LSLString
  898. {
  899. public string m_string;
  900. #region Constructors
  901. public LSLString(string s)
  902. {
  903. m_string = s;
  904. }
  905. public LSLString(double d)
  906. {
  907. string s=String.Format("{0:0.000000}", d);
  908. m_string=s;
  909. }
  910. #endregion
  911. #region Operators
  912. static public implicit operator Boolean(LSLString s)
  913. {
  914. if (s.m_string.Length == 0)
  915. {
  916. return false;
  917. }
  918. else
  919. {
  920. return true;
  921. }
  922. }
  923. static public implicit operator String(LSLString s)
  924. {
  925. return s.m_string;
  926. }
  927. static public implicit operator LSLString(string s)
  928. {
  929. return new LSLString(s);
  930. }
  931. public static string ToString(LSLString s)
  932. {
  933. return s.m_string;
  934. }
  935. public override string ToString()
  936. {
  937. return m_string;
  938. }
  939. public static bool operator ==(LSLString s1, string s2)
  940. {
  941. return s1.m_string == s2;
  942. }
  943. public static bool operator !=(LSLString s1, string s2)
  944. {
  945. return s1.m_string != s2;
  946. }
  947. public static explicit operator double(LSLString s)
  948. {
  949. return Convert.ToDouble(s.m_string);
  950. }
  951. public static explicit operator LSLInteger(LSLString s)
  952. {
  953. return new LSLInteger(Convert.ToInt32(s.m_string));
  954. }
  955. public static explicit operator LSLString(double d)
  956. {
  957. return new LSLString(d);
  958. }
  959. #endregion
  960. #region Overriders
  961. public override bool Equals(object o)
  962. {
  963. return m_string == o.ToString();
  964. }
  965. public override int GetHashCode()
  966. {
  967. return m_string.GetHashCode();
  968. }
  969. #endregion
  970. #region " Standard string functions "
  971. //Clone,CompareTo,Contains
  972. //CopyTo,EndsWith,Equals,GetEnumerator,GetHashCode,GetType,GetTypeCode
  973. //IndexOf,IndexOfAny,Insert,IsNormalized,LastIndexOf,LastIndexOfAny
  974. //Length,Normalize,PadLeft,PadRight,Remove,Replace,Split,StartsWith,Substring,ToCharArray,ToLowerInvariant
  975. //ToString,ToUpper,ToUpperInvariant,Trim,TrimEnd,TrimStart
  976. public bool Contains(string value) { return m_string.Contains(value); }
  977. public int IndexOf(string value) { return m_string.IndexOf(value); }
  978. public int Length { get { return m_string.Length; } }
  979. #endregion
  980. }
  981. [Serializable]
  982. public struct LSLInteger
  983. {
  984. public int value;
  985. #region Constructors
  986. public LSLInteger(int i)
  987. {
  988. value = i;
  989. }
  990. public LSLInteger(double d)
  991. {
  992. value = (int)d;
  993. }
  994. #endregion
  995. static public implicit operator Int32(LSLInteger i)
  996. {
  997. return i.value;
  998. }
  999. static public explicit operator LSLString(LSLInteger i)
  1000. {
  1001. return new LSLString(i.ToString());
  1002. }
  1003. static public implicit operator Boolean(LSLInteger i)
  1004. {
  1005. if (i.value == 0)
  1006. {
  1007. return false;
  1008. }
  1009. else
  1010. {
  1011. return true;
  1012. }
  1013. }
  1014. static public implicit operator LSLInteger(int i)
  1015. {
  1016. return new LSLInteger(i);
  1017. }
  1018. static public explicit operator LSLInteger(string s)
  1019. {
  1020. return new LSLInteger(int.Parse(s));
  1021. }
  1022. static public implicit operator LSLInteger(double d)
  1023. {
  1024. return new LSLInteger(d);
  1025. }
  1026. static public LSLInteger operator &(LSLInteger i1, LSLInteger i2)
  1027. {
  1028. int ret = i1.value & i2.value;
  1029. return ret;
  1030. }
  1031. public static LSLInteger operator ++(LSLInteger i)
  1032. {
  1033. i.value++;
  1034. return i;
  1035. }
  1036. public static LSLInteger operator --(LSLInteger i)
  1037. {
  1038. i.value--;
  1039. return i;
  1040. }
  1041. //static public implicit operator System.Double(LSLInteger i)
  1042. //{
  1043. // return (double)i.value;
  1044. //}
  1045. #region Overriders
  1046. public override string ToString()
  1047. {
  1048. return this.value.ToString();
  1049. }
  1050. #endregion
  1051. }
  1052. [Serializable]
  1053. public struct LSLFloat
  1054. {
  1055. public double value;
  1056. #region Constructors
  1057. public LSLFloat(int i)
  1058. {
  1059. this.value = (double)i;
  1060. }
  1061. public LSLFloat(double d)
  1062. {
  1063. this.value = d;
  1064. }
  1065. #endregion
  1066. #region Operators
  1067. static public implicit operator Double(LSLFloat f)
  1068. {
  1069. return f.value;
  1070. }
  1071. //static public implicit operator System.Int32(LSLFloat f)
  1072. //{
  1073. // return (int)f.value;
  1074. //}
  1075. static public implicit operator Boolean(LSLFloat f)
  1076. {
  1077. if (f.value == 0)
  1078. {
  1079. return false;
  1080. }
  1081. else
  1082. {
  1083. return true;
  1084. }
  1085. }
  1086. static public implicit operator LSLFloat(int i)
  1087. {
  1088. return new LSLFloat(i);
  1089. }
  1090. static public implicit operator LSLFloat(double d)
  1091. {
  1092. return new LSLFloat(d);
  1093. }
  1094. #endregion
  1095. #region Overriders
  1096. public override string ToString()
  1097. {
  1098. return this.value.ToString();
  1099. }
  1100. #endregion
  1101. }
  1102. }
  1103. }