Converters.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include "Converters.h"
  2. #include "nsIStringStream.h"
  3. #include "nsCOMPtr.h"
  4. #include "nsComponentManagerUtils.h"
  5. #include <stdio.h>
  6. //////////////////////////////////////////////////
  7. // TestConverter
  8. //////////////////////////////////////////////////
  9. #define NS_TESTCONVERTER_CID \
  10. { /* B8A067B0-4450-11d3-A16E-0050041CAF44 */ \
  11. 0xb8a067b0, \
  12. 0x4450, \
  13. 0x11d3, \
  14. {0xa1, 0x6e, 0x00, 0x50, 0x04, 0x1c, 0xaf, 0x44} \
  15. }
  16. NS_DEFINE_CID(kTestConverterCID, NS_TESTCONVERTER_CID);
  17. NS_IMPL_ISUPPORTS(TestConverter,
  18. nsIStreamConverter,
  19. nsIStreamListener,
  20. nsIRequestObserver)
  21. TestConverter::TestConverter() {
  22. }
  23. // Convert aFromStream (of type aFromType), to _retval (nsIInputStream of type aToType).
  24. // This Convert method simply converts the stream byte-by-byte, to the first character
  25. // in the aToType "string".
  26. NS_IMETHODIMP
  27. TestConverter::Convert(nsIInputStream *aFromStream,
  28. const char *aFromType,
  29. const char *aToType,
  30. nsISupports *ctxt,
  31. nsIInputStream **_retval) {
  32. char buf[1024+1];
  33. uint32_t read;
  34. nsresult rv = aFromStream->Read(buf, 1024, &read);
  35. if (NS_FAILED(rv) || read == 0) return rv;
  36. // verify that the data we're converting matches the from type
  37. // if it doesn't then we're being handed the wrong data.
  38. char fromChar = *aFromType;
  39. if (fromChar != buf[0]) {
  40. printf("We're receiving %c, but are supposed to have %c.\n", buf[0], fromChar);
  41. return NS_ERROR_FAILURE;
  42. }
  43. // Get the first character
  44. char toChar = *aToType;
  45. for (uint32_t i = 0; i < read; i++)
  46. buf[i] = toChar;
  47. buf[read] = '\0';
  48. nsCOMPtr<nsIStringInputStream> str
  49. (do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv));
  50. NS_ENSURE_SUCCESS(rv, rv);
  51. rv = str->SetData(buf, read);
  52. NS_ENSURE_SUCCESS(rv, rv);
  53. NS_ADDREF(*_retval = str);
  54. return NS_OK;
  55. }
  56. /* This method initializes any internal state before the stream converter
  57. * begins asynchronous conversion */
  58. NS_IMETHODIMP
  59. TestConverter::AsyncConvertData(const char *aFromType,
  60. const char *aToType,
  61. nsIStreamListener *aListener,
  62. nsISupports *ctxt) {
  63. NS_ASSERTION(aListener, "null listener");
  64. mListener = aListener;
  65. // based on these types, setup internal state to handle the appropriate conversion.
  66. fromType = aFromType;
  67. toType = aToType;
  68. return NS_OK;
  69. }
  70. // nsIStreamListener method
  71. /* This method handles asyncronous conversion of data. */
  72. NS_IMETHODIMP
  73. TestConverter::OnDataAvailable(nsIRequest* request,
  74. nsISupports *ctxt,
  75. nsIInputStream *inStr,
  76. uint64_t sourceOffset,
  77. uint32_t count) {
  78. nsresult rv;
  79. nsCOMPtr<nsIInputStream> convertedStream;
  80. // just make a syncronous call to the Convert() method.
  81. // Anything can happen here, I just happen to be using the sync call to
  82. // do the actual conversion.
  83. rv = Convert(inStr, fromType.get(), toType.get(), ctxt, getter_AddRefs(convertedStream));
  84. if (NS_FAILED(rv)) return rv;
  85. uint64_t len = 0;
  86. convertedStream->Available(&len);
  87. uint64_t offset = sourceOffset;
  88. while (len > 0) {
  89. uint32_t count = saturated(len);
  90. rv = mListener->OnDataAvailable(request, ctxt, convertedStream, offset, count);
  91. if (NS_FAILED(rv)) return rv;
  92. offset += count;
  93. len -= count;
  94. }
  95. return NS_OK;
  96. }
  97. // nsIRequestObserver methods
  98. /* These methods just pass through directly to the mListener */
  99. NS_IMETHODIMP
  100. TestConverter::OnStartRequest(nsIRequest* request, nsISupports *ctxt) {
  101. return mListener->OnStartRequest(request, ctxt);
  102. }
  103. NS_IMETHODIMP
  104. TestConverter::OnStopRequest(nsIRequest* request, nsISupports *ctxt,
  105. nsresult aStatus) {
  106. return mListener->OnStopRequest(request, ctxt, aStatus);
  107. }
  108. nsresult
  109. CreateTestConverter(nsISupports* aOuter, REFNSIID aIID, void** aResult)
  110. {
  111. nsCOMPtr<nsISupports> conv = new TestConverter();
  112. return conv->QueryInterface(aIID, aResult);
  113. }