Point Cloud Library (PCL) 1.12.0
Loading...
Searching...
No Matches
low_level_io.h
1/*
2 * Software License Agreement (BSD License)
3 *
4 * Point Cloud Library (PCL) - www.pointclouds.org
5 * Copyright (c) 2012-, Open Perception, Inc.
6 * Copyright (c) 2018 Fizyr BV. - https://fizyr.com
7 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided
19 * with the distribution.
20 * * Neither the name of the copyright holder(s) nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38/**
39 * This file defines compatibility wrappers for low level I/O functions.
40 * Implemented as inlinable functions to prevent any performance overhead.
41 */
42
43#pragma once
44
45#ifdef _WIN32
46# ifndef WIN32_LEAN_AND_MEAN
47# define WIN32_LEAN_AND_MEAN
48# endif
49# ifndef NOMINMAX
50# define NOMINMAX
51# endif
52# include <io.h>
53# include <windows.h>
54# ifdef _MSC_VER
55// ssize_t is already defined in MinGW and its definition conflicts with that of
56// SSIZE_T on a 32-bit target, so do this only for MSVC.
57# include <basetsd.h>
58using ssize_t = SSIZE_T;
59# endif /* _MSC_VER */
60#else
61# include <unistd.h>
62# include <sys/mman.h>
63# include <sys/types.h>
64# include <sys/stat.h>
65# include <sys/fcntl.h>
66# include <cerrno>
67#endif
68#include <cstddef>
69
70namespace pcl
71{
72 namespace io
73 {
74#ifdef _WIN32
75 inline int raw_open(const char * pathname, int flags, int mode)
76 {
77 return ::_open(pathname, flags, mode);
78 }
79
80 inline int raw_open(const char * pathname, int flags)
81 {
82 return ::_open(pathname, flags);
83 }
84
85 inline int raw_close(int fd)
86 {
87 return ::_close(fd);
88 }
89
90 inline int raw_lseek(int fd, long offset, int whence)
91 {
92 return ::_lseek(fd, offset, whence);
93 }
94
95 inline int raw_read(int fd, void * buffer, std::size_t count)
96 {
97 return ::_read(fd, buffer, count);
98 }
99
100 inline int raw_write(int fd, const void * buffer, std::size_t count)
101 {
102 return ::_write(fd, buffer, count);
103 }
104
105 inline int raw_ftruncate(int fd, long length)
106 {
107 return ::_chsize(fd, length);
108 }
109
110 inline int raw_fallocate(int fd, long length)
111 {
112 // Doesn't actually allocate, but best we can do?
113 return raw_ftruncate(fd, length);
114 }
115#else
116 inline int raw_open(const char * pathname, int flags, int mode)
117 {
118 return ::open(pathname, flags, mode);
119 }
120
121 inline int raw_open(const char * pathname, int flags)
122 {
123 return ::open(pathname, flags);
124 }
125
126 inline int raw_close(int fd)
127 {
128 return ::close(fd);
129 }
130
131 inline off_t raw_lseek(int fd, off_t offset, int whence)
132 {
133 return ::lseek(fd, offset, whence);
134 }
135
136 inline ssize_t raw_read(int fd, void * buffer, std::size_t count)
137 {
138 return ::read(fd, buffer, count);
139 }
140
141 inline ssize_t raw_write(int fd, const void * buffer, std::size_t count)
142 {
143 return ::write(fd, buffer, count);
144 }
145
146 inline int raw_ftruncate(int fd, off_t length)
147 {
148 return ::ftruncate(fd, length);
149 }
150
151# ifdef __APPLE__
152 inline int raw_fallocate(int fd, off_t length)
153 {
154 // OS X doesn't have posix_fallocate, but it has a fcntl that does the job.
155 // It may make the file too big though, so we truncate before returning.
156
157 // Try to allocate contiguous space first.
158 ::fstore_t store = {F_ALLOCATEALL | F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, length, 0};
159 if (::fcntl(fd, F_PREALLOCATE, &store) != -1)
160 return raw_ftruncate(fd, length);
161
162 // Try fragmented if it failed.
163 store.fst_flags = F_ALLOCATEALL;
164 if (::fcntl(fd, F_PREALLOCATE, &store) != -1)
165 return raw_ftruncate(fd, length);
166
167 // Fragmented also failed.
168 return -1;
169 }
170
171# else // __APPLE__
172 inline int raw_fallocate(int fd, off_t length)
173 {
174# ifdef ANDROID
175 // Android's libc doesn't have posix_fallocate.
176 if (::fallocate(fd, 0, 0, length) == 0)
177 return 0;
178# else
179 // Conforming POSIX systems have posix_fallocate.
180 if (::posix_fallocate(fd, 0, length) == 0)
181 return 0;
182# endif
183
184 // EINVAL should indicate an unsupported filesystem.
185 // All other errors are passed up.
186 if (errno != EINVAL)
187 return -1;
188
189 // Try to deal with unsupported filesystems by simply seeking + writing.
190 // This may not really allocate space, but the file size will be set.
191 // Writes to the mmapped file may still trigger SIGBUS errors later.
192
193 // Remember the old position and seek to the desired length.
194 off_t old_pos = raw_lseek(fd, 0, SEEK_CUR);
195 if (old_pos == -1)
196 return -1;
197 if (raw_lseek(fd, length - 1, SEEK_SET) == -1)
198 return -1;
199
200 // Write a single byte to resize the file.
201 char buffer = 0;
202 ssize_t written = raw_write(fd, &buffer, 1);
203
204 // Seek back to the old position.
205 if (raw_lseek(fd, old_pos, SEEK_SET) == -1)
206 return -1;
207
208 // Fail if we didn't write exactly one byte,
209 if (written != 1)
210 return -1;
211
212 return 0;
213 }
214# endif // __APPLE
215#endif // _WIN32
216
217 }
218}
Iterator class for point clouds with or without given indices.
int raw_ftruncate(int fd, long length)
int raw_close(int fd)
int raw_lseek(int fd, long offset, int whence)
int raw_write(int fd, const void *buffer, std::size_t count)
int raw_fallocate(int fd, long length)
int raw_open(const char *pathname, int flags, int mode)
int raw_read(int fd, void *buffer, std::size_t count)