mem_buffer_util.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/fuchsia/mem_buffer_util.h"
  5. #include <lib/fdio/io.h>
  6. #include <lib/zx/vmo.h>
  7. #include <string>
  8. #include <utility>
  9. #include "base/files/file.h"
  10. #include "base/fuchsia/fuchsia_logging.h"
  11. #include "base/numerics/safe_conversions.h"
  12. #include "base/strings/string_piece.h"
  13. #include "base/strings/utf_string_conversions.h"
  14. namespace base {
  15. absl::optional<std::u16string> ReadUTF8FromVMOAsUTF16(
  16. const fuchsia::mem::Buffer& buffer) {
  17. absl::optional<std::string> output_utf8 = StringFromMemBuffer(buffer);
  18. if (!output_utf8)
  19. return absl::nullopt;
  20. std::u16string output;
  21. return UTF8ToUTF16(&output_utf8->front(), output_utf8->size(), &output)
  22. ? absl::optional<std::u16string>(std::move(output))
  23. : absl::nullopt;
  24. }
  25. zx::vmo VmoFromString(StringPiece data, StringPiece name) {
  26. zx::vmo vmo;
  27. // The `ZX_PROP_VMO_CONTENT_SIZE` property is automatically set on VMO
  28. // creation.
  29. zx_status_t status = zx::vmo::create(data.size(), 0, &vmo);
  30. ZX_CHECK(status == ZX_OK, status) << "zx_vmo_create";
  31. status = vmo.set_property(ZX_PROP_NAME, name.data(), name.size());
  32. ZX_DCHECK(status == ZX_OK, status);
  33. if (data.size() > 0) {
  34. status = vmo.write(data.data(), 0, data.size());
  35. ZX_CHECK(status == ZX_OK, status) << "zx_vmo_write";
  36. }
  37. return vmo;
  38. }
  39. fuchsia::mem::Buffer MemBufferFromString(StringPiece data, StringPiece name) {
  40. fuchsia::mem::Buffer buffer;
  41. buffer.vmo = VmoFromString(data, name);
  42. buffer.size = data.size();
  43. return buffer;
  44. }
  45. fuchsia::mem::Buffer MemBufferFromString16(StringPiece16 data,
  46. StringPiece name) {
  47. return MemBufferFromString(
  48. StringPiece(reinterpret_cast<const char*>(data.data()),
  49. data.size() * sizeof(char16_t)),
  50. name);
  51. }
  52. absl::optional<std::string> StringFromVmo(const zx::vmo& vmo) {
  53. std::string result;
  54. size_t size;
  55. zx_status_t status = vmo.get_prop_content_size(&size);
  56. if (status != ZX_OK) {
  57. ZX_LOG(ERROR, status) << "zx::vmo::get_prop_content_size";
  58. return absl::nullopt;
  59. }
  60. if (size == 0)
  61. return result;
  62. result.resize(size);
  63. status = vmo.read(&result[0], 0, size);
  64. if (status == ZX_OK)
  65. return result;
  66. ZX_LOG(ERROR, status) << "zx_vmo_read";
  67. return absl::nullopt;
  68. }
  69. absl::optional<std::string> StringFromMemBuffer(
  70. const fuchsia::mem::Buffer& buffer) {
  71. std::string result;
  72. if (buffer.size == 0)
  73. return result;
  74. result.resize(buffer.size);
  75. zx_status_t status = buffer.vmo.read(&result[0], 0, buffer.size);
  76. if (status == ZX_OK)
  77. return result;
  78. ZX_LOG(ERROR, status) << "zx_vmo_read";
  79. return absl::nullopt;
  80. }
  81. absl::optional<std::string> StringFromMemData(const fuchsia::mem::Data& data) {
  82. switch (data.Which()) {
  83. case fuchsia::mem::Data::kBytes: {
  84. const std::vector<uint8_t>& bytes = data.bytes();
  85. return std::string(bytes.begin(), bytes.end());
  86. }
  87. case fuchsia::mem::Data::kBuffer:
  88. return StringFromMemBuffer(data.buffer());
  89. case fuchsia::mem::Data::kUnknown:
  90. case fuchsia::mem::Data::Invalid:
  91. // TODO(fxbug.dev/66155): Determine whether to use a default case instead.
  92. break;
  93. }
  94. return absl::nullopt;
  95. }
  96. fuchsia::mem::Buffer MemBufferFromFile(File file) {
  97. if (!file.IsValid())
  98. return {};
  99. zx::vmo vmo;
  100. zx_status_t status =
  101. fdio_get_vmo_copy(file.GetPlatformFile(), vmo.reset_and_get_address());
  102. if (status != ZX_OK) {
  103. ZX_LOG(ERROR, status) << "fdio_get_vmo_copy";
  104. return {};
  105. }
  106. fuchsia::mem::Buffer output;
  107. output.vmo = std::move(vmo);
  108. output.size = checked_cast<uint64_t>(file.GetLength());
  109. return output;
  110. }
  111. fuchsia::mem::Buffer CloneBuffer(const fuchsia::mem::Buffer& buffer,
  112. StringPiece name) {
  113. fuchsia::mem::Buffer output;
  114. output.size = buffer.size;
  115. zx_status_t status = buffer.vmo.create_child(
  116. ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE, 0, buffer.size, &output.vmo);
  117. ZX_CHECK(status == ZX_OK, status) << "zx_vmo_create_child";
  118. status = output.vmo.set_property(ZX_PROP_NAME, name.data(), name.size());
  119. ZX_DCHECK(status == ZX_OK, status);
  120. return output;
  121. }
  122. } // namespace base