ExtensionMethods.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using System.Linq;
  3. using System.Net;
  4. using System.Net.Sockets;
  5. using System.Text;
  6. namespace UdPunching
  7. {
  8. public static class ExtensionMethods
  9. {
  10. private static readonly DateTime UnixTimeStampOrig = new DateTime(1970, 1, 1);
  11. public static bool IpEndPointEqualsTo(this EndPoint me, EndPoint another)
  12. {
  13. if (me is IPEndPoint ipMe && another is IPEndPoint ipAnother)
  14. return ipMe.Port == ipAnother.Port && ipMe.Address.Equals(ipAnother.Address);
  15. return false;
  16. }
  17. public static int ToUnixTimeStamp(this DateTime me)
  18. {
  19. return (int)me.ToUniversalTime().Subtract(UnixTimeStampOrig).TotalSeconds;
  20. }
  21. public static int ReadUnixTimeStamp(this byte[] buf, int index, out DateTime timeStamp)
  22. {
  23. var i32 = buf.ToLeInt32(index);
  24. timeStamp = UnixTimeStampOrig.AddSeconds(i32).ToLocalTime();
  25. return 4;
  26. }
  27. public static int ReadIpEndPoint(this byte[] buf, int index, out IPEndPoint ipEndPoint)
  28. {
  29. var strAddress = buf.GetAsciiString(15, index);
  30. var port = buf.GetLeInt16(index + 15);
  31. ipEndPoint = new IPEndPoint(IPAddress.Parse(strAddress.Trim()), port);
  32. return 17;
  33. }
  34. public static IPEndPoint ParseToIpEndPointV4(this string str)
  35. {
  36. var parts = str.Split(':');
  37. if (2 != parts.Length) throw new ArgumentException("invalid addr port parts");
  38. if (IPAddress.TryParse(parts[0], out var addr) && int.TryParse(parts[1], out var port)) return new IPEndPoint(addr, port);
  39. throw new FormatException("parse fail");
  40. }
  41. //--------- underlying -------------
  42. public static byte[] ToLeBytes(this int value)
  43. {
  44. return new[]
  45. {
  46. (byte)(value & 0xFF),
  47. (byte)((value>>8 ) & 0xFF),
  48. (byte)((value>>16) & 0xFF),
  49. (byte)((value>>24) & 0xFF),
  50. };
  51. }
  52. public static int ToLeInt32(this byte[] buf, int index)
  53. {
  54. return buf[index]
  55. | (buf[index + 1] << 8)
  56. | (buf[index + 2] << 16)
  57. | (buf[index + 3] << 24)
  58. ;
  59. }
  60. public static byte[] ToLe16Bytes(this int value)
  61. {
  62. return new[]
  63. {
  64. (byte)(value & 0xFF),
  65. (byte)((value>>8 ) & 0xFF),
  66. };
  67. }
  68. public static void ToLe16Bytes(this int value, byte[] buf, int index = 0)
  69. {
  70. buf[index] = (byte)(value & 0xFF);
  71. buf[index + 1] = (byte)((value >> 8) & 0xFF);
  72. }
  73. public static int GetLeInt16(this byte[] buf, int index)
  74. {
  75. return buf[index]
  76. | buf[index + 1] << 8
  77. ;
  78. }
  79. public static string ToPaddingString(this IPAddress ipAddress)
  80. {
  81. if (ipAddress.AddressFamily != AddressFamily.InterNetwork) throw new NotSupportedException("Only ipv4");
  82. return ipAddress.ToString().PadRight(15, ' ');
  83. }
  84. public static byte[] ToAsciiBytes(this string str) => Encoding.ASCII.GetBytes(str);
  85. public static void ToAsciiBytes(this string str, byte[] buf, int index = 0) => Encoding.ASCII.GetBytes(str, 0, str.Length, buf, index);
  86. public static string GetAsciiString(this byte[] buf, int count, int index = 0) => Encoding.ASCII.GetString(buf.Skip(index).Take(count).ToArray());
  87. }
  88. }