webview_data_stream_memory.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #include "webview/webview_data_stream_memory.h"
  8. #if !defined Q_OS_WIN && !defined Q_OS_MAC
  9. #include <sys/mman.h>
  10. #endif // !Q_OS_WIN && !Q_OS_MAC
  11. namespace Webview {
  12. DataStreamFromMemory::DataStreamFromMemory(
  13. QByteArray data,
  14. std::string mime)
  15. : _data(data)
  16. , _mime(mime) {
  17. #if !defined Q_OS_WIN && !defined Q_OS_MAC
  18. const auto handle = memfd_create("webview-data-stream", MFD_CLOEXEC);
  19. if (handle == -1) {
  20. return;
  21. }
  22. if (ftruncate(handle, data.size()) != 0) {
  23. close(handle);
  24. return;
  25. }
  26. const auto shared = mmap(
  27. nullptr,
  28. data.size(),
  29. PROT_READ | PROT_WRITE,
  30. MAP_SHARED,
  31. handle,
  32. 0);
  33. if (shared == MAP_FAILED) {
  34. close(handle);
  35. return;
  36. }
  37. memcpy(shared, data.constData(), data.size());
  38. _handle = handle;
  39. _data.setRawData((char*)shared, data.size());
  40. #endif // !Q_OS_WIN && !Q_OS_MAC
  41. }
  42. DataStreamFromMemory::~DataStreamFromMemory() {
  43. #if !defined Q_OS_WIN && !defined Q_OS_MAC
  44. if (_handle) {
  45. munmap((void*)_data.constData(), _data.size());
  46. close(_handle);
  47. }
  48. #endif // !Q_OS_WIN && !Q_OS_MAC
  49. }
  50. int DataStreamFromMemory::handle() {
  51. return _handle;
  52. }
  53. std::int64_t DataStreamFromMemory::size() {
  54. return _data.size();
  55. }
  56. std::string DataStreamFromMemory::mime() {
  57. return _mime;
  58. }
  59. std::int64_t DataStreamFromMemory::seek(
  60. int origin,
  61. std::int64_t position) {
  62. const auto length = size();
  63. switch (origin) {
  64. case SEEK_SET:
  65. return (position >= 0 && position <= length)
  66. ? ((_offset = position))
  67. : -1;
  68. case SEEK_CUR:
  69. return (_offset + position >= 0 && _offset + position <= length)
  70. ? ((_offset += position))
  71. : -1;
  72. case SEEK_END:
  73. return (length + position >= 0 && position <= 0)
  74. ? ((_offset = length + position))
  75. : -1;
  76. }
  77. return -1;
  78. }
  79. std::int64_t DataStreamFromMemory::read(
  80. void *buffer,
  81. std::int64_t requested) {
  82. if (requested < 0) {
  83. return -1;
  84. }
  85. const auto copy = std::min(std::int64_t(size() - _offset), requested);
  86. if (copy > 0) {
  87. memcpy(buffer, _data.constData() + _offset, copy);
  88. _offset += copy;
  89. }
  90. return copy;
  91. }
  92. } // namespace Webview