diff options
author | ft@noemail | 2015-03-04 00:17:24 +0100 |
---|---|---|
committer | BlueWall | 2015-03-03 18:39:49 -0500 |
commit | fb48ee1cb608f5facdcd257f13a7e49c2ce52946 (patch) | |
tree | fac8f7d3437031fe7e6e4fed9e1cf13562cb3f78 /OpenSim/Framework/SLUtil.cs | |
parent | Revert "corrected osMakeNotecard(string data) text length was calculated wron... (diff) | |
download | opensim-SC_OLD-fb48ee1cb608f5facdcd257f13a7e49c2ce52946.zip opensim-SC_OLD-fb48ee1cb608f5facdcd257f13a7e49c2ce52946.tar.gz opensim-SC_OLD-fb48ee1cb608f5facdcd257f13a7e49c2ce52946.tar.bz2 opensim-SC_OLD-fb48ee1cb608f5facdcd257f13a7e49c2ce52946.tar.xz |
corrected script notecard parser. It now handles notecards with inventory as well.
Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/SLUtil.cs | 328 |
1 files changed, 244 insertions, 84 deletions
diff --git a/OpenSim/Framework/SLUtil.cs b/OpenSim/Framework/SLUtil.cs index 9249105..027fc0e 100644 --- a/OpenSim/Framework/SLUtil.cs +++ b/OpenSim/Framework/SLUtil.cs | |||
@@ -25,13 +25,9 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenMetaverse; | ||
28 | using System; | 29 | using System; |
29 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
30 | using System.IO; | ||
31 | using System.Reflection; | ||
32 | using System.Xml; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | 31 | ||
36 | namespace OpenSim.Framework | 32 | namespace OpenSim.Framework |
37 | { | 33 | { |
@@ -251,106 +247,270 @@ namespace OpenSim.Framework | |||
251 | 247 | ||
252 | #endregion SL / file extension / content-type conversions | 248 | #endregion SL / file extension / content-type conversions |
253 | 249 | ||
254 | /// <summary> | 250 | private class NotecardReader |
255 | /// Parse a notecard in Linden format to a string of ordinary text. | ||
256 | /// </summary> | ||
257 | /// <param name="rawInput"></param> | ||
258 | /// <returns></returns> | ||
259 | public static string ParseNotecardToString(string rawInput) | ||
260 | { | 251 | { |
261 | string[] output = ParseNotecardToList(rawInput).ToArray(); | 252 | private string rawInput; |
253 | private int lineNumber; | ||
262 | 254 | ||
263 | // foreach (string line in output) | 255 | public int LineNumber |
264 | // m_log.DebugFormat("[PARSE NOTECARD]: ParseNotecardToString got line {0}", line); | 256 | { |
265 | 257 | get | |
266 | return string.Join("\n", output); | 258 | { |
259 | return lineNumber; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | public NotecardReader(string _rawInput) | ||
264 | { | ||
265 | rawInput = (string)_rawInput.Clone(); | ||
266 | lineNumber = 0; | ||
267 | } | ||
268 | |||
269 | public string getLine() | ||
270 | { | ||
271 | if(rawInput.Length == 0) | ||
272 | { | ||
273 | throw new NotANotecardFormatException(lineNumber + 1); | ||
274 | } | ||
275 | |||
276 | int pos = rawInput.IndexOf('\n'); | ||
277 | if(pos < 0) | ||
278 | { | ||
279 | pos = rawInput.Length; | ||
280 | } | ||
281 | |||
282 | /* cut line from rest */ | ||
283 | ++lineNumber; | ||
284 | string line = rawInput.Substring(0, pos); | ||
285 | if (pos + 1 >= rawInput.Length) | ||
286 | { | ||
287 | rawInput = string.Empty; | ||
288 | } | ||
289 | else | ||
290 | { | ||
291 | rawInput = rawInput.Substring(pos + 1); | ||
292 | } | ||
293 | /* clean up line from double spaces and tabs */ | ||
294 | line = line.Replace("\t", " "); | ||
295 | while(line.IndexOf(" ") >= 0) | ||
296 | { | ||
297 | line = line.Replace(" ", " "); | ||
298 | } | ||
299 | return line.Replace("\r", "").Trim(); | ||
300 | } | ||
301 | |||
302 | public string getBlock(int length) | ||
303 | { | ||
304 | /* cut line from rest */ | ||
305 | if(length > rawInput.Length) | ||
306 | { | ||
307 | throw new NotANotecardFormatException(lineNumber); | ||
308 | } | ||
309 | string line = rawInput.Substring(0, length); | ||
310 | rawInput = rawInput.Substring(length); | ||
311 | return line; | ||
312 | } | ||
267 | } | 313 | } |
268 | 314 | ||
269 | /// <summary> | 315 | public class NotANotecardFormatException : Exception |
270 | /// Parse a notecard in Linden format to a list of ordinary lines. | ||
271 | /// </summary> | ||
272 | /// <param name="rawInput"></param> | ||
273 | /// <returns></returns> | ||
274 | public static List<string> ParseNotecardToList(string rawInput) | ||
275 | { | 316 | { |
276 | string[] input; | 317 | public int lineNumber; |
277 | int idx = 0; | 318 | public NotANotecardFormatException(int _lineNumber) |
278 | int level = 0; | 319 | : base() |
279 | List<string> output = new List<string>(); | ||
280 | string[] words; | ||
281 | |||
282 | //The Linden format always ends with a } after the input data. | ||
283 | //Strip off trailing } so there is nothing after the input data. | ||
284 | int i = rawInput.LastIndexOf("}"); | ||
285 | rawInput = rawInput.Remove(i, rawInput.Length-i); | ||
286 | input = rawInput.Replace("\r", "").Split('\n'); | ||
287 | |||
288 | while (idx < input.Length) | ||
289 | { | 320 | { |
290 | if (input[idx] == "{") | 321 | lineNumber = _lineNumber; |
322 | } | ||
323 | } | ||
324 | |||
325 | private static void skipSection(NotecardReader reader) | ||
326 | { | ||
327 | if (reader.getLine() != "{") | ||
328 | throw new NotANotecardFormatException(reader.LineNumber); | ||
329 | |||
330 | string line; | ||
331 | while ((line = reader.getLine()) != "}") | ||
332 | { | ||
333 | if(line.IndexOf('{')>=0) | ||
334 | { | ||
335 | throw new NotANotecardFormatException(reader.LineNumber); | ||
336 | } | ||
337 | } | ||
338 | } | ||
339 | |||
340 | private static void skipInventoryItem(NotecardReader reader) | ||
341 | { | ||
342 | if (reader.getLine() != "{") | ||
343 | throw new NotANotecardFormatException(reader.LineNumber); | ||
344 | |||
345 | string line; | ||
346 | while((line = reader.getLine()) != "}") | ||
347 | { | ||
348 | string[] data = line.Split(' '); | ||
349 | if(data.Length == 0) | ||
291 | { | 350 | { |
292 | level++; | ||
293 | idx++; | ||
294 | continue; | 351 | continue; |
295 | } | 352 | } |
353 | if(data[0] == "permissions") | ||
354 | { | ||
355 | skipSection(reader); | ||
356 | } | ||
357 | else if(data[0] == "sale_info") | ||
358 | { | ||
359 | skipSection(reader); | ||
360 | } | ||
361 | else if (line.IndexOf('{') >= 0) | ||
362 | { | ||
363 | throw new NotANotecardFormatException(reader.LineNumber); | ||
364 | } | ||
365 | } | ||
366 | } | ||
367 | |||
368 | private static void skipInventoryItems(NotecardReader reader) | ||
369 | { | ||
370 | if(reader.getLine() != "{") | ||
371 | { | ||
372 | throw new NotANotecardFormatException(reader.LineNumber); | ||
373 | } | ||
296 | 374 | ||
297 | if (input[idx]== "}") | 375 | string line; |
376 | while((line = reader.getLine()) != "}") | ||
377 | { | ||
378 | string[] data = line.Split(' '); | ||
379 | if(data.Length == 0) | ||
298 | { | 380 | { |
299 | level--; | ||
300 | idx++; | ||
301 | continue; | 381 | continue; |
302 | } | 382 | } |
303 | 383 | ||
304 | switch (level) | 384 | if(data[0] == "inv_item") |
305 | { | 385 | { |
306 | case 0: | 386 | skipInventoryItem(reader); |
307 | words = input[idx].Split(' '); // Linden text ver | 387 | } |
308 | // Notecards are created *really* empty. Treat that as "no text" (just like after saving an empty notecard) | 388 | else if (line.IndexOf('{') >= 0) |
309 | if (words.Length < 3) | 389 | { |
310 | return output; | 390 | throw new NotANotecardFormatException(reader.LineNumber); |
311 | 391 | } | |
312 | int version = int.Parse(words[3]); | ||
313 | if (version != 2) | ||
314 | return output; | ||
315 | break; | ||
316 | case 1: | ||
317 | words = input[idx].Split(' '); | ||
318 | if (words[0] == "LLEmbeddedItems") | ||
319 | break; | ||
320 | if (words[0] == "Text") | ||
321 | { | ||
322 | idx++; //Now points to first line of notecard text | ||
323 | 392 | ||
324 | //Number of lines in notecard. | 393 | } |
325 | int lines = input.Length - idx; | 394 | } |
326 | int line = 0; | ||
327 | 395 | ||
328 | while (line < lines) | 396 | private static void skipInventory(NotecardReader reader) |
329 | { | 397 | { |
330 | // m_log.DebugFormat("[PARSE NOTECARD]: Adding line {0}", input[idx]); | 398 | if (reader.getLine() != "{") |
331 | output.Add(input[idx]); | 399 | throw new NotANotecardFormatException(reader.LineNumber); |
332 | idx++; | ||
333 | line++; | ||
334 | } | ||
335 | 400 | ||
336 | return output; | 401 | string line; |
337 | } | 402 | while((line = reader.getLine()) != "}") |
338 | break; | 403 | { |
339 | case 2: | 404 | string[] data = line.Split(' '); |
340 | words = input[idx].Split(' '); // count | 405 | if(data[0] == "count") |
341 | if (words[0] == "count") | 406 | { |
407 | int count = Int32.Parse(data[1]); | ||
408 | for(int i = 0; i < count; ++i) | ||
342 | { | 409 | { |
343 | int c = int.Parse(words[1]); | 410 | skipInventoryItems(reader); |
344 | if (c > 0) | ||
345 | return output; | ||
346 | break; | ||
347 | } | 411 | } |
348 | break; | ||
349 | } | 412 | } |
350 | idx++; | 413 | else if (line.IndexOf('{') >= 0) |
414 | { | ||
415 | throw new NotANotecardFormatException(reader.LineNumber); | ||
416 | } | ||
351 | } | 417 | } |
352 | 418 | } | |
353 | return output; | 419 | |
420 | private static string readNotecardText(NotecardReader reader) | ||
421 | { | ||
422 | if (reader.getLine() != "{") | ||
423 | throw new NotANotecardFormatException(reader.LineNumber); | ||
424 | |||
425 | string notecardString = string.Empty; | ||
426 | string line; | ||
427 | while((line = reader.getLine()) != "}") | ||
428 | { | ||
429 | string[] data = line.Split(' '); | ||
430 | if (data.Length == 0) | ||
431 | { | ||
432 | continue; | ||
433 | } | ||
434 | |||
435 | if (data[0] == "LLEmbeddedItems") | ||
436 | { | ||
437 | skipInventory(reader); | ||
438 | } | ||
439 | else if(data[0] == "Text" && data.Length == 3) | ||
440 | { | ||
441 | int length = Int32.Parse(data[2]); | ||
442 | notecardString = reader.getBlock(length); | ||
443 | } | ||
444 | else if (line.IndexOf('{') >= 0) | ||
445 | { | ||
446 | throw new NotANotecardFormatException(reader.LineNumber); | ||
447 | } | ||
448 | |||
449 | } | ||
450 | return notecardString; | ||
451 | } | ||
452 | |||
453 | private static string readNotecard(byte[] rawInput) | ||
454 | { | ||
455 | string rawIntermedInput = string.Empty; | ||
456 | |||
457 | /* make up a Raw Encoding here */ | ||
458 | foreach(byte c in rawInput) | ||
459 | { | ||
460 | char d = (char)c; | ||
461 | rawIntermedInput += d; | ||
462 | } | ||
463 | |||
464 | NotecardReader reader = new NotecardReader(rawIntermedInput); | ||
465 | string line; | ||
466 | try | ||
467 | { | ||
468 | line = reader.getLine(); | ||
469 | } | ||
470 | catch(Exception) | ||
471 | { | ||
472 | return System.Text.Encoding.UTF8.GetString(rawInput); | ||
473 | } | ||
474 | string[] versioninfo = line.Split(' '); | ||
475 | if(versioninfo.Length < 3) | ||
476 | { | ||
477 | return System.Text.Encoding.UTF8.GetString(rawInput); | ||
478 | } | ||
479 | else if(versioninfo[0] != "Linden" || versioninfo[1] != "text") | ||
480 | { | ||
481 | return System.Text.Encoding.UTF8.GetString(rawInput); | ||
482 | } | ||
483 | else | ||
484 | { | ||
485 | /* now we actually decode the Encoding, before we needed it in raw */ | ||
486 | string o = readNotecardText(reader); | ||
487 | byte[] a = new byte[o.Length]; | ||
488 | for(int i = 0; i < o.Length; ++i) | ||
489 | { | ||
490 | a[i] = (byte)o[i]; | ||
491 | } | ||
492 | return System.Text.Encoding.UTF8.GetString(a); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | /// <summary> | ||
497 | /// Parse a notecard in Linden format to a string of ordinary text. | ||
498 | /// </summary> | ||
499 | /// <param name="rawInput"></param> | ||
500 | /// <returns></returns> | ||
501 | public static string ParseNotecardToString(byte[] rawInput) | ||
502 | { | ||
503 | return readNotecard(rawInput); | ||
504 | } | ||
505 | |||
506 | /// <summary> | ||
507 | /// Parse a notecard in Linden format to a list of ordinary lines. | ||
508 | /// </summary> | ||
509 | /// <param name="rawInput"></param> | ||
510 | /// <returns></returns> | ||
511 | public static string[] ParseNotecardToArray(byte[] rawInput) | ||
512 | { | ||
513 | return readNotecard(rawInput).Replace("\r", "").Split('\n'); | ||
354 | } | 514 | } |
355 | } | 515 | } |
356 | } | 516 | } |