HttpHandler.fortunes.cs 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. 
  2. using BeetleX.Light.Memory;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Globalization;
  6. using System.Text;
  7. using System.Text.Encodings.Web;
  8. using System.Text.Unicode;
  9. using System.Threading.Tasks;
  10. namespace PlatformBenchmarks
  11. {
  12. public partial class HttpHandler
  13. {
  14. static readonly HtmlEncoder htmlEncoder = CreateHtmlEncoder();
  15. static HtmlEncoder CreateHtmlEncoder()
  16. {
  17. var settings = new TextEncoderSettings(UnicodeRanges.BasicLatin, UnicodeRanges.Katakana, UnicodeRanges.Hiragana);
  18. settings.AllowCharacter('\u2014'); // allow EM DASH through
  19. return HtmlEncoder.Create(settings);
  20. }
  21. private readonly static AsciiString _fortunesTableStart = "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>";
  22. private readonly static AsciiString _fortunesRowStart = "<tr><td>";
  23. private readonly static AsciiString _fortunesColumn = "</td><td>";
  24. private readonly static AsciiString _fortunesRowEnd = "</td></tr>";
  25. private readonly static AsciiString _fortunesTableEnd = "</table></body></html>";
  26. public async Task fortunes(IStreamWriter stream)
  27. {
  28. ContentLengthMemory content = new ContentLengthMemory();
  29. try
  30. {
  31. var data = await this._db.LoadFortunesRows();
  32. stream.Write(_HtmlResultPreamble.Data, 0, _HtmlResultPreamble.Length);
  33. content.Data = GetContentLengthMemory(stream);
  34. GMTDate.Default.Write(stream);
  35. stream.WriteSequenceNetStream.StartWriteLength();
  36. stream.Write(_fortunesTableStart.Data, 0, _fortunesTableStart.Length);
  37. foreach (var item in data)
  38. {
  39. stream.Write(_fortunesRowStart.Data, 0, _fortunesRowStart.Length);
  40. stream.WriteString(item.Id.ToString(CultureInfo.InvariantCulture));
  41. stream.Write(_fortunesColumn.Data, 0, _fortunesColumn.Length);
  42. stream.WriteString(htmlEncoder.Encode(item.Message));
  43. stream.Write(_fortunesRowEnd.Data, 0, _fortunesRowEnd.Length);
  44. }
  45. stream.Write(_fortunesTableEnd.Data, 0, _fortunesTableEnd.Length);
  46. }
  47. catch (Exception e_)
  48. {
  49. Context.GetLoger(BeetleX.Light.Logs.LogLevel.Error)?.WriteException(Context, "PlatformBenchmarks", "fortunes", e_);
  50. stream.WriteString(e_.Message);
  51. }
  52. var len = stream.WriteSequenceNetStream.EndWriteLength();
  53. content.Full(len);
  54. }
  55. internal void WriteNumeric(IStreamWriter stream, uint number)
  56. {
  57. const byte AsciiDigitStart = (byte)'0';
  58. if (number < 10)
  59. {
  60. stream.WriteByte((byte)(number + AsciiDigitStart));
  61. }
  62. else if (number < 100)
  63. {
  64. var tens = (byte)((number * 205u) >> 11); // div10, valid to 1028
  65. var span = new byte[2];
  66. span[0] = (byte)(tens + AsciiDigitStart);
  67. span[1] = (byte)(number - (tens * 10) + AsciiDigitStart);
  68. stream.Write(span, 0, 2);
  69. }
  70. else if (number < 1000)
  71. {
  72. var digit0 = (byte)((number * 41u) >> 12); // div100, valid to 1098
  73. var digits01 = (byte)((number * 205u) >> 11); // div10, valid to 1028
  74. var span = new byte[3];
  75. span[0] = (byte)(digit0 + AsciiDigitStart);
  76. span[1] = (byte)(digits01 - (digit0 * 10) + AsciiDigitStart);
  77. span[2] = (byte)(number - (digits01 * 10) + AsciiDigitStart);
  78. stream.Write(span, 0, 3);
  79. }
  80. }
  81. }
  82. }