diff options
author | Justin Clarke Casey | 2008-04-18 19:03:28 +0000 |
---|---|---|
committer | Justin Clarke Casey | 2008-04-18 19:03:28 +0000 |
commit | cd09677469b51f2858917d3e2c583680e3a0b281 (patch) | |
tree | 3f91a2320fb5ef365c008b3c0bfe3e3da2c325e0 /OpenSim/Region | |
parent | * Refactor: Remove redundant try/catch from asset request since this is now h... (diff) | |
download | opensim-SC-cd09677469b51f2858917d3e2c583680e3a0b281.zip opensim-SC-cd09677469b51f2858917d3e2c583680e3a0b281.tar.gz opensim-SC-cd09677469b51f2858917d3e2c583680e3a0b281.tar.bz2 opensim-SC-cd09677469b51f2858917d3e2c583680e3a0b281.tar.xz |
From: Alan M Webb <awebb@vnet.ibm.com>
Robust implementations of GetSubString, InsertString, and
DeleteSubstring. The existing implementations only worked for arguments
consistent with the underlying .Net implementation and did not
accomodate LL's negative indices.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs | 261 |
1 files changed, 219 insertions, 42 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs index 57a579a..26e56c7 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs | |||
@@ -1306,53 +1306,230 @@ namespace OpenSim.Region.ScriptEngine.Common | |||
1306 | m_host.PreloadSound(sound); | 1306 | m_host.PreloadSound(sound); |
1307 | } | 1307 | } |
1308 | 1308 | ||
1309 | /// <summary> | ||
1310 | /// Return a portion of the designated string bounded by | ||
1311 | /// inclusive indices (start and end). As usual, the negative | ||
1312 | /// indices, and the tolerance for out-of-bound values, makes | ||
1313 | /// this more complicated than it might otherwise seem. | ||
1314 | /// </summary> | ||
1315 | |||
1309 | public string llGetSubString(string src, int start, int end) | 1316 | public string llGetSubString(string src, int start, int end) |
1310 | { | 1317 | { |
1318 | |||
1311 | m_host.AddScriptLPS(1); | 1319 | m_host.AddScriptLPS(1); |
1312 | // substring expects length | ||
1313 | // return src.Substring(start, end); | ||
1314 | 1320 | ||
1315 | // if one is negative so use length of string as base | 1321 | // Normalize indices (if negative). |
1316 | // if start > end then it is exclusive | 1322 | // After normlaization they may still be |
1317 | // for length add +1 for char at location=0 | 1323 | // negative, but that is now relative to |
1318 | if (start < 0) { start = src.Length-start; } | 1324 | // the start, rather than the end, of the |
1319 | if (end < 0) { end = src.Length - end; } | 1325 | // sequence. |
1320 | if (start > end) | 1326 | |
1327 | if (start < 0) | ||
1328 | { | ||
1329 | start = src.Length+start; | ||
1330 | } | ||
1331 | if (end < 0) | ||
1332 | { | ||
1333 | end = src.Length+end; | ||
1334 | } | ||
1335 | |||
1336 | // Conventional substring | ||
1337 | if (start <= end) | ||
1321 | { | 1338 | { |
1322 | return src.Substring(0, 1+end) + src.Substring(start, src.Length - start); | 1339 | // Implies both bounds are out-of-range. |
1340 | if(end < 0 || start >= src.Length) | ||
1341 | { | ||
1342 | return String.Empty; | ||
1343 | } | ||
1344 | // If end is positive, then it directly | ||
1345 | // corresponds to the lengt of the substring | ||
1346 | // needed (plus one of course). BUT, it | ||
1347 | // must be within bounds. | ||
1348 | if(end >= src.Length) | ||
1349 | { | ||
1350 | end = src.Length-1; | ||
1351 | } | ||
1352 | |||
1353 | if(start < 0) | ||
1354 | { | ||
1355 | return src.Substring(0,end+1); | ||
1356 | } | ||
1357 | // Both indices are positive | ||
1358 | return src.Substring(start, (end+1) - start); | ||
1323 | } | 1359 | } |
1360 | |||
1361 | // Inverted substring (end < start) | ||
1324 | else | 1362 | else |
1325 | { | 1363 | { |
1326 | return src.Substring(start, (1+end) - start); | 1364 | // Implies both indices are below the |
1365 | // lower bound. In the inverted case, that | ||
1366 | // means the entire string will be returned | ||
1367 | // unchanged. | ||
1368 | if(start < 0) | ||
1369 | { | ||
1370 | return src; | ||
1371 | } | ||
1372 | // If both indices are greater than the upper | ||
1373 | // bound the result may seem initially counter | ||
1374 | // intuitive. | ||
1375 | if(end >= src.Length) | ||
1376 | { | ||
1377 | return src; | ||
1378 | } | ||
1379 | |||
1380 | if(end < 0) | ||
1381 | { | ||
1382 | if(start < src.Length) | ||
1383 | { | ||
1384 | return src.Substring(start); | ||
1385 | } | ||
1386 | else | ||
1387 | { | ||
1388 | return String.Empty; | ||
1389 | } | ||
1390 | } | ||
1391 | else | ||
1392 | { | ||
1393 | if(start < src.Length) | ||
1394 | { | ||
1395 | return src.Substring(0,end+1) + src.Substring(start); | ||
1396 | } | ||
1397 | else | ||
1398 | { | ||
1399 | return src.Substring(0,end+1); | ||
1400 | } | ||
1401 | } | ||
1327 | } | 1402 | } |
1328 | } | 1403 | } |
1329 | 1404 | ||
1405 | /// <summary> | ||
1406 | /// Delete substring removes the specified substring bounded | ||
1407 | /// by the inclusive indices start and end. Indices may be | ||
1408 | /// negative (indicating end-relative) and may be inverted, | ||
1409 | /// i.e. end < start. | ||
1410 | /// </summary> | ||
1411 | |||
1330 | public string llDeleteSubString(string src, int start, int end) | 1412 | public string llDeleteSubString(string src, int start, int end) |
1331 | { | 1413 | { |
1414 | |||
1332 | m_host.AddScriptLPS(1); | 1415 | m_host.AddScriptLPS(1); |
1333 | //return src.Remove(start, end - start); | 1416 | |
1334 | // if one is negative so use length of string as base | 1417 | // Normalize indices (if negative). |
1335 | // if start > end then it is exclusive | 1418 | // After normlaization they may still be |
1336 | // for length add +1 for char at location=0 | 1419 | // negative, but that is now relative to |
1337 | if (start < 0) { start = src.Length - start; } | 1420 | // the start, rather than the end, of the |
1338 | if (end < 0) { end = src.Length - end; } | 1421 | // sequence. |
1339 | if (start > end) | 1422 | if (start < 0) |
1423 | { | ||
1424 | start = src.Length+start; | ||
1425 | } | ||
1426 | if (end < 0) | ||
1340 | { | 1427 | { |
1341 | return src.Remove(0, 1 + end) + src.Remove(start, src.Length - start); | 1428 | end = src.Length+end; |
1429 | } | ||
1430 | // Conventionally delimited substring | ||
1431 | if (start <= end) | ||
1432 | { | ||
1433 | // If both bounds are outside of the existing | ||
1434 | // string, then return unchanges. | ||
1435 | if(end < 0 || start >= src.Length) | ||
1436 | { | ||
1437 | return src; | ||
1438 | } | ||
1439 | // At least one bound is in-range, so we | ||
1440 | // need to clip the out-of-bound argument. | ||
1441 | if(start < 0) | ||
1442 | { | ||
1443 | start = 0; | ||
1444 | } | ||
1445 | |||
1446 | if(end >= src.Length) | ||
1447 | { | ||
1448 | end = src.Length-1; | ||
1449 | } | ||
1450 | |||
1451 | return src.Remove(start,end-start+1); | ||
1342 | } | 1452 | } |
1453 | // Inverted substring | ||
1343 | else | 1454 | else |
1344 | { | 1455 | { |
1345 | return src.Remove(start, (1 + end) - start); | 1456 | // In this case, out of bounds means that |
1457 | // the existing string is part of the cut. | ||
1458 | if(start < 0 || end >= src.Length) | ||
1459 | { | ||
1460 | return String.Empty; | ||
1461 | } | ||
1462 | |||
1463 | if(end > 0) | ||
1464 | { | ||
1465 | if(start < src.Length) | ||
1466 | { | ||
1467 | return src.Remove(start).Remove(0,end+1); | ||
1468 | } | ||
1469 | else | ||
1470 | { | ||
1471 | return src.Remove(0,end+1); | ||
1472 | } | ||
1473 | } | ||
1474 | else | ||
1475 | { | ||
1476 | if(start < src.Length) | ||
1477 | { | ||
1478 | return src.Remove(start); | ||
1479 | } | ||
1480 | else | ||
1481 | { | ||
1482 | return src; | ||
1483 | } | ||
1484 | } | ||
1346 | } | 1485 | } |
1347 | } | 1486 | } |
1348 | 1487 | ||
1349 | 1488 | /// <summary> | |
1350 | public string llInsertString(string dst, int position, string src) | 1489 | /// Insert string inserts the specified string identified by src |
1490 | /// at the index indicated by index. Index may be negative, in | ||
1491 | /// which case it is end-relative. The index may exceed either | ||
1492 | /// string bound, with the result being a concatenation. | ||
1493 | /// </summary> | ||
1494 | |||
1495 | public string llInsertString(string dest, int index, string src) | ||
1351 | { | 1496 | { |
1497 | |||
1352 | m_host.AddScriptLPS(1); | 1498 | m_host.AddScriptLPS(1); |
1353 | return dst.Insert(position, src); | ||
1354 | } | ||
1355 | 1499 | ||
1500 | // Normalize indices (if negative). | ||
1501 | // After normlaization they may still be | ||
1502 | // negative, but that is now relative to | ||
1503 | // the start, rather than the end, of the | ||
1504 | // sequence. | ||
1505 | if (index < 0) | ||
1506 | { | ||
1507 | index = dest.Length+index; | ||
1508 | |||
1509 | // Negative now means it is less than the lower | ||
1510 | // bound of the string. | ||
1511 | |||
1512 | if(index < 0) | ||
1513 | { | ||
1514 | return src+dest; | ||
1515 | } | ||
1516 | |||
1517 | } | ||
1518 | |||
1519 | if(index >= dest.Length) | ||
1520 | { | ||
1521 | return dest+src; | ||
1522 | } | ||
1523 | |||
1524 | // The index is in bounds. | ||
1525 | // In this case the index refers to the index that will | ||
1526 | // be assigned to the first character of the inserted string. | ||
1527 | // So unlike the other string operations, we do not add one | ||
1528 | // to get the correct string length. | ||
1529 | return dest.Substring(0,index)+src+dest.Substring(index); | ||
1530 | |||
1531 | } | ||
1532 | |||
1356 | public string llToUpper(string src) | 1533 | public string llToUpper(string src) |
1357 | { | 1534 | { |
1358 | m_host.AddScriptLPS(1); | 1535 | m_host.AddScriptLPS(1); |
@@ -2176,7 +2353,7 @@ namespace OpenSim.Region.ScriptEngine.Common | |||
2176 | public string llGetScriptName() | 2353 | public string llGetScriptName() |
2177 | { | 2354 | { |
2178 | 2355 | ||
2179 | string result = null; | 2356 | string result = String.Empty; |
2180 | 2357 | ||
2181 | m_host.AddScriptLPS(1); | 2358 | m_host.AddScriptLPS(1); |
2182 | 2359 | ||
@@ -2184,7 +2361,7 @@ namespace OpenSim.Region.ScriptEngine.Common | |||
2184 | { | 2361 | { |
2185 | if(item.Type == 10 && item.ItemID == m_itemID) | 2362 | if(item.Type == 10 && item.ItemID == m_itemID) |
2186 | { | 2363 | { |
2187 | result = item.Name; | 2364 | result = item.Name!=null?item.Name:String.Empty; |
2188 | break; | 2365 | break; |
2189 | } | 2366 | } |
2190 | } | 2367 | } |
@@ -2244,19 +2421,19 @@ namespace OpenSim.Region.ScriptEngine.Common | |||
2244 | m_host.AddScriptLPS(1); | 2421 | m_host.AddScriptLPS(1); |
2245 | foreach (KeyValuePair<LLUUID, TaskInventoryItem> inv in m_host.TaskInventory) | 2422 | foreach (KeyValuePair<LLUUID, TaskInventoryItem> inv in m_host.TaskInventory) |
2246 | { | 2423 | { |
2247 | if(inv.Value.Name == name) | 2424 | if(inv.Value.Name == name) |
2248 | { | 2425 | { |
2249 | if((inv.Value.OwnerMask & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) | 2426 | if((inv.Value.OwnerMask & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) |
2250 | { | 2427 | { |
2251 | return inv.Value.AssetID.ToString(); | 2428 | return inv.Value.AssetID.ToString(); |
2252 | } | 2429 | } |
2253 | else | 2430 | else |
2254 | { | 2431 | { |
2255 | return LLUUID.Zero.ToString(); | 2432 | return LLUUID.Zero.ToString(); |
2256 | } | 2433 | } |
2257 | } | 2434 | } |
2258 | } | 2435 | } |
2259 | return LLUUID.Zero.ToString(); | 2436 | return LLUUID.Zero.ToString(); |
2260 | } | 2437 | } |
2261 | 2438 | ||
2262 | public void llAllowInventoryDrop(int add) | 2439 | public void llAllowInventoryDrop(int add) |
@@ -2900,13 +3077,13 @@ namespace OpenSim.Region.ScriptEngine.Common | |||
2900 | public string llGetObjectName() | 3077 | public string llGetObjectName() |
2901 | { | 3078 | { |
2902 | m_host.AddScriptLPS(1); | 3079 | m_host.AddScriptLPS(1); |
2903 | return m_host.Name; | 3080 | return m_host.Name!=null?m_host.Name:String.Empty; |
2904 | } | 3081 | } |
2905 | 3082 | ||
2906 | public void llSetObjectName(string name) | 3083 | public void llSetObjectName(string name) |
2907 | { | 3084 | { |
2908 | m_host.AddScriptLPS(1); | 3085 | m_host.AddScriptLPS(1); |
2909 | m_host.Name = name; | 3086 | m_host.Name = name!=null?name:String.Empty; |
2910 | } | 3087 | } |
2911 | 3088 | ||
2912 | public string llGetDate() | 3089 | public string llGetDate() |
@@ -3759,13 +3936,13 @@ namespace OpenSim.Region.ScriptEngine.Common | |||
3759 | 3936 | ||
3760 | public string llGetObjectDesc() | 3937 | public string llGetObjectDesc() |
3761 | { | 3938 | { |
3762 | return m_host.Description; | 3939 | return m_host.Description!=null?m_host.Description:String.Empty; |
3763 | } | 3940 | } |
3764 | 3941 | ||
3765 | public void llSetObjectDesc(string desc) | 3942 | public void llSetObjectDesc(string desc) |
3766 | { | 3943 | { |
3767 | m_host.AddScriptLPS(1); | 3944 | m_host.AddScriptLPS(1); |
3768 | m_host.Description = desc; | 3945 | m_host.Description = desc!=null?desc:String.Empty; |
3769 | } | 3946 | } |
3770 | 3947 | ||
3771 | public string llGetCreator() | 3948 | public string llGetCreator() |