1 /**
2  * @file   vfs_file_handle.cc
3  *
4  * @section LICENSE
5  *
6  * The MIT License
7  *
8  * @copyright Copyright (c) 2017-2021 TileDB, Inc.
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a copy
11  * of this software and associated documentation files (the "Software"), to deal
12  * in the Software without restriction, including without limitation the rights
13  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  * copies of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in
18  * all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26  * THE SOFTWARE.
27  *
28  * @section DESCRIPTION
29  *
30  * This file implements the VFSFileHandle class.
31  */
32 
33 #include "tiledb/sm/filesystem/vfs_file_handle.h"
34 #include "tiledb/common/logger.h"
35 #include "tiledb/sm/enums/vfs_mode.h"
36 #include "tiledb/sm/filesystem/vfs.h"
37 
38 #include <sstream>
39 
40 using namespace tiledb::common;
41 
42 namespace tiledb {
43 namespace sm {
44 
45 /* ********************************* */
46 /*     CONSTRUCTORS & DESTRUCTORS    */
47 /* ********************************* */
48 
VFSFileHandle(const URI & uri,VFS * vfs,VFSMode mode)49 VFSFileHandle::VFSFileHandle(const URI& uri, VFS* vfs, VFSMode mode)
50     : uri_(uri)
51     , vfs_(vfs)
52     , mode_(mode) {
53   is_open_ = true;
54 }
55 
56 /* ********************************* */
57 /*                API                */
58 /* ********************************* */
59 
close()60 Status VFSFileHandle::close() {
61   if (!is_open_) {
62     std::stringstream msg;
63     msg << "Cannot close file '" << uri_.to_string() << "'; File is not open";
64     auto st = Status::VFSFileHandleError(msg.str());
65     return LOG_STATUS(st);
66   }
67 
68   // Close file in write or append mode
69   if (mode_ != tiledb::sm::VFSMode::VFS_READ) {
70     RETURN_NOT_OK(vfs_->close_file(uri_));
71 
72     // Create an empty file if the file does not exist
73     bool exists;
74     RETURN_NOT_OK(vfs_->is_file(uri_, &exists));
75     if (!exists)
76       RETURN_NOT_OK(vfs_->touch(uri_));
77   }
78 
79   is_open_ = false;
80 
81   return Status::Ok();
82 }
83 
is_open() const84 bool VFSFileHandle::is_open() const {
85   return is_open_;
86 }
87 
open()88 Status VFSFileHandle::open() {
89   return vfs_->open_file(uri_, mode_);
90 }
91 
read(uint64_t offset,void * buffer,uint64_t nbytes)92 Status VFSFileHandle::read(uint64_t offset, void* buffer, uint64_t nbytes) {
93   if (!is_open_) {
94     std::stringstream msg;
95     msg << "Cannot read from file '" << uri_.to_string()
96         << "'; File is not open";
97     auto st = Status::VFSFileHandleError(msg.str());
98     return LOG_STATUS(st);
99   }
100 
101   return vfs_->read(uri_, offset, buffer, nbytes);
102 }
103 
sync()104 Status VFSFileHandle::sync() {
105   if (!is_open_) {
106     std::stringstream msg;
107     msg << "Cannot sync file '" << uri_.to_string() << "'; File is not open";
108     auto st = Status::VFSFileHandleError(msg.str());
109     return LOG_STATUS(st);
110   }
111 
112   return vfs_->sync(uri_);
113 }
114 
uri() const115 URI VFSFileHandle::uri() const {
116   return uri_;
117 }
118 
write(const void * buffer,uint64_t nbytes)119 Status VFSFileHandle::write(const void* buffer, uint64_t nbytes) {
120   if (!is_open_) {
121     std::stringstream msg;
122     msg << "Cannot write to file '" << uri_.to_string()
123         << "'; File is not open";
124     auto st = Status::VFSFileHandleError(msg.str());
125     return LOG_STATUS(st);
126   }
127 
128   return vfs_->write(uri_, buffer, nbytes);
129 }
130 
131 }  // namespace sm
132 }  // namespace tiledb
133