Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: base/file_reader.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/file_reader.h ('k') | base/file_reader_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2003-2009 Google Inc.
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 "omaha/base/file_reader.h"
17 #include "omaha/base/debug.h"
18
19 namespace omaha {
20
21 FileReader::FileReader()
22 : file_is_open_(false),
23 buffered_byte_count_(0),
24 current_position_(0),
25 file_buffer_size_(0),
26 is_unicode_(false) {}
27
28 FileReader::~FileReader() {
29 if (file_is_open_) {
30 file_.Close();
31 file_is_open_ = false;
32 }
33 }
34
35 HRESULT FileReader::Init(const TCHAR* file_name, size_t buffer_size) {
36 ASSERT1(file_name);
37 ASSERT1(buffer_size);
38 file_buffer_size_ = buffer_size;
39 file_buffer_.reset(new byte[file_buffer_size()]);
40 HRESULT hr = file_.OpenShareMode(file_name, false, false, FILE_SHARE_WRITE |
41 FILE_SHARE_READ);
42 file_is_open_ = SUCCEEDED(hr);
43 is_unicode_ = false;
44
45 if (FAILED(hr)) {
46 return hr;
47 }
48
49 hr = file_.SeekToBegin();
50 if (FAILED(hr)) {
51 return hr;
52 }
53
54 const int unicode_header_length = 2;
55
56 char buf[unicode_header_length] = {0};
57 uint32 bytes_read = 0;
58 hr = file_.Read(sizeof(buf), reinterpret_cast<byte*>(buf), &bytes_read);
59 if (FAILED(hr)) {
60 return hr;
61 }
62
63 if (bytes_read == sizeof(buf)) {
64 char unicode_buf[unicode_header_length] = {0xff, 0xfe};
65 is_unicode_ = (memcmp(buf, unicode_buf, sizeof(buf)) == 0);
66 }
67
68 if (!is_unicode_) {
69 file_.SeekToBegin();
70 }
71
72 if (is_unicode_ && (buffer_size < sizeof(WCHAR))) {
73 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
74 }
75
76 return S_OK;
77 }
78
79 HRESULT FileReader::GetNextChar(bool peek, CString* next_char) {
80 ASSERT1(next_char);
81 next_char->Empty();
82
83 // Do we need to read in more of the file?
84 if (current_position_ >= buffered_byte_count_) {
85 current_position_ = 0;
86 if (FAILED(file_.Read(file_buffer_size(),
87 file_buffer_.get(),
88 &buffered_byte_count_))) {
89 // There is no more of the file buffered.
90 buffered_byte_count_ = 0;
91 }
92 }
93
94 // Have we gone past the end of the file?
95 if (current_position_ >= buffered_byte_count_) {
96 return E_FAIL;
97 }
98
99 if (is_unicode_) {
100 // Need to make sure there are at least 2 characters still in the buffer.
101 // If we're right at the end of the buffer and there's only one character,
102 // then we will need to read more from the file.
103
104 if (current_position_ + 1 >= buffered_byte_count_) {
105 // We need one more byte to make a WCHAR.
106 // Due to the need to peek, we're going to take that byte and put it at
107 // the beginning of the file_buffer_ and read in as many remaining bytes
108 // as we can from the file.
109
110 // Copy current (and last) byte to the beginning of the buffer.
111 file_buffer_[0] = file_buffer_[current_position_];
112
113 // Reset current_position.
114 current_position_ = 0;
115
116 if (SUCCEEDED(file_.Read(file_buffer_size() - 1,
117 file_buffer_.get() + 1,
118 &buffered_byte_count_))) {
119 // Incrememt count to deal with byte we pre-filled at offset 0.
120 buffered_byte_count_++;
121 } else {
122 // We've got a Unicode file with an extra byte. We're going to drop the
123 // byte and call it end of file.
124 buffered_byte_count_ = 0;
125 return E_FAIL;
126 }
127 }
128
129 // Get the next character.
130 char c1 = file_buffer_[current_position_];
131 ++current_position_;
132 char c2 = file_buffer_[current_position_];
133 ++current_position_;
134
135 if (peek) {
136 // Reset the current position pointer backwards if we're peeking.
137 current_position_ -= 2;
138 }
139
140 WCHAR c = (static_cast<WCHAR>(c2) << 8) | static_cast<WCHAR>(c1);
141
142 *next_char = c;
143 } else {
144 char c = file_buffer_[current_position_];
145 if (!peek) {
146 ++current_position_;
147 }
148 *next_char = c;
149 }
150
151 return S_OK;
152 }
153
154 HRESULT FileReader::ReadLineString(CString* line) {
155 ASSERT1(line);
156
157 line->Empty();
158
159 while (true) {
160 CString current_char;
161 HRESULT hr = GetNextChar(false, &current_char);
162 // If we failed to get the next char, we're at the end of the file.
163 // If the current line is empty, then fail out signalling we're done.
164 // Otherwise, return the current line and we'll fail out on the next call to
165 // ReadLine().
166 if (FAILED(hr)) {
167 if (line->IsEmpty()) {
168 return hr;
169 } else {
170 return S_OK;
171 }
172 }
173
174 // Have we reached end of line?
175 if (current_char.Compare(_T("\r")) == 0) {
176 // Seek ahead to see if the next char is "\n"
177 CString next_char;
178 GetNextChar(true, &next_char);
179 if (next_char.Compare(_T("\n")) == 0) {
180 // Get in the next char too.
181 GetNextChar(false, &next_char);
182 }
183 break;
184 } else if (current_char.Compare(_T("\n")) == 0) {
185 break;
186 }
187
188 line->Append(current_char);
189 }
190
191 return S_OK;
192 }
193
194 HRESULT FileReader::ReadLineAnsi(size_t max_len, char* line) {
195 ASSERT1(line);
196 ASSERT1(max_len);
197
198 size_t total_len = 0;
199
200 while (true) {
201 // Do we need to read in more of the file?
202 if (current_position_ >= buffered_byte_count_) {
203 current_position_ = 0;
204 if (FAILED(file_.Read(file_buffer_size(),
205 file_buffer_.get(),
206 &buffered_byte_count_))) {
207 // There is no more of the file buffered.
208 buffered_byte_count_ = 0;
209 }
210 }
211
212 // Have we gone past the end of the file?
213 if (current_position_ >= buffered_byte_count_) {
214 break;
215 }
216
217 // Get the next character.
218 char c = file_buffer_[current_position_];
219 ++current_position_;
220
221 // Have we reached end of line?
222 // TODO(omaha): if the line is terminated with a \r\n pair then perhaps
223 // the code should skip the whole pair not only half of it.
224 if (c == '\n' || c == '\r') {
225 break;
226 }
227
228 // Fill up the passed in buffer for the line.
229 if (total_len < max_len - 1) {
230 line[total_len] = c;
231 ++total_len;
232 }
233 }
234 // Terminate the passed in buffer.
235 ASSERT1(total_len < max_len);
236 line[total_len] = '\0';
237
238 // If we are out of bytes and we didn't read in any bytes.
239 // then fail signaling end of file.
240 if (!buffered_byte_count_ && !total_len) {
241 return E_FAIL;
242 }
243
244 return S_OK;
245 }
246
247 } // namespace omaha
248
OLDNEW
« no previous file with comments | « base/file_reader.h ('k') | base/file_reader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698