opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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 //
1381 // BELOW IS WORK IN PROGRESS... IT WILL CHANGE, SO DON'T USE YET! :)
1382 //
1383  
1384 public struct StringTest
1385 {
1386 // Our own little string
1387 internal string actualString;
1388 public static implicit operator bool(StringTest mString)
1389 {
1390 if (mString.actualString.Length == 0)
1391 return true;
1392 return false;
1393 }
1394 public override string ToString()
1395 {
1396 return actualString;
1397 }
1398  
1399 }
1400  
1401 [Serializable]
1402 public struct key
1403 {
1404 public string value;
1405  
1406 #region Constructors
1407 public key(string s)
1408 {
1409 value = s;
1410 }
1411  
1412 #endregion
1413  
1414 #region Methods
1415  
1416 static public bool Parse2Key(string s)
1417 {
1418 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);
1419 if (isuuid.IsMatch(s))
1420 {
1421 return true;
1422 }
1423 else
1424 {
1425 return false;
1426 }
1427 }
1428  
1429 #endregion
1430  
1431 #region Operators
1432  
1433 static public implicit operator Boolean(key k)
1434 {
1435 if (k.value.Length == 0)
1436 {
1437 return false;
1438 }
1439  
1440 if (k.value == "00000000-0000-0000-0000-000000000000")
1441 {
1442 return false;
1443 }
1444 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);
1445 if (isuuid.IsMatch(k.value))
1446 {
1447 return true;
1448 }
1449 else
1450 {
1451 return false;
1452 }
1453 }
1454  
1455 static public implicit operator key(string s)
1456 {
1457 return new key(s);
1458 }
1459  
1460 static public implicit operator String(key k)
1461 {
1462 return k.value;
1463 }
1464  
1465 static public implicit operator LSLString(key k)
1466 {
1467 return k.value;
1468 }
1469  
1470 public static bool operator ==(key k1, key k2)
1471 {
1472 return k1.value == k2.value;
1473 }
1474 public static bool operator !=(key k1, key k2)
1475 {
1476 return k1.value != k2.value;
1477 }
1478  
1479 #endregion
1480  
1481 #region Overriders
1482  
1483 public override bool Equals(object o)
1484 {
1485 return o.ToString() == value;
1486 }
1487  
1488 public override int GetHashCode()
1489 {
1490 return value.GetHashCode();
1491 }
1492  
1493 public override string ToString()
1494 {
1495 return value;
1496 }
1497  
1498 #endregion
1499 }
1500  
1501 [Serializable]
1502 public struct LSLString
1503 {
1504 public string m_string;
1505  
1506 #region Constructors
1507  
1508 public LSLString(string s)
1509 {
1510 m_string = s;
1511 }
1512  
1513 public LSLString(double d)
1514 {
1515 string s = String.Format(Culture.FormatProvider, "{0:0.000000}", d);
1516 m_string = s;
1517 }
1518  
1519 public LSLString(LSLFloat f)
1520 {
1521 string s = String.Format(Culture.FormatProvider, "{0:0.000000}", f.value);
1522 m_string = s;
1523 }
1524  
1525 public LSLString(int i)
1526 {
1527 string s = String.Format("{0}", i);
1528 m_string = s;
1529 }
1530  
1531 public LSLString(LSLInteger i) : this(i.value) {}
1532  
1533 #endregion
1534  
1535 #region Operators
1536 static public implicit operator Boolean(LSLString s)
1537 {
1538 if (s.m_string.Length == 0)
1539 {
1540 return false;
1541 }
1542 else
1543 {
1544 return true;
1545 }
1546 }
1547  
1548  
1549  
1550 static public implicit operator String(LSLString s)
1551 {
1552 return s.m_string;
1553 }
1554  
1555 static public implicit operator LSLString(string s)
1556 {
1557 return new LSLString(s);
1558 }
1559  
1560 public static string ToString(LSLString s)
1561 {
1562 return s.m_string;
1563 }
1564  
1565 public override string ToString()
1566 {
1567 return m_string;
1568 }
1569  
1570 public static bool operator ==(LSLString s1, string s2)
1571 {
1572 return s1.m_string == s2;
1573 }
1574  
1575 public static bool operator !=(LSLString s1, string s2)
1576 {
1577 return s1.m_string != s2;
1578 }
1579  
1580 public static LSLString operator +(LSLString s1, LSLString s2)
1581 {
1582 return new LSLString(s1.m_string + s2.m_string);
1583 }
1584  
1585 public static explicit operator double(LSLString s)
1586 {
1587 return new LSLFloat(s).value;
1588 }
1589  
1590 public static explicit operator LSLInteger(LSLString s)
1591 {
1592 return new LSLInteger(s.m_string);
1593 }
1594  
1595 public static explicit operator LSLString(double d)
1596 {
1597 return new LSLString(d);
1598 }
1599  
1600 static public explicit operator LSLString(int i)
1601 {
1602 return new LSLString(i);
1603 }
1604  
1605 public static explicit operator LSLString(LSLFloat f)
1606 {
1607 return new LSLString(f);
1608 }
1609  
1610 static public explicit operator LSLString(bool b)
1611 {
1612 if (b)
1613 return new LSLString("1");
1614 else
1615 return new LSLString("0");
1616 }
1617  
1618 public static implicit operator Vector3(LSLString s)
1619 {
1620 return new Vector3(s.m_string);
1621 }
1622  
1623 public static implicit operator Quaternion(LSLString s)
1624 {
1625 return new Quaternion(s.m_string);
1626 }
1627  
1628 public static implicit operator LSLFloat(LSLString s)
1629 {
1630 return new LSLFloat(s);
1631 }
1632  
1633 public static implicit operator list(LSLString s)
1634 {
1635 return new list(new object[]{s});
1636 }
1637  
1638 #endregion
1639  
1640 #region Overriders
1641 public override bool Equals(object o)
1642 {
1643 return m_string == o.ToString();
1644 }
1645  
1646 public override int GetHashCode()
1647 {
1648 return m_string.GetHashCode();
1649 }
1650  
1651 #endregion
1652  
1653 #region " Standard string functions "
1654 //Clone,CompareTo,Contains
1655 //CopyTo,EndsWith,Equals,GetEnumerator,GetHashCode,GetType,GetTypeCode
1656 //IndexOf,IndexOfAny,Insert,IsNormalized,LastIndexOf,LastIndexOfAny
1657 //Length,Normalize,PadLeft,PadRight,Remove,Replace,Split,StartsWith,Substring,ToCharArray,ToLowerInvariant
1658 //ToString,ToUpper,ToUpperInvariant,Trim,TrimEnd,TrimStart
1659 public bool Contains(string value) { return m_string.Contains(value); }
1660 public int IndexOf(string value) { return m_string.IndexOf(value); }
1661 public int Length { get { return m_string.Length; } }
1662  
1663  
1664 #endregion
1665 }
1666  
1667 [Serializable]
1668 public struct LSLInteger
1669 {
1670 public int value;
1671 private static readonly Regex castRegex = new Regex(@"(^[ ]*0[xX][0-9A-Fa-f][0-9A-Fa-f]*)|(^[ ]*(-?|\+?)[0-9][0-9]*)");
1672  
1673 #region Constructors
1674 public LSLInteger(int i)
1675 {
1676 value = i;
1677 }
1678  
1679 public LSLInteger(uint i)
1680 {
1681 value = (int)i;
1682 }
1683  
1684 public LSLInteger(double d)
1685 {
1686 value = (int)d;
1687 }
1688  
1689 public LSLInteger(string s)
1690 {
1691 Match m = castRegex.Match(s);
1692 string v = m.Groups[0].Value;
1693 // Leading plus sign is allowed, but ignored
1694 v = v.Replace("+", "");
1695  
1696 if (v == String.Empty)
1697 {
1698 value = 0;
1699 }
1700 else
1701 {
1702 try
1703 {
1704 if (v.Contains("x") || v.Contains("X"))
1705 {
1706 value = int.Parse(v.Substring(2), System.Globalization.NumberStyles.HexNumber);
1707 }
1708 else
1709 {
1710 value = int.Parse(v, System.Globalization.NumberStyles.Integer);
1711 }
1712 }
1713 catch (OverflowException)
1714 {
1715 value = -1;
1716 }
1717 }
1718 }
1719  
1720 #endregion
1721  
1722 #region Operators
1723  
1724 static public implicit operator int(LSLInteger i)
1725 {
1726 return i.value;
1727 }
1728  
1729 static public explicit operator uint(LSLInteger i)
1730 {
1731 return (uint)i.value;
1732 }
1733  
1734 static public explicit operator LSLString(LSLInteger i)
1735 {
1736 return new LSLString(i.ToString());
1737 }
1738  
1739 public static implicit operator list(LSLInteger i)
1740 {
1741 return new list(new object[] { i });
1742 }
1743  
1744 static public implicit operator Boolean(LSLInteger i)
1745 {
1746 if (i.value == 0)
1747 {
1748 return false;
1749 }
1750 else
1751 {
1752 return true;
1753 }
1754 }
1755  
1756 static public implicit operator LSLInteger(int i)
1757 {
1758 return new LSLInteger(i);
1759 }
1760  
1761 static public explicit operator LSLInteger(string s)
1762 {
1763 return new LSLInteger(s);
1764 }
1765  
1766 static public implicit operator LSLInteger(uint u)
1767 {
1768 return new LSLInteger(u);
1769 }
1770  
1771 static public explicit operator LSLInteger(double d)
1772 {
1773 return new LSLInteger(d);
1774 }
1775  
1776 static public explicit operator LSLInteger(LSLFloat f)
1777 {
1778 return new LSLInteger(f.value);
1779 }
1780  
1781 static public implicit operator LSLInteger(bool b)
1782 {
1783 if (b)
1784 return new LSLInteger(1);
1785 else
1786 return new LSLInteger(0);
1787 }
1788  
1789 static public LSLInteger operator ==(LSLInteger i1, LSLInteger i2)
1790 {
1791 bool ret = i1.value == i2.value;
1792 return new LSLInteger((ret ? 1 : 0));
1793 }
1794  
1795 static public LSLInteger operator !=(LSLInteger i1, LSLInteger i2)
1796 {
1797 bool ret = i1.value != i2.value;
1798 return new LSLInteger((ret ? 1 : 0));
1799 }
1800  
1801 static public LSLInteger operator <(LSLInteger i1, LSLInteger i2)
1802 {
1803 bool ret = i1.value < i2.value;
1804 return new LSLInteger((ret ? 1 : 0));
1805 }
1806 static public LSLInteger operator <=(LSLInteger i1, LSLInteger i2)
1807 {
1808 bool ret = i1.value <= i2.value;
1809 return new LSLInteger((ret ? 1 : 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, int i2)
1825 {
1826 return new LSLInteger(i1.value + i2);
1827 }
1828  
1829 static public LSLInteger operator -(LSLInteger i1, int i2)
1830 {
1831 return new LSLInteger(i1.value - i2);
1832 }
1833  
1834 static public LSLInteger operator *(LSLInteger i1, int i2)
1835 {
1836 return new LSLInteger(i1.value * i2);
1837 }
1838  
1839 static public LSLInteger operator /(LSLInteger i1, int i2)
1840 {
1841 return new LSLInteger(i1.value / i2);
1842 }
1843  
1844 // static public LSLFloat operator +(LSLInteger i1, double f)
1845 // {
1846 // return new LSLFloat((double)i1.value + f);
1847 // }
1848 //
1849 // static public LSLFloat operator -(LSLInteger i1, double f)
1850 // {
1851 // return new LSLFloat((double)i1.value - f);
1852 // }
1853 //
1854 // static public LSLFloat operator *(LSLInteger i1, double f)
1855 // {
1856 // return new LSLFloat((double)i1.value * f);
1857 // }
1858 //
1859 // static public LSLFloat operator /(LSLInteger i1, double f)
1860 // {
1861 // return new LSLFloat((double)i1.value / f);
1862 // }
1863  
1864 static public LSLInteger operator -(LSLInteger i)
1865 {
1866 return new LSLInteger(-i.value);
1867 }
1868  
1869 static public LSLInteger operator ~(LSLInteger i)
1870 {
1871 return new LSLInteger(~i.value);
1872 }
1873  
1874 public override bool Equals(Object o)
1875 {
1876 if (!(o is LSLInteger))
1877 {
1878 if (o is int)
1879 {
1880 return value == (int)o;
1881 }
1882 else
1883 {
1884 return false;
1885 }
1886 }
1887  
1888 return value == ((LSLInteger)o).value;
1889 }
1890  
1891 public override int GetHashCode()
1892 {
1893 return value;
1894 }
1895  
1896 static public LSLInteger operator &(LSLInteger i1, LSLInteger i2)
1897 {
1898 int ret = i1.value & i2.value;
1899 return ret;
1900 }
1901  
1902 static public LSLInteger operator %(LSLInteger i1, LSLInteger i2)
1903 {
1904 int ret = i1.value % i2.value;
1905 return ret;
1906 }
1907  
1908 static public LSLInteger operator |(LSLInteger i1, LSLInteger i2)
1909 {
1910 int ret = i1.value | i2.value;
1911 return ret;
1912 }
1913  
1914 static public LSLInteger operator ^(LSLInteger i1, LSLInteger i2)
1915 {
1916 int ret = i1.value ^ i2.value;
1917 return ret;
1918 }
1919  
1920 static public LSLInteger operator !(LSLInteger i1)
1921 {
1922 return i1.value == 0 ? 1 : 0;
1923 }
1924  
1925 public static LSLInteger operator ++(LSLInteger i)
1926 {
1927 i.value++;
1928 return i;
1929 }
1930  
1931  
1932 public static LSLInteger operator --(LSLInteger i)
1933 {
1934 i.value--;
1935 return i;
1936 }
1937  
1938 public static LSLInteger operator << (LSLInteger i, int s)
1939 {
1940 return i.value << s;
1941 }
1942  
1943 public static LSLInteger operator >> (LSLInteger i, int s)
1944 {
1945 return i.value >> s;
1946 }
1947  
1948 static public implicit operator System.Double(LSLInteger i)
1949 {
1950 return (double)i.value;
1951 }
1952  
1953 public static bool operator true(LSLInteger i)
1954 {
1955 return i.value != 0;
1956 }
1957  
1958 public static bool operator false(LSLInteger i)
1959 {
1960 return i.value == 0;
1961 }
1962  
1963 #endregion
1964  
1965 #region Overriders
1966  
1967 public override string ToString()
1968 {
1969 return this.value.ToString();
1970 }
1971  
1972 #endregion
1973 }
1974  
1975 [Serializable]
1976 public struct LSLFloat
1977 {
1978 public double value;
1979  
1980 #region Constructors
1981  
1982 public LSLFloat(int i)
1983 {
1984 this.value = (double)i;
1985 }
1986  
1987 public LSLFloat(double d)
1988 {
1989 this.value = d;
1990 }
1991  
1992 public LSLFloat(string s)
1993 {
1994 Regex r = new Regex("^ *(\\+|-)?([0-9]+\\.?[0-9]*|\\.[0-9]+)([eE](\\+|-)?[0-9]+)?");
1995 Match m = r.Match(s);
1996 string v = m.Groups[0].Value;
1997  
1998 v = v.Trim();
1999  
2000 if (v == String.Empty || v == null)
2001 v = "0.0";
2002 else
2003 if (!v.Contains(".") && !v.ToLower().Contains("e"))
2004 v = v + ".0";
2005 else
2006 if (v.EndsWith("."))
2007 v = v + "0";
2008 this.value = double.Parse(v, System.Globalization.NumberStyles.Float, Culture.NumberFormatInfo);
2009 }
2010  
2011 #endregion
2012  
2013 #region Operators
2014  
2015 static public explicit operator float(LSLFloat f)
2016 {
2017 return (float)f.value;
2018 }
2019  
2020 static public explicit operator int(LSLFloat f)
2021 {
2022 return (int)f.value;
2023 }
2024  
2025 static public explicit operator uint(LSLFloat f)
2026 {
2027 return (uint) Math.Abs(f.value);
2028 }
2029  
2030 static public implicit operator Boolean(LSLFloat f)
2031 {
2032 if (f.value == 0.0)
2033 {
2034 return false;
2035 }
2036 else
2037 {
2038 return true;
2039 }
2040 }
2041  
2042 static public implicit operator LSLFloat(int i)
2043 {
2044 return new LSLFloat(i);
2045 }
2046  
2047 static public implicit operator LSLFloat(LSLInteger i)
2048 {
2049 return new LSLFloat(i.value);
2050 }
2051  
2052 static public explicit operator LSLFloat(string s)
2053 {
2054 return new LSLFloat(s);
2055 }
2056  
2057 public static implicit operator list(LSLFloat f)
2058 {
2059 return new list(new object[] { f });
2060 }
2061  
2062 static public implicit operator LSLFloat(double d)
2063 {
2064 return new LSLFloat(d);
2065 }
2066  
2067 static public implicit operator LSLFloat(bool b)
2068 {
2069 if (b)
2070 return new LSLFloat(1.0);
2071 else
2072 return new LSLFloat(0.0);
2073 }
2074  
2075 static public bool operator ==(LSLFloat f1, LSLFloat f2)
2076 {
2077 return f1.value == f2.value;
2078 }
2079  
2080 static public bool operator !=(LSLFloat f1, LSLFloat f2)
2081 {
2082 return f1.value != f2.value;
2083 }
2084  
2085 static public LSLFloat operator ++(LSLFloat f)
2086 {
2087 f.value++;
2088 return f;
2089 }
2090  
2091 static public LSLFloat operator --(LSLFloat f)
2092 {
2093 f.value--;
2094 return f;
2095 }
2096  
2097 static public LSLFloat operator +(LSLFloat f, int i)
2098 {
2099 return new LSLFloat(f.value + (double)i);
2100 }
2101  
2102 static public LSLFloat operator -(LSLFloat f, int i)
2103 {
2104 return new LSLFloat(f.value - (double)i);
2105 }
2106  
2107 static public LSLFloat operator *(LSLFloat f, int i)
2108 {
2109 return new LSLFloat(f.value * (double)i);
2110 }
2111  
2112 static public LSLFloat operator /(LSLFloat f, int i)
2113 {
2114 return new LSLFloat(f.value / (double)i);
2115 }
2116  
2117 static public LSLFloat operator +(LSLFloat lhs, LSLFloat rhs)
2118 {
2119 return new LSLFloat(lhs.value + rhs.value);
2120 }
2121  
2122 static public LSLFloat operator -(LSLFloat lhs, LSLFloat rhs)
2123 {
2124 return new LSLFloat(lhs.value - rhs.value);
2125 }
2126  
2127 static public LSLFloat operator *(LSLFloat lhs, LSLFloat rhs)
2128 {
2129 return new LSLFloat(lhs.value * rhs.value);
2130 }
2131  
2132 static public LSLFloat operator /(LSLFloat lhs, LSLFloat rhs)
2133 {
2134 return new LSLFloat(lhs.value / rhs.value);
2135 }
2136  
2137 static public LSLFloat operator -(LSLFloat f)
2138 {
2139 return new LSLFloat(-f.value);
2140 }
2141  
2142 static public implicit operator System.Double(LSLFloat f)
2143 {
2144 return f.value;
2145 }
2146  
2147 #endregion
2148  
2149 #region Overriders
2150  
2151 public override string ToString()
2152 {
2153 return String.Format(Culture.FormatProvider, "{0:0.000000}", this.value);
2154 }
2155  
2156 public override bool Equals(Object o)
2157 {
2158 if (!(o is LSLFloat))
2159 return false;
2160 return value == ((LSLFloat)o).value;
2161 }
2162  
2163 public override int GetHashCode()
2164 {
2165 return value.GetHashCode();
2166 }
2167  
2168  
2169 #endregion
2170 }
2171 }
2172 }