clockwerk-opensim – Blame information for rev 1

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