blob: aeed7c1db012b853a1ff6daf19a91d0e79ccc679 [file] [log] [blame]
// Copyright 2022 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#pragma once
#include <filesystem>
#include <string>
#include <string_view>
#include <variant>
#include "pw_status/status.h"
#include "pw_stream/std_file_stream.h"
#include "pw_transfer/handler.h"
namespace pw::transfer {
/// `AtomicFileTransferHandler` is intended to be used as a transfer handler for
/// files. It ensures that the target file of the transfer is always in a
/// correct state. In particular, the transfer is first done to a temporary file
/// and once complete, the original targeted file is updated.
class AtomicFileTransferHandler : public ReadWriteHandler {
public:
/// @param[in] resource_id An ID for the resource that's being transferred.
///
/// @param[in] file_path The target file to update.
AtomicFileTransferHandler(uint32_t resource_id, std::string_view file_path)
: ReadWriteHandler(resource_id), path_(file_path) {}
AtomicFileTransferHandler(const AtomicFileTransferHandler& rhs) = delete;
AtomicFileTransferHandler& operator=(const AtomicFileTransferHandler&) =
delete;
~AtomicFileTransferHandler() override = default;
/// Prepares `AtomicFileTransferHandler` for a read transfer.
///
/// @pre The read transfer has not been initialized before the call to this
/// method.
///
/// @returns @rst
///
/// .. pw-status-codes::
///
/// OK: ``AtomicFileTransferHandler`` is ready for the transfer.
///
/// @endrst
Status PrepareRead() override;
/// Handler function that is called by the transfer thread after a read
/// transfer completes.
///
/// @param[in] Status A `pw::Status` object provided by the transfer thread
/// indicating whether the transfer succeeded.
///
/// @pre The read transfer is done before the call to this method.
void FinalizeRead(Status) override;
/// Prepares `AtomicFileTransferHandler` for a write transfer.
///
/// @pre The write transfer has not been initialized before the call to this
/// method.
///
/// @returns @rst
///
/// .. pw-status-codes::
///
/// OK: ``AtomicFileTransferHandler`` is ready for the transfer.
///
/// @endrst
Status PrepareWrite() override;
/// Indicates whether the write transfer was successful.
///
/// @pre The write transfer is done.
///
/// @returns @rst
///
/// .. pw-status-codes::
///
/// OK: The transfer data was successfully written.
///
/// @endrst
Status FinalizeWrite(Status) override;
private:
std::string path_;
std::variant<std::monostate, stream::StdFileReader, stream::StdFileWriter>
stream_{};
};
} // namespace pw::transfer