1 : // Copyright 2011 Google Inc. All Rights Reserved.
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 : // Internal implementation details for msf_stream.h. Not meant to be included
16 : // directly.
17 :
18 : #ifndef SYZYGY_MSF_MSF_STREAM_IMPL_H_
19 : #define SYZYGY_MSF_MSF_STREAM_IMPL_H_
20 :
21 : #include <vector>
22 :
23 : #include "base/logging.h"
24 : #include "syzygy/msf/msf_decl.h"
25 :
26 : namespace msf {
27 : namespace detail {
28 :
29 : namespace {
30 :
31 : const size_t kInvalidLength = 0xFFFFFFFF;
32 :
33 : } // namespace
34 :
35 : template <MsfFileType T>
36 : template <typename ItemType>
37 E : bool MsfStreamImpl<T>::Read(ItemType* dest, size_t count, size_t* items_read) {
38 E : DCHECK(dest != NULL);
39 E : DCHECK(items_read != NULL);
40 :
41 E : size_t requested_bytes = sizeof(ItemType) * count;
42 E : if (requested_bytes == 0) {
43 i : *items_read = count;
44 i : return true;
45 : }
46 :
47 E : size_t seviceable_bytes = requested_bytes;
48 E : if (requested_bytes > bytes_left()) {
49 E : seviceable_bytes = bytes_left() - bytes_left() % sizeof(ItemType);
50 : }
51 E : if (seviceable_bytes == 0) {
52 E : *items_read = 0;
53 E : return false;
54 : }
55 :
56 E : size_t bytes_read = 0;
57 E : bool result = ReadBytes(dest, seviceable_bytes, &bytes_read);
58 E : *items_read = bytes_read / sizeof(ItemType);
59 E : return result && *items_read == count;
60 E : }
61 :
62 : template <MsfFileType T>
63 : template <typename ItemType>
64 E : bool MsfStreamImpl<T>::Read(ItemType* dest, size_t count) {
65 E : DCHECK(dest != NULL);
66 E : size_t items_read = 0;
67 E : return Read(dest, count, &items_read) && items_read == count;
68 E : }
69 :
70 : template <MsfFileType T>
71 : template <typename ItemType>
72 E : bool MsfStreamImpl<T>::Read(std::vector<ItemType>* dest, size_t count) {
73 E : DCHECK(dest != NULL);
74 E : dest->clear();
75 E : if (sizeof(ItemType) * count > bytes_left())
76 E : return false;
77 E : dest->resize(count);
78 :
79 E : if (count == 0)
80 E : return true;
81 :
82 E : size_t items_read = 0;
83 E : bool result = Read(&dest->at(0), count, &items_read);
84 E : dest->resize(items_read);
85 E : return result;
86 E : }
87 :
88 : template <MsfFileType T>
89 : template <typename ItemType>
90 E : bool MsfStreamImpl<T>::Read(std::vector<ItemType>* dest) {
91 E : DCHECK(dest != NULL);
92 E : dest->clear();
93 E : if ((bytes_left() % sizeof(ItemType)) != 0)
94 E : return false;
95 E : return Read(dest, bytes_left() / sizeof(ItemType));
96 E : }
97 :
98 : template <MsfFileType T>
99 : MsfStreamImpl<T>::MsfStreamImpl(size_t length)
100 E : : length_(length == kInvalidLength ? 0 : length), pos_(0) {
101 E : }
102 :
103 : template <MsfFileType T>
104 E : MsfStreamImpl<T>::~MsfStreamImpl() {
105 E : }
106 :
107 : template <MsfFileType T>
108 E : bool MsfStreamImpl<T>::Seek(size_t pos) {
109 E : if (pos > length_)
110 E : return false;
111 :
112 E : pos_ = pos;
113 E : return true;
114 E : }
115 :
116 : } // namespace detail
117 : } // namespace msf
118 :
119 : #endif // SYZYGY_MSF_MSF_STREAM_IMPL_H_
|