1/********************************************************************
2 * Copyright (c) 2013 - 2014, Pivotal Inc.
3 * All rights reserved.
4 *
5 * Author: Zhanwei Wang
6 ********************************************************************/
7/********************************************************************
8 * 2014 -
9 * open source under Apache License Version 2.0
10 ********************************************************************/
11/**
12 * Licensed to the Apache Software Foundation (ASF) under one
13 * or more contributor license agreements. See the NOTICE file
14 * distributed with this work for additional information
15 * regarding copyright ownership. The ASF licenses this file
16 * to you under the Apache License, Version 2.0 (the
17 * "License"); you may not use this file except in compliance
18 * with the License. You may obtain a copy of the License at
19 *
20 * http://www.apache.org/licenses/LICENSE-2.0
21 *
22 * Unless required by applicable law or agreed to in writing, software
23 * distributed under the License is distributed on an "AS IS" BASIS,
24 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
27 */
28#include <string>
29#include <limits>
30
31#include "Exception.h"
32#include "ExceptionInternal.h"
33#include "FileWrapper.h"
34
35namespace Hdfs {
36namespace Internal {
37
38CFileWrapper::CFileWrapper() :
39 file(NULL) {
40}
41
42CFileWrapper::~CFileWrapper() {
43 close();
44}
45
46bool CFileWrapper::open(int fd, bool delegate) {
47 int newfd = fd;
48
49 if (!delegate) {
50 newfd = dup(fd);
51
52 if (newfd < 0) {
53 THROW(HdfsIOException, "Cannot duplicate file descriptor: %s",
54 GetSystemErrorInfo(errno));
55 }
56 }
57
58 file = fdopen(newfd, "rb");
59
60 if (NULL == file && !delegate) {
61 ::close(newfd);
62 }
63
64 return NULL != file;
65}
66
67bool CFileWrapper::open(const std::string & path) {
68 this->path = path;
69 file = fopen(path.c_str(), "rb");
70 return NULL != file;
71}
72
73void CFileWrapper::close() {
74 if (NULL != file) {
75 fclose(file);
76 file = NULL;
77 }
78}
79
80const char * CFileWrapper::read(std::vector<char> & buffer, int32_t size) {
81 buffer.resize(size);
82 copy(&buffer[0], size);
83 return &buffer[0];
84}
85
86void CFileWrapper::copy(char * buffer, int32_t size) {
87 int32_t todo = size, done;
88
89 while (todo > 0) {
90 done = fread(buffer + (size - todo), sizeof(char), todo, file);
91
92 if (done < 0) {
93 THROW(HdfsIOException, "Cannot read file \"%s\", %s.", path.c_str(),
94 GetSystemErrorInfo(errno));
95 } else if (0 == done) {
96 THROW(HdfsIOException, "Cannot read file \"%s\", End of file.",
97 path.c_str());
98 }
99
100 todo -= done;
101 }
102}
103
104void CFileWrapper::seek(int64_t offset) {
105 assert(offset >= 0);
106 int64_t todo = offset, batch;
107 bool seek_set = true;
108
109 do {
110 batch = todo < std::numeric_limits<long>::max()
111 ? todo
112 : std::numeric_limits<long>::max();
113 off_t rc = fseek(file, static_cast<long>(batch),
114 seek_set ? SEEK_SET : SEEK_CUR);
115 seek_set = false;
116
117 if (rc != 0) {
118 THROW(HdfsIOException, "Cannot lseek file: %s, %s", path.c_str(),
119 GetSystemErrorInfo(errno));
120 }
121
122 todo -= batch;
123 } while (todo > 0);
124}
125
126}
127}
128