xref: /aosp_15_r20/external/pigweed/pw_transfer/public/pw_transfer/atomic_file_transfer_handler.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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