corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * Copyright (c) 2006-2014, openmetaverse.org
3 * All rights reserved.
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 *
8 * - Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 * - Neither the name of the openmetaverse.org nor the names
11 * of its contributors may be used to endorse or promote products derived from
12 * this software without specific prior written permission.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26  
27 using System;
28 using System.Collections;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Reflection;
32 using System.Text;
33  
34 namespace OpenMetaverse.StructuredData
35 {
36 /// <summary>
37 ///
38 /// </summary>
39 public enum OSDType
40 {
41 /// <summary></summary>
42 Unknown,
43 /// <summary></summary>
44 Boolean,
45 /// <summary></summary>
46 Integer,
47 /// <summary></summary>
48 Real,
49 /// <summary></summary>
50 String,
51 /// <summary></summary>
52 UUID,
53 /// <summary></summary>
54 Date,
55 /// <summary></summary>
56 URI,
57 /// <summary></summary>
58 Binary,
59 /// <summary></summary>
60 Map,
61 /// <summary></summary>
62 Array
63 }
64  
65 public enum OSDFormat
66 {
67 Xml = 0,
68 Json,
69 Binary
70 }
71  
72 /// <summary>
73 ///
74 /// </summary>
75 public class OSDException : Exception
76 {
77 public OSDException(string message) : base(message) { }
78 }
79  
80 /// <summary>
81 ///
82 /// </summary>
83 public partial class OSD
84 {
85 public virtual OSDType Type { get { return OSDType.Unknown; } }
86  
87 public virtual bool AsBoolean() { return false; }
88 public virtual int AsInteger() { return 0; }
89 public virtual uint AsUInteger() { return 0; }
90 public virtual long AsLong() { return 0; }
91 public virtual ulong AsULong() { return 0; }
92 public virtual double AsReal() { return 0d; }
93 public virtual string AsString() { return String.Empty; }
94 public virtual UUID AsUUID() { return UUID.Zero; }
95 public virtual DateTime AsDate() { return Utils.Epoch; }
96 public virtual Uri AsUri() { return null; }
97 public virtual byte[] AsBinary() { return Utils.EmptyBytes; }
98 public virtual Vector2 AsVector2() { return Vector2.Zero; }
99 public virtual Vector3 AsVector3() { return Vector3.Zero; }
100 public virtual Vector3d AsVector3d() { return Vector3d.Zero; }
101 public virtual Vector4 AsVector4() { return Vector4.Zero; }
102 public virtual Quaternion AsQuaternion() { return Quaternion.Identity; }
103 public virtual Color4 AsColor4() { return Color4.Black; }
104 public virtual OSD Copy() { return new OSD(); }
105  
106 public override string ToString() { return "undef"; }
107  
108 public static OSD FromBoolean(bool value) { return new OSDBoolean(value); }
109 public static OSD FromInteger(int value) { return new OSDInteger(value); }
110 public static OSD FromInteger(uint value) { return new OSDInteger((int)value); }
111 public static OSD FromInteger(short value) { return new OSDInteger((int)value); }
112 public static OSD FromInteger(ushort value) { return new OSDInteger((int)value); }
113 public static OSD FromInteger(sbyte value) { return new OSDInteger((int)value); }
114 public static OSD FromInteger(byte value) { return new OSDInteger((int)value); }
115 public static OSD FromUInteger(uint value) { return new OSDBinary(value); }
116 public static OSD FromLong(long value) { return new OSDBinary(value); }
117 public static OSD FromULong(ulong value) { return new OSDBinary(value); }
118 public static OSD FromReal(double value) { return new OSDReal(value); }
119 public static OSD FromReal(float value) { return new OSDReal((double)value); }
120 public static OSD FromString(string value) { return new OSDString(value); }
121 public static OSD FromUUID(UUID value) { return new OSDUUID(value); }
122 public static OSD FromDate(DateTime value) { return new OSDDate(value); }
123 public static OSD FromUri(Uri value) { return new OSDUri(value); }
124 public static OSD FromBinary(byte[] value) { return new OSDBinary(value); }
125  
126 public static OSD FromVector2(Vector2 value)
127 {
128 OSDArray array = new OSDArray();
129 array.Add(OSD.FromReal(value.X));
130 array.Add(OSD.FromReal(value.Y));
131 return array;
132 }
133  
134 public static OSD FromVector3(Vector3 value)
135 {
136 OSDArray array = new OSDArray();
137 array.Add(OSD.FromReal(value.X));
138 array.Add(OSD.FromReal(value.Y));
139 array.Add(OSD.FromReal(value.Z));
140 return array;
141 }
142  
143 public static OSD FromVector3d(Vector3d value)
144 {
145 OSDArray array = new OSDArray();
146 array.Add(OSD.FromReal(value.X));
147 array.Add(OSD.FromReal(value.Y));
148 array.Add(OSD.FromReal(value.Z));
149 return array;
150 }
151  
152 public static OSD FromVector4(Vector4 value)
153 {
154 OSDArray array = new OSDArray();
155 array.Add(OSD.FromReal(value.X));
156 array.Add(OSD.FromReal(value.Y));
157 array.Add(OSD.FromReal(value.Z));
158 array.Add(OSD.FromReal(value.W));
159 return array;
160 }
161  
162 public static OSD FromQuaternion(Quaternion value)
163 {
164 OSDArray array = new OSDArray();
165 array.Add(OSD.FromReal(value.X));
166 array.Add(OSD.FromReal(value.Y));
167 array.Add(OSD.FromReal(value.Z));
168 array.Add(OSD.FromReal(value.W));
169 return array;
170 }
171  
172 public static OSD FromColor4(Color4 value)
173 {
174 OSDArray array = new OSDArray();
175 array.Add(OSD.FromReal(value.R));
176 array.Add(OSD.FromReal(value.G));
177 array.Add(OSD.FromReal(value.B));
178 array.Add(OSD.FromReal(value.A));
179 return array;
180 }
181  
182 public static OSD FromObject(object value)
183 {
184 if (value == null) { return new OSD(); }
185 else if (value is bool) { return new OSDBoolean((bool)value); }
186 else if (value is int) { return new OSDInteger((int)value); }
187 else if (value is uint) { return new OSDBinary((uint)value); }
188 else if (value is short) { return new OSDInteger((int)(short)value); }
189 else if (value is ushort) { return new OSDInteger((int)(ushort)value); }
190 else if (value is sbyte) { return new OSDInteger((int)(sbyte)value); }
191 else if (value is byte) { return new OSDInteger((int)(byte)value); }
192 else if (value is double) { return new OSDReal((double)value); }
193 else if (value is float) { return new OSDReal((double)(float)value); }
194 else if (value is string) { return new OSDString((string)value); }
195 else if (value is UUID) { return new OSDUUID((UUID)value); }
196 else if (value is DateTime) { return new OSDDate((DateTime)value); }
197 else if (value is Uri) { return new OSDUri((Uri)value); }
198 else if (value is byte[]) { return new OSDBinary((byte[])value); }
199 else if (value is long) { return new OSDBinary((long)value); }
200 else if (value is ulong) { return new OSDBinary((ulong)value); }
201 else if (value is Vector2) { return FromVector2((Vector2)value); }
202 else if (value is Vector3) { return FromVector3((Vector3)value); }
203 else if (value is Vector3d) { return FromVector3d((Vector3d)value); }
204 else if (value is Vector4) { return FromVector4((Vector4)value); }
205 else if (value is Quaternion) { return FromQuaternion((Quaternion)value); }
206 else if (value is Color4) { return FromColor4((Color4)value); }
207 else return new OSD();
208 }
209  
210 public static object ToObject(Type type, OSD value)
211 {
212 if (type == typeof(ulong))
213 {
214 if (value.Type == OSDType.Binary)
215 {
216 byte[] bytes = value.AsBinary();
217 return Utils.BytesToUInt64(bytes);
218 }
219 else
220 {
221 return (ulong)value.AsInteger();
222 }
223 }
224 else if (type == typeof(uint))
225 {
226 if (value.Type == OSDType.Binary)
227 {
228 byte[] bytes = value.AsBinary();
229 return Utils.BytesToUInt(bytes);
230 }
231 else
232 {
233 return (uint)value.AsInteger();
234 }
235 }
236 else if (type == typeof(ushort))
237 {
238 return (ushort)value.AsInteger();
239 }
240 else if (type == typeof(byte))
241 {
242 return (byte)value.AsInteger();
243 }
244 else if (type == typeof(short))
245 {
246 return (short)value.AsInteger();
247 }
248 else if (type == typeof(string))
249 {
250 return value.AsString();
251 }
252 else if (type == typeof(bool))
253 {
254 return value.AsBoolean();
255 }
256 else if (type == typeof(float))
257 {
258 return (float)value.AsReal();
259 }
260 else if (type == typeof(double))
261 {
262 return value.AsReal();
263 }
264 else if (type == typeof(int))
265 {
266 return value.AsInteger();
267 }
268 else if (type == typeof(UUID))
269 {
270 return value.AsUUID();
271 }
272 else if (type == typeof(Vector3))
273 {
274 if (value.Type == OSDType.Array)
275 return ((OSDArray)value).AsVector3();
276 else
277 return Vector3.Zero;
278 }
279 else if (type == typeof(Vector4))
280 {
281 if (value.Type == OSDType.Array)
282 return ((OSDArray)value).AsVector4();
283 else
284 return Vector4.Zero;
285 }
286 else if (type == typeof(Quaternion))
287 {
288 if (value.Type == OSDType.Array)
289 return ((OSDArray)value).AsQuaternion();
290 else
291 return Quaternion.Identity;
292 }
293 else if (type == typeof(OSDArray))
294 {
295 OSDArray newArray = new OSDArray();
296 foreach (OSD o in (OSDArray)value)
297 newArray.Add(o);
298 return newArray;
299 }
300 else if (type == typeof(OSDMap))
301 {
302 OSDMap newMap = new OSDMap();
303 foreach (KeyValuePair<string, OSD> o in (OSDMap)value)
304 newMap.Add(o);
305 return newMap;
306 }
307 else
308 {
309 return null;
310 }
311 }
312  
313 #region Implicit Conversions
314  
315 public static implicit operator OSD(bool value) { return new OSDBoolean(value); }
316 public static implicit operator OSD(int value) { return new OSDInteger(value); }
317 public static implicit operator OSD(uint value) { return new OSDInteger((int)value); }
318 public static implicit operator OSD(short value) { return new OSDInteger((int)value); }
319 public static implicit operator OSD(ushort value) { return new OSDInteger((int)value); }
320 public static implicit operator OSD(sbyte value) { return new OSDInteger((int)value); }
321 public static implicit operator OSD(byte value) { return new OSDInteger((int)value); }
322 public static implicit operator OSD(long value) { return new OSDBinary(value); }
323 public static implicit operator OSD(ulong value) { return new OSDBinary(value); }
324 public static implicit operator OSD(double value) { return new OSDReal(value); }
325 public static implicit operator OSD(float value) { return new OSDReal(value); }
326 public static implicit operator OSD(string value) { return new OSDString(value); }
327 public static implicit operator OSD(UUID value) { return new OSDUUID(value); }
328 public static implicit operator OSD(DateTime value) { return new OSDDate(value); }
329 public static implicit operator OSD(Uri value) { return new OSDUri(value); }
330 public static implicit operator OSD(byte[] value) { return new OSDBinary(value); }
331 public static implicit operator OSD(Vector2 value) { return OSD.FromVector2(value); }
332 public static implicit operator OSD(Vector3 value) { return OSD.FromVector3(value); }
333 public static implicit operator OSD(Vector3d value) { return OSD.FromVector3d(value); }
334 public static implicit operator OSD(Vector4 value) { return OSD.FromVector4(value); }
335 public static implicit operator OSD(Quaternion value) { return OSD.FromQuaternion(value); }
336 public static implicit operator OSD(Color4 value) { return OSD.FromColor4(value); }
337  
338 public static implicit operator bool(OSD value) { return value.AsBoolean(); }
339 public static implicit operator int(OSD value) { return value.AsInteger(); }
340 public static implicit operator uint(OSD value) { return value.AsUInteger(); }
341 public static implicit operator long(OSD value) { return value.AsLong(); }
342 public static implicit operator ulong(OSD value) { return value.AsULong(); }
343 public static implicit operator double(OSD value) { return value.AsReal(); }
344 public static implicit operator float(OSD value) { return (float)value.AsReal(); }
345 public static implicit operator string(OSD value) { return value.AsString(); }
346 public static implicit operator UUID(OSD value) { return value.AsUUID(); }
347 public static implicit operator DateTime(OSD value) { return value.AsDate(); }
348 public static implicit operator Uri(OSD value) { return value.AsUri(); }
349 public static implicit operator byte[](OSD value) { return value.AsBinary(); }
350 public static implicit operator Vector2(OSD value) { return value.AsVector2(); }
351 public static implicit operator Vector3(OSD value) { return value.AsVector3(); }
352 public static implicit operator Vector3d(OSD value) { return value.AsVector3d(); }
353 public static implicit operator Vector4(OSD value) { return value.AsVector4(); }
354 public static implicit operator Quaternion(OSD value) { return value.AsQuaternion(); }
355 public static implicit operator Color4(OSD value) { return value.AsColor4(); }
356  
357 #endregion Implicit Conversions
358  
359 /// <summary>
360 /// Uses reflection to create an SDMap from all of the SD
361 /// serializable types in an object
362 /// </summary>
363 /// <param name="obj">Class or struct containing serializable types</param>
364 /// <returns>An SDMap holding the serialized values from the
365 /// container object</returns>
366 public static OSDMap SerializeMembers(object obj)
367 {
368 Type t = obj.GetType();
369 FieldInfo[] fields = t.GetFields();
370  
371 OSDMap map = new OSDMap(fields.Length);
372  
373 for (int i = 0; i < fields.Length; i++)
374 {
375 FieldInfo field = fields[i];
376 if (!Attribute.IsDefined(field, typeof(NonSerializedAttribute)))
377 {
378 OSD serializedField = OSD.FromObject(field.GetValue(obj));
379  
380 if (serializedField.Type != OSDType.Unknown || field.FieldType == typeof(string) || field.FieldType == typeof(byte[]))
381 map.Add(field.Name, serializedField);
382 }
383 }
384  
385 return map;
386 }
387  
388 /// <summary>
389 /// Uses reflection to deserialize member variables in an object from
390 /// an SDMap
391 /// </summary>
392 /// <param name="obj">Reference to an object to fill with deserialized
393 /// values</param>
394 /// <param name="serialized">Serialized values to put in the target
395 /// object</param>
396 public static void DeserializeMembers(ref object obj, OSDMap serialized)
397 {
398 Type t = obj.GetType();
399 FieldInfo[] fields = t.GetFields();
400  
401 for (int i = 0; i < fields.Length; i++)
402 {
403 FieldInfo field = fields[i];
404 if (!Attribute.IsDefined(field, typeof(NonSerializedAttribute)))
405 {
406 OSD serializedField;
407 if (serialized.TryGetValue(field.Name, out serializedField))
408 field.SetValue(obj, ToObject(field.FieldType, serializedField));
409 }
410 }
411 }
412 }
413  
414 /// <summary>
415 ///
416 /// </summary>
417 public sealed class OSDBoolean : OSD
418 {
419 private bool value;
420  
421 private static byte[] trueBinary = { 0x31 };
422 private static byte[] falseBinary = { 0x30 };
423  
424 public override OSDType Type { get { return OSDType.Boolean; } }
425  
426 public OSDBoolean(bool value)
427 {
428 this.value = value;
429 }
430  
431 public override bool AsBoolean() { return value; }
432 public override int AsInteger() { return value ? 1 : 0; }
433 public override double AsReal() { return value ? 1d : 0d; }
434 public override string AsString() { return value ? "1" : "0"; }
435 public override byte[] AsBinary() { return value ? trueBinary : falseBinary; }
436 public override OSD Copy() { return new OSDBoolean(value); }
437  
438 public override string ToString() { return AsString(); }
439 }
440  
441 /// <summary>
442 ///
443 /// </summary>
444 public sealed class OSDInteger : OSD
445 {
446 private int value;
447  
448 public override OSDType Type { get { return OSDType.Integer; } }
449  
450 public OSDInteger(int value)
451 {
452 this.value = value;
453 }
454  
455 public override bool AsBoolean() { return value != 0; }
456 public override int AsInteger() { return value; }
457 public override uint AsUInteger() { return (uint)value; }
458 public override long AsLong() { return value; }
459 public override ulong AsULong() { return (ulong)value; }
460 public override double AsReal() { return (double)value; }
461 public override string AsString() { return value.ToString(); }
462 public override byte[] AsBinary() { return Utils.IntToBytesBig(value); }
463 public override OSD Copy() { return new OSDInteger(value); }
464  
465 public override string ToString() { return AsString(); }
466 }
467  
468 /// <summary>
469 ///
470 /// </summary>
471 public sealed class OSDReal : OSD
472 {
473 private double value;
474  
475 public override OSDType Type { get { return OSDType.Real; } }
476  
477 public OSDReal(double value)
478 {
479 this.value = value;
480 }
481  
482 public override bool AsBoolean() { return (!Double.IsNaN(value) && value != 0d); }
483 public override OSD Copy() { return new OSDReal(value); }
484  
485 public override int AsInteger()
486 {
487 if (Double.IsNaN(value))
488 return 0;
489 if (value > (double)Int32.MaxValue)
490 return Int32.MaxValue;
491 if (value < (double)Int32.MinValue)
492 return Int32.MinValue;
493 return (int)Math.Round(value);
494 }
495  
496 public override uint AsUInteger()
497 {
498 if (Double.IsNaN(value))
499 return 0;
500 if (value > (double)UInt32.MaxValue)
501 return UInt32.MaxValue;
502 if (value < (double)UInt32.MinValue)
503 return UInt32.MinValue;
504 return (uint)Math.Round(value);
505 }
506  
507 public override long AsLong()
508 {
509 if (Double.IsNaN(value))
510 return 0;
511 if (value > (double)Int64.MaxValue)
512 return Int64.MaxValue;
513 if (value < (double)Int64.MinValue)
514 return Int64.MinValue;
515 return (long)Math.Round(value);
516 }
517  
518 public override ulong AsULong()
519 {
520 if (Double.IsNaN(value))
521 return 0;
522 if (value > (double)UInt64.MaxValue)
523 return Int32.MaxValue;
524 if (value < (double)UInt64.MinValue)
525 return UInt64.MinValue;
526 return (ulong)Math.Round(value);
527 }
528  
529 public override double AsReal() { return value; }
530 // "r" ensures the value will correctly round-trip back through Double.TryParse
531 public override string AsString() { return value.ToString("r", Utils.EnUsCulture); }
532 public override byte[] AsBinary() { return Utils.DoubleToBytesBig(value); }
533 public override string ToString() { return AsString(); }
534 }
535  
536 /// <summary>
537 ///
538 /// </summary>
539 public sealed class OSDString : OSD
540 {
541 private string value;
542  
543 public override OSDType Type { get { return OSDType.String; } }
544  
545 public override OSD Copy() { return new OSDString(value); }
546  
547 public OSDString(string value)
548 {
549 // Refuse to hold null pointers
550 if (value != null)
551 this.value = value;
552 else
553 this.value = String.Empty;
554 }
555  
556 public override bool AsBoolean()
557 {
558 if (String.IsNullOrEmpty(value))
559 return false;
560  
561 if (value == "0" || value.ToLower() == "false")
562 return false;
563  
564 return true;
565 }
566  
567 public override int AsInteger()
568 {
569 double dbl;
570 if (Double.TryParse(value, out dbl))
571 return (int)Math.Floor(dbl);
572 else
573 return 0;
574 }
575  
576 public override uint AsUInteger()
577 {
578 double dbl;
579 if (Double.TryParse(value, out dbl))
580 return (uint)Math.Floor(dbl);
581 else
582 return 0;
583 }
584  
585 public override long AsLong()
586 {
587 double dbl;
588 if (Double.TryParse(value, out dbl))
589 return (long)Math.Floor(dbl);
590 else
591 return 0;
592 }
593  
594 public override ulong AsULong()
595 {
596 double dbl;
597 if (Double.TryParse(value, out dbl))
598 return (ulong)Math.Floor(dbl);
599 else
600 return 0;
601 }
602  
603 public override double AsReal()
604 {
605 double dbl;
606 if (Double.TryParse(value, out dbl))
607 return dbl;
608 else
609 return 0d;
610 }
611  
612 public override string AsString() { return value; }
613 public override byte[] AsBinary() { return Encoding.UTF8.GetBytes(value); }
614 public override UUID AsUUID()
615 {
616 UUID uuid;
617 if (UUID.TryParse(value, out uuid))
618 return uuid;
619 else
620 return UUID.Zero;
621 }
622 public override DateTime AsDate()
623 {
624 DateTime dt;
625 if (DateTime.TryParse(value, out dt))
626 return dt;
627 else
628 return Utils.Epoch;
629 }
630 public override Uri AsUri()
631 {
632 Uri uri;
633 if (Uri.TryCreate(value, UriKind.RelativeOrAbsolute, out uri))
634 return uri;
635 else
636 return null;
637 }
638  
639 public override string ToString() { return AsString(); }
640 }
641  
642 /// <summary>
643 ///
644 /// </summary>
645 public sealed class OSDUUID : OSD
646 {
647 private UUID value;
648  
649 public override OSDType Type { get { return OSDType.UUID; } }
650  
651 public OSDUUID(UUID value)
652 {
653 this.value = value;
654 }
655  
656 public override OSD Copy() { return new OSDUUID(value); }
657 public override bool AsBoolean() { return (value == UUID.Zero) ? false : true; }
658 public override string AsString() { return value.ToString(); }
659 public override UUID AsUUID() { return value; }
660 public override byte[] AsBinary() { return value.GetBytes(); }
661 public override string ToString() { return AsString(); }
662 }
663  
664 /// <summary>
665 ///
666 /// </summary>
667 public sealed class OSDDate : OSD
668 {
669 private DateTime value;
670  
671 public override OSDType Type { get { return OSDType.Date; } }
672  
673 public OSDDate(DateTime value)
674 {
675 this.value = value;
676 }
677  
678 public override string AsString()
679 {
680 string format;
681 if (value.Millisecond > 0)
682 format = "yyyy-MM-ddTHH:mm:ss.ffZ";
683 else
684 format = "yyyy-MM-ddTHH:mm:ssZ";
685 return value.ToUniversalTime().ToString(format);
686 }
687  
688 public override int AsInteger()
689 {
690 return (int)Utils.DateTimeToUnixTime(value);
691 }
692  
693 public override uint AsUInteger()
694 {
695 return Utils.DateTimeToUnixTime(value);
696 }
697  
698 public override long AsLong()
699 {
700 return (long)Utils.DateTimeToUnixTime(value);
701 }
702  
703 public override ulong AsULong()
704 {
705 return Utils.DateTimeToUnixTime(value);
706 }
707  
708 public override byte[] AsBinary()
709 {
710 TimeSpan ts = value.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
711 return Utils.DoubleToBytes(ts.TotalSeconds);
712 }
713  
714 public override OSD Copy() { return new OSDDate(value); }
715 public override DateTime AsDate() { return value; }
716 public override string ToString() { return AsString(); }
717 }
718  
719 /// <summary>
720 ///
721 /// </summary>
722 public sealed class OSDUri : OSD
723 {
724 private Uri value;
725  
726 public override OSDType Type { get { return OSDType.URI; } }
727  
728 public OSDUri(Uri value)
729 {
730 this.value = value;
731 }
732  
733 public override string AsString()
734 {
735 if (value != null)
736 {
737 if (value.IsAbsoluteUri)
738 return value.AbsoluteUri;
739 else
740 return value.ToString();
741 }
742 return string.Empty;
743 }
744  
745 public override OSD Copy() { return new OSDUri(value); }
746 public override Uri AsUri() { return value; }
747 public override byte[] AsBinary() { return Encoding.UTF8.GetBytes(AsString()); }
748 public override string ToString() { return AsString(); }
749 }
750  
751 /// <summary>
752 ///
753 /// </summary>
754 public sealed class OSDBinary : OSD
755 {
756 private byte[] value;
757  
758 public override OSDType Type { get { return OSDType.Binary; } }
759  
760 public OSDBinary(byte[] value)
761 {
762 if (value != null)
763 this.value = value;
764 else
765 this.value = Utils.EmptyBytes;
766 }
767  
768 public OSDBinary(uint value)
769 {
770 this.value = new byte[]
771 {
772 (byte)((value >> 24) % 256),
773 (byte)((value >> 16) % 256),
774 (byte)((value >> 8) % 256),
775 (byte)(value % 256)
776 };
777 }
778  
779 public OSDBinary(long value)
780 {
781 this.value = new byte[]
782 {
783 (byte)((value >> 56) % 256),
784 (byte)((value >> 48) % 256),
785 (byte)((value >> 40) % 256),
786 (byte)((value >> 32) % 256),
787 (byte)((value >> 24) % 256),
788 (byte)((value >> 16) % 256),
789 (byte)((value >> 8) % 256),
790 (byte)(value % 256)
791 };
792 }
793  
794 public OSDBinary(ulong value)
795 {
796 this.value = new byte[]
797 {
798 (byte)((value >> 56) % 256),
799 (byte)((value >> 48) % 256),
800 (byte)((value >> 40) % 256),
801 (byte)((value >> 32) % 256),
802 (byte)((value >> 24) % 256),
803 (byte)((value >> 16) % 256),
804 (byte)((value >> 8) % 256),
805 (byte)(value % 256)
806 };
807 }
808  
809 public override OSD Copy() { return new OSDBinary(value); }
810 public override string AsString() { return Convert.ToBase64String(value); }
811 public override byte[] AsBinary() { return value; }
812  
813 public override uint AsUInteger()
814 {
815 return (uint)(
816 (value[0] << 24) +
817 (value[1] << 16) +
818 (value[2] << 8) +
819 (value[3] << 0));
820 }
821  
822 public override long AsLong()
823 {
824 return (long)(
825 ((long)value[0] << 56) +
826 ((long)value[1] << 48) +
827 ((long)value[2] << 40) +
828 ((long)value[3] << 32) +
829 ((long)value[4] << 24) +
830 ((long)value[5] << 16) +
831 ((long)value[6] << 8) +
832 ((long)value[7] << 0));
833 }
834  
835 public override ulong AsULong()
836 {
837 return (ulong)(
838 ((ulong)value[0] << 56) +
839 ((ulong)value[1] << 48) +
840 ((ulong)value[2] << 40) +
841 ((ulong)value[3] << 32) +
842 ((ulong)value[4] << 24) +
843 ((ulong)value[5] << 16) +
844 ((ulong)value[6] << 8) +
845 ((ulong)value[7] << 0));
846 }
847  
848 public override string ToString()
849 {
850 return Utils.BytesToHexString(value, null);
851 }
852 }
853  
854 /// <summary>
855 ///
856 /// </summary>
857 public sealed class OSDMap : OSD, IDictionary<string, OSD>
858 {
859 private Dictionary<string, OSD> value;
860  
861 public override OSDType Type { get { return OSDType.Map; } }
862  
863 public OSDMap()
864 {
865 value = new Dictionary<string, OSD>();
866 }
867  
868 public OSDMap(int capacity)
869 {
870 value = new Dictionary<string, OSD>(capacity);
871 }
872  
873 public OSDMap(Dictionary<string, OSD> value)
874 {
875 if (value != null)
876 this.value = value;
877 else
878 this.value = new Dictionary<string, OSD>();
879 }
880  
881 public override bool AsBoolean() { return value.Count > 0; }
882  
883 public override string ToString()
884 {
885 return OSDParser.SerializeJsonString(this, true);
886 }
887  
888 public override OSD Copy()
889 {
890 return new OSDMap(new Dictionary<string, OSD>(value));
891 }
892  
893 #region IDictionary Implementation
894  
895 public int Count { get { return value.Count; } }
896 public bool IsReadOnly { get { return false; } }
897 public ICollection<string> Keys { get { return value.Keys; } }
898 public ICollection<OSD> Values { get { return value.Values; } }
899 public OSD this[string key]
900 {
901 get
902 {
903 OSD llsd;
904 if (this.value.TryGetValue(key, out llsd))
905 return llsd;
906 else
907 return new OSD();
908 }
909 set { this.value[key] = value; }
910 }
911  
912 public bool ContainsKey(string key)
913 {
914 return value.ContainsKey(key);
915 }
916  
917 public void Add(string key, OSD llsd)
918 {
919 value.Add(key, llsd);
920 }
921  
922 public void Add(KeyValuePair<string, OSD> kvp)
923 {
924 value.Add(kvp.Key, kvp.Value);
925 }
926  
927 public bool Remove(string key)
928 {
929 return value.Remove(key);
930 }
931  
932 public bool TryGetValue(string key, out OSD llsd)
933 {
934 return value.TryGetValue(key, out llsd);
935 }
936  
937 public void Clear()
938 {
939 value.Clear();
940 }
941  
942 public bool Contains(KeyValuePair<string, OSD> kvp)
943 {
944 // This is a bizarre function... we don't really implement it
945 // properly, hopefully no one wants to use it
946 return value.ContainsKey(kvp.Key);
947 }
948  
949 public void CopyTo(KeyValuePair<string, OSD>[] array, int index)
950 {
951 throw new NotImplementedException();
952 }
953  
954 public bool Remove(KeyValuePair<string, OSD> kvp)
955 {
956 return this.value.Remove(kvp.Key);
957 }
958  
959 public System.Collections.IDictionaryEnumerator GetEnumerator()
960 {
961 return value.GetEnumerator();
962 }
963  
964 IEnumerator<KeyValuePair<string, OSD>> IEnumerable<KeyValuePair<string, OSD>>.GetEnumerator()
965 {
966 return null;
967 }
968  
969 IEnumerator IEnumerable.GetEnumerator()
970 {
971 return value.GetEnumerator();
972 }
973  
974 #endregion IDictionary Implementation
975 }
976  
977 /// <summary>
978 ///
979 /// </summary>
980 public sealed class OSDArray : OSD, IList<OSD>
981 {
982 private List<OSD> value;
983  
984 public override OSDType Type { get { return OSDType.Array; } }
985  
986 public OSDArray()
987 {
988 value = new List<OSD>();
989 }
990  
991 public OSDArray(int capacity)
992 {
993 value = new List<OSD>(capacity);
994 }
995  
996 public OSDArray(List<OSD> value)
997 {
998 if (value != null)
999 this.value = value;
1000 else
1001 this.value = new List<OSD>();
1002 }
1003  
1004 public override byte[] AsBinary()
1005 {
1006 byte[] binary = new byte[value.Count];
1007  
1008 for (int i = 0; i < value.Count; i++)
1009 binary[i] = (byte)value[i].AsInteger();
1010  
1011 return binary;
1012 }
1013  
1014 public override long AsLong()
1015 {
1016 OSDBinary binary = new OSDBinary(AsBinary());
1017 return binary.AsLong();
1018 }
1019  
1020 public override ulong AsULong()
1021 {
1022 OSDBinary binary = new OSDBinary(AsBinary());
1023 return binary.AsULong();
1024 }
1025  
1026 public override uint AsUInteger()
1027 {
1028 OSDBinary binary = new OSDBinary(AsBinary());
1029 return binary.AsUInteger();
1030 }
1031  
1032 public override Vector2 AsVector2()
1033 {
1034 Vector2 vector = Vector2.Zero;
1035  
1036 if (this.Count == 2)
1037 {
1038 vector.X = (float)this[0].AsReal();
1039 vector.Y = (float)this[1].AsReal();
1040 }
1041  
1042 return vector;
1043 }
1044  
1045 public override Vector3 AsVector3()
1046 {
1047 Vector3 vector = Vector3.Zero;
1048  
1049 if (this.Count == 3)
1050 {
1051 vector.X = (float)this[0].AsReal();
1052 vector.Y = (float)this[1].AsReal();
1053 vector.Z = (float)this[2].AsReal();
1054 }
1055  
1056 return vector;
1057 }
1058  
1059 public override Vector3d AsVector3d()
1060 {
1061 Vector3d vector = Vector3d.Zero;
1062  
1063 if (this.Count == 3)
1064 {
1065 vector.X = this[0].AsReal();
1066 vector.Y = this[1].AsReal();
1067 vector.Z = this[2].AsReal();
1068 }
1069  
1070 return vector;
1071 }
1072  
1073 public override Vector4 AsVector4()
1074 {
1075 Vector4 vector = Vector4.Zero;
1076  
1077 if (this.Count == 4)
1078 {
1079 vector.X = (float)this[0].AsReal();
1080 vector.Y = (float)this[1].AsReal();
1081 vector.Z = (float)this[2].AsReal();
1082 vector.W = (float)this[3].AsReal();
1083 }
1084  
1085 return vector;
1086 }
1087  
1088 public override Quaternion AsQuaternion()
1089 {
1090 Quaternion quaternion = Quaternion.Identity;
1091  
1092 if (this.Count == 4)
1093 {
1094 quaternion.X = (float)this[0].AsReal();
1095 quaternion.Y = (float)this[1].AsReal();
1096 quaternion.Z = (float)this[2].AsReal();
1097 quaternion.W = (float)this[3].AsReal();
1098 }
1099  
1100 return quaternion;
1101 }
1102  
1103 public override Color4 AsColor4()
1104 {
1105 Color4 color = Color4.Black;
1106  
1107 if (this.Count == 4)
1108 {
1109 color.R = (float)this[0].AsReal();
1110 color.G = (float)this[1].AsReal();
1111 color.B = (float)this[2].AsReal();
1112 color.A = (float)this[3].AsReal();
1113 }
1114  
1115 return color;
1116 }
1117  
1118 public override OSD Copy()
1119 {
1120 return new OSDArray(new List<OSD>(value));
1121 }
1122  
1123 public override bool AsBoolean() { return value.Count > 0; }
1124  
1125 public override string ToString()
1126 {
1127 return OSDParser.SerializeJsonString(this, true);
1128 }
1129  
1130 #region IList Implementation
1131  
1132 public int Count { get { return value.Count; } }
1133 public bool IsReadOnly { get { return false; } }
1134 public OSD this[int index]
1135 {
1136 get { return value[index]; }
1137 set { this.value[index] = value; }
1138 }
1139  
1140 public int IndexOf(OSD llsd)
1141 {
1142 return value.IndexOf(llsd);
1143 }
1144  
1145 public void Insert(int index, OSD llsd)
1146 {
1147 value.Insert(index, llsd);
1148 }
1149  
1150 public void RemoveAt(int index)
1151 {
1152 value.RemoveAt(index);
1153 }
1154  
1155 public void Add(OSD llsd)
1156 {
1157 value.Add(llsd);
1158 }
1159  
1160 public void Clear()
1161 {
1162 value.Clear();
1163 }
1164  
1165 public bool Contains(OSD llsd)
1166 {
1167 return value.Contains(llsd);
1168 }
1169  
1170 public bool Contains(string element)
1171 {
1172 for (int i = 0; i < value.Count; i++)
1173 {
1174 if (value[i].Type == OSDType.String && value[i].AsString() == element)
1175 return true;
1176 }
1177  
1178 return false;
1179 }
1180  
1181 public void CopyTo(OSD[] array, int index)
1182 {
1183 throw new NotImplementedException();
1184 }
1185  
1186 public bool Remove(OSD llsd)
1187 {
1188 return value.Remove(llsd);
1189 }
1190  
1191 IEnumerator IEnumerable.GetEnumerator()
1192 {
1193 return value.GetEnumerator();
1194 }
1195  
1196 IEnumerator<OSD> IEnumerable<OSD>.GetEnumerator()
1197 {
1198 return value.GetEnumerator();
1199 }
1200  
1201 #endregion IList Implementation
1202 }
1203  
1204 public partial class OSDParser
1205 {
1206 const string LLSD_BINARY_HEADER = "<? llsd/binary ?>";
1207 const string LLSD_XML_HEADER = "<llsd>";
1208 const string LLSD_XML_ALT_HEADER = "<?xml";
1209 const string LLSD_XML_ALT2_HEADER = "<? llsd/xml ?>";
1210  
1211 public static OSD Deserialize(byte[] data)
1212 {
1213 string header = Encoding.ASCII.GetString(data, 0, data.Length >= 17 ? 17 : data.Length);
1214  
1215 try
1216 {
1217 string uHeader = Encoding.UTF8.GetString(data, 0, data.Length >= 17 ? 17 : data.Length).TrimStart();
1218 if (uHeader.StartsWith(LLSD_XML_HEADER, StringComparison.InvariantCultureIgnoreCase) ||
1219 uHeader.StartsWith(LLSD_XML_ALT_HEADER, StringComparison.InvariantCultureIgnoreCase) ||
1220 uHeader.StartsWith(LLSD_XML_ALT2_HEADER, StringComparison.InvariantCultureIgnoreCase))
1221 {
1222 return DeserializeLLSDXml(data);
1223 }
1224 }
1225 catch { }
1226  
1227 if (header.StartsWith(LLSD_BINARY_HEADER, StringComparison.InvariantCultureIgnoreCase))
1228 {
1229 return DeserializeLLSDBinary(data);
1230 }
1231 else if (header.StartsWith(LLSD_XML_HEADER, StringComparison.InvariantCultureIgnoreCase) ||
1232 header.StartsWith(LLSD_XML_ALT_HEADER, StringComparison.InvariantCultureIgnoreCase) ||
1233 header.StartsWith(LLSD_XML_ALT2_HEADER, StringComparison.InvariantCultureIgnoreCase))
1234 {
1235 return DeserializeLLSDXml(data);
1236 }
1237 else
1238 {
1239 return DeserializeJson(Encoding.UTF8.GetString(data));
1240 }
1241 }
1242  
1243 public static OSD Deserialize(string data)
1244 {
1245 if (data.StartsWith(LLSD_BINARY_HEADER, StringComparison.InvariantCultureIgnoreCase))
1246 {
1247 return DeserializeLLSDBinary(Encoding.UTF8.GetBytes(data));
1248 }
1249 else if (data.StartsWith(LLSD_XML_HEADER, StringComparison.InvariantCultureIgnoreCase) ||
1250 data.StartsWith(LLSD_XML_ALT_HEADER, StringComparison.InvariantCultureIgnoreCase) ||
1251 data.StartsWith(LLSD_XML_ALT2_HEADER, StringComparison.InvariantCultureIgnoreCase))
1252 {
1253 return DeserializeLLSDXml(data);
1254 }
1255 else
1256 {
1257 return DeserializeJson(data);
1258 }
1259 }
1260  
1261 public static OSD Deserialize(Stream stream)
1262 {
1263 if (stream.CanSeek)
1264 {
1265 byte[] headerData = new byte[14];
1266 stream.Read(headerData, 0, 14);
1267 stream.Seek(0, SeekOrigin.Begin);
1268 string header = Encoding.ASCII.GetString(headerData);
1269  
1270 if (header.StartsWith(LLSD_BINARY_HEADER))
1271 return DeserializeLLSDBinary(stream);
1272 else if (header.StartsWith(LLSD_XML_HEADER) || header.StartsWith(LLSD_XML_ALT_HEADER) || header.StartsWith(LLSD_XML_ALT2_HEADER))
1273 return DeserializeLLSDXml(stream);
1274 else
1275 return DeserializeJson(stream);
1276 }
1277 else
1278 {
1279 throw new OSDException("Cannot deserialize structured data from unseekable streams");
1280 }
1281 }
1282 }
1283 }