summaryrefslogtreecommitdiff
path: root/chromium/fuchsia/base/mem_buffer_util.cc
blob: efc7162078b6951b671923f4d9755e93111dfee9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "fuchsia/base/mem_buffer_util.h"

#include <lib/fdio/io.h>

#include <lib/zx/vmo.h>
#include <string>

#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/memory_mapped_file.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/stl_util.h"
#include "base/threading/thread_restrictions.h"

namespace cr_fuchsia {

bool ReadUTF8FromVMOAsUTF16(const fuchsia::mem::Buffer& buffer,
                            base::string16* output) {
  std::string output_utf8;
  if (!StringFromMemBuffer(buffer, &output_utf8))
    return false;
  return base::UTF8ToUTF16(&output_utf8.front(), output_utf8.size(), output);
}

fuchsia::mem::Buffer MemBufferFromString(base::StringPiece data,
                                         base::StringPiece name) {
  fuchsia::mem::Buffer buffer;

  zx_status_t status = zx::vmo::create(data.size(), 0, &buffer.vmo);
  ZX_CHECK(status == ZX_OK, status) << "zx_vmo_create";
  status = buffer.vmo.set_property(ZX_PROP_NAME, name.data(), name.size());
  ZX_DCHECK(status == ZX_OK, status);
  if (data.size() > 0) {
    status = buffer.vmo.write(data.data(), 0, data.size());
    ZX_CHECK(status == ZX_OK, status) << "zx_vmo_write";
  }

  buffer.size = data.size();
  return buffer;
}

fuchsia::mem::Buffer MemBufferFromString16(const base::StringPiece16& data,
                                           base::StringPiece name) {
  return MemBufferFromString(
      base::StringPiece(reinterpret_cast<const char*>(data.data()),
                        data.size() * sizeof(base::char16)),
      name);
}

bool StringFromMemBuffer(const fuchsia::mem::Buffer& buffer,
                         std::string* output) {
  output->resize(buffer.size);
  if (buffer.size == 0) {
    return true;
  }
  zx_status_t status = buffer.vmo.read(&output->at(0), 0, buffer.size);
  if (status != ZX_OK) {
    ZX_LOG(ERROR, status) << "zx_vmo_read";
    return false;
  }
  return true;
}

fuchsia::mem::Buffer MemBufferFromFile(base::File file) {
  if (!file.IsValid())
    return {};

  zx::vmo vmo;
  zx_status_t status =
      fdio_get_vmo_copy(file.GetPlatformFile(), vmo.reset_and_get_address());
  if (status != ZX_OK) {
    ZX_LOG(ERROR, status) << "fdio_get_vmo_copy";
    return {};
  }

  fuchsia::mem::Buffer output;
  output.vmo = std::move(vmo);
  output.size = file.GetLength();
  return output;
}

fuchsia::mem::Buffer CloneBuffer(const fuchsia::mem::Buffer& buffer,
                                 base::StringPiece name) {
  fuchsia::mem::Buffer output;
  output.size = buffer.size;
  zx_status_t status = buffer.vmo.create_child(ZX_VMO_CHILD_COPY_ON_WRITE, 0,
                                               buffer.size, &output.vmo);
  ZX_CHECK(status == ZX_OK, status) << "zx_vmo_create_child";

  status = output.vmo.set_property(ZX_PROP_NAME, name.data(), name.size());
  ZX_DCHECK(status == ZX_OK, status);

  return output;
}

}  // namespace cr_fuchsia