1 // Copyright 2022 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 #pragma once 15 16 #include <filesystem> 17 #include <string> 18 #include <string_view> 19 #include <variant> 20 21 #include "pw_status/status.h" 22 #include "pw_stream/std_file_stream.h" 23 #include "pw_transfer/handler.h" 24 25 namespace pw::transfer { 26 27 /// `AtomicFileTransferHandler` is intended to be used as a transfer handler for 28 /// files. It ensures that the target file of the transfer is always in a 29 /// correct state. In particular, the transfer is first done to a temporary file 30 /// and once complete, the original targeted file is updated. 31 class AtomicFileTransferHandler : public ReadWriteHandler { 32 public: 33 /// @param[in] resource_id An ID for the resource that's being transferred. 34 /// 35 /// @param[in] file_path The target file to update. AtomicFileTransferHandler(uint32_t resource_id,std::string_view file_path)36 AtomicFileTransferHandler(uint32_t resource_id, std::string_view file_path) 37 : ReadWriteHandler(resource_id), path_(file_path) {} 38 39 AtomicFileTransferHandler(const AtomicFileTransferHandler& rhs) = delete; 40 AtomicFileTransferHandler& operator=(const AtomicFileTransferHandler&) = 41 delete; 42 ~AtomicFileTransferHandler() override = default; 43 44 /// Prepares `AtomicFileTransferHandler` for a read transfer. 45 /// 46 /// @pre The read transfer has not been initialized before the call to this 47 /// method. 48 /// 49 /// @returns @rst 50 /// 51 /// .. pw-status-codes:: 52 /// 53 /// OK: ``AtomicFileTransferHandler`` is ready for the transfer. 54 /// 55 /// @endrst 56 Status PrepareRead() override; 57 /// Handler function that is called by the transfer thread after a read 58 /// transfer completes. 59 /// 60 /// @param[in] Status A `pw::Status` object provided by the transfer thread 61 /// indicating whether the transfer succeeded. 62 /// 63 /// @pre The read transfer is done before the call to this method. 64 void FinalizeRead(Status) override; 65 /// Prepares `AtomicFileTransferHandler` for a write transfer. 66 /// 67 /// @pre The write transfer has not been initialized before the call to this 68 /// method. 69 /// 70 /// @returns @rst 71 /// 72 /// .. pw-status-codes:: 73 /// 74 /// OK: ``AtomicFileTransferHandler`` is ready for the transfer. 75 /// 76 /// @endrst 77 Status PrepareWrite() override; 78 /// Indicates whether the write transfer was successful. 79 /// 80 /// @pre The write transfer is done. 81 /// 82 /// @returns @rst 83 /// 84 /// .. pw-status-codes:: 85 /// 86 /// OK: The transfer data was successfully written. 87 /// 88 /// @endrst 89 Status FinalizeWrite(Status) override; 90 91 private: 92 std::string path_; 93 std::variant<std::monostate, stream::StdFileReader, stream::StdFileWriter> 94 stream_{}; 95 }; 96 97 } // namespace pw::transfer 98