xref: /aosp_15_r20/external/pigweed/pw_stream/public/pw_stream/seek.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2021 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 
15 // Defines functions for implementing seeking in a stream.
16 #pragma once
17 
18 #include <cstddef>
19 
20 #include "pw_stream/stream.h"
21 
22 namespace pw::stream {
23 
24 // Adds a seek offset to the specified origin.
ResolveSeekOffset(ptrdiff_t offset,Stream::Whence origin,size_t end_position,size_t current_position)25 constexpr ptrdiff_t ResolveSeekOffset(ptrdiff_t offset,
26                                       Stream::Whence origin,
27                                       size_t end_position,
28                                       size_t current_position) {
29   switch (origin) {
30     case Stream::kBeginning:
31       return offset;
32     case Stream::kCurrent:
33       return static_cast<ptrdiff_t>(current_position) + offset;
34     case Stream::kEnd:
35     default:
36       return static_cast<ptrdiff_t>(end_position) + offset;
37   }
38 }
39 
40 // Implements seek for a class that supports absolute position changes. The
41 // new position is calculated and assigned to the provided position variable.
42 //
43 // Returns OUT_OF_RANGE for seeks to a negative position or past the end.
CalculateSeek(ptrdiff_t offset,Stream::Whence origin,size_t end_position,size_t & current_position)44 constexpr Status CalculateSeek(ptrdiff_t offset,
45                                Stream::Whence origin,
46                                size_t end_position,
47                                size_t& current_position) {
48   const ptrdiff_t new_position =
49       ResolveSeekOffset(offset, origin, end_position, current_position);
50 
51   if (new_position < 0 || static_cast<size_t>(new_position) > end_position) {
52     return Status::OutOfRange();
53   }
54 
55   current_position = static_cast<size_t>(new_position);
56   return OkStatus();
57 }
58 
59 }  // namespace pw::stream
60