blob: a8009f08343a384780088b5ede12fe5e7c741c33 [file] [log] [blame]
Prathmesh Prabhu28b4a3b2014-03-28 11:52:09 -07001// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/protobuf_lite_streams.h"
6
7#include <fcntl.h>
8#include <sys/types.h>
9
Ben Chan11c213f2014-09-05 08:21:06 -070010#include <base/files/file_util.h>
Prathmesh Prabhu28b4a3b2014-03-28 11:52:09 -070011#include <base/posix/eintr_wrapper.h>
12
13using google::protobuf::io::CopyingInputStream;
14using google::protobuf::io::CopyingInputStreamAdaptor;
15using std::string;
16
17namespace shill {
18
Paul Stewart1a212a62015-06-16 13:13:10 -070019CopyingInputStreamAdaptor* protobuf_lite_file_input_stream(
20 const string& file_path) {
Prathmesh Prabhu28b4a3b2014-03-28 11:52:09 -070021 int fd = HANDLE_EINTR(open(file_path.c_str(), O_RDONLY));
22 if (fd == -1) {
23 PLOG(ERROR) << __func__ << ": "
24 << "Could not load protobuf file [" << file_path << "] ";
Ben Chancc225ef2014-09-30 13:26:51 -070025 return nullptr;
Prathmesh Prabhu28b4a3b2014-03-28 11:52:09 -070026 }
27
Paul Stewart1a212a62015-06-16 13:13:10 -070028 auto* file_stream(new ProtobufLiteCopyingFileInputStream(fd));
29 auto* adaptor(new CopyingInputStreamAdaptor(
Prathmesh Prabhu28b4a3b2014-03-28 11:52:09 -070030 static_cast<CopyingInputStream*>(file_stream)));
31 // Pass ownership of |file_stream|.
32 adaptor->SetOwnsCopyingStream(true);
33 return adaptor;
34}
35
36
37ProtobufLiteCopyingFileInputStream::ProtobufLiteCopyingFileInputStream(int fd)
38 : fd_(fd),
Ben Chan6fbf64f2014-05-21 18:07:01 -070039 scoped_fd_closer_(fd_),
Prathmesh Prabhu28b4a3b2014-03-28 11:52:09 -070040 previous_seek_failed_(false) {}
41
42ProtobufLiteCopyingFileInputStream::~ProtobufLiteCopyingFileInputStream() {}
43
Paul Stewart1a212a62015-06-16 13:13:10 -070044int ProtobufLiteCopyingFileInputStream::Read(void* buffer, int size) {
Prathmesh Prabhu28b4a3b2014-03-28 11:52:09 -070045 return HANDLE_EINTR(read(fd_, buffer, size));
46}
47
48int ProtobufLiteCopyingFileInputStream::Skip(int count) {
49 if (!previous_seek_failed_ &&
50 lseek(fd_, count, SEEK_CUR) != static_cast<off_t>(-1)) {
51 // seek succeeded.
52 return count;
53 }
54 // Let's not attempt to seek again later.
55 previous_seek_failed_ = true;
56 return CopyingInputStream::Skip(count);
57}
58
59} // namespace shill