aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/LLSDxmlEncode.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/LLSDxmlEncode.cs')
-rw-r--r--OpenSim/Framework/LLSDxmlEncode.cs725
1 files changed, 725 insertions, 0 deletions
diff --git a/OpenSim/Framework/LLSDxmlEncode.cs b/OpenSim/Framework/LLSDxmlEncode.cs
new file mode 100644
index 0000000..a740866
--- /dev/null
+++ b/OpenSim/Framework/LLSDxmlEncode.cs
@@ -0,0 +1,725 @@
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// a class for low level LLSD encoding into a provided StringBuilder
29// for cases where we already need to know the low level detail
30// and so using something like OSD or even protbuf is just a pure waste
31
32using System;
33using System.Globalization;
34using System.Text;
35using OpenMetaverse;
36
37namespace OpenSim.Framework
38{
39 public static class LLSDxmlEncode
40 {
41 static readonly DateTime depoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
42
43 public static void AddStart(StringBuilder sb, bool addxmlversion = false)
44 {
45 if(addxmlversion)
46 sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><llsd>"); // legacy llsd xml name still valid
47 else
48 sb.Append("<llsd>");
49 }
50
51 // got tired of creating a stringbuilder all the time;
52 public static StringBuilder Start(int size = 256, bool addxmlversion = false)
53 {
54 StringBuilder sb = new StringBuilder(size);
55 if(addxmlversion)
56 sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><llsd>"); // legacy llsd xml name still valid
57 else
58 sb.Append("<llsd>");
59 return sb;
60 }
61
62 public static void AddEnd(StringBuilder sb)
63 {
64 sb.Append("</llsd>");
65 }
66
67 public static string End(StringBuilder sb)
68 {
69 sb.Append("</llsd>");
70 return sb.ToString();
71 }
72
73 // map == a list of key value pairs
74 public static void AddMap(StringBuilder sb)
75 {
76 sb.Append("<map>");
77 }
78
79 public static void AddEndMap(StringBuilder sb)
80 {
81 sb.Append("</map>");
82 }
83
84 public static void AddEmptyMap(StringBuilder sb)
85 {
86 sb.Append("<map />");
87 }
88
89 // array == a list values
90 public static void AddArray(StringBuilder sb)
91 {
92 sb.Append("<array>");
93 }
94
95 public static void AddEndArray(StringBuilder sb)
96 {
97 sb.Append("</array>");
98 }
99
100 public static void AddEmptyArray(StringBuilder sb)
101 {
102 sb.Append("<array />");
103 }
104
105 // undefined or null
106 public static void AddUnknownElem(StringBuilder sb)
107 {
108 sb.Append("<undef />");
109 }
110
111 public static void AddElem(bool e, StringBuilder sb)
112 {
113 if(e)
114 sb.Append("<boolean>1</boolean>");
115 else
116 sb.Append("<boolean />");
117 }
118
119 public static void AddElem(byte e, StringBuilder sb)
120 {
121 if(e == 0)
122 sb.Append("<integer />");
123 else
124 {
125 sb.Append("<integer>");
126 sb.Append(e.ToString());
127 sb.Append("</integer>");
128 }
129 }
130
131 public static void AddElem(byte[] e, StringBuilder sb)
132 {
133 if(e == null || e.Length == 0)
134 sb.Append("binary />");
135 else
136 {
137 sb.Append("<binary>"); // encode64 is default
138 sb.Append(Convert.ToBase64String(e,Base64FormattingOptions.None));
139 sb.Append("</binary>");
140 }
141 }
142
143 public static void AddElem(int e, StringBuilder sb)
144 {
145 if(e == 0)
146 sb.Append("<integer />");
147 else
148 {
149 sb.Append("<integer>");
150 sb.Append(e.ToString());
151 sb.Append("</integer>");
152 }
153 }
154
155 public static void AddElem(float e, StringBuilder sb)
156 {
157 if(e == 0)
158 sb.Append("<real />");
159 else
160 {
161 sb.Append("<real>");
162 sb.Append(e.ToString(CultureInfo.InvariantCulture));
163 sb.Append("</real>");
164 }
165 }
166
167 public static void AddElem(Vector2 e, StringBuilder sb)
168 {
169 sb.Append("<map><key>x</key>");
170
171 if(e.X == 0)
172 sb.Append("<real /><key>y</key>");
173 else
174 {
175 sb.Append("<real>");
176 sb.Append(e.X.ToString(CultureInfo.InvariantCulture));
177 sb.Append("</real><key>y</key>");
178 }
179
180 if(e.Y == 0)
181 sb.Append("<real /></map>");
182 else
183 {
184 sb.Append("<real>");
185 sb.Append(e.Y.ToString(CultureInfo.InvariantCulture));
186 sb.Append("</real></map>");
187 }
188 }
189
190 public static void AddElem(Vector3 e, StringBuilder sb)
191 {
192 sb.Append("<map>key>x</key>");
193
194 if(e.X == 0)
195 sb.Append("<real /><key>y</key>");
196 else
197 {
198 sb.Append("<real>");
199 sb.Append(e.X.ToString(CultureInfo.InvariantCulture));
200 sb.Append("</real><key>y</key>");
201 }
202
203 if(e.Y == 0)
204 sb.Append("<real /><key>z</key>");
205 else
206 {
207 sb.Append("<real>");
208 sb.Append(e.Y.ToString(CultureInfo.InvariantCulture));
209 sb.Append("</real><key>z</key>");
210 }
211
212 if(e.Z == 0)
213 sb.Append("<real /></map>");
214 else
215 {
216 sb.Append("<real>");
217 sb.Append(e.Z.ToString(CultureInfo.InvariantCulture));
218 sb.Append("</real></map>");
219 }
220 }
221
222 public static void AddElem(Quaternion e, StringBuilder sb)
223 {
224 sb.Append("<map><key>x</key>");
225
226 if(e.X == 0)
227 sb.Append("<real /><key>y</key>");
228 else
229 {
230 sb.Append("<real>");
231 sb.Append(e.X.ToString(CultureInfo.InvariantCulture));
232 sb.Append("</real><key>y</key>");
233 }
234
235 if(e.Y == 0)
236 sb.Append("<real /><key>z</key>");
237 else
238 {
239 sb.Append("<real>");
240 sb.Append(e.Y.ToString(CultureInfo.InvariantCulture));
241 sb.Append("</real><key>z</key>");
242 }
243 if(e.Z == 0)
244 sb.Append("<real /><key>w</key>");
245 else
246 {
247 sb.Append("<real>");
248 sb.Append(e.Z.ToString(CultureInfo.InvariantCulture));
249 sb.Append("</real><key>w</key>");
250 }
251
252 if(e.W == 0)
253 sb.Append("<real /></map>");
254 else
255 {
256 sb.Append("<real>");
257 sb.Append(e.W.ToString(CultureInfo.InvariantCulture));
258 sb.Append("</real></map>");
259 }
260 }
261
262 public static void AddElem(double e, StringBuilder sb)
263 {
264 if(e == 0)
265 sb.Append("<real />");
266 else
267 {
268 sb.Append("<real>");
269 sb.Append(e.ToString(CultureInfo.InvariantCulture));
270 sb.Append("</real>");
271 }
272 }
273
274 public static void AddElem(UUID e, StringBuilder sb)
275 {
276 if(e == UUID.Zero)
277 sb.Append("<uuid />");
278 else
279 {
280 sb.Append("<uuid>");
281 EscapeToXML(e.ToString(), sb);
282 sb.Append("</uuid>");
283 }
284 }
285
286 public static void AddElem(string e, StringBuilder sb)
287 {
288 if(String.IsNullOrEmpty(e))
289 sb.Append("<string />");
290 else
291 {
292 sb.Append("<string>");
293 sb.Append(e.ToString());
294 sb.Append("</string>");
295 }
296 }
297
298 public static void AddRawElem(string e, StringBuilder sb)
299 {
300 if(String.IsNullOrEmpty(e))
301 sb.Append("<string />");
302 else
303 {
304 sb.Append("<string>");
305 sb.Append(e);
306 sb.Append("</string>");
307 }
308 }
309
310 public static void AddElem(Uri e, StringBuilder sb)
311 {
312 if(e == null)
313 {
314 sb.Append("<uri />");
315 return;
316 }
317
318 string s;
319 if (e.IsAbsoluteUri)
320 s = e.AbsoluteUri;
321 else
322 s = e.ToString();
323
324 if(String.IsNullOrEmpty(s))
325 sb.Append("<uri />");
326 else
327 {
328 sb.Append("<uri>");
329 sb.Append(s);
330 sb.Append("</uri>");
331 }
332 }
333
334 public static void AddElem(DateTime e, StringBuilder sb)
335 {
336 DateTime u = e.ToUniversalTime();
337 if(u == depoch)
338 {
339 sb.Append("<date />");
340 return;
341 }
342 string format;
343 if(u.Hour == 0 && u.Minute == 0 && u.Second == 0)
344 format = "yyyy-MM-dd";
345 else if (u.Millisecond > 0)
346 format = "yyyy-MM-ddTHH:mm:ss.ffZ";
347 else
348 format = "yyyy-MM-ddTHH:mm:ssZ";
349 sb.Append("<date>");
350 sb.Append(u.ToString(format,CultureInfo.InvariantCulture));
351 sb.Append("</date>");
352 }
353
354//************ key value *******************
355// assumes name is a valid llsd key
356
357 public static void AddMap(string name, StringBuilder sb)
358 {
359 sb.Append("<key>");
360 sb.Append(name);
361 sb.Append("</key><map>");
362 }
363
364 public static void AddEmptyMap(string name, StringBuilder sb)
365 {
366 sb.Append("<key>");
367 sb.Append(name);
368 sb.Append("</key><map />");
369 }
370
371 // array == a list values
372 public static void AddArray(string name, StringBuilder sb)
373 {
374 sb.Append("<key>");
375 sb.Append(name);
376 sb.Append("</key><array>");
377 }
378
379 public static void AddEmptyArray(string name, StringBuilder sb)
380 {
381 sb.Append("<key>");
382 sb.Append(name);
383 sb.Append("</key><array />");
384 }
385
386 // undefined or null
387 public static void AddUnknownElem(string name, StringBuilder sb)
388 {
389 sb.Append("<key>");
390 sb.Append(name);
391 sb.Append("</key><undef />");
392 }
393
394 public static void AddElem(string name, bool e, StringBuilder sb)
395 {
396 sb.Append("<key>");
397 sb.Append(name);
398 sb.Append("</key>");
399
400 if(e)
401 sb.Append("<boolean>1</boolean>");
402 else
403 sb.Append("<boolean />");
404 }
405
406 public static void AddElem(string name, byte e, StringBuilder sb)
407 {
408 sb.Append("<key>");
409 sb.Append(name);
410 sb.Append("</key>");
411
412 if(e == 0)
413 sb.Append("<integer />");
414 else
415 {
416 sb.Append("<integer>");
417 sb.Append(e.ToString());
418 sb.Append("</integer>");
419 }
420 }
421
422 public static void AddElem(string name, byte[] e, StringBuilder sb)
423 {
424 sb.Append("<key>");
425 sb.Append(name);
426 sb.Append("</key>");
427
428 if(e == null || e.Length == 0)
429 sb.Append("binary />");
430 else
431 {
432 sb.Append("<binary>"); // encode64 is default
433 sb.Append(Convert.ToBase64String(e,Base64FormattingOptions.None));
434 sb.Append("</binary>");
435 }
436 }
437
438 public static void AddElem(string name, int e, StringBuilder sb)
439 {
440 sb.Append("<key>");
441 sb.Append(name);
442 sb.Append("</key>");
443
444 if(e == 0)
445 sb.Append("<integer />");
446 else
447 {
448 sb.Append("<integer>");
449 sb.Append(e.ToString());
450 sb.Append("</integer>");
451 }
452 }
453
454 public static void AddElem(string name, float e, StringBuilder sb)
455 {
456 sb.Append("<key>");
457 sb.Append(name);
458 sb.Append("</key>");
459
460 if(e == 0)
461 sb.Append("<real />");
462 else
463 {
464 sb.Append("<real>");
465 sb.Append(e.ToString(CultureInfo.InvariantCulture));
466 sb.Append("</real>");
467 }
468 }
469
470 public static void AddElem(string name, Vector2 e, StringBuilder sb)
471 {
472 sb.Append("<key>");
473 sb.Append(name);
474 sb.Append("</key><map><key>x</key>");
475
476 if(e.X == 0)
477 sb.Append("<real /><key>y</key>");
478 else
479 {
480 sb.Append("<real>");
481 sb.Append(e.X.ToString(CultureInfo.InvariantCulture));
482 sb.Append("</real><key>y</key>");
483 }
484
485 if(e.Y == 0)
486 sb.Append("<real /></map>");
487 else
488 {
489 sb.Append("<real>");
490 sb.Append(e.Y.ToString(CultureInfo.InvariantCulture));
491 sb.Append("</real></map>");
492 }
493 }
494
495 public static void AddElem(string name, Vector3 e, StringBuilder sb)
496 {
497 sb.Append("<key>");
498 sb.Append(name);
499 sb.Append("</key><map>key>x</key>");
500
501 if(e.X == 0)
502 sb.Append("<real /><key>y</key>");
503 else
504 {
505 sb.Append("<real>");
506 sb.Append(e.X.ToString(CultureInfo.InvariantCulture));
507 sb.Append("</real><key>y</key>");
508 }
509
510 if(e.Y == 0)
511 sb.Append("<real /><key>z</key>");
512 else
513 {
514 sb.Append("<real>");
515 sb.Append(e.Y.ToString(CultureInfo.InvariantCulture));
516 sb.Append("</real><key>z</key>");
517 }
518
519 if(e.Z == 0)
520 sb.Append("<real /></map>");
521 else
522 {
523 sb.Append("<real>");
524 sb.Append(e.Z.ToString(CultureInfo.InvariantCulture));
525 sb.Append("</real></map>");
526 }
527 }
528
529 public static void AddElem(string name, Quaternion e, StringBuilder sb)
530 {
531 sb.Append("<key>");
532 sb.Append(name);
533 sb.Append("</key><map><key>x</key>");
534
535 if(e.X == 0)
536 sb.Append("<real /><key>y</key>");
537 else
538 {
539 sb.Append("<real>");
540 sb.Append(e.X.ToString(CultureInfo.InvariantCulture));
541 sb.Append("</real><key>y</key>");
542 }
543
544 if(e.Y == 0)
545 sb.Append("<real /><key>z</key>");
546 else
547 {
548 sb.Append("<real>");
549 sb.Append(e.Y.ToString(CultureInfo.InvariantCulture));
550 sb.Append("</real><key>z</key>");
551 }
552 if(e.Z == 0)
553 sb.Append("<real /><key>w</key>");
554 else
555 {
556 sb.Append("<real>");
557 sb.Append(e.Z.ToString(CultureInfo.InvariantCulture));
558 sb.Append("</real><key>w</key>");
559 }
560
561 if(e.W == 0)
562 sb.Append("<real /></map>");
563 else
564 {
565 sb.Append("<real>");
566 sb.Append(e.W.ToString(CultureInfo.InvariantCulture));
567 sb.Append("</real></map>");
568 }
569 }
570
571 public static void AddElem(string name, double e, StringBuilder sb)
572 {
573 sb.Append("<key>");
574 sb.Append(name);
575 sb.Append("</key>");
576
577 if(e == 0)
578 sb.Append("<real />");
579 else
580 {
581 sb.Append("<real>");
582 sb.Append(e.ToString(CultureInfo.InvariantCulture));
583 sb.Append("</real>");
584 }
585 }
586
587 public static void AddElem(string name, UUID e, StringBuilder sb)
588 {
589 sb.Append("<key>");
590 sb.Append(name);
591 sb.Append("</key>");
592
593 if(e == UUID.Zero)
594 sb.Append("<uuid />");
595 else
596 {
597 sb.Append("<uuid>");
598 EscapeToXML(e.ToString(), sb);
599 sb.Append("</uuid>");
600 }
601 }
602
603 public static void AddElem(string name, string e, StringBuilder sb)
604 {
605 sb.Append("<key>");
606 sb.Append(name);
607 sb.Append("</key>");
608
609 if(String.IsNullOrEmpty(e))
610 sb.Append("<string />");
611 else
612 {
613 sb.Append("<string>");
614 sb.Append(e.ToString());
615 sb.Append("</string>");
616 }
617 }
618
619 public static void AddRawElem(string name, string e, StringBuilder sb)
620 {
621 sb.Append("<key>");
622 sb.Append(name);
623 sb.Append("</key>");
624
625 if(String.IsNullOrEmpty(e))
626 sb.Append("<string />");
627 else
628 {
629 sb.Append("<string>");
630 sb.Append(e);
631 sb.Append("</string>");
632 }
633 }
634
635 public static void AddElem(string name, Uri e, StringBuilder sb)
636 {
637 sb.Append("<key>");
638 sb.Append(name);
639 sb.Append("</key>");
640
641 if(e == null)
642 {
643 sb.Append("<uri />");
644 return;
645 }
646
647 string s;
648 if (e.IsAbsoluteUri)
649 s = e.AbsoluteUri;
650 else
651 s = e.ToString();
652
653 if(String.IsNullOrEmpty(s))
654 sb.Append("<uri />");
655 else
656 {
657 sb.Append("<uri>");
658 sb.Append(s);
659 sb.Append("</uri>");
660 }
661 }
662
663 public static void AddElem(string name, DateTime e, StringBuilder sb)
664 {
665 sb.Append("<key>");
666 sb.Append(name);
667 sb.Append("</key>");
668
669 DateTime u = e.ToUniversalTime();
670 if(u == depoch)
671 {
672 sb.Append("<date />");
673 return;
674 }
675 string format;
676 if(u.Hour == 0 && u.Minute == 0 && u.Second == 0)
677 format = "yyyy-MM-dd";
678 else if (u.Millisecond > 0)
679 format = "yyyy-MM-ddTHH:mm:ss.ffZ";
680 else
681 format = "yyyy-MM-ddTHH:mm:ssZ";
682 sb.Append("<date>");
683 sb.Append(u.ToString(format,CultureInfo.InvariantCulture));
684 sb.Append("</date>");
685 }
686
687 public static void AddLLSD(string e, StringBuilder sb)
688 {
689 sb.Append(e);
690 }
691
692 public static void EscapeToXML(string s, StringBuilder sb)
693 {
694 int i;
695 char c;
696 int len = s.Length;
697
698 for (i = 0; i < len; i++)
699 {
700 c = s[i];
701 switch (c)
702 {
703 case '<':
704 sb.Append("&lt;");
705 break;
706 case '>':
707 sb.Append("&gt;");
708 break;
709 case '&':
710 sb.Append("&amp;");
711 break;
712 case '"':
713 sb.Append("&quot;");
714 break;
715 case '\\':
716 sb.Append("&apos;");
717 break;
718 default:
719 sb.Append(c);
720 break;
721 }
722 }
723 }
724 }
725}