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