aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorft@noemail2015-03-04 00:17:24 +0100
committerBlueWall2015-03-03 18:39:49 -0500
commitfb48ee1cb608f5facdcd257f13a7e49c2ce52946 (patch)
treefac8f7d3437031fe7e6e4fed9e1cf13562cb3f78 /OpenSim
parentRevert "corrected osMakeNotecard(string data) text length was calculated wron... (diff)
downloadopensim-SC-fb48ee1cb608f5facdcd257f13a7e49c2ce52946.zip
opensim-SC-fb48ee1cb608f5facdcd257f13a7e49c2ce52946.tar.gz
opensim-SC-fb48ee1cb608f5facdcd257f13a7e49c2ce52946.tar.bz2
opensim-SC-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 'OpenSim')
-rw-r--r--OpenSim/Framework/SLUtil.cs328
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs19
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs3
4 files changed, 262 insertions, 94 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
28using OpenMetaverse;
28using System; 29using System;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Xml;
33using log4net;
34using OpenMetaverse;
35 31
36namespace OpenSim.Framework 32namespace 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}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
index b69676b..edf51a2 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -595,11 +595,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
595 595
596 try 596 try
597 { 597 {
598 string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data)); 598 string jsondata = SLUtil.ParseNotecardToString(a.Data);
599 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; 599 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
600 m_comms.DispatchReply(scriptID, result, "", reqID.ToString()); 600 m_comms.DispatchReply(scriptID, result, "", reqID.ToString());
601 return; 601 return;
602 } 602 }
603 catch(SLUtil.NotANotecardFormatException e)
604 {
605 m_log.WarnFormat("[JsonStoreScripts]: Notecard parsing failed; assetId {0} at line number {1}", assetID.ToString(), e.lineNumber);
606 }
603 catch (Exception e) 607 catch (Exception e)
604 { 608 {
605 m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message); 609 m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index bb8ec9c..6a30da2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -11632,9 +11632,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11632 return; 11632 return;
11633 } 11633 }
11634 11634
11635 string data = Encoding.UTF8.GetString(a.Data); 11635 NotecardCache.Cache(id, a.Data);
11636 //m_log.Debug(data);
11637 NotecardCache.Cache(id, data);
11638 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString()); 11636 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString());
11639 }); 11637 });
11640 11638
@@ -11688,7 +11686,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11688 11686
11689 string data = Encoding.UTF8.GetString(a.Data); 11687 string data = Encoding.UTF8.GetString(a.Data);
11690 //m_log.Debug(data); 11688 //m_log.Debug(data);
11691 NotecardCache.Cache(id, data); 11689 NotecardCache.Cache(id, a.Data);
11692 AsyncCommands.DataserverPlugin.DataserverReply( 11690 AsyncCommands.DataserverPlugin.DataserverReply(
11693 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); 11691 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
11694 }); 11692 });
@@ -12461,10 +12459,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12461 public DateTime lastRef; 12459 public DateTime lastRef;
12462 } 12460 }
12463 12461
12464 protected static Dictionary<UUID, Notecard> m_Notecards = 12462 private static Dictionary<UUID, Notecard> m_Notecards =
12465 new Dictionary<UUID, Notecard>(); 12463 new Dictionary<UUID, Notecard>();
12466 12464
12467 public static void Cache(UUID assetID, string text) 12465 public static void Cache(UUID assetID, byte[] text)
12468 { 12466 {
12469 CheckCache(); 12467 CheckCache();
12470 12468
@@ -12475,7 +12473,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12475 12473
12476 Notecard nc = new Notecard(); 12474 Notecard nc = new Notecard();
12477 nc.lastRef = DateTime.Now; 12475 nc.lastRef = DateTime.Now;
12478 nc.text = SLUtil.ParseNotecardToList(text).ToArray(); 12476 try
12477 {
12478 nc.text = SLUtil.ParseNotecardToArray(text);
12479 }
12480 catch(SLUtil.NotANotecardFormatException)
12481 {
12482 nc.text = new string[0];
12483 }
12479 m_Notecards[assetID] = nc; 12484 m_Notecards[assetID] = nc;
12480 } 12485 }
12481 } 12486 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 10ddf14..3afebe2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -1926,8 +1926,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1926 if (a == null) 1926 if (a == null)
1927 return UUID.Zero; 1927 return UUID.Zero;
1928 1928
1929 string data = Encoding.UTF8.GetString(a.Data); 1929 NotecardCache.Cache(assetID, a.Data);
1930 NotecardCache.Cache(assetID, data);
1931 }; 1930 };
1932 1931
1933 return assetID; 1932 return assetID;