blob: 1e28d66904938d378896c01678250c6592962fc1 [file] [log] [blame]
// Copyright 2020 The Fuchsia 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 "src/storage/volume_image/partition.h"
#include <sstream>
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "src/storage/volume_image/address_descriptor.h"
#include "src/storage/volume_image/volume_descriptor.h"
namespace storage::volume_image {
bool Partition::LessThan::operator()(const Partition& lhs, const Partition& rhs) const {
return std::tie(lhs.volume().name, lhs.volume().instance) <
std::tie(rhs.volume().name, rhs.volume().instance);
}
fit::result<Partition, std::string> Partition::Create(std::string_view serialized_volume_image,
std::unique_ptr<Reader> reader) {
rapidjson::Document document;
rapidjson::ParseResult result =
document.Parse(reinterpret_cast<const char*>(serialized_volume_image.data()),
serialized_volume_image.size());
if (result.IsError()) {
std::ostringstream error;
error << "Error parsing serialized VolumeDescriptor. "
<< rapidjson::GetParseError_En(result.Code()) << std::endl;
return fit::error(error.str());
}
if (!document.HasMember("volume")) {
return fit::error("volume_image missing volume_descriptor field 'volume'.");
}
if (!document.HasMember("address")) {
return fit::error("volume_image missing address_descriptor field 'address'.");
}
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
document["volume"].Accept(writer);
auto volume_descriptor_result =
VolumeDescriptor::Deserialize(std::string_view(buffer.GetString()));
if (volume_descriptor_result.is_error()) {
return volume_descriptor_result.take_error_result();
}
buffer.Clear();
writer.Reset(buffer);
document["address"].Accept(writer);
auto address_descriptor_result =
AddressDescriptor::Deserialize(std::string_view(buffer.GetString()));
if (address_descriptor_result.is_error()) {
return address_descriptor_result.take_error_result();
}
return fit::ok(Partition(volume_descriptor_result.take_value(),
address_descriptor_result.take_value(), std::move(reader)));
}
} // namespace storage::volume_image