WebHeaderEncoding.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. using System.Text;
  2. namespace SocketHttpListener.Net
  3. {
  4. // we use this static class as a helper class to encode/decode HTTP headers.
  5. // what we need is a 1-1 correspondence between a char in the range U+0000-U+00FF
  6. // and a byte in the range 0x00-0xFF (which is the range that can hit the network).
  7. // The Latin-1 encoding (ISO-88591-1) (GetEncoding(28591)) works for byte[] to string, but is a little slow.
  8. // It doesn't work for string -> byte[] because of best-fit-mapping problems.
  9. internal static class WebHeaderEncoding
  10. {
  11. // We don't want '?' replacement characters, just fail.
  12. private static readonly Encoding s_utf8Decoder = Encoding.GetEncoding("utf-8", EncoderFallback.ExceptionFallback, DecoderFallback.ExceptionFallback);
  13. internal static unsafe string GetString(byte[] bytes, int byteIndex, int byteCount)
  14. {
  15. fixed (byte* pBytes = bytes)
  16. return GetString(pBytes + byteIndex, byteCount);
  17. }
  18. internal static unsafe string GetString(byte* pBytes, int byteCount)
  19. {
  20. if (byteCount < 1)
  21. return "";
  22. string s = new string('\0', byteCount);
  23. fixed (char* pStr = s)
  24. {
  25. char* pString = pStr;
  26. while (byteCount >= 8)
  27. {
  28. pString[0] = (char)pBytes[0];
  29. pString[1] = (char)pBytes[1];
  30. pString[2] = (char)pBytes[2];
  31. pString[3] = (char)pBytes[3];
  32. pString[4] = (char)pBytes[4];
  33. pString[5] = (char)pBytes[5];
  34. pString[6] = (char)pBytes[6];
  35. pString[7] = (char)pBytes[7];
  36. pString += 8;
  37. pBytes += 8;
  38. byteCount -= 8;
  39. }
  40. for (int i = 0; i < byteCount; i++)
  41. {
  42. pString[i] = (char)pBytes[i];
  43. }
  44. }
  45. return s;
  46. }
  47. internal static int GetByteCount(string myString)
  48. {
  49. return myString.Length;
  50. }
  51. internal static unsafe void GetBytes(string myString, int charIndex, int charCount, byte[] bytes, int byteIndex)
  52. {
  53. if (myString.Length == 0)
  54. {
  55. return;
  56. }
  57. fixed (byte* bufferPointer = bytes)
  58. {
  59. byte* newBufferPointer = bufferPointer + byteIndex;
  60. int finalIndex = charIndex + charCount;
  61. while (charIndex < finalIndex)
  62. {
  63. *newBufferPointer++ = (byte)myString[charIndex++];
  64. }
  65. }
  66. }
  67. internal static unsafe byte[] GetBytes(string myString)
  68. {
  69. byte[] bytes = new byte[myString.Length];
  70. if (myString.Length != 0)
  71. {
  72. GetBytes(myString, 0, myString.Length, bytes, 0);
  73. }
  74. return bytes;
  75. }
  76. }
  77. }