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.Generic;
29 using System.Text;
30 using System.IO;
31  
32 namespace OpenMetaverse.StructuredData
33 {
34 /// <summary>
35 ///
36 /// </summary>
37 public static partial class OSDParser
38 {
39 private const string baseIndent = " ";
40  
41 private const char undefNotationValue = '!';
42  
43 private const char trueNotationValueOne = '1';
44 private const char trueNotationValueTwo = 't';
45 private static readonly char[] trueNotationValueTwoFull = { 't', 'r', 'u', 'e' };
46 private const char trueNotationValueThree = 'T';
47 private static readonly char[] trueNotationValueThreeFull = { 'T', 'R', 'U', 'E' };
48  
49 private const char falseNotationValueOne = '0';
50 private const char falseNotationValueTwo = 'f';
51 private static readonly char[] falseNotationValueTwoFull = { 'f', 'a', 'l', 's', 'e' };
52 private const char falseNotationValueThree = 'F';
53 private static readonly char[] falseNotationValueThreeFull = { 'F', 'A', 'L', 'S', 'E' };
54  
55 private const char integerNotationMarker = 'i';
56 private const char realNotationMarker = 'r';
57 private const char uuidNotationMarker = 'u';
58 private const char binaryNotationMarker = 'b';
59 private const char stringNotationMarker = 's';
60 private const char uriNotationMarker = 'l';
61 private const char dateNotationMarker = 'd';
62  
63 private const char arrayBeginNotationMarker = '[';
64 private const char arrayEndNotationMarker = ']';
65  
66 private const char mapBeginNotationMarker = '{';
67 private const char mapEndNotationMarker = '}';
68 private const char kommaNotationDelimiter = ',';
69 private const char keyNotationDelimiter = ':';
70  
71 private const char sizeBeginNotationMarker = '(';
72 private const char sizeEndNotationMarker = ')';
73 private const char doubleQuotesNotationMarker = '"';
74 private const char singleQuotesNotationMarker = '\'';
75  
76 public static OSD DeserializeLLSDNotation(string notationData)
77 {
78 StringReader reader = new StringReader(notationData);
79 OSD osd = DeserializeLLSDNotation(reader);
80 reader.Close();
81 return osd;
82 }
83  
84 public static OSD DeserializeLLSDNotation(StringReader reader)
85 {
86 OSD osd = DeserializeLLSDNotationElement(reader);
87 return osd;
88 }
89  
90 public static string SerializeLLSDNotation(OSD osd)
91 {
92 StringWriter writer = SerializeLLSDNotationStream(osd);
93 string s = writer.ToString();
94 writer.Close();
95  
96 return s;
97 }
98  
99 public static StringWriter SerializeLLSDNotationStream(OSD osd)
100 {
101 StringWriter writer = new StringWriter();
102  
103 SerializeLLSDNotationElement(writer, osd);
104 return writer;
105 }
106  
107 public static string SerializeLLSDNotationFormatted(OSD osd)
108 {
109 StringWriter writer = SerializeLLSDNotationStreamFormatted(osd);
110 string s = writer.ToString();
111 writer.Close();
112  
113 return s;
114 }
115  
116 public static StringWriter SerializeLLSDNotationStreamFormatted(OSD osd)
117 {
118 StringWriter writer = new StringWriter();
119  
120 string indent = String.Empty;
121 SerializeLLSDNotationElementFormatted(writer, indent, osd);
122 return writer;
123 }
124  
125 /// <summary>
126 ///
127 /// </summary>
128 /// <param name="reader"></param>
129 /// <returns></returns>
130 private static OSD DeserializeLLSDNotationElement(StringReader reader)
131 {
132 int character = ReadAndSkipWhitespace(reader);
133 if (character < 0)
134 return new OSD(); // server returned an empty file, so we're going to pass along a null LLSD object
135  
136 OSD osd;
137 int matching;
138 switch ((char)character)
139 {
140 case undefNotationValue:
141 osd = new OSD();
142 break;
143 case trueNotationValueOne:
144 osd = OSD.FromBoolean(true);
145 break;
146 case trueNotationValueTwo:
147 matching = BufferCharactersEqual(reader, trueNotationValueTwoFull, 1);
148 if (matching > 1 && matching < trueNotationValueTwoFull.Length)
149 throw new OSDException("Notation LLSD parsing: True value parsing error:");
150 osd = OSD.FromBoolean(true);
151 break;
152 case trueNotationValueThree:
153 matching = BufferCharactersEqual(reader, trueNotationValueThreeFull, 1);
154 if (matching > 1 && matching < trueNotationValueThreeFull.Length)
155 throw new OSDException("Notation LLSD parsing: True value parsing error:");
156 osd = OSD.FromBoolean(true);
157 break;
158 case falseNotationValueOne:
159 osd = OSD.FromBoolean(false);
160 break;
161 case falseNotationValueTwo:
162 matching = BufferCharactersEqual(reader, falseNotationValueTwoFull, 1);
163 if (matching > 1 && matching < falseNotationValueTwoFull.Length)
164 throw new OSDException("Notation LLSD parsing: True value parsing error:");
165 osd = OSD.FromBoolean(false);
166 break;
167 case falseNotationValueThree:
168 matching = BufferCharactersEqual(reader, falseNotationValueThreeFull, 1);
169 if (matching > 1 && matching < falseNotationValueThreeFull.Length)
170 throw new OSDException("Notation LLSD parsing: True value parsing error:");
171 osd = OSD.FromBoolean(false);
172 break;
173 case integerNotationMarker:
174 osd = DeserializeLLSDNotationInteger(reader);
175 break;
176 case realNotationMarker:
177 osd = DeserializeLLSDNotationReal(reader);
178 break;
179 case uuidNotationMarker:
180 char[] uuidBuf = new char[36];
181 if (reader.Read(uuidBuf, 0, 36) < 36)
182 throw new OSDException("Notation LLSD parsing: Unexpected end of stream in UUID.");
183 UUID lluuid;
184 if (!UUID.TryParse(new String(uuidBuf), out lluuid))
185 throw new OSDException("Notation LLSD parsing: Invalid UUID discovered.");
186 osd = OSD.FromUUID(lluuid);
187 break;
188 case binaryNotationMarker:
189 byte[] bytes = Utils.EmptyBytes;
190 int bChar = reader.Peek();
191 if (bChar < 0)
192 throw new OSDException("Notation LLSD parsing: Unexpected end of stream in binary.");
193 if ((char)bChar == sizeBeginNotationMarker)
194 {
195 throw new OSDException("Notation LLSD parsing: Raw binary encoding not supported.");
196 }
197 else if (Char.IsDigit((char)bChar))
198 {
199 char[] charsBaseEncoding = new char[2];
200 if (reader.Read(charsBaseEncoding, 0, 2) < 2)
201 throw new OSDException("Notation LLSD parsing: Unexpected end of stream in binary.");
202 int baseEncoding;
203 if (!Int32.TryParse(new String(charsBaseEncoding), out baseEncoding))
204 throw new OSDException("Notation LLSD parsing: Invalid binary encoding base.");
205 if (baseEncoding == 64)
206 {
207 if (reader.Read() < 0)
208 throw new OSDException("Notation LLSD parsing: Unexpected end of stream in binary.");
209 string bytes64 = GetStringDelimitedBy(reader, doubleQuotesNotationMarker);
210 bytes = Convert.FromBase64String(bytes64);
211 }
212 else
213 {
214 throw new OSDException("Notation LLSD parsing: Encoding base" + baseEncoding + " + not supported.");
215 }
216 }
217 osd = OSD.FromBinary(bytes);
218 break;
219 case stringNotationMarker:
220 int numChars = GetLengthInBrackets(reader);
221 if (reader.Read() < 0)
222 throw new OSDException("Notation LLSD parsing: Unexpected end of stream in string.");
223 char[] chars = new char[numChars];
224 if (reader.Read(chars, 0, numChars) < numChars)
225 throw new OSDException("Notation LLSD parsing: Unexpected end of stream in string.");
226 if (reader.Read() < 0)
227 throw new OSDException("Notation LLSD parsing: Unexpected end of stream in string.");
228 osd = OSD.FromString(new String(chars));
229 break;
230 case singleQuotesNotationMarker:
231 string sOne = GetStringDelimitedBy(reader, singleQuotesNotationMarker);
232 osd = OSD.FromString(sOne);
233 break;
234 case doubleQuotesNotationMarker:
235 string sTwo = GetStringDelimitedBy(reader, doubleQuotesNotationMarker);
236 osd = OSD.FromString(sTwo);
237 break;
238 case uriNotationMarker:
239 if (reader.Read() < 0)
240 throw new OSDException("Notation LLSD parsing: Unexpected end of stream in string.");
241 string sUri = GetStringDelimitedBy(reader, doubleQuotesNotationMarker);
242  
243 Uri uri;
244 try
245 {
246 uri = new Uri(sUri, UriKind.RelativeOrAbsolute);
247 }
248 catch
249 {
250 throw new OSDException("Notation LLSD parsing: Invalid Uri format detected.");
251 }
252 osd = OSD.FromUri(uri);
253 break;
254 case dateNotationMarker:
255 if (reader.Read() < 0)
256 throw new OSDException("Notation LLSD parsing: Unexpected end of stream in date.");
257 string date = GetStringDelimitedBy(reader, doubleQuotesNotationMarker);
258 DateTime dt;
259 if (!DateTime.TryParse(date, out dt))
260 throw new OSDException("Notation LLSD parsing: Invalid date discovered.");
261 osd = OSD.FromDate(dt);
262 break;
263 case arrayBeginNotationMarker:
264 osd = DeserializeLLSDNotationArray(reader);
265 break;
266 case mapBeginNotationMarker:
267 osd = DeserializeLLSDNotationMap(reader);
268 break;
269 default:
270 throw new OSDException("Notation LLSD parsing: Unknown type marker '" + (char)character + "'.");
271 }
272 return osd;
273 }
274  
275 private static OSD DeserializeLLSDNotationInteger(StringReader reader)
276 {
277 int character;
278 StringBuilder s = new StringBuilder();
279 if (((character = reader.Peek()) > 0) && ((char)character == '-'))
280 {
281 s.Append((char)character);
282 reader.Read();
283 }
284  
285 while ((character = reader.Peek()) > 0 &&
286 Char.IsDigit((char)character))
287 {
288 s.Append((char)character);
289 reader.Read();
290 }
291 int integer;
292 if (!Int32.TryParse(s.ToString(), out integer))
293 throw new OSDException("Notation LLSD parsing: Can't parse integer value." + s.ToString());
294  
295 return OSD.FromInteger(integer);
296 }
297  
298 private static OSD DeserializeLLSDNotationReal(StringReader reader)
299 {
300 int character;
301 StringBuilder s = new StringBuilder();
302 if (((character = reader.Peek()) > 0) &&
303 ((char)character == '-' && (char)character == '+'))
304 {
305 s.Append((char)character);
306 reader.Read();
307 }
308 while (((character = reader.Peek()) > 0) &&
309 (Char.IsDigit((char)character) || (char)character == '.' ||
310 (char)character == 'e' || (char)character == 'E' ||
311 (char)character == '+' || (char)character == '-'))
312 {
313 s.Append((char)character);
314 reader.Read();
315 }
316 double dbl;
317 if (!Utils.TryParseDouble(s.ToString(), out dbl))
318 throw new OSDException("Notation LLSD parsing: Can't parse real value: " + s.ToString());
319  
320 return OSD.FromReal(dbl);
321 }
322  
323 private static OSD DeserializeLLSDNotationArray(StringReader reader)
324 {
325 int character;
326 OSDArray osdArray = new OSDArray();
327 while (((character = PeekAndSkipWhitespace(reader)) > 0) &&
328 ((char)character != arrayEndNotationMarker))
329 {
330 osdArray.Add(DeserializeLLSDNotationElement(reader));
331  
332 character = ReadAndSkipWhitespace(reader);
333 if (character < 0)
334 throw new OSDException("Notation LLSD parsing: Unexpected end of array discovered.");
335 else if ((char)character == kommaNotationDelimiter)
336 continue;
337 else if ((char)character == arrayEndNotationMarker)
338 break;
339 }
340 if (character < 0)
341 throw new OSDException("Notation LLSD parsing: Unexpected end of array discovered.");
342  
343 return (OSD)osdArray;
344 }
345  
346 private static OSD DeserializeLLSDNotationMap(StringReader reader)
347 {
348 int character;
349 OSDMap osdMap = new OSDMap();
350 while (((character = PeekAndSkipWhitespace(reader)) > 0) &&
351 ((char)character != mapEndNotationMarker))
352 {
353 OSD osdKey = DeserializeLLSDNotationElement(reader);
354 if (osdKey.Type != OSDType.String)
355 throw new OSDException("Notation LLSD parsing: Invalid key in map");
356 string key = osdKey.AsString();
357  
358 character = ReadAndSkipWhitespace(reader);
359 if ((char)character != keyNotationDelimiter)
360 throw new OSDException("Notation LLSD parsing: Unexpected end of stream in map.");
361 if ((char)character != keyNotationDelimiter)
362 throw new OSDException("Notation LLSD parsing: Invalid delimiter in map.");
363  
364 osdMap[key] = DeserializeLLSDNotationElement(reader);
365 character = ReadAndSkipWhitespace(reader);
366 if (character < 0)
367 throw new OSDException("Notation LLSD parsing: Unexpected end of map discovered.");
368 else if ((char)character == kommaNotationDelimiter)
369 continue;
370 else if ((char)character == mapEndNotationMarker)
371 break;
372 }
373 if (character < 0)
374 throw new OSDException("Notation LLSD parsing: Unexpected end of map discovered.");
375  
376 return (OSD)osdMap;
377 }
378  
379 private static void SerializeLLSDNotationElement(StringWriter writer, OSD osd)
380 {
381  
382 switch (osd.Type)
383 {
384 case OSDType.Unknown:
385 writer.Write(undefNotationValue);
386 break;
387 case OSDType.Boolean:
388 if (osd.AsBoolean())
389 writer.Write(trueNotationValueTwo);
390 else
391 writer.Write(falseNotationValueTwo);
392 break;
393 case OSDType.Integer:
394 writer.Write(integerNotationMarker);
395 writer.Write(osd.AsString());
396 break;
397 case OSDType.Real:
398 writer.Write(realNotationMarker);
399 writer.Write(osd.AsString());
400 break;
401 case OSDType.UUID:
402 writer.Write(uuidNotationMarker);
403 writer.Write(osd.AsString());
404 break;
405 case OSDType.String:
406 writer.Write(singleQuotesNotationMarker);
407 writer.Write(EscapeCharacter(osd.AsString(), singleQuotesNotationMarker));
408 writer.Write(singleQuotesNotationMarker);
409 break;
410 case OSDType.Binary:
411 writer.Write(binaryNotationMarker);
412 writer.Write("64");
413 writer.Write(doubleQuotesNotationMarker);
414 writer.Write(osd.AsString());
415 writer.Write(doubleQuotesNotationMarker);
416 break;
417 case OSDType.Date:
418 writer.Write(dateNotationMarker);
419 writer.Write(doubleQuotesNotationMarker);
420 writer.Write(osd.AsString());
421 writer.Write(doubleQuotesNotationMarker);
422 break;
423 case OSDType.URI:
424 writer.Write(uriNotationMarker);
425 writer.Write(doubleQuotesNotationMarker);
426 writer.Write(EscapeCharacter(osd.AsString(), doubleQuotesNotationMarker));
427 writer.Write(doubleQuotesNotationMarker);
428 break;
429 case OSDType.Array:
430 SerializeLLSDNotationArray(writer, (OSDArray)osd);
431 break;
432 case OSDType.Map:
433 SerializeLLSDNotationMap(writer, (OSDMap)osd);
434 break;
435 default:
436 throw new OSDException("Notation serialization: Not existing element discovered.");
437  
438 }
439 }
440  
441 private static void SerializeLLSDNotationArray(StringWriter writer, OSDArray osdArray)
442 {
443 writer.Write(arrayBeginNotationMarker);
444 int lastIndex = osdArray.Count - 1;
445  
446 for (int idx = 0; idx <= lastIndex; idx++)
447 {
448 SerializeLLSDNotationElement(writer, osdArray[idx]);
449 if (idx < lastIndex)
450 writer.Write(kommaNotationDelimiter);
451 }
452 writer.Write(arrayEndNotationMarker);
453 }
454  
455 private static void SerializeLLSDNotationMap(StringWriter writer, OSDMap osdMap)
456 {
457 writer.Write(mapBeginNotationMarker);
458 int lastIndex = osdMap.Count - 1;
459 int idx = 0;
460  
461 foreach (KeyValuePair<string, OSD> kvp in osdMap)
462 {
463 writer.Write(singleQuotesNotationMarker);
464 writer.Write(EscapeCharacter(kvp.Key, singleQuotesNotationMarker));
465 writer.Write(singleQuotesNotationMarker);
466 writer.Write(keyNotationDelimiter);
467 SerializeLLSDNotationElement(writer, kvp.Value);
468 if (idx < lastIndex)
469 writer.Write(kommaNotationDelimiter);
470  
471 idx++;
472 }
473 writer.Write(mapEndNotationMarker);
474 }
475  
476 private static void SerializeLLSDNotationElementFormatted(StringWriter writer, string indent, OSD osd)
477 {
478 switch (osd.Type)
479 {
480 case OSDType.Unknown:
481 writer.Write(undefNotationValue);
482 break;
483 case OSDType.Boolean:
484 if (osd.AsBoolean())
485 writer.Write(trueNotationValueTwo);
486 else
487 writer.Write(falseNotationValueTwo);
488 break;
489 case OSDType.Integer:
490 writer.Write(integerNotationMarker);
491 writer.Write(osd.AsString());
492 break;
493 case OSDType.Real:
494 writer.Write(realNotationMarker);
495 writer.Write(osd.AsString());
496 break;
497 case OSDType.UUID:
498 writer.Write(uuidNotationMarker);
499 writer.Write(osd.AsString());
500 break;
501 case OSDType.String:
502 writer.Write(singleQuotesNotationMarker);
503 writer.Write(EscapeCharacter(osd.AsString(), singleQuotesNotationMarker));
504 writer.Write(singleQuotesNotationMarker);
505 break;
506 case OSDType.Binary:
507 writer.Write(binaryNotationMarker);
508 writer.Write("64");
509 writer.Write(doubleQuotesNotationMarker);
510 writer.Write(osd.AsString());
511 writer.Write(doubleQuotesNotationMarker);
512 break;
513 case OSDType.Date:
514 writer.Write(dateNotationMarker);
515 writer.Write(doubleQuotesNotationMarker);
516 writer.Write(osd.AsString());
517 writer.Write(doubleQuotesNotationMarker);
518 break;
519 case OSDType.URI:
520 writer.Write(uriNotationMarker);
521 writer.Write(doubleQuotesNotationMarker);
522 writer.Write(EscapeCharacter(osd.AsString(), doubleQuotesNotationMarker));
523 writer.Write(doubleQuotesNotationMarker);
524 break;
525 case OSDType.Array:
526 SerializeLLSDNotationArrayFormatted(writer, indent + baseIndent, (OSDArray)osd);
527 break;
528 case OSDType.Map:
529 SerializeLLSDNotationMapFormatted(writer, indent + baseIndent, (OSDMap)osd);
530 break;
531 default:
532 throw new OSDException("Notation serialization: Not existing element discovered.");
533  
534 }
535 }
536  
537 private static void SerializeLLSDNotationArrayFormatted(StringWriter writer, string intend, OSDArray osdArray)
538 {
539 writer.WriteLine();
540 writer.Write(intend);
541 writer.Write(arrayBeginNotationMarker);
542 int lastIndex = osdArray.Count - 1;
543  
544 for (int idx = 0; idx <= lastIndex; idx++)
545 {
546 if (osdArray[idx].Type != OSDType.Array && osdArray[idx].Type != OSDType.Map)
547 writer.WriteLine();
548 writer.Write(intend + baseIndent);
549 SerializeLLSDNotationElementFormatted(writer, intend, osdArray[idx]);
550 if (idx < lastIndex)
551 {
552 writer.Write(kommaNotationDelimiter);
553 }
554 }
555 writer.WriteLine();
556 writer.Write(intend);
557 writer.Write(arrayEndNotationMarker);
558 }
559  
560 private static void SerializeLLSDNotationMapFormatted(StringWriter writer, string intend, OSDMap osdMap)
561 {
562 writer.WriteLine();
563 writer.Write(intend);
564 writer.WriteLine(mapBeginNotationMarker);
565 int lastIndex = osdMap.Count - 1;
566 int idx = 0;
567  
568 foreach (KeyValuePair<string, OSD> kvp in osdMap)
569 {
570 writer.Write(intend + baseIndent);
571 writer.Write(singleQuotesNotationMarker);
572 writer.Write(EscapeCharacter(kvp.Key, singleQuotesNotationMarker));
573 writer.Write(singleQuotesNotationMarker);
574 writer.Write(keyNotationDelimiter);
575 SerializeLLSDNotationElementFormatted(writer, intend, kvp.Value);
576 if (idx < lastIndex)
577 {
578 writer.WriteLine();
579 writer.Write(intend + baseIndent);
580 writer.WriteLine(kommaNotationDelimiter);
581 }
582  
583 idx++;
584 }
585 writer.WriteLine();
586 writer.Write(intend);
587 writer.Write(mapEndNotationMarker);
588 }
589  
590 /// <summary>
591 ///
592 /// </summary>
593 /// <param name="reader"></param>
594 /// <returns></returns>
595 public static int PeekAndSkipWhitespace(StringReader reader)
596 {
597 int character;
598 while ((character = reader.Peek()) > 0)
599 {
600 char c = (char)character;
601 if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
602 {
603 reader.Read();
604 continue;
605 }
606 else
607 break;
608 }
609 return character;
610 }
611  
612 /// <summary>
613 ///
614 /// </summary>
615 /// <param name="reader"></param>
616 /// <returns></returns>
617 public static int ReadAndSkipWhitespace(StringReader reader)
618 {
619 int character = PeekAndSkipWhitespace(reader);
620 reader.Read();
621 return character;
622 }
623  
624 /// <summary>
625 ///
626 /// </summary>
627 /// <param name="reader"></param>
628 /// <returns></returns>
629 public static int GetLengthInBrackets(StringReader reader)
630 {
631 int character;
632 StringBuilder s = new StringBuilder();
633 if (((character = PeekAndSkipWhitespace(reader)) > 0) &&
634 ((char)character == sizeBeginNotationMarker))
635 {
636 reader.Read();
637 }
638 while (((character = reader.Read()) > 0) &&
639 Char.IsDigit((char)character) &&
640 ((char)character != sizeEndNotationMarker))
641 {
642 s.Append((char)character);
643 }
644 if (character < 0)
645 throw new OSDException("Notation LLSD parsing: Can't parse length value cause unexpected end of stream.");
646 int length;
647 if (!Int32.TryParse(s.ToString(), out length))
648 throw new OSDException("Notation LLSD parsing: Can't parse length value.");
649  
650 return length;
651 }
652  
653 /// <summary>
654 ///
655 /// </summary>
656 /// <param name="reader"></param>
657 /// <param name="delimiter"></param>
658 /// <returns></returns>
659 public static string GetStringDelimitedBy(StringReader reader, char delimiter)
660 {
661 int character;
662 bool foundEscape = false;
663 StringBuilder s = new StringBuilder();
664 while (((character = reader.Read()) > 0) &&
665 (((char)character != delimiter) ||
666 ((char)character == delimiter && foundEscape)))
667 {
668  
669 if (foundEscape)
670 {
671 foundEscape = false;
672 switch ((char)character)
673 {
674 case 'a':
675 s.Append('\a');
676 break;
677 case 'b':
678 s.Append('\b');
679 break;
680 case 'f':
681 s.Append('\f');
682 break;
683 case 'n':
684 s.Append('\n');
685 break;
686 case 'r':
687 s.Append('\r');
688 break;
689 case 't':
690 s.Append('\t');
691 break;
692 case 'v':
693 s.Append('\v');
694 break;
695 default:
696 s.Append((char)character);
697 break;
698 }
699 }
700 else if ((char)character == '\\')
701 foundEscape = true;
702 else
703 s.Append((char)character);
704  
705 }
706 if (character < 0)
707 throw new OSDException("Notation LLSD parsing: Can't parse text because unexpected end of stream while expecting a '"
708 + delimiter + "' character.");
709  
710 return s.ToString();
711 }
712  
713 /// <summary>
714 ///
715 /// </summary>
716 /// <param name="reader"></param>
717 /// <param name="buffer"></param>
718 /// <param name="offset"></param>
719 /// <returns></returns>
720 public static int BufferCharactersEqual(StringReader reader, char[] buffer, int offset)
721 {
722  
723 int character;
724 int lastIndex = buffer.Length - 1;
725 int crrIndex = offset;
726 bool charactersEqual = true;
727  
728 while ((character = reader.Peek()) > 0 &&
729 crrIndex <= lastIndex &&
730 charactersEqual)
731 {
732 if (((char)character) != buffer[crrIndex])
733 {
734 charactersEqual = false;
735 break;
736 }
737 crrIndex++;
738 reader.Read();
739 }
740  
741 return crrIndex;
742 }
743  
744 /// <summary>
745 ///
746 /// </summary>
747 /// <param name="s"></param>
748 /// <param name="c"></param>
749 /// <returns></returns>
750 public static string UnescapeCharacter(String s, char c)
751 {
752 string oldOne = "\\" + c;
753 string newOne = new String(c, 1);
754  
755 String sOne = s.Replace("\\\\", "\\").Replace(oldOne, newOne);
756 return sOne;
757 }
758  
759 /// <summary>
760 ///
761 /// </summary>
762 /// <param name="s"></param>
763 /// <param name="c"></param>
764 /// <returns></returns>
765 public static string EscapeCharacter(String s, char c)
766 {
767 string oldOne = new String(c, 1);
768 string newOne = "\\" + c;
769  
770 String sOne = s.Replace("\\", "\\\\").Replace(oldOne, newOne);
771 return sOne;
772 }
773 }
774 }