Skip to content

Commit 86ec45e

Browse files
committed
Add xio_gdal_handler
1 parent 156617a commit 86ec45e

File tree

7 files changed

+243
-8
lines changed

7 files changed

+243
-8
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ set(XTENSOR_IO_HEADERS
6262
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xio_aws_handler.hpp
6363
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xio_disk_handler.hpp
6464
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xio_gcs_handler.hpp
65+
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xio_gdal_handler.hpp
6566
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xio_gzip.hpp
67+
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xio_file.hpp
68+
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xio_vsilfile.hpp
6669
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xnpz.hpp
6770
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xtensor-io.hpp
6871
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xtensor_io_config.hpp

include/xtensor-io/xio_binary.hpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "xtensor/xadapt.hpp"
1616
#include "xtensor-io.hpp"
1717
#include "xfile_array.hpp"
18+
#include "xio_file.hpp"
1819

1920
namespace xt
2021
{
@@ -24,13 +25,13 @@ namespace xt
2425
// we check that `fclose` can be called on them!
2526
template<typename T, class I>
2627
auto load_bin_imp(I& file, std::string& buffer)
27-
-> decltype(fclose(file), void())
28+
-> decltype(file.ftell(), void())
2829
{
29-
fseek(file, 0, SEEK_END);
30-
std::size_t size = ftell(file);
30+
file.fseek(0, SEEK_END);
31+
std::size_t size = file.ftell();
3132
buffer.resize(size);
32-
rewind(file);
33-
fread(&buffer[0], 1, size, file);
33+
file.rewind();
34+
file.fread(&buffer[0], 1, size);
3435
}
3536

3637
// load_bin "overload" for stream-like objects
@@ -61,10 +62,10 @@ namespace xt
6162
// we check that `fclose` can be called on them!
6263
template <class O>
6364
auto dump_bin_imp(O& file, const char* uncompressed_buffer, std::size_t uncompressed_size)
64-
-> decltype(fclose(file), void())
65+
-> decltype(file.ftell(), void())
6566
{
66-
fwrite(uncompressed_buffer, 1, uncompressed_size, file);
67-
fflush(file);
67+
file.fwrite(uncompressed_buffer, 1, uncompressed_size);
68+
file.fflush();
6869
}
6970

7071
// dump_bin "overload" for stream-like objects

include/xtensor-io/xio_file.hpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#ifndef XTENSOR_IO_FILE_HPP
2+
#define XTENSOR_IO_FILE_HPP
3+
4+
#include <stdio.h>
5+
6+
namespace xt
7+
{
8+
class xfile
9+
{
10+
public:
11+
xfile(FILE* stream);
12+
size_t fwrite(const void* ptr, size_t size, size_t count);
13+
size_t fread(void* ptr, size_t size, size_t count);
14+
long int ftell();
15+
int fseek(long int offset, int origin);
16+
void rewind();
17+
int fflush();
18+
private:
19+
FILE* m_stream;
20+
};
21+
22+
inline xfile::xfile(FILE* stream)
23+
: m_stream(stream)
24+
{
25+
}
26+
27+
inline size_t xfile::fwrite(const void* ptr, size_t size, size_t count)
28+
{
29+
return ::fwrite(ptr, size, count, m_stream);
30+
}
31+
32+
inline size_t xfile::fread(void* ptr, size_t size, size_t count)
33+
{
34+
return ::fread(ptr, size, count, m_stream);
35+
}
36+
37+
inline long int xfile::ftell()
38+
{
39+
return ::ftell(m_stream);
40+
}
41+
42+
inline int xfile::fseek(long int offset, int origin)
43+
{
44+
return ::fseek(m_stream, offset, origin);
45+
}
46+
47+
inline void xfile::rewind()
48+
{
49+
::rewind(m_stream);
50+
}
51+
52+
inline int xfile::fflush()
53+
{
54+
return ::fflush(m_stream);
55+
}
56+
}
57+
58+
#endif
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#ifndef XTENSOR_IO_GDAL_HANDLER_HPP
2+
#define XTENSOR_IO_GDAL_HANDLER_HPP
3+
4+
#include <xtensor/xarray.hpp>
5+
#include <xtensor/xexpression.hpp>
6+
#include <xtensor-io/xfile_array.hpp>
7+
#include <xtensor-io/xio_vsilfile.hpp>
8+
9+
#include <cpl_vsi.h>
10+
11+
namespace xt
12+
{
13+
struct xio_gdal_config
14+
{
15+
};
16+
17+
template <class C>
18+
class xio_gdal_handler
19+
{
20+
public:
21+
using io_config = xio_gdal_config;
22+
23+
template <class E>
24+
void write(const xexpression<E>& expression, const std::string& path, xfile_dirty dirty);
25+
26+
template <class ET>
27+
void read(ET& array, const std::string& path);
28+
29+
void configure(const C& format_config, const xio_gdal_config& io_config);
30+
void configure_io(const xio_gdal_config& io_config);
31+
32+
private:
33+
34+
C m_format_config;
35+
};
36+
37+
template <class C>
38+
template <class E>
39+
inline void xio_gdal_handler<C>::write(const xexpression<E>& expression, const std::string& path, xfile_dirty dirty)
40+
{
41+
if (m_format_config.will_dump(dirty))
42+
{
43+
VSILFILE* out_file = VSIFOpenL(path.c_str(), "wb");
44+
if (out_file != NULL)
45+
{
46+
auto f = xvsilfile(out_file);
47+
dump_file(f, expression, m_format_config);
48+
}
49+
else
50+
{
51+
XTENSOR_THROW(std::runtime_error, "write: failed to open file " + path);
52+
}
53+
}
54+
}
55+
56+
template <class C>
57+
template <class ET>
58+
inline void xio_gdal_handler<C>::read(ET& array, const std::string& path)
59+
{
60+
VSILFILE* in_file = VSIFOpenL(path.c_str(), "rb");
61+
if (in_file != NULL)
62+
{
63+
auto f = xvsilfile(in_file);
64+
load_file<ET>(f, array, m_format_config);
65+
}
66+
else
67+
{
68+
XTENSOR_THROW(std::runtime_error, "read: failed to open file " + path);
69+
}
70+
}
71+
72+
template <class C>
73+
inline void xio_gdal_handler<C>::configure(const C& format_config, const xio_gdal_config& io_config)
74+
{
75+
m_format_config = format_config;
76+
}
77+
78+
template <class C>
79+
inline void xio_gdal_handler<C>::configure_io(const xio_gdal_config& io_config)
80+
{
81+
}
82+
83+
}
84+
85+
#endif

include/xtensor-io/xio_vsilfile.hpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#ifndef XTENSOR_IO_VSILFILE_HPP
2+
#define XTENSOR_IO_VSILFILE_HPP
3+
4+
#include <cpl_vsi.h>
5+
6+
namespace xt
7+
{
8+
class xvsilfile
9+
{
10+
public:
11+
xvsilfile(VSILFILE* stream);
12+
size_t fwrite(const void* ptr, size_t size, size_t count);
13+
size_t fread(void* ptr, size_t size, size_t count);
14+
long int ftell();
15+
int fseek(long int offset, int origin);
16+
void rewind();
17+
int fflush();
18+
private:
19+
VSILFILE* m_stream;
20+
};
21+
22+
inline xvsilfile::xvsilfile(VSILFILE* stream)
23+
: m_stream(stream)
24+
{
25+
}
26+
27+
inline size_t xvsilfile::fwrite(const void* ptr, size_t size, size_t count)
28+
{
29+
return VSIFWriteL(ptr, size, count, m_stream);
30+
}
31+
32+
inline size_t xvsilfile::fread(void* ptr, size_t size, size_t count)
33+
{
34+
return VSIFReadL(ptr, size, count, m_stream);
35+
}
36+
37+
inline long int xvsilfile::ftell()
38+
{
39+
return VSIFTellL(m_stream);
40+
}
41+
42+
inline int xvsilfile::fseek(long int offset, int origin)
43+
{
44+
return VSIFSeekL(m_stream, offset, origin);
45+
}
46+
47+
inline void xvsilfile::rewind()
48+
{
49+
VSIRewindL(m_stream);
50+
}
51+
52+
inline int xvsilfile::fflush()
53+
{
54+
return VSIFFlushL(m_stream);
55+
}
56+
}
57+
58+
#endif

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ set(XTENSOR_IO_TESTS
8585
test_xio_binary.cpp
8686
test_xio_gcs_handler.cpp
8787
test_xio_aws_handler.cpp
88+
test_xio_gdal_handler.cpp
8889
)
8990

9091
set(XTENSOR_IO_HO_TESTS

test/test_xio_gdal_handler.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/***************************************************************************
2+
* Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
3+
* Copyright (c) QuantStack *
4+
* *
5+
* Distributed under the terms of the BSD 3-Clause License. *
6+
* *
7+
* The full license is in the file LICENSE, distributed with this software. *
8+
****************************************************************************/
9+
10+
#include "gtest/gtest.h"
11+
12+
#include <cpl_vsi.h>
13+
#include "xtensor-io/xio_vsilfile.hpp"
14+
#include "xtensor-io/xio_binary.hpp"
15+
#include "xtensor-io/xio_gdal_handler.hpp"
16+
17+
namespace xt
18+
{
19+
TEST(xio_gdal_handler, write_read)
20+
{
21+
VSIInstallMemFileHandler();
22+
xio_gdal_handler<xio_binary_config> h;
23+
xarray<int32_t> a0 = {3, 2, 1, 4};
24+
h.write(a0, "/vsimem/test_file.tif", xfile_dirty(true));
25+
xarray<int32_t> a1;
26+
h.read(a1, "/vsimem/test_file.tif");
27+
EXPECT_TRUE(xt::all(xt::equal(a0, a1)));
28+
}
29+
}

0 commit comments

Comments
 (0)