aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Util.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Util.cs')
-rw-r--r--OpenSim/Framework/Util.cs284
1 files changed, 243 insertions, 41 deletions
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index a5f798d..4dafaef 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -61,6 +61,15 @@ namespace OpenSim.Framework
61 public enum PermissionMask : uint 61 public enum PermissionMask : uint
62 { 62 {
63 None = 0, 63 None = 0,
64
65 // folded perms
66 foldedTransfer = 1,
67 foldedModify = 1 << 1,
68 foldedCopy = 1 << 2,
69
70 foldedMask = 0x07,
71
72 //
64 Transfer = 1 << 13, 73 Transfer = 1 << 13,
65 Modify = 1 << 14, 74 Modify = 1 << 14,
66 Copy = 1 << 15, 75 Copy = 1 << 15,
@@ -131,10 +140,14 @@ namespace OpenSim.Framework
131 140
132 public static readonly int MAX_THREADPOOL_LEVEL = 3; 141 public static readonly int MAX_THREADPOOL_LEVEL = 3;
133 142
143 public static double TimeStampClockPeriodMS;
144
134 static Util() 145 static Util()
135 { 146 {
136 LogThreadPool = 0; 147 LogThreadPool = 0;
137 LogOverloads = true; 148 LogOverloads = true;
149 TimeStampClockPeriodMS = 1000.0D / (double)Stopwatch.Frequency;
150 m_log.InfoFormat("[UTIL] TimeStamp clock with period of {0}ms", Math.Round(TimeStampClockPeriodMS,6,MidpointRounding.AwayFromZero));
138 } 151 }
139 152
140 private static uint nextXferID = 5000; 153 private static uint nextXferID = 5000;
@@ -267,14 +280,12 @@ namespace OpenSim.Framework
267 /// </summary> 280 /// </summary>
268 /// <param name="a">A 3d vector</param> 281 /// <param name="a">A 3d vector</param>
269 /// <returns>A new vector which is normalized form of the vector</returns> 282 /// <returns>A new vector which is normalized form of the vector</returns>
270 /// <remarks>The vector paramater cannot be <0,0,0></remarks> 283
271 public static Vector3 GetNormalizedVector(Vector3 a) 284 public static Vector3 GetNormalizedVector(Vector3 a)
272 { 285 {
273 if (IsZeroVector(a)) 286 Vector3 v = new Vector3(a.X, a.Y, a.Z);
274 throw new ArgumentException("Vector paramater cannot be a zero vector."); 287 v.Normalize();
275 288 return v;
276 float Mag = (float) GetMagnitude(a);
277 return new Vector3(a.X / Mag, a.Y / Mag, a.Z / Mag);
278 } 289 }
279 290
280 /// <summary> 291 /// <summary>
@@ -641,19 +652,25 @@ namespace OpenSim.Framework
641 /// </summary> 652 /// </summary>
642 /// <param name="data"></param> 653 /// <param name="data"></param>
643 /// <returns></returns> 654 /// <returns></returns>
655
644 public static string Md5Hash(string data) 656 public static string Md5Hash(string data)
645 { 657 {
646 byte[] dataMd5 = ComputeMD5Hash(data); 658 return Md5Hash(data, Encoding.Default);
659 }
660
661 public static string Md5Hash(string data, Encoding encoding)
662 {
663 byte[] dataMd5 = ComputeMD5Hash(data, encoding);
647 StringBuilder sb = new StringBuilder(); 664 StringBuilder sb = new StringBuilder();
648 for (int i = 0; i < dataMd5.Length; i++) 665 for (int i = 0; i < dataMd5.Length; i++)
649 sb.AppendFormat("{0:x2}", dataMd5[i]); 666 sb.AppendFormat("{0:x2}", dataMd5[i]);
650 return sb.ToString(); 667 return sb.ToString();
651 } 668 }
652 669
653 private static byte[] ComputeMD5Hash(string data) 670 private static byte[] ComputeMD5Hash(string data, Encoding encoding)
654 { 671 {
655 MD5 md5 = MD5.Create(); 672 MD5 md5 = MD5.Create();
656 return md5.ComputeHash(Encoding.Default.GetBytes(data)); 673 return md5.ComputeHash(encoding.GetBytes(data));
657 } 674 }
658 675
659 /// <summary> 676 /// <summary>
@@ -661,6 +678,12 @@ namespace OpenSim.Framework
661 /// </summary> 678 /// </summary>
662 /// <param name="data"></param> 679 /// <param name="data"></param>
663 /// <returns></returns> 680 /// <returns></returns>
681
682 public static string SHA1Hash(string data, Encoding enc)
683 {
684 return SHA1Hash(enc.GetBytes(data));
685 }
686
664 public static string SHA1Hash(string data) 687 public static string SHA1Hash(string data)
665 { 688 {
666 return SHA1Hash(Encoding.Default.GetBytes(data)); 689 return SHA1Hash(Encoding.Default.GetBytes(data));
@@ -714,17 +737,26 @@ namespace OpenSim.Framework
714 /// <param name="oldy">Old region y-coord</param> 737 /// <param name="oldy">Old region y-coord</param>
715 /// <param name="newy">New region y-coord</param> 738 /// <param name="newy">New region y-coord</param>
716 /// <returns></returns> 739 /// <returns></returns>
717 public static bool IsOutsideView(float drawdist, uint oldx, uint newx, uint oldy, uint newy) 740 public static bool IsOutsideView(float drawdist, uint oldx, uint newx, uint oldy, uint newy,
741 int oldsizex, int oldsizey, int newsizex, int newsizey)
718 { 742 {
719 int dd = (int)((drawdist + Constants.RegionSize - 1) / Constants.RegionSize); 743 // we still need to make sure we see new region 1stNeighbors
720 744
721 int startX = (int)oldx - dd; 745 oldx *= Constants.RegionSize;
722 int startY = (int)oldy - dd; 746 newx *= Constants.RegionSize;
747 if (oldx + oldsizex + drawdist < newx)
748 return true;
749 if (newx + newsizex + drawdist < oldx)
750 return true;
723 751
724 int endX = (int)oldx + dd; 752 oldy *= Constants.RegionSize;
725 int endY = (int)oldy + dd; 753 newy *= Constants.RegionSize;
754 if (oldy + oldsizey + drawdist < newy)
755 return true;
756 if (newy + newsizey + drawdist< oldy)
757 return true;
726 758
727 return (newx < startX || endX < newx || newy < startY || endY < newy); 759 return false;
728 } 760 }
729 761
730 public static string FieldToString(byte[] bytes) 762 public static string FieldToString(byte[] bytes)
@@ -805,6 +837,16 @@ namespace OpenSim.Framework
805 } 837 }
806 838
807 /// <summary> 839 /// <summary>
840 /// Converts a URL to a IPAddress
841 /// </summary>
842 /// <param name="url">URL Standard Format</param>
843 /// <returns>A resolved IP Address</returns>
844 public static IPAddress GetHostFromURL(string url)
845 {
846 return GetHostFromDNS(url.Split(new char[] {'/', ':'})[3]);
847 }
848
849 /// <summary>
808 /// Returns a IP address from a specified DNS, favouring IPv4 addresses. 850 /// Returns a IP address from a specified DNS, favouring IPv4 addresses.
809 /// </summary> 851 /// </summary>
810 /// <param name="dnsAddress">DNS Hostname</param> 852 /// <param name="dnsAddress">DNS Hostname</param>
@@ -1065,6 +1107,25 @@ namespace OpenSim.Framework
1065 } 1107 }
1066 } 1108 }
1067 1109
1110 public static string GetConfigVarWithDefaultSection(IConfigSource config, string varname, string section)
1111 {
1112 // First, check the Startup section, the default section
1113 IConfig cnf = config.Configs["Startup"];
1114 if (cnf == null)
1115 return string.Empty;
1116 string val = cnf.GetString(varname, string.Empty);
1117
1118 // Then check for an overwrite of the default in the given section
1119 if (!string.IsNullOrEmpty(section))
1120 {
1121 cnf = config.Configs[section];
1122 if (cnf != null)
1123 val = cnf.GetString(varname, val);
1124 }
1125
1126 return val;
1127 }
1128
1068 /// <summary> 1129 /// <summary>
1069 /// Gets the value of a configuration variable by looking into 1130 /// Gets the value of a configuration variable by looking into
1070 /// multiple sections in order. The latter sections overwrite 1131 /// multiple sections in order. The latter sections overwrite
@@ -1388,6 +1449,46 @@ namespace OpenSim.Framework
1388 return ret; 1449 return ret;
1389 } 1450 }
1390 1451
1452 public static string Compress(string text)
1453 {
1454 byte[] buffer = Util.UTF8.GetBytes(text);
1455 MemoryStream memory = new MemoryStream();
1456 using (GZipStream compressor = new GZipStream(memory, CompressionMode.Compress, true))
1457 {
1458 compressor.Write(buffer, 0, buffer.Length);
1459 }
1460
1461 memory.Position = 0;
1462
1463 byte[] compressed = new byte[memory.Length];
1464 memory.Read(compressed, 0, compressed.Length);
1465
1466 byte[] compressedBuffer = new byte[compressed.Length + 4];
1467 Buffer.BlockCopy(compressed, 0, compressedBuffer, 4, compressed.Length);
1468 Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, compressedBuffer, 0, 4);
1469 return Convert.ToBase64String(compressedBuffer);
1470 }
1471
1472 public static string Decompress(string compressedText)
1473 {
1474 byte[] compressedBuffer = Convert.FromBase64String(compressedText);
1475 using (MemoryStream memory = new MemoryStream())
1476 {
1477 int msgLength = BitConverter.ToInt32(compressedBuffer, 0);
1478 memory.Write(compressedBuffer, 4, compressedBuffer.Length - 4);
1479
1480 byte[] buffer = new byte[msgLength];
1481
1482 memory.Position = 0;
1483 using (GZipStream decompressor = new GZipStream(memory, CompressionMode.Decompress))
1484 {
1485 decompressor.Read(buffer, 0, buffer.Length);
1486 }
1487
1488 return Util.UTF8.GetString(buffer);
1489 }
1490 }
1491
1391 /// <summary> 1492 /// <summary>
1392 /// Copy data from one stream to another, leaving the read position of both streams at the beginning. 1493 /// Copy data from one stream to another, leaving the read position of both streams at the beginning.
1393 /// </summary> 1494 /// </summary>
@@ -1524,19 +1625,19 @@ namespace OpenSim.Framework
1524 { 1625 {
1525 string os = String.Empty; 1626 string os = String.Empty;
1526 1627
1527 if (Environment.OSVersion.Platform != PlatformID.Unix) 1628// if (Environment.OSVersion.Platform != PlatformID.Unix)
1528 { 1629// {
1529 os = Environment.OSVersion.ToString(); 1630// os = Environment.OSVersion.ToString();
1530 } 1631// }
1531 else 1632// else
1532 { 1633// {
1533 os = ReadEtcIssue(); 1634// os = ReadEtcIssue();
1534 } 1635// }
1535 1636//
1536 if (os.Length > 45) 1637// if (os.Length > 45)
1537 { 1638// {
1538 os = os.Substring(0, 45); 1639// os = os.Substring(0, 45);
1539 } 1640// }
1540 1641
1541 return os; 1642 return os;
1542 } 1643 }
@@ -1645,7 +1746,7 @@ namespace OpenSim.Framework
1645 1746
1646 public static Guid GetHashGuid(string data, string salt) 1747 public static Guid GetHashGuid(string data, string salt)
1647 { 1748 {
1648 byte[] hash = ComputeMD5Hash(data + salt); 1749 byte[] hash = ComputeMD5Hash(data + salt, Encoding.Default);
1649 1750
1650 //string s = BitConverter.ToString(hash); 1751 //string s = BitConverter.ToString(hash);
1651 1752
@@ -1792,6 +1893,32 @@ namespace OpenSim.Framework
1792 return found.ToArray(); 1893 return found.ToArray();
1793 } 1894 }
1794 1895
1896 public static string ServerURI(string uri)
1897 {
1898 if (uri == string.Empty)
1899 return string.Empty;
1900
1901 // Get rid of eventual slashes at the end
1902 uri = uri.TrimEnd('/');
1903
1904 IPAddress ipaddr1 = null;
1905 string port1 = "";
1906 try
1907 {
1908 ipaddr1 = Util.GetHostFromURL(uri);
1909 }
1910 catch { }
1911
1912 try
1913 {
1914 port1 = uri.Split(new char[] { ':' })[2];
1915 }
1916 catch { }
1917
1918 // We tried our best to convert the domain names to IP addresses
1919 return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri;
1920 }
1921
1795 /// <summary> 1922 /// <summary>
1796 /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary. 1923 /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary.
1797 /// </summary> 1924 /// </summary>
@@ -1818,17 +1945,26 @@ namespace OpenSim.Framework
1818 /// <returns></returns> 1945 /// <returns></returns>
1819 public static byte[] StringToBytes256(string str) 1946 public static byte[] StringToBytes256(string str)
1820 { 1947 {
1821 if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } 1948 if (String.IsNullOrEmpty(str))
1822 if (str.Length > 254) str = str.Remove(254); 1949 return Utils.EmptyBytes;
1823 if (!str.EndsWith("\0")) { str += "\0"; } 1950
1951 if (!str.EndsWith("\0"))
1952 str += "\0";
1824 1953
1825 // Because this is UTF-8 encoding and not ASCII, it's possible we 1954 // Because this is UTF-8 encoding and not ASCII, it's possible we
1826 // might have gotten an oversized array even after the string trim 1955 // might have gotten an oversized array even after the string trim
1827 byte[] data = UTF8.GetBytes(str); 1956 byte[] data = UTF8.GetBytes(str);
1957
1828 if (data.Length > 256) 1958 if (data.Length > 256)
1829 { 1959 {
1830 Array.Resize<byte>(ref data, 256); 1960 int cut = 255;
1831 data[255] = 0; 1961 if((data[cut] & 0x80 ) != 0 )
1962 {
1963 while(cut > 0 && (data[cut] & 0xc0) != 0xc0)
1964 cut--;
1965 }
1966 Array.Resize<byte>(ref data, cut + 1);
1967 data[cut] = 0;
1832 } 1968 }
1833 1969
1834 return data; 1970 return data;
@@ -1860,23 +1996,82 @@ namespace OpenSim.Framework
1860 /// <returns></returns> 1996 /// <returns></returns>
1861 public static byte[] StringToBytes1024(string str) 1997 public static byte[] StringToBytes1024(string str)
1862 { 1998 {
1863 if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } 1999 if (String.IsNullOrEmpty(str))
1864 if (str.Length > 1023) str = str.Remove(1023); 2000 return Utils.EmptyBytes;
1865 if (!str.EndsWith("\0")) { str += "\0"; } 2001
2002 if (!str.EndsWith("\0"))
2003 str += "\0";
1866 2004
1867 // Because this is UTF-8 encoding and not ASCII, it's possible we 2005 // Because this is UTF-8 encoding and not ASCII, it's possible we
1868 // might have gotten an oversized array even after the string trim 2006 // might have gotten an oversized array even after the string trim
1869 byte[] data = UTF8.GetBytes(str); 2007 byte[] data = UTF8.GetBytes(str);
2008
1870 if (data.Length > 1024) 2009 if (data.Length > 1024)
1871 { 2010 {
1872 Array.Resize<byte>(ref data, 1024); 2011 int cut = 1023;
1873 data[1023] = 0; 2012 if((data[cut] & 0x80 ) != 0 )
2013 {
2014 while(cut > 0 && (data[cut] & 0xc0) != 0xc0)
2015 cut--;
2016 }
2017 Array.Resize<byte>(ref data, cut + 1);
2018 data[cut] = 0;
1874 } 2019 }
1875 2020
1876 return data; 2021 return data;
1877 } 2022 }
1878 2023
1879 /// <summary> 2024 /// <summary>
2025 /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to MaxLength bytes if necessary.
2026 /// </summary>
2027 /// <param name="str">
2028 /// If null or empty, then an bytes[0] is returned.
2029 /// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
2030 /// </param>
2031 /// <param name="args">
2032 /// Arguments to substitute into the string via the {} mechanism.
2033 /// </param>
2034 /// <returns></returns>
2035 public static byte[] StringToBytes(string str, int MaxLength, params object[] args)
2036 {
2037 return StringToBytes1024(string.Format(str, args), MaxLength);
2038 }
2039
2040 /// <summary>
2041 /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to MaxLength bytes if necessary.
2042 /// </summary>
2043 /// <param name="str">
2044 /// If null or empty, then an bytes[0] is returned.
2045 /// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
2046 /// </param>
2047 /// <returns></returns>
2048 public static byte[] StringToBytes(string str, int MaxLength)
2049 {
2050 if (String.IsNullOrEmpty(str))
2051 return Utils.EmptyBytes;
2052
2053 if (!str.EndsWith("\0"))
2054 str += "\0";
2055
2056 // Because this is UTF-8 encoding and not ASCII, it's possible we
2057 // might have gotten an oversized array even after the string trim
2058 byte[] data = UTF8.GetBytes(str);
2059
2060 if (data.Length > MaxLength)
2061 {
2062 int cut = MaxLength -1 ;
2063 if((data[cut] & 0x80 ) != 0 )
2064 {
2065 while(cut > 0 && (data[cut] & 0xc0) != 0xc0)
2066 cut--;
2067 }
2068 Array.Resize<byte>(ref data, cut + 1);
2069 data[cut] = 0;
2070 }
2071
2072 return data;
2073 }
2074 /// <summary>
1880 /// Pretty format the hashtable contents to a single line. 2075 /// Pretty format the hashtable contents to a single line.
1881 /// </summary> 2076 /// </summary>
1882 /// <remarks> 2077 /// <remarks>
@@ -1986,7 +2181,7 @@ namespace OpenSim.Framework
1986 2181
1987 STPStartInfo startInfo = new STPStartInfo(); 2182 STPStartInfo startInfo = new STPStartInfo();
1988 startInfo.ThreadPoolName = "Util"; 2183 startInfo.ThreadPoolName = "Util";
1989 startInfo.IdleTimeout = 2000; 2184 startInfo.IdleTimeout = 20000;
1990 startInfo.MaxWorkerThreads = maxThreads; 2185 startInfo.MaxWorkerThreads = maxThreads;
1991 startInfo.MinWorkerThreads = minThreads; 2186 startInfo.MinWorkerThreads = minThreads;
1992 2187
@@ -2539,6 +2734,13 @@ namespace OpenSim.Framework
2539 return tcA - tcB; 2734 return tcA - tcB;
2540 } 2735 }
2541 2736
2737 // returns a timestamp in ms as double
2738 // using the time resolution avaiable to StopWatch
2739 public static double GetTimeStampMS()
2740 {
2741 return (double)Stopwatch.GetTimestamp() * TimeStampClockPeriodMS;
2742 }
2743
2542 /// <summary> 2744 /// <summary>
2543 /// Formats a duration (given in milliseconds). 2745 /// Formats a duration (given in milliseconds).
2544 /// </summary> 2746 /// </summary>