AppletSession.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. using System;
  2. namespace Ryujinx.HLE.HOS.Services.Am.AppletAE
  3. {
  4. internal class AppletSession
  5. {
  6. private IAppletFifo<byte[]> _inputData;
  7. private IAppletFifo<byte[]> _outputData;
  8. public event EventHandler DataAvailable;
  9. public int Length
  10. {
  11. get { return _inputData.Count; }
  12. }
  13. public AppletSession()
  14. : this(new AppletFifo<byte[]>(),
  15. new AppletFifo<byte[]>())
  16. { }
  17. public AppletSession(
  18. IAppletFifo<byte[]> inputData,
  19. IAppletFifo<byte[]> outputData)
  20. {
  21. _inputData = inputData;
  22. _outputData = outputData;
  23. _inputData.DataAvailable += OnDataAvailable;
  24. }
  25. private void OnDataAvailable(object sender, EventArgs e)
  26. {
  27. DataAvailable?.Invoke(this, null);
  28. }
  29. public void Push(byte[] item)
  30. {
  31. if (!this.TryPush(item))
  32. {
  33. // TODO(jduncanator): Throw a proper exception
  34. throw new InvalidOperationException();
  35. }
  36. }
  37. public bool TryPush(byte[] item)
  38. {
  39. return _outputData.TryAdd(item);
  40. }
  41. public byte[] Pop()
  42. {
  43. if (this.TryPop(out byte[] item))
  44. {
  45. return item;
  46. }
  47. throw new InvalidOperationException("Input data empty.");
  48. }
  49. public bool TryPop(out byte[] item)
  50. {
  51. return _inputData.TryTake(out item);
  52. }
  53. /// <summary>
  54. /// This returns an AppletSession that can be used at the
  55. /// other end of the pipe. Pushing data into this new session
  56. /// will put it in the first session's input buffer, and vice
  57. /// versa.
  58. /// </summary>
  59. public AppletSession GetConsumer()
  60. {
  61. return new AppletSession(this._outputData, this._inputData);
  62. }
  63. }
  64. }