using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text;
[assembly: InternalsVisibleTo("UnityEditor.CacheServerTests")]
namespace UnityEditor.Build.CacheServer
{
internal static class Util
{
private const string IpAddressKey = "CacheServerIPAddress";
private static int ReverseByte(int b)
{
return ((b & 0x0F) << 4) | ((b >> 4) & 0x0F);
}
private static byte[] StringToByteArray(string input, bool asGuid)
{
var bytes = new byte[input.Length / 2];
for (var i = 0; i < input.Length; i += 2)
{
var b = Convert.ToByte(input.Substring(i, 2), 16);
bytes[i / 2] = asGuid ? (byte)ReverseByte(b) : b;
}
return bytes;
}
///
/// Convert a hex string to a byte array that represents an Asset Hash
///
/// 32 character hex string
/// byte array
public static byte[] StringToHash(string hashStr)
{
Debug.Assert(hashStr.Length == 32);
return StringToByteArray(hashStr, false);
}
///
/// Convert a hex string to a byte array that represents an Asset GUID
///
/// 32 character hex string
/// byte array
public static byte[] StringToGuid(string guidStr)
{
Debug.Assert(guidStr.Length == 32);
return StringToByteArray(guidStr, true);
}
///
/// Parse an ascii byte array at start as an int value
///
/// byte array
/// offset
///
public static int ReadUInt32(byte[] bytes, int index)
{
Debug.Assert(bytes.Length + index >= 8);
return Int32.Parse(Encoding.ASCII.GetString(bytes, index, 8), NumberStyles.HexNumber);
}
///
/// Encode an integer as an ascii byte array
///
/// integer
/// true ensure the byte array is as short as possible; false to pad to 8 bytes
///
public static byte[] EncodeInt32(int input, bool minLength = false)
{
return Encoding.ASCII.GetBytes(input.ToString(minLength ? "X" : "X8"));
}
///
/// Parse a subset of an ascii byte array as a long value
///
/// byte array
/// offset within to read from
///
public static long ReadUInt64(byte[] bytes, int index)
{
Debug.Assert(bytes.Length + index >= 16);
return Int64.Parse(Encoding.ASCII.GetString(bytes, index, 16), NumberStyles.HexNumber);
}
///
/// Encode a long value into an ascii byte array
///
/// long value
///
public static byte[] EncodeInt64(long input)
{
return Encoding.ASCII.GetBytes(input.ToString("X16"));
}
///
/// Compare two byte arrays for value equality
///
/// first array
/// second array
///
public static bool ByteArraysAreEqual(byte[] ar1, byte[] ar2)
{
return ar1.Length == ar2.Length && ByteArraysAreEqual(ar1, 0, ar2, 0, ar1.Length);
}
///
/// Compare two byte arrays for value equality at specific offsets and length
///
/// first array
/// offset within first array
/// second array
/// offset within second array
/// number of bytes to compare
///
public static bool ByteArraysAreEqual(byte[] ar1, int start1, byte[] ar2, int start2, int count)
{
Debug.Assert(start1 >= 0 && start2 >= 0 && count >= 0);
if (start1 + count > ar1.Length)
return false;
if (start2 + count > ar2.Length)
return false;
for (var i = 0; i < count; i++)
if (ar1[start1 + i] != ar2[start2 + i])
return false;
return true;
}
///
/// Retrieve the configured cache server address for the Unity Editor
///
public static string ConfigCacheServerAddress
{
get { return EditorPrefs.GetString(IpAddressKey); }
}
///
/// Parse an address string in the format of 'address:port' to a string address and integer port number
///
/// combined address string
/// address part
/// port part
public static void ParseCacheServerIpAddress(string address, out string host, out int port)
{
host = null;
port = 8126;
var parts = address.Split(':');
if (parts.Length > 0)
host = parts[0];
if (parts.Length > 1)
port = int.Parse(parts[1]);
}
}
}