xref: /aosp_15_r20/external/tink/cc/internal/test_random_access_stream.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://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,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ///////////////////////////////////////////////////////////////////////////////
16 #include "tink/internal/test_random_access_stream.h"
17 
18 #include <stdint.h>
19 
20 #include <algorithm>
21 #include <memory>
22 #include <string>
23 #include <utility>
24 
25 #include "absl/status/status.h"
26 #include "tink/random_access_stream.h"
27 #include "tink/util/buffer.h"
28 #include "tink/util/status.h"
29 
30 namespace crypto {
31 namespace tink {
32 namespace internal {
33 
PRead(int64_t position,int count,util::Buffer * dest_buffer)34 util::Status TestRandomAccessStream::PRead(int64_t position, int count,
35                                            util::Buffer* dest_buffer) {
36   if (dest_buffer == nullptr) {
37     return util::Status(absl::StatusCode::kInvalidArgument,
38                         "dest_buffer must be non-null");
39   }
40   if (count <= 0) {
41     return util::Status(absl::StatusCode::kInvalidArgument,
42                         "count must be positive");
43   }
44   if (count > dest_buffer->allocated_size()) {
45     return util::Status(absl::StatusCode::kInvalidArgument, "buffer too small");
46   }
47   if (position < 0) {
48     return util::Status(absl::StatusCode::kInvalidArgument,
49                         "position cannot be negative");
50   }
51   if (position >= content_.size()) {
52     dest_buffer->set_size(0).IgnoreError();
53     return util::Status(absl::StatusCode::kOutOfRange, "EOF");
54   }
55   util::Status status = dest_buffer->set_size(count);
56   if (!status.ok()) {
57     return status;
58   }
59   int read_count =
60       std::min(count, static_cast<int>(content_.size() - position));
61   std::copy(content_.begin() + position,
62             content_.begin() + position + read_count,
63             dest_buffer->get_mem_block());
64   status = dest_buffer->set_size(read_count);
65   if (!status.ok()) {
66     return status;
67   }
68   if (position + read_count == content_.size()) {
69     // We reached EOF.
70     return util::Status(absl::StatusCode::kOutOfRange, "EOF");
71   }
72   return util::OkStatus();
73 }
74 
ReadAllFromRandomAccessStream(RandomAccessStream * random_access_stream,std::string & contents,int chunk_size)75 util::Status ReadAllFromRandomAccessStream(
76     RandomAccessStream* random_access_stream, std::string& contents,
77     int chunk_size) {
78   if (chunk_size < 1) {
79     return util::Status(absl::StatusCode::kInvalidArgument,
80                         "chunk_size must be greater than zero");
81   }
82   contents.clear();
83   std::unique_ptr<util::Buffer> buffer =
84       *std::move(util::Buffer::New(chunk_size));
85   int64_t position = 0;
86   auto status = util::OkStatus();
87   while (status.ok()) {
88     status = random_access_stream->PRead(position, chunk_size, buffer.get());
89     contents.append(buffer->get_mem_block(), buffer->size());
90     position = contents.size();
91   }
92   return status;
93 }
94 
95 }  // namespace internal
96 }  // namespace tink
97 }  // namespace crypto
98