| 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 |  | 
| 35 | namespace Hdfs { | 
| 36 | namespace Internal { | 
| 37 |  | 
| 38 | CFileWrapper::CFileWrapper() : | 
| 39 |     file(NULL) { | 
| 40 | } | 
| 41 |  | 
| 42 | CFileWrapper::~CFileWrapper() { | 
| 43 |     close(); | 
| 44 | } | 
| 45 |  | 
| 46 | bool 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 |  | 
| 67 | bool CFileWrapper::open(const std::string & path) { | 
| 68 |     this->path = path; | 
| 69 |     file = fopen(path.c_str(), "rb" ); | 
| 70 |     return NULL != file; | 
| 71 | } | 
| 72 |  | 
| 73 | void CFileWrapper::close() { | 
| 74 |     if (NULL != file) { | 
| 75 |         fclose(file); | 
| 76 |         file = NULL; | 
| 77 |     } | 
| 78 | } | 
| 79 |  | 
| 80 | const 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 |  | 
| 86 | void 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 |  | 
| 104 | void 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 |  |