LSL_Types.cs 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233
  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;
  31. using System.Text.RegularExpressions;
  32. using OpenSim.Framework;
  33. using OpenMetaverse;
  34. using OMV_Vector3 = OpenMetaverse.Vector3;
  35. using OMV_Vector3d = OpenMetaverse.Vector3d;
  36. using OMV_Quaternion = OpenMetaverse.Quaternion;
  37. namespace OpenSim.Region.ScriptEngine.Shared
  38. {
  39. [Serializable]
  40. public partial class LSL_Types
  41. {
  42. // Types are kept is separate .dll to avoid having to add whatever .dll it is in it to script AppDomain
  43. [Serializable]
  44. public struct Vector3
  45. {
  46. public double x;
  47. public double y;
  48. public double z;
  49. #region Constructors
  50. public Vector3(Vector3 vector)
  51. {
  52. x = (float)vector.x;
  53. y = (float)vector.y;
  54. z = (float)vector.z;
  55. }
  56. public Vector3(OMV_Vector3 vector)
  57. {
  58. x = vector.X;
  59. y = vector.Y;
  60. z = vector.Z;
  61. }
  62. public Vector3(OMV_Vector3d vector)
  63. {
  64. x = vector.X;
  65. y = vector.Y;
  66. z = vector.Z;
  67. }
  68. public Vector3(double X, double Y, double Z)
  69. {
  70. x = X;
  71. y = Y;
  72. z = Z;
  73. }
  74. public Vector3(string str)
  75. {
  76. str = str.Replace('<', ' ');
  77. str = str.Replace('>', ' ');
  78. string[] tmps = str.Split(new Char[] { ',', '<', '>' });
  79. if (tmps.Length < 3)
  80. {
  81. x=y=z=0;
  82. return;
  83. }
  84. bool res;
  85. res = Double.TryParse(tmps[0], NumberStyles.Float, Culture.NumberFormatInfo, out x);
  86. res = res & Double.TryParse(tmps[1], NumberStyles.Float, Culture.NumberFormatInfo, out y);
  87. res = res & Double.TryParse(tmps[2], NumberStyles.Float, Culture.NumberFormatInfo, out z);
  88. }
  89. #endregion
  90. #region Overriders
  91. public static implicit operator Boolean(Vector3 vec)
  92. {
  93. if (vec.x != 0)
  94. return true;
  95. if (vec.y != 0)
  96. return true;
  97. if (vec.z != 0)
  98. return true;
  99. return false;
  100. }
  101. public override string ToString()
  102. {
  103. string s = String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
  104. return s;
  105. }
  106. public static explicit operator LSLString(Vector3 vec)
  107. {
  108. string s = String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
  109. return new LSLString(s);
  110. }
  111. public static explicit operator string(Vector3 vec)
  112. {
  113. string s = String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
  114. return s;
  115. }
  116. public static explicit operator Vector3(string s)
  117. {
  118. return new Vector3(s);
  119. }
  120. public static implicit operator list(Vector3 vec)
  121. {
  122. return new list(new object[] { vec });
  123. }
  124. public static implicit operator OMV_Vector3(Vector3 vec)
  125. {
  126. return new OMV_Vector3((float)vec.x, (float)vec.y, (float)vec.z);
  127. }
  128. public static implicit operator Vector3(OMV_Vector3 vec)
  129. {
  130. return new Vector3(vec);
  131. }
  132. public static implicit operator OMV_Vector3d(Vector3 vec)
  133. {
  134. return new OMV_Vector3d(vec.x, vec.y, vec.z);
  135. }
  136. public static implicit operator Vector3(OMV_Vector3d vec)
  137. {
  138. return new Vector3(vec);
  139. }
  140. public static bool operator ==(Vector3 lhs, Vector3 rhs)
  141. {
  142. return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
  143. }
  144. public static bool operator !=(Vector3 lhs, Vector3 rhs)
  145. {
  146. return !(lhs == rhs);
  147. }
  148. public override int GetHashCode()
  149. {
  150. return (x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode());
  151. }
  152. public override bool Equals(object o)
  153. {
  154. if (!(o is Vector3)) return false;
  155. Vector3 vector = (Vector3)o;
  156. return (x == vector.x && y == vector.y && z == vector.z);
  157. }
  158. public static Vector3 operator -(Vector3 vector)
  159. {
  160. return new Vector3(-vector.x, -vector.y, -vector.z);
  161. }
  162. #endregion
  163. #region Vector & Vector Math
  164. // Vector-Vector Math
  165. public static Vector3 operator +(Vector3 lhs, Vector3 rhs)
  166. {
  167. return new Vector3(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
  168. }
  169. public static Vector3 operator -(Vector3 lhs, Vector3 rhs)
  170. {
  171. return new Vector3(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
  172. }
  173. public static LSLFloat operator *(Vector3 lhs, Vector3 rhs)
  174. {
  175. return Dot(lhs, rhs);
  176. }
  177. public static Vector3 operator %(Vector3 v1, Vector3 v2)
  178. {
  179. //Cross product
  180. Vector3 tv;
  181. tv.x = (v1.y * v2.z) - (v1.z * v2.y);
  182. tv.y = (v1.z * v2.x) - (v1.x * v2.z);
  183. tv.z = (v1.x * v2.y) - (v1.y * v2.x);
  184. return tv;
  185. }
  186. #endregion
  187. #region Vector & Float Math
  188. // Vector-Float and Float-Vector Math
  189. public static Vector3 operator *(Vector3 vec, float val)
  190. {
  191. return new Vector3(vec.x * val, vec.y * val, vec.z * val);
  192. }
  193. public static Vector3 operator *(float val, Vector3 vec)
  194. {
  195. return new Vector3(vec.x * val, vec.y * val, vec.z * val);
  196. }
  197. public static Vector3 operator /(Vector3 v, float f)
  198. {
  199. v.x = v.x / f;
  200. v.y = v.y / f;
  201. v.z = v.z / f;
  202. return v;
  203. }
  204. #endregion
  205. #region Vector & Double Math
  206. public static Vector3 operator *(Vector3 vec, double val)
  207. {
  208. return new Vector3(vec.x * val, vec.y * val, vec.z * val);
  209. }
  210. public static Vector3 operator *(double val, Vector3 vec)
  211. {
  212. return new Vector3(vec.x * val, vec.y * val, vec.z * val);
  213. }
  214. public static Vector3 operator /(Vector3 v, double f)
  215. {
  216. v.x = v.x / f;
  217. v.y = v.y / f;
  218. v.z = v.z / f;
  219. return v;
  220. }
  221. #endregion
  222. #region Vector & Rotation Math
  223. // Vector-Rotation Math
  224. public static Vector3 operator *(Vector3 v, Quaternion r)
  225. {
  226. Quaternion vq = new Quaternion(v.x, v.y, v.z, 0);
  227. Quaternion nq = new Quaternion(-r.x, -r.y, -r.z, r.s);
  228. // adapted for operator * computing "b * a"
  229. Quaternion result = nq * (vq * r);
  230. return new Vector3(result.x, result.y, result.z);
  231. }
  232. public static Vector3 operator /(Vector3 v, Quaternion r)
  233. {
  234. r.s = -r.s;
  235. return v * r;
  236. }
  237. #endregion
  238. #region Static Helper Functions
  239. public static double Dot(Vector3 v1, Vector3 v2)
  240. {
  241. return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
  242. }
  243. public static Vector3 Cross(Vector3 v1, Vector3 v2)
  244. {
  245. return new Vector3
  246. (
  247. v1.y * v2.z - v1.z * v2.y,
  248. v1.z * v2.x - v1.x * v2.z,
  249. v1.x * v2.y - v1.y * v2.x
  250. );
  251. }
  252. public static double Mag(Vector3 v)
  253. {
  254. return Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
  255. }
  256. public static Vector3 Norm(Vector3 vector)
  257. {
  258. double mag = Mag(vector);
  259. if (mag > 0.0)
  260. {
  261. double invMag = 1.0 / mag;
  262. return vector * invMag;
  263. }
  264. return new Vector3(0, 0, 0);
  265. }
  266. #endregion
  267. }
  268. [Serializable]
  269. public struct Quaternion
  270. {
  271. public double x;
  272. public double y;
  273. public double z;
  274. public double s;
  275. #region Constructors
  276. public Quaternion(Quaternion Quat)
  277. {
  278. x = (float)Quat.x;
  279. y = (float)Quat.y;
  280. z = (float)Quat.z;
  281. s = (float)Quat.s;
  282. if (s == 0 && x == 0 && y == 0 && z == 0)
  283. s = 1;
  284. }
  285. public Quaternion(double X, double Y, double Z, double S)
  286. {
  287. x = X;
  288. y = Y;
  289. z = Z;
  290. s = S;
  291. if (s == 0 && x == 0 && y == 0 && z == 0)
  292. s = 1;
  293. }
  294. public Quaternion(string str)
  295. {
  296. str = str.Replace('<', ' ');
  297. str = str.Replace('>', ' ');
  298. string[] tmps = str.Split(new Char[] { ',', '<', '>' });
  299. if (tmps.Length < 4)
  300. {
  301. x=y=z=s=0;
  302. return;
  303. }
  304. bool res;
  305. res = Double.TryParse(tmps[0], NumberStyles.Float, Culture.NumberFormatInfo, out x);
  306. res = res & Double.TryParse(tmps[1], NumberStyles.Float, Culture.NumberFormatInfo, out y);
  307. res = res & Double.TryParse(tmps[2], NumberStyles.Float, Culture.NumberFormatInfo, out z);
  308. res = res & Double.TryParse(tmps[3], NumberStyles.Float, Culture.NumberFormatInfo, out s);
  309. if (s == 0 && x == 0 && y == 0 && z == 0)
  310. s = 1;
  311. }
  312. public Quaternion(OMV_Quaternion rot)
  313. {
  314. x = rot.X;
  315. y = rot.Y;
  316. z = rot.Z;
  317. s = rot.W;
  318. }
  319. #endregion
  320. #region Methods
  321. public Quaternion Normalize()
  322. {
  323. double length = Math.Sqrt(x * x + y * y + z * z + s * s);
  324. if (length < float.Epsilon)
  325. {
  326. x = 0;
  327. y = 0;
  328. z = 0;
  329. s = 1;
  330. }
  331. else
  332. {
  333. double invLength = 1.0 / length;
  334. x *= invLength;
  335. y *= invLength;
  336. z *= invLength;
  337. s *= invLength;
  338. }
  339. return this;
  340. }
  341. #endregion
  342. #region Overriders
  343. public static implicit operator Boolean(Quaternion q)
  344. {
  345. if (q.x != 0)
  346. return true;
  347. if (q.y != 0)
  348. return true;
  349. if (q.z != 0)
  350. return true;
  351. if (q.s != 1.0f)
  352. return true;
  353. return false;
  354. }
  355. public override int GetHashCode()
  356. {
  357. return (x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode() ^ s.GetHashCode());
  358. }
  359. public override bool Equals(object o)
  360. {
  361. if (!(o is Quaternion)) return false;
  362. Quaternion quaternion = (Quaternion)o;
  363. return x == quaternion.x && y == quaternion.y && z == quaternion.z && s == quaternion.s;
  364. }
  365. public override string ToString()
  366. {
  367. string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
  368. return st;
  369. }
  370. public static explicit operator string(Quaternion r)
  371. {
  372. string s=String.Format(Culture.FormatProvider,"<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
  373. return s;
  374. }
  375. public static explicit operator LSLString(Quaternion r)
  376. {
  377. string s=String.Format(Culture.FormatProvider,"<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
  378. return new LSLString(s);
  379. }
  380. public static explicit operator Quaternion(string s)
  381. {
  382. return new Quaternion(s);
  383. }
  384. public static implicit operator list(Quaternion r)
  385. {
  386. return new list(new object[] { r });
  387. }
  388. public static implicit operator OMV_Quaternion(Quaternion rot)
  389. {
  390. // LSL quaternions can normalize to 0, normal Quaternions can't.
  391. if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
  392. rot.z = 1; // ZERO_ROTATION = 0,0,0,1
  393. OMV_Quaternion omvrot = new OMV_Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
  394. omvrot.Normalize();
  395. return omvrot;
  396. }
  397. public static implicit operator Quaternion(OMV_Quaternion rot)
  398. {
  399. return new Quaternion(rot);
  400. }
  401. public static bool operator ==(Quaternion lhs, Quaternion rhs)
  402. {
  403. // Return true if the fields match:
  404. return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.s == rhs.s;
  405. }
  406. public static bool operator !=(Quaternion lhs, Quaternion rhs)
  407. {
  408. return !(lhs == rhs);
  409. }
  410. public static double Mag(Quaternion q)
  411. {
  412. return Math.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.s * q.s);
  413. }
  414. #endregion
  415. public static Quaternion operator +(Quaternion a, Quaternion b)
  416. {
  417. return new Quaternion(a.x + b.x, a.y + b.y, a.z + b.z, a.s + b.s);
  418. }
  419. public static Quaternion operator /(Quaternion a, Quaternion b)
  420. {
  421. b.s = -b.s;
  422. return a * b;
  423. }
  424. public static Quaternion operator -(Quaternion a, Quaternion b)
  425. {
  426. return new Quaternion(a.x - b.x, a.y - b.y, a.z - b.z, a.s - b.s);
  427. }
  428. // using the equations below, we need to do "b * a" to be compatible with LSL
  429. public static Quaternion operator *(Quaternion b, Quaternion a)
  430. {
  431. Quaternion c;
  432. c.x = a.s * b.x + a.x * b.s + a.y * b.z - a.z * b.y;
  433. c.y = a.s * b.y + a.y * b.s + a.z * b.x - a.x * b.z;
  434. c.z = a.s * b.z + a.z * b.s + a.x * b.y - a.y * b.x;
  435. c.s = a.s * b.s - a.x * b.x - a.y * b.y - a.z * b.z;
  436. return c;
  437. }
  438. }
  439. [Serializable]
  440. public class list
  441. {
  442. private object[] m_data;
  443. public list(params object[] args)
  444. {
  445. m_data = args;
  446. }
  447. public int Length
  448. {
  449. get
  450. {
  451. if (m_data == null)
  452. m_data=new Object[0];
  453. return m_data.Length;
  454. }
  455. }
  456. public int Size
  457. {
  458. get
  459. {
  460. if (m_data == null)
  461. m_data=new Object[0];
  462. int size = 0;
  463. foreach (Object o in m_data)
  464. {
  465. if (o is LSL_Types.LSLInteger)
  466. size += 4;
  467. else if (o is LSL_Types.LSLFloat)
  468. size += 8;
  469. else if (o is LSL_Types.LSLString)
  470. size += ((LSL_Types.LSLString)o).m_string == null ? 0 : ((LSL_Types.LSLString)o).m_string.Length;
  471. else if (o is LSL_Types.key)
  472. size += ((LSL_Types.key)o).value.Length;
  473. else if (o is LSL_Types.Vector3)
  474. size += 32;
  475. else if (o is LSL_Types.Quaternion)
  476. size += 64;
  477. else if (o is int)
  478. size += 4;
  479. else if (o is uint)
  480. size += 4;
  481. else if (o is string)
  482. size += ((string)o).Length;
  483. else if (o is float)
  484. size += 8;
  485. else if (o is double)
  486. size += 16;
  487. else
  488. throw new Exception("Unknown type in List.Size: " + o.GetType().ToString());
  489. }
  490. return size;
  491. }
  492. }
  493. public object[] Data
  494. {
  495. get {
  496. if (m_data == null)
  497. m_data=new Object[0];
  498. return m_data;
  499. }
  500. set {m_data = value; }
  501. }
  502. /// <summary>
  503. /// Obtain LSL type from an index.
  504. /// </summary>
  505. /// <remarks>
  506. /// This is needed because LSL lists allow for multiple types, and safely
  507. /// iterating in them requires a type check.
  508. /// </remarks>
  509. /// <returns></returns>
  510. /// <param name='itemIndex'></param>
  511. public Type GetLSLListItemType(int itemIndex)
  512. {
  513. return Data[itemIndex].GetType();
  514. }
  515. /// <summary>
  516. /// Obtain float from an index.
  517. /// </summary>
  518. /// <remarks>
  519. /// For cases where implicit conversions would apply if items
  520. /// were not in a list (e.g. integer to float, but not float
  521. /// to integer) functions check for alternate types so as to
  522. /// down-cast from Object to the correct type.
  523. /// Note: no checks for item index being valid are performed
  524. /// </remarks>
  525. /// <returns></returns>
  526. /// <param name='itemIndex'></param>
  527. public LSL_Types.LSLFloat GetLSLFloatItem(int itemIndex)
  528. {
  529. if (Data[itemIndex] is LSL_Types.LSLInteger)
  530. {
  531. return (LSL_Types.LSLInteger)Data[itemIndex];
  532. }
  533. else if (Data[itemIndex] is Int32)
  534. {
  535. return new LSL_Types.LSLFloat((int)Data[itemIndex]);
  536. }
  537. else if (Data[itemIndex] is float)
  538. {
  539. return new LSL_Types.LSLFloat((float)Data[itemIndex]);
  540. }
  541. else if (Data[itemIndex] is Double)
  542. {
  543. return new LSL_Types.LSLFloat((Double)Data[itemIndex]);
  544. }
  545. else if (Data[itemIndex] is LSL_Types.LSLString)
  546. {
  547. return new LSL_Types.LSLFloat(Data[itemIndex].ToString());
  548. }
  549. else
  550. {
  551. return (LSL_Types.LSLFloat)Data[itemIndex];
  552. }
  553. }
  554. public LSL_Types.LSLString GetLSLStringItem(int itemIndex)
  555. {
  556. if (Data[itemIndex] is LSL_Types.key)
  557. {
  558. return (LSL_Types.key)Data[itemIndex];
  559. }
  560. else
  561. {
  562. return new LSL_Types.LSLString(Data[itemIndex].ToString());
  563. }
  564. }
  565. public LSL_Types.LSLInteger GetLSLIntegerItem(int itemIndex)
  566. {
  567. if (Data[itemIndex] is LSL_Types.LSLInteger)
  568. return (LSL_Types.LSLInteger)Data[itemIndex];
  569. if (Data[itemIndex] is LSL_Types.LSLFloat)
  570. return new LSLInteger((int)Data[itemIndex]);
  571. else if (Data[itemIndex] is Int32)
  572. return new LSLInteger((int)Data[itemIndex]);
  573. else if (Data[itemIndex] is LSL_Types.LSLString)
  574. return new LSLInteger(Data[itemIndex].ToString());
  575. else
  576. throw new InvalidCastException(string.Format(
  577. "{0} expected but {1} given",
  578. typeof(LSL_Types.LSLInteger).Name,
  579. Data[itemIndex] != null ?
  580. Data[itemIndex].GetType().Name : "null"));
  581. }
  582. public LSL_Types.Vector3 GetVector3Item(int itemIndex)
  583. {
  584. if (Data[itemIndex] is LSL_Types.Vector3)
  585. {
  586. return (LSL_Types.Vector3)Data[itemIndex];
  587. }
  588. else if(Data[itemIndex] is OpenMetaverse.Vector3)
  589. {
  590. return new LSL_Types.Vector3(
  591. (OpenMetaverse.Vector3)Data[itemIndex]);
  592. }
  593. else
  594. {
  595. throw new InvalidCastException(string.Format(
  596. "{0} expected but {1} given",
  597. typeof(LSL_Types.Vector3).Name,
  598. Data[itemIndex] != null ?
  599. Data[itemIndex].GetType().Name : "null"));
  600. }
  601. }
  602. // use LSL_Types.Quaternion to parse and store a vector4 for lightShare
  603. public LSL_Types.Quaternion GetVector4Item(int itemIndex)
  604. {
  605. if (Data[itemIndex] is LSL_Types.Quaternion)
  606. {
  607. LSL_Types.Quaternion q = (LSL_Types.Quaternion)Data[itemIndex];
  608. return q;
  609. }
  610. else if(Data[itemIndex] is OpenMetaverse.Quaternion)
  611. {
  612. LSL_Types.Quaternion q = new LSL_Types.Quaternion(
  613. (OpenMetaverse.Quaternion)Data[itemIndex]);
  614. q.Normalize();
  615. return q;
  616. }
  617. else
  618. {
  619. throw new InvalidCastException(string.Format(
  620. "{0} expected but {1} given",
  621. typeof(LSL_Types.Quaternion).Name,
  622. Data[itemIndex] != null ?
  623. Data[itemIndex].GetType().Name : "null"));
  624. }
  625. }
  626. public LSL_Types.Quaternion GetQuaternionItem(int itemIndex)
  627. {
  628. if (Data[itemIndex] is LSL_Types.Quaternion)
  629. {
  630. LSL_Types.Quaternion q = (LSL_Types.Quaternion)Data[itemIndex];
  631. q.Normalize();
  632. return q;
  633. }
  634. else if(Data[itemIndex] is OpenMetaverse.Quaternion)
  635. {
  636. LSL_Types.Quaternion q = new LSL_Types.Quaternion(
  637. (OpenMetaverse.Quaternion)Data[itemIndex]);
  638. q.Normalize();
  639. return q;
  640. }
  641. else
  642. {
  643. throw new InvalidCastException(string.Format(
  644. "{0} expected but {1} given",
  645. typeof(LSL_Types.Quaternion).Name,
  646. Data[itemIndex] != null ?
  647. Data[itemIndex].GetType().Name : "null"));
  648. }
  649. }
  650. public LSL_Types.key GetKeyItem(int itemIndex)
  651. {
  652. return (LSL_Types.key)Data[itemIndex];
  653. }
  654. public static list operator +(list a, list b)
  655. {
  656. object[] tmp;
  657. tmp = new object[a.Length + b.Length];
  658. a.Data.CopyTo(tmp, 0);
  659. b.Data.CopyTo(tmp, a.Length);
  660. return new list(tmp);
  661. }
  662. private void ExtendAndAdd(object o)
  663. {
  664. object[] tmp;
  665. tmp = new object[Data.Length + 1];
  666. Data.CopyTo(tmp, 0);
  667. tmp.SetValue(o, tmp.Length - 1);
  668. Data = tmp;
  669. }
  670. public static implicit operator Boolean(list l)
  671. {
  672. return l.Length != 0;
  673. }
  674. public static list operator +(list a, LSLString s)
  675. {
  676. a.ExtendAndAdd(s);
  677. return a;
  678. }
  679. public static list operator +(list a, LSLInteger i)
  680. {
  681. a.ExtendAndAdd(i);
  682. return a;
  683. }
  684. public static list operator +(list a, LSLFloat d)
  685. {
  686. a.ExtendAndAdd(d);
  687. return a;
  688. }
  689. public static bool operator ==(list a, list b)
  690. {
  691. int la = -1;
  692. int lb = -1;
  693. try { la = a.Length; }
  694. catch (NullReferenceException) { }
  695. try { lb = b.Length; }
  696. catch (NullReferenceException) { }
  697. return la == lb;
  698. }
  699. public static bool operator !=(list a, list b)
  700. {
  701. int la = -1;
  702. int lb = -1;
  703. try { la = a.Length; }
  704. catch (NullReferenceException) { }
  705. try { lb = b.Length; }
  706. catch (NullReferenceException) { }
  707. return la != lb;
  708. }
  709. public void Add(object o)
  710. {
  711. object[] tmp;
  712. tmp = new object[Data.Length + 1];
  713. Data.CopyTo(tmp, 0);
  714. tmp[Data.Length] = o; // Since this is tmp.Length - 1
  715. Data = tmp;
  716. }
  717. public bool Contains(object o)
  718. {
  719. bool ret = false;
  720. foreach (object i in Data)
  721. {
  722. if (i == o)
  723. {
  724. ret = true;
  725. break;
  726. }
  727. }
  728. return ret;
  729. }
  730. public list DeleteSublist(int start, int end)
  731. {
  732. // Not an easy one
  733. // If start <= end, remove that part
  734. // if either is negative, count from the end of the array
  735. // if the resulting start > end, remove all BUT that part
  736. Object[] ret;
  737. if (start < 0)
  738. start=Data.Length+start;
  739. if (start < 0)
  740. start=0;
  741. if (end < 0)
  742. end=Data.Length+end;
  743. if (end < 0)
  744. end=0;
  745. if (start > end)
  746. {
  747. if (end >= Data.Length)
  748. return new list(new Object[0]);
  749. if (start >= Data.Length)
  750. start=Data.Length-1;
  751. return GetSublist(end, start);
  752. }
  753. // start >= 0 && end >= 0 here
  754. if (start >= Data.Length)
  755. {
  756. ret=new Object[Data.Length];
  757. Array.Copy(Data, 0, ret, 0, Data.Length);
  758. return new list(ret);
  759. }
  760. if (end >= Data.Length)
  761. end=Data.Length-1;
  762. // now, this makes the math easier
  763. int remove=end+1-start;
  764. ret=new Object[Data.Length-remove];
  765. if (ret.Length == 0)
  766. return new list(ret);
  767. int src;
  768. int dest=0;
  769. for (src = 0; src < Data.Length; src++)
  770. {
  771. if (src < start || src > end)
  772. ret[dest++]=Data[src];
  773. }
  774. return new list(ret);
  775. }
  776. public list GetSublist(int start, int end)
  777. {
  778. object[] ret;
  779. // Take care of neg start or end's
  780. // NOTE that either index may still be negative after
  781. // adding the length, so we must take additional
  782. // measures to protect against this. Note also that
  783. // after normalisation the negative indices are no
  784. // longer relative to the end of the list.
  785. if (start < 0)
  786. {
  787. start = Data.Length + start;
  788. }
  789. if (end < 0)
  790. {
  791. end = Data.Length + end;
  792. }
  793. // The conventional case is start <= end
  794. // NOTE that the case of an empty list is
  795. // dealt with by the initial test. Start
  796. // less than end is taken to be the most
  797. // common case.
  798. if (start <= end)
  799. {
  800. // Start sublist beyond length
  801. // Also deals with start AND end still negative
  802. if (start >= Data.Length || end < 0)
  803. {
  804. return new list();
  805. }
  806. // Sublist extends beyond the end of the supplied list
  807. if (end >= Data.Length)
  808. {
  809. end = Data.Length - 1;
  810. }
  811. // Sublist still starts before the beginning of the list
  812. if (start < 0)
  813. {
  814. start = 0;
  815. }
  816. ret = new object[end - start + 1];
  817. Array.Copy(Data, start, ret, 0, end - start + 1);
  818. return new list(ret);
  819. }
  820. // Deal with the segmented case: 0->end + start->EOL
  821. else
  822. {
  823. list result;
  824. // If end is negative, then prefix list is empty
  825. if (end < 0)
  826. {
  827. result = new list();
  828. // If start is still negative, then the whole of
  829. // the existing list is returned. This case is
  830. // only admitted if end is also still negative.
  831. if (start < 0)
  832. {
  833. return this;
  834. }
  835. }
  836. else
  837. {
  838. result = GetSublist(0,end);
  839. }
  840. // If start is outside of list, then just return
  841. // the prefix, whatever it is.
  842. if (start >= Data.Length)
  843. {
  844. return result;
  845. }
  846. return result + GetSublist(start, Data.Length);
  847. }
  848. }
  849. private static int compare(object left, object right, int ascending)
  850. {
  851. if (!left.GetType().Equals(right.GetType()))
  852. {
  853. // unequal types are always "equal" for comparison purposes.
  854. // this way, the bubble sort will never swap them, and we'll
  855. // get that feathered effect we're looking for
  856. return 0;
  857. }
  858. int ret = 0;
  859. if (left is key)
  860. {
  861. key l = (key)left;
  862. key r = (key)right;
  863. ret = String.CompareOrdinal(l.value, r.value);
  864. }
  865. else if (left is LSLString)
  866. {
  867. LSLString l = (LSLString)left;
  868. LSLString r = (LSLString)right;
  869. ret = String.CompareOrdinal(l.m_string, r.m_string);
  870. }
  871. else if (left is LSLInteger)
  872. {
  873. LSLInteger l = (LSLInteger)left;
  874. LSLInteger r = (LSLInteger)right;
  875. ret = Math.Sign(l.value - r.value);
  876. }
  877. else if (left is LSLFloat)
  878. {
  879. LSLFloat l = (LSLFloat)left;
  880. LSLFloat r = (LSLFloat)right;
  881. ret = Math.Sign(l.value - r.value);
  882. }
  883. else if (left is Vector3)
  884. {
  885. Vector3 l = (Vector3)left;
  886. Vector3 r = (Vector3)right;
  887. ret = Math.Sign(Vector3.Mag(l) - Vector3.Mag(r));
  888. }
  889. else if (left is Quaternion)
  890. {
  891. Quaternion l = (Quaternion)left;
  892. Quaternion r = (Quaternion)right;
  893. ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
  894. }
  895. if (ascending == 0)
  896. {
  897. ret = 0 - ret;
  898. }
  899. return ret;
  900. }
  901. class HomogeneousComparer : IComparer
  902. {
  903. public HomogeneousComparer()
  904. {
  905. }
  906. public int Compare(object lhs, object rhs)
  907. {
  908. return compare(lhs, rhs, 1);
  909. }
  910. }
  911. public list Sort(int stride, int ascending)
  912. {
  913. if (Data.Length == 0)
  914. return new list(); // Don't even bother
  915. object[] ret = new object[Data.Length];
  916. Array.Copy(Data, 0, ret, 0, Data.Length);
  917. if (stride <= 0)
  918. {
  919. stride = 1;
  920. }
  921. if ((Data.Length % stride) != 0)
  922. return new list(ret);
  923. // we can optimize here in the case where stride == 1 and the list
  924. // consists of homogeneous types
  925. if (stride == 1)
  926. {
  927. bool homogeneous = true;
  928. int index;
  929. for (index = 1; index < Data.Length; index++)
  930. {
  931. if (!Data[0].GetType().Equals(Data[index].GetType()))
  932. {
  933. homogeneous = false;
  934. break;
  935. }
  936. }
  937. if (homogeneous)
  938. {
  939. Array.Sort(ret, new HomogeneousComparer());
  940. if (ascending == 0)
  941. {
  942. Array.Reverse(ret);
  943. }
  944. return new list(ret);
  945. }
  946. }
  947. // Because of the desired type specific feathered sorting behavior
  948. // requried by the spec, we MUST use a non-optimized bubble sort here.
  949. // Anything else will give you the incorrect behavior.
  950. // begin bubble sort...
  951. int i;
  952. int j;
  953. int k;
  954. int n = Data.Length;
  955. for (i = 0; i < (n-stride); i += stride)
  956. {
  957. for (j = i + stride; j < n; j += stride)
  958. {
  959. if (compare(ret[i], ret[j], ascending) > 0)
  960. {
  961. for (k = 0; k < stride; k++)
  962. {
  963. object tmp = ret[i + k];
  964. ret[i + k] = ret[j + k];
  965. ret[j + k] = tmp;
  966. }
  967. }
  968. }
  969. }
  970. // end bubble sort
  971. return new list(ret);
  972. }
  973. #region CSV Methods
  974. public static list FromCSV(string csv)
  975. {
  976. return new list(csv.Split(','));
  977. }
  978. public string ToCSV()
  979. {
  980. if(m_data == null || m_data.Length == 0)
  981. return String.Empty;
  982. Object o = m_data[0];
  983. int len = m_data.Length;
  984. if(len == 1)
  985. return o.ToString();
  986. StringBuilder sb = new StringBuilder(1024);
  987. sb.Append(o.ToString());
  988. for(int i = 1 ; i < len; i++)
  989. {
  990. sb.Append(",");
  991. sb.Append(o.ToString());
  992. }
  993. return sb.ToString();
  994. }
  995. private string ToSoup()
  996. {
  997. if(m_data == null || m_data.Length == 0)
  998. return String.Empty;
  999. StringBuilder sb = new StringBuilder(1024);
  1000. foreach (object o in m_data)
  1001. {
  1002. sb.Append(o.ToString());
  1003. }
  1004. return sb.ToString();
  1005. }
  1006. public static explicit operator String(list l)
  1007. {
  1008. return l.ToSoup();
  1009. }
  1010. public static explicit operator LSLString(list l)
  1011. {
  1012. return new LSLString(l.ToSoup());
  1013. }
  1014. public override string ToString()
  1015. {
  1016. return ToSoup();
  1017. }
  1018. #endregion
  1019. #region Statistic Methods
  1020. public double Min()
  1021. {
  1022. double minimum = double.PositiveInfinity;
  1023. double entry;
  1024. for (int i = 0; i < Data.Length; i++)
  1025. {
  1026. if (double.TryParse(Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
  1027. {
  1028. if (entry < minimum) minimum = entry;
  1029. }
  1030. }
  1031. return minimum;
  1032. }
  1033. public double Max()
  1034. {
  1035. double maximum = double.NegativeInfinity;
  1036. double entry;
  1037. for (int i = 0; i < Data.Length; i++)
  1038. {
  1039. if (double.TryParse(Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
  1040. {
  1041. if (entry > maximum) maximum = entry;
  1042. }
  1043. }
  1044. return maximum;
  1045. }
  1046. public double Range()
  1047. {
  1048. return (this.Max() / this.Min());
  1049. }
  1050. public int NumericLength()
  1051. {
  1052. int count = 0;
  1053. double entry;
  1054. for (int i = 0; i < Data.Length; i++)
  1055. {
  1056. if (double.TryParse(Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
  1057. {
  1058. count++;
  1059. }
  1060. }
  1061. return count;
  1062. }
  1063. public static list ToDoubleList(list src)
  1064. {
  1065. list ret = new list();
  1066. double entry;
  1067. for (int i = 0; i < src.Data.Length; i++)
  1068. {
  1069. if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
  1070. {
  1071. ret.Add(entry);
  1072. }
  1073. }
  1074. return ret;
  1075. }
  1076. public double Sum()
  1077. {
  1078. double sum = 0;
  1079. double entry;
  1080. for (int i = 0; i < Data.Length; i++)
  1081. {
  1082. if (double.TryParse(Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
  1083. {
  1084. sum = sum + entry;
  1085. }
  1086. }
  1087. return sum;
  1088. }
  1089. public double SumSqrs()
  1090. {
  1091. double sum = 0;
  1092. double entry;
  1093. for (int i = 0; i < Data.Length; i++)
  1094. {
  1095. if (double.TryParse(Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
  1096. {
  1097. sum = sum + Math.Pow(entry, 2);
  1098. }
  1099. }
  1100. return sum;
  1101. }
  1102. public double Mean()
  1103. {
  1104. return (this.Sum() / this.NumericLength());
  1105. }
  1106. public void NumericSort()
  1107. {
  1108. IComparer Numeric = new NumericComparer();
  1109. Array.Sort(Data, Numeric);
  1110. }
  1111. public void AlphaSort()
  1112. {
  1113. IComparer Alpha = new AlphaCompare();
  1114. Array.Sort(Data, Alpha);
  1115. }
  1116. public double Median()
  1117. {
  1118. return Qi(0.5);
  1119. }
  1120. public double GeometricMean()
  1121. {
  1122. double ret = 1.0;
  1123. list nums = ToDoubleList(this);
  1124. for (int i = 0; i < nums.Data.Length; i++)
  1125. {
  1126. ret *= (double)nums.Data[i];
  1127. }
  1128. return Math.Exp(Math.Log(ret) / (double)nums.Data.Length);
  1129. }
  1130. public double HarmonicMean()
  1131. {
  1132. double ret = 0.0;
  1133. list nums = ToDoubleList(this);
  1134. for (int i = 0; i < nums.Data.Length; i++)
  1135. {
  1136. ret += 1.0 / (double)nums.Data[i];
  1137. }
  1138. return ((double)nums.Data.Length / ret);
  1139. }
  1140. public double Variance()
  1141. {
  1142. double s = 0;
  1143. list num = ToDoubleList(this);
  1144. for (int i = 0; i < num.Data.Length; i++)
  1145. {
  1146. s += Math.Pow((double)num.Data[i], 2);
  1147. }
  1148. return (s - num.Data.Length * Math.Pow(num.Mean(), 2)) / (num.Data.Length - 1);
  1149. }
  1150. public double StdDev()
  1151. {
  1152. return Math.Sqrt(this.Variance());
  1153. }
  1154. public double Qi(double i)
  1155. {
  1156. list j = this;
  1157. j.NumericSort();
  1158. if (Math.Ceiling(this.Length * i) == this.Length * i)
  1159. {
  1160. return (double)((double)j.Data[(int)(this.Length * i - 1)] + (double)j.Data[(int)(this.Length * i)]) / 2;
  1161. }
  1162. else
  1163. {
  1164. return (double)j.Data[((int)(Math.Ceiling(this.Length * i))) - 1];
  1165. }
  1166. }
  1167. #endregion
  1168. public string ToPrettyString()
  1169. {
  1170. if(m_data == null || m_data.Length == 0)
  1171. return "[]";
  1172. StringBuilder sb = new StringBuilder(1024);
  1173. int len = m_data.Length;
  1174. int last = len - 1;
  1175. object o;
  1176. sb.Append("[");
  1177. for(int i = 0; i < len; i++ )
  1178. {
  1179. o = m_data[i];
  1180. if (o is String)
  1181. {
  1182. sb.Append("\"");
  1183. sb.Append((String)o);
  1184. sb.Append("\"");
  1185. }
  1186. else
  1187. {
  1188. sb.Append(o.ToString());
  1189. }
  1190. if(i < last)
  1191. sb.Append(",");
  1192. }
  1193. sb.Append("]");
  1194. return sb.ToString();
  1195. }
  1196. public class AlphaCompare : IComparer
  1197. {
  1198. int IComparer.Compare(object x, object y)
  1199. {
  1200. return string.Compare(x.ToString(), y.ToString());
  1201. }
  1202. }
  1203. public class NumericComparer : IComparer
  1204. {
  1205. int IComparer.Compare(object x, object y)
  1206. {
  1207. double a;
  1208. double b;
  1209. if (!double.TryParse(x.ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out a))
  1210. {
  1211. a = 0.0;
  1212. }
  1213. if (!double.TryParse(y.ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out b))
  1214. {
  1215. b = 0.0;
  1216. }
  1217. if (a < b)
  1218. {
  1219. return -1;
  1220. }
  1221. else if (a == b)
  1222. {
  1223. return 0;
  1224. }
  1225. else
  1226. {
  1227. return 1;
  1228. }
  1229. }
  1230. }
  1231. public override bool Equals(object o)
  1232. {
  1233. if (!(o is list))
  1234. return false;
  1235. return Data.Length == ((list)o).Data.Length;
  1236. }
  1237. public override int GetHashCode()
  1238. {
  1239. return Data.GetHashCode();
  1240. }
  1241. }
  1242. [Serializable]
  1243. public struct key
  1244. {
  1245. public string value;
  1246. #region Constructors
  1247. public key(string s)
  1248. {
  1249. value = s;
  1250. }
  1251. #endregion
  1252. #region Methods
  1253. static public bool Parse2Key(string s)
  1254. {
  1255. 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);
  1256. if (isuuid.IsMatch(s))
  1257. {
  1258. return true;
  1259. }
  1260. else
  1261. {
  1262. return false;
  1263. }
  1264. }
  1265. #endregion
  1266. #region Operators
  1267. static public implicit operator Boolean(key k)
  1268. {
  1269. if (k.value.Length == 0)
  1270. {
  1271. return false;
  1272. }
  1273. if (k.value == "00000000-0000-0000-0000-000000000000")
  1274. {
  1275. return false;
  1276. }
  1277. 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);
  1278. if (isuuid.IsMatch(k.value))
  1279. {
  1280. return true;
  1281. }
  1282. else
  1283. {
  1284. return false;
  1285. }
  1286. }
  1287. public static bool operator true(key k)
  1288. {
  1289. return (Boolean)k;
  1290. }
  1291. public static bool operator false(key k)
  1292. {
  1293. return !(Boolean)k;
  1294. }
  1295. static public implicit operator key(string s)
  1296. {
  1297. return new key(s);
  1298. }
  1299. static public implicit operator String(key k)
  1300. {
  1301. return k.value;
  1302. }
  1303. static public implicit operator LSLString(key k)
  1304. {
  1305. return k.value;
  1306. }
  1307. public static bool operator ==(key k1, key k2)
  1308. {
  1309. return k1.value == k2.value;
  1310. }
  1311. public static bool operator !=(key k1, key k2)
  1312. {
  1313. return k1.value != k2.value;
  1314. }
  1315. #endregion
  1316. #region Overriders
  1317. public override bool Equals(object o)
  1318. {
  1319. return o.ToString() == value;
  1320. }
  1321. public override int GetHashCode()
  1322. {
  1323. return value.GetHashCode();
  1324. }
  1325. public override string ToString()
  1326. {
  1327. return value;
  1328. }
  1329. #endregion
  1330. }
  1331. [Serializable]
  1332. public struct LSLString
  1333. {
  1334. public string m_string;
  1335. #region Constructors
  1336. public LSLString(string s)
  1337. {
  1338. m_string = s;
  1339. }
  1340. public LSLString(double d)
  1341. {
  1342. string s = String.Format(Culture.FormatProvider, "{0:0.000000}", d);
  1343. m_string = s;
  1344. }
  1345. public LSLString(LSLFloat f)
  1346. {
  1347. string s = String.Format(Culture.FormatProvider, "{0:0.000000}", f.value);
  1348. m_string = s;
  1349. }
  1350. public LSLString(int i)
  1351. {
  1352. string s = String.Format("{0}", i);
  1353. m_string = s;
  1354. }
  1355. public LSLString(LSLInteger i) : this(i.value) {}
  1356. #endregion
  1357. #region Operators
  1358. static public implicit operator Boolean(LSLString s)
  1359. {
  1360. if (s.m_string.Length == 0)
  1361. {
  1362. return false;
  1363. }
  1364. else
  1365. {
  1366. return true;
  1367. }
  1368. }
  1369. static public implicit operator String(LSLString s)
  1370. {
  1371. return s.m_string;
  1372. }
  1373. static public implicit operator LSLString(string s)
  1374. {
  1375. return new LSLString(s);
  1376. }
  1377. public static string ToString(LSLString s)
  1378. {
  1379. return s.m_string;
  1380. }
  1381. public override string ToString()
  1382. {
  1383. return m_string;
  1384. }
  1385. public static bool operator ==(LSLString s1, string s2)
  1386. {
  1387. return s1.m_string == s2;
  1388. }
  1389. public static bool operator !=(LSLString s1, string s2)
  1390. {
  1391. return s1.m_string != s2;
  1392. }
  1393. public static LSLString operator +(LSLString s1, LSLString s2)
  1394. {
  1395. return new LSLString(s1.m_string + s2.m_string);
  1396. }
  1397. public static explicit operator double(LSLString s)
  1398. {
  1399. return new LSLFloat(s).value;
  1400. }
  1401. public static explicit operator LSLInteger(LSLString s)
  1402. {
  1403. return new LSLInteger(s.m_string);
  1404. }
  1405. public static explicit operator LSLString(double d)
  1406. {
  1407. return new LSLString(d);
  1408. }
  1409. static public explicit operator LSLString(int i)
  1410. {
  1411. return new LSLString(i);
  1412. }
  1413. public static explicit operator LSLString(LSLFloat f)
  1414. {
  1415. return new LSLString(f);
  1416. }
  1417. static public explicit operator LSLString(bool b)
  1418. {
  1419. if (b)
  1420. return new LSLString("1");
  1421. else
  1422. return new LSLString("0");
  1423. }
  1424. public static implicit operator Vector3(LSLString s)
  1425. {
  1426. return new Vector3(s.m_string);
  1427. }
  1428. public static implicit operator Quaternion(LSLString s)
  1429. {
  1430. return new Quaternion(s.m_string);
  1431. }
  1432. public static implicit operator LSLFloat(LSLString s)
  1433. {
  1434. return new LSLFloat(s);
  1435. }
  1436. public static implicit operator list(LSLString s)
  1437. {
  1438. return new list(new object[]{s});
  1439. }
  1440. #endregion
  1441. #region Overriders
  1442. public override bool Equals(object o)
  1443. {
  1444. return m_string == o.ToString();
  1445. }
  1446. public override int GetHashCode()
  1447. {
  1448. return m_string.GetHashCode();
  1449. }
  1450. #endregion
  1451. #region " Standard string functions "
  1452. //Clone,CompareTo,Contains
  1453. //CopyTo,EndsWith,Equals,GetEnumerator,GetHashCode,GetType,GetTypeCode
  1454. //IndexOf,IndexOfAny,Insert,IsNormalized,LastIndexOf,LastIndexOfAny
  1455. //Length,Normalize,PadLeft,PadRight,Remove,Replace,Split,StartsWith,Substring,ToCharArray,ToLowerInvariant
  1456. //ToString,ToUpper,ToUpperInvariant,Trim,TrimEnd,TrimStart
  1457. public bool Contains(string value) { return m_string.Contains(value); }
  1458. public int IndexOf(string value) { return m_string.IndexOf(value); }
  1459. public int Length { get { return m_string.Length; } }
  1460. #endregion
  1461. }
  1462. [Serializable]
  1463. public struct LSLInteger
  1464. {
  1465. public int value;
  1466. private static readonly Regex castRegex = new Regex(@"(^[ ]*0[xX][0-9A-Fa-f][0-9A-Fa-f]*)|(^[ ]*(-?|\+?)[0-9][0-9]*)");
  1467. #region Constructors
  1468. public LSLInteger(int i)
  1469. {
  1470. value = i;
  1471. }
  1472. public LSLInteger(uint i)
  1473. {
  1474. value = (int)i;
  1475. }
  1476. public LSLInteger(double d)
  1477. {
  1478. value = (int)d;
  1479. }
  1480. public LSLInteger(string s)
  1481. {
  1482. Match m = castRegex.Match(s);
  1483. string v = m.Groups[0].Value;
  1484. // Leading plus sign is allowed, but ignored
  1485. v = v.Replace("+", "");
  1486. if (v == String.Empty)
  1487. {
  1488. value = 0;
  1489. }
  1490. else
  1491. {
  1492. try
  1493. {
  1494. if (v.Contains("x") || v.Contains("X"))
  1495. {
  1496. value = int.Parse(v.Substring(2), System.Globalization.NumberStyles.HexNumber);
  1497. }
  1498. else
  1499. {
  1500. value = int.Parse(v, System.Globalization.NumberStyles.Integer);
  1501. }
  1502. }
  1503. catch (OverflowException)
  1504. {
  1505. value = -1;
  1506. }
  1507. }
  1508. }
  1509. #endregion
  1510. #region Operators
  1511. static public implicit operator int(LSLInteger i)
  1512. {
  1513. return i.value;
  1514. }
  1515. static public explicit operator uint(LSLInteger i)
  1516. {
  1517. return (uint)i.value;
  1518. }
  1519. static public explicit operator LSLString(LSLInteger i)
  1520. {
  1521. return new LSLString(i.ToString());
  1522. }
  1523. public static implicit operator list(LSLInteger i)
  1524. {
  1525. return new list(new object[] { i });
  1526. }
  1527. static public implicit operator Boolean(LSLInteger i)
  1528. {
  1529. if (i.value == 0)
  1530. {
  1531. return false;
  1532. }
  1533. else
  1534. {
  1535. return true;
  1536. }
  1537. }
  1538. static public implicit operator LSLInteger(int i)
  1539. {
  1540. return new LSLInteger(i);
  1541. }
  1542. static public explicit operator LSLInteger(string s)
  1543. {
  1544. return new LSLInteger(s);
  1545. }
  1546. static public implicit operator LSLInteger(uint u)
  1547. {
  1548. return new LSLInteger(u);
  1549. }
  1550. static public explicit operator LSLInteger(double d)
  1551. {
  1552. return new LSLInteger(d);
  1553. }
  1554. static public explicit operator LSLInteger(LSLFloat f)
  1555. {
  1556. return new LSLInteger(f.value);
  1557. }
  1558. static public implicit operator LSLInteger(bool b)
  1559. {
  1560. if (b)
  1561. return new LSLInteger(1);
  1562. else
  1563. return new LSLInteger(0);
  1564. }
  1565. static public LSLInteger operator ==(LSLInteger i1, LSLInteger i2)
  1566. {
  1567. bool ret = i1.value == i2.value;
  1568. return new LSLInteger((ret ? 1 : 0));
  1569. }
  1570. static public LSLInteger operator !=(LSLInteger i1, LSLInteger i2)
  1571. {
  1572. bool ret = i1.value != i2.value;
  1573. return new LSLInteger((ret ? 1 : 0));
  1574. }
  1575. static public LSLInteger operator <(LSLInteger i1, LSLInteger i2)
  1576. {
  1577. bool ret = i1.value < i2.value;
  1578. return new LSLInteger((ret ? 1 : 0));
  1579. }
  1580. static public LSLInteger operator <=(LSLInteger i1, LSLInteger i2)
  1581. {
  1582. bool ret = i1.value <= i2.value;
  1583. return new LSLInteger((ret ? 1 : 0));
  1584. }
  1585. static public LSLInteger operator >(LSLInteger i1, LSLInteger i2)
  1586. {
  1587. bool ret = i1.value > i2.value;
  1588. return new LSLInteger((ret ? 1 : 0));
  1589. }
  1590. static public LSLInteger operator >=(LSLInteger i1, LSLInteger i2)
  1591. {
  1592. bool ret = i1.value >= i2.value;
  1593. return new LSLInteger((ret ? 1 : 0));
  1594. }
  1595. static public LSLInteger operator +(LSLInteger i1, int i2)
  1596. {
  1597. return new LSLInteger(i1.value + i2);
  1598. }
  1599. static public LSLInteger operator -(LSLInteger i1, int i2)
  1600. {
  1601. return new LSLInteger(i1.value - i2);
  1602. }
  1603. static public LSLInteger operator *(LSLInteger i1, int i2)
  1604. {
  1605. return new LSLInteger(i1.value * i2);
  1606. }
  1607. static public LSLInteger operator /(LSLInteger i1, int i2)
  1608. {
  1609. return new LSLInteger(i1.value / i2);
  1610. }
  1611. // static public LSLFloat operator +(LSLInteger i1, double f)
  1612. // {
  1613. // return new LSLFloat((double)i1.value + f);
  1614. // }
  1615. //
  1616. // static public LSLFloat operator -(LSLInteger i1, double f)
  1617. // {
  1618. // return new LSLFloat((double)i1.value - f);
  1619. // }
  1620. //
  1621. // static public LSLFloat operator *(LSLInteger i1, double f)
  1622. // {
  1623. // return new LSLFloat((double)i1.value * f);
  1624. // }
  1625. //
  1626. // static public LSLFloat operator /(LSLInteger i1, double f)
  1627. // {
  1628. // return new LSLFloat((double)i1.value / f);
  1629. // }
  1630. static public LSLInteger operator -(LSLInteger i)
  1631. {
  1632. return new LSLInteger(-i.value);
  1633. }
  1634. static public LSLInteger operator ~(LSLInteger i)
  1635. {
  1636. return new LSLInteger(~i.value);
  1637. }
  1638. public override bool Equals(Object o)
  1639. {
  1640. if (!(o is LSLInteger))
  1641. {
  1642. if (o is int)
  1643. {
  1644. return value == (int)o;
  1645. }
  1646. else
  1647. {
  1648. return false;
  1649. }
  1650. }
  1651. return value == ((LSLInteger)o).value;
  1652. }
  1653. public override int GetHashCode()
  1654. {
  1655. return value;
  1656. }
  1657. static public LSLInteger operator &(LSLInteger i1, LSLInteger i2)
  1658. {
  1659. int ret = i1.value & i2.value;
  1660. return ret;
  1661. }
  1662. static public LSLInteger operator %(LSLInteger i1, LSLInteger i2)
  1663. {
  1664. int ret = i1.value % i2.value;
  1665. return ret;
  1666. }
  1667. static public LSLInteger operator |(LSLInteger i1, LSLInteger i2)
  1668. {
  1669. int ret = i1.value | i2.value;
  1670. return ret;
  1671. }
  1672. static public LSLInteger operator ^(LSLInteger i1, LSLInteger i2)
  1673. {
  1674. int ret = i1.value ^ i2.value;
  1675. return ret;
  1676. }
  1677. static public LSLInteger operator !(LSLInteger i1)
  1678. {
  1679. return i1.value == 0 ? 1 : 0;
  1680. }
  1681. public static LSLInteger operator ++(LSLInteger i)
  1682. {
  1683. i.value++;
  1684. return i;
  1685. }
  1686. public static LSLInteger operator --(LSLInteger i)
  1687. {
  1688. i.value--;
  1689. return i;
  1690. }
  1691. public static LSLInteger operator << (LSLInteger i, int s)
  1692. {
  1693. return i.value << s;
  1694. }
  1695. public static LSLInteger operator >> (LSLInteger i, int s)
  1696. {
  1697. return i.value >> s;
  1698. }
  1699. static public implicit operator System.Double(LSLInteger i)
  1700. {
  1701. return (double)i.value;
  1702. }
  1703. public static bool operator true(LSLInteger i)
  1704. {
  1705. return i.value != 0;
  1706. }
  1707. public static bool operator false(LSLInteger i)
  1708. {
  1709. return i.value == 0;
  1710. }
  1711. #endregion
  1712. #region Overriders
  1713. public override string ToString()
  1714. {
  1715. return this.value.ToString();
  1716. }
  1717. #endregion
  1718. }
  1719. [Serializable]
  1720. public struct LSLFloat
  1721. {
  1722. public double value;
  1723. #region Constructors
  1724. public LSLFloat(int i)
  1725. {
  1726. this.value = (double)i;
  1727. }
  1728. public LSLFloat(double d)
  1729. {
  1730. this.value = d;
  1731. }
  1732. public LSLFloat(string s)
  1733. {
  1734. Regex r = new Regex("^ *(\\+|-)?([0-9]+\\.?[0-9]*|\\.[0-9]+)([eE](\\+|-)?[0-9]+)?");
  1735. Match m = r.Match(s);
  1736. string v = m.Groups[0].Value;
  1737. v = v.Trim();
  1738. if (v == String.Empty || v == null)
  1739. v = "0.0";
  1740. else
  1741. if (!v.Contains(".") && !v.ToLower().Contains("e"))
  1742. v = v + ".0";
  1743. else
  1744. if (v.EndsWith("."))
  1745. v = v + "0";
  1746. this.value = double.Parse(v, System.Globalization.NumberStyles.Float, Culture.NumberFormatInfo);
  1747. }
  1748. #endregion
  1749. #region Operators
  1750. static public explicit operator float(LSLFloat f)
  1751. {
  1752. return (float)f.value;
  1753. }
  1754. static public explicit operator int(LSLFloat f)
  1755. {
  1756. return (int)f.value;
  1757. }
  1758. static public explicit operator uint(LSLFloat f)
  1759. {
  1760. return (uint) Math.Abs(f.value);
  1761. }
  1762. static public implicit operator Boolean(LSLFloat f)
  1763. {
  1764. if (f.value == 0.0)
  1765. {
  1766. return false;
  1767. }
  1768. else
  1769. {
  1770. return true;
  1771. }
  1772. }
  1773. static public implicit operator LSLFloat(int i)
  1774. {
  1775. return new LSLFloat(i);
  1776. }
  1777. static public implicit operator LSLFloat(LSLInteger i)
  1778. {
  1779. return new LSLFloat(i.value);
  1780. }
  1781. static public explicit operator LSLFloat(string s)
  1782. {
  1783. return new LSLFloat(s);
  1784. }
  1785. public static implicit operator list(LSLFloat f)
  1786. {
  1787. return new list(new object[] { f });
  1788. }
  1789. static public implicit operator LSLFloat(double d)
  1790. {
  1791. return new LSLFloat(d);
  1792. }
  1793. static public implicit operator LSLFloat(bool b)
  1794. {
  1795. if (b)
  1796. return new LSLFloat(1.0);
  1797. else
  1798. return new LSLFloat(0.0);
  1799. }
  1800. static public bool operator ==(LSLFloat f1, LSLFloat f2)
  1801. {
  1802. return f1.value == f2.value;
  1803. }
  1804. static public bool operator !=(LSLFloat f1, LSLFloat f2)
  1805. {
  1806. return f1.value != f2.value;
  1807. }
  1808. static public LSLFloat operator ++(LSLFloat f)
  1809. {
  1810. f.value++;
  1811. return f;
  1812. }
  1813. static public LSLFloat operator --(LSLFloat f)
  1814. {
  1815. f.value--;
  1816. return f;
  1817. }
  1818. static public LSLFloat operator +(LSLFloat f, int i)
  1819. {
  1820. return new LSLFloat(f.value + (double)i);
  1821. }
  1822. static public LSLFloat operator -(LSLFloat f, int i)
  1823. {
  1824. return new LSLFloat(f.value - (double)i);
  1825. }
  1826. static public LSLFloat operator *(LSLFloat f, int i)
  1827. {
  1828. return new LSLFloat(f.value * (double)i);
  1829. }
  1830. static public LSLFloat operator /(LSLFloat f, int i)
  1831. {
  1832. return new LSLFloat(f.value / (double)i);
  1833. }
  1834. static public LSLFloat operator +(LSLFloat lhs, LSLFloat rhs)
  1835. {
  1836. return new LSLFloat(lhs.value + rhs.value);
  1837. }
  1838. static public LSLFloat operator -(LSLFloat lhs, LSLFloat rhs)
  1839. {
  1840. return new LSLFloat(lhs.value - rhs.value);
  1841. }
  1842. static public LSLFloat operator *(LSLFloat lhs, LSLFloat rhs)
  1843. {
  1844. return new LSLFloat(lhs.value * rhs.value);
  1845. }
  1846. static public LSLFloat operator /(LSLFloat lhs, LSLFloat rhs)
  1847. {
  1848. return new LSLFloat(lhs.value / rhs.value);
  1849. }
  1850. static public LSLFloat operator -(LSLFloat f)
  1851. {
  1852. return new LSLFloat(-f.value);
  1853. }
  1854. static public implicit operator System.Double(LSLFloat f)
  1855. {
  1856. return f.value;
  1857. }
  1858. #endregion
  1859. #region Overriders
  1860. public override string ToString()
  1861. {
  1862. return String.Format(Culture.FormatProvider, "{0:0.000000}", this.value);
  1863. }
  1864. public override bool Equals(Object o)
  1865. {
  1866. if (!(o is LSLFloat))
  1867. return false;
  1868. return value == ((LSLFloat)o).value;
  1869. }
  1870. public override int GetHashCode()
  1871. {
  1872. return value.GetHashCode();
  1873. }
  1874. #endregion
  1875. }
  1876. }
  1877. }