Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ Le format est basé sur [Keep a Changelog](https://keepachangelog.com/) et ce pr

## [Unreleased]

### Changed
- `Storage` : les erreurs de lecture (`read` et `read_full`) sont remontées sous forme d'exception :
- `NotFoundStorageException`
- `UnreachableStorageException`
- `ForbiddenStorageException`

### Fixed

- TiffHeader : définition des en-têtes pour des images deux canaux entiers 8 bits
Expand Down
9 changes: 1 addition & 8 deletions cmake/modules/FindBoostLog.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ FIND_LIBRARY(BOOSTLOGSETUP_LIBRARY NAMES libboost_log_setup.so PATHS
/usr/lib64
)

FIND_LIBRARY(BOOSTSYSTEM_LIBRARY NAMES libboost_system.so PATHS
/usr/lib/x86_64-linux-gnu/
/usr/local/lib
/usr/lib
/usr/lib64
)

FIND_LIBRARY(BOOSTFILESYSTEM_LIBRARY NAMES libboost_filesystem.so PATHS
/usr/lib/x86_64-linux-gnu/
/usr/local/lib
Expand All @@ -47,4 +40,4 @@ FIND_LIBRARY(BOOSTTHREAD_LIBRARY NAMES libboost_thread.so PATHS
)

INCLUDE( "FindPackageHandleStandardArgs" )
FIND_PACKAGE_HANDLE_STANDARD_ARGS( "BoostLog" DEFAULT_MSG BOOSTLOG_INCLUDE_DIR BOOSTLOG_LIBRARY BOOSTLOGSETUP_LIBRARY BOOSTTHREAD_LIBRARY BOOSTFILESYSTEM_LIBRARY BOOSTSYSTEM_LIBRARY)
FIND_PACKAGE_HANDLE_STANDARD_ARGS( "BoostLog" DEFAULT_MSG BOOSTLOG_INCLUDE_DIR BOOSTLOG_LIBRARY BOOSTLOGSETUP_LIBRARY BOOSTTHREAD_LIBRARY BOOSTFILESYSTEM_LIBRARY)
2 changes: 0 additions & 2 deletions cmake/modules/dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ if(NOT TARGET boostlog)
set_property(TARGET boostlogsetup PROPERTY IMPORTED_LOCATION ${BOOSTLOGSETUP_LIBRARY})
add_library(boostthread SHARED IMPORTED)
set_property(TARGET boostthread PROPERTY IMPORTED_LOCATION ${BOOSTTHREAD_LIBRARY})
add_library(boostsystem SHARED IMPORTED)
set_property(TARGET boostsystem PROPERTY IMPORTED_LOCATION ${BOOSTSYSTEM_LIBRARY})
add_library(boostfilesystem SHARED IMPORTED)
set_property(TARGET boostfilesystem PROPERTY IMPORTED_LOCATION ${BOOSTFILESYSTEM_LIBRARY})
add_definitions(-DBOOST_LOG_DYN_LINK -DBOOST_SYSTEM_USE_UTF8)
Expand Down
18 changes: 16 additions & 2 deletions include/rok4/storage/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
#include <string.h>
#include <sstream>

#include "utils/Exception.h"

#define ROK4_OBJECT_READ_ATTEMPTS "ROK4_OBJECT_READ_ATTEMPTS"
#define ROK4_OBJECT_WRITE_ATTEMPTS "ROK4_OBJECT_WRITE_ATTEMPTS"
#define ROK4_OBJECT_ATTEMPTS_WAIT "ROK4_OBJECT_ATTEMPTS_WAIT"
Expand Down Expand Up @@ -234,13 +236,19 @@ class Context {
* \param[in] offset À partir d'où on veut lire
* \param[in] size Nombre d'octet que l'on veut lire
* \param[in] name Nom de l'objet que l'on veut lire
* \return Taille effectivement lue, un nombre négatif en cas d'erreur
* \return Taille effectivement lue
* \throw NotFoundStorageException
* \throw UnreachableStorageException
* \throw ForbiddenStorageException
* \~english \brief Get the data in the named object
* \param[in,out] data Buffer where to store read data. Have to be initialized
* \param[in] offset From where we want to read
* \param[in] size Number of bytes we want to read
* \param[in] name Object's name we want to read
* \return Real size of read data, negative integer if an error occured
* \return Real size of read data
* \throw NotFoundStorageException
* \throw UnreachableStorageException
* \throw ForbiddenStorageException
*/
virtual int read(uint8_t* data, int offset, int size, std::string name) = 0;

Expand All @@ -250,10 +258,16 @@ class Context {
* \param[in,out] size Taille effectivement lue, un nombre négatif en cas d'erreur
* \param[in] name Nom de l'objet que l'on veut lire
* \return Buffer stockant la donnée lue.
* \throw NotFoundStorageException
* \throw UnreachableStorageException
* \throw ForbiddenStorageException
* \~english \brief Get the data in the named object or file
* \param[in,out] size Real size of read data, negative integer if an error occured
* \param[in] name Object's name we want to read
* \return Buffer where read data is stored.
* \throw NotFoundStorageException
* \throw UnreachableStorageException
* \throw ForbiddenStorageException
*/
virtual uint8_t* read_full(int& size, std::string name) = 0;

Expand Down
1 change: 1 addition & 0 deletions include/rok4/thirdparty/json11.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#include <vector>
#include <map>
#include <memory>
#include <cstdint>
#include <initializer_list>

#ifdef _MSC_VER
Expand Down
85 changes: 85 additions & 0 deletions include/rok4/utils/Exception.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright © (2011) Institut national de l'information
* géographique et forestière
*
* Géoportail SAV <contact.geoservices@ign.fr>
*
* This software is a computer program whose purpose is to publish geographic
* data using OGC WMS and WMTS protocol.
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
*
* knowledge of the CeCILL-C license and that you accept its terms.
*/

/**
* \file Exception.h
* \~french
* \brief Définition de la gestion des exceptions
* \~english
* \brief Define the exceptions handler
*/

#pragma once

using namespace std;

#include <string>

/**
* \author Institut national de l'information géographique et forestière
* \~french
* \brief Erreur de stockage
*/
class StorageException : public exception {
private:
string message;

public:
// Constructor accepting const char*
StorageException(const char* msg) : message(msg) {}

// Override what() method, marked
// noexcept for modern C++
const char* what() const noexcept {
return message.c_str();
}
};

class NotFoundStorageException : public StorageException {
public:
NotFoundStorageException(std::string msg) : StorageException(msg.c_str()) {}
};

class UnreachableStorageException : public StorageException {
public:
UnreachableStorageException(std::string msg) : StorageException(msg.c_str()) {}
};

class ForbiddenStorageException : public StorageException {
public:
ForbiddenStorageException(std::string msg) : StorageException(msg.c_str()) {}
};
83 changes: 43 additions & 40 deletions src/datasource/StoreDataSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,15 @@ const uint8_t* StoreDataSource::get_data ( size_t &tile_size ) {
if (tile_indice == -1) {
// On a directement la taille et l'offset
data = new uint8_t[wanted_size];
int read_size = context->read(data, offset, wanted_size, name);
if (read_size < 0) {
BOOST_LOG_TRIVIAL(error) << "Cannot read " << context->get_path(name) << " from size and offset" ;
try {
int read_size = context->read(data, offset, wanted_size, name);
tile_size = read_size;
size = tile_size;
} catch (StorageException& err) {
delete[] data;
data = NULL;
return NULL;
throw;
}
tile_size = read_size;
size = tile_size;
} else {
// Nous n'avons pas les infos de taille et d'offset pour la tuile, nous allons devoir les récupérer lire
// On va regarder si on n'a pas nos informations dans le cache
Expand All @@ -114,40 +114,41 @@ const uint8_t* StoreDataSource::get_data ( size_t &tile_size ) {
// Rien de valide dans le cache, on va lire l'index de la dalle
BOOST_LOG_TRIVIAL(debug) << "pas de cache";

std::string originalFullName (full_name);
std::string originalTrayName (context->get_tray());
std::string original_full_name (full_name);
std::string original_tray_name (context->get_tray());

int headerIndexSize = ROK4_IMAGE_HEADER_SIZE + 2 * 4 * tiles_number;
uint8_t* indexheader = new uint8_t[headerIndexSize];
int realSize = context->read(indexheader, 0, headerIndexSize, name);
int header_index_size = ROK4_IMAGE_HEADER_SIZE + 2 * 4 * tiles_number;
uint8_t* index_header = new uint8_t[header_index_size];
int real_size;

if ( realSize < 0) {
BOOST_LOG_TRIVIAL(error) << "Cannot read header and index of slab " << full_name ;
delete[] indexheader;
return NULL;
try {
real_size = context->read(index_header, 0, header_index_size, name);
} catch (StorageException& err) {
delete[] index_header;
throw;
}

if ( realSize < headerIndexSize ) {
if ( real_size < header_index_size ) {

// On a lu moins que ce qu'on voulait :
// - soit c'est une dalle symbolique, ce qu'on va confirmer via la signature
// - soit c'est une dalle cassée

// Dans le cas d'un header de type objet lien, on verifie d'abord que la signature concernée est bien presente dans le header de l'objet
if ( realSize < ROK4_SYMLINK_SIGNATURE_SIZE || strncmp((char*) indexheader, ROK4_SYMLINK_SIGNATURE, ROK4_SYMLINK_SIGNATURE_SIZE) != 0 ) {
if ( real_size < ROK4_SYMLINK_SIGNATURE_SIZE || strncmp((char*) index_header, ROK4_SYMLINK_SIGNATURE, ROK4_SYMLINK_SIGNATURE_SIZE) != 0 ) {
BOOST_LOG_TRIVIAL(error) << "Read data in " << full_name << " is neither an header and an index (too small) nor a link (no signature)";
delete[] indexheader;
delete[] index_header;
return NULL;
}

// On est dans le cas d'un objet symbolique

BOOST_LOG_TRIVIAL(debug) << "dalle symbolique";

char tmpName[realSize-ROK4_SYMLINK_SIGNATURE_SIZE+1];
memcpy((uint8_t*) tmpName, indexheader+ROK4_SYMLINK_SIGNATURE_SIZE,realSize-ROK4_SYMLINK_SIGNATURE_SIZE);
tmpName[realSize-ROK4_SYMLINK_SIGNATURE_SIZE] = '\0';
full_name = std::string (tmpName);
char tmp_name[real_size-ROK4_SYMLINK_SIGNATURE_SIZE+1];
memcpy((uint8_t*) tmp_name, index_header+ROK4_SYMLINK_SIGNATURE_SIZE,real_size-ROK4_SYMLINK_SIGNATURE_SIZE);
tmp_name[real_size-ROK4_SYMLINK_SIGNATURE_SIZE] = '\0';
full_name = std::string (tmp_name);
name = full_name;


Expand All @@ -162,7 +163,7 @@ const uint8_t* StoreDataSource::get_data ( size_t &tile_size ) {
std::string tray_name = token;
name.erase(0, tray_name.length() + 1);

if (originalTrayName != tray_name) {
if (original_tray_name != tray_name) {
// Récupération ou ajout du nouveau contexte de stockage
// On reprécise le contexte d'origine, pour utiliser le même cluster en cas S3
context = StoragePool::get_context(context->get_type(), tray_name, context);
Expand All @@ -174,27 +175,27 @@ const uint8_t* StoreDataSource::get_data ( size_t &tile_size ) {
}
}

BOOST_LOG_TRIVIAL(debug) << "Symbolic slab detected : " << originalFullName << " -> " << full_name ;

int realSize = context->read(indexheader, 0, headerIndexSize, name);
BOOST_LOG_TRIVIAL(debug) << "Symbolic slab detected : " << original_full_name << " -> " << full_name ;

if ( realSize < 0) {
BOOST_LOG_TRIVIAL(error) << "Cannot read header and index of slab " << full_name ;
delete[] indexheader;
return NULL;
try {
real_size = context->read(index_header, 0, header_index_size, name);
} catch (StorageException& err) {
delete[] index_header;
throw;
}
if ( realSize < headerIndexSize ) {
BOOST_LOG_TRIVIAL(error) << "Read data in slab " << full_name << " (referenced by " << originalFullName << ") is too small to be an header and an index";
delete[] indexheader;

if ( real_size < header_index_size ) {
BOOST_LOG_TRIVIAL(error) << "Read data in slab " << full_name << " (referenced by " << original_full_name << ") is too small to be an header and an index";
delete[] index_header;
return NULL;
}

}

IndexCache::add_slab_infos(originalFullName, context, name, tiles_number, indexheader + ROK4_IMAGE_HEADER_SIZE, indexheader + ROK4_IMAGE_HEADER_SIZE + 4 * tiles_number);
offset = *((uint32_t*) (indexheader + ROK4_IMAGE_HEADER_SIZE + 4 * tile_indice ));
wanted_size = *((uint32_t*) (indexheader + ROK4_IMAGE_HEADER_SIZE + 4 * tiles_number + 4 * tile_indice ));
delete[] indexheader;
IndexCache::add_slab_infos(original_full_name, context, name, tiles_number, index_header + ROK4_IMAGE_HEADER_SIZE, index_header + ROK4_IMAGE_HEADER_SIZE + 4 * tiles_number);
offset = *((uint32_t*) (index_header + ROK4_IMAGE_HEADER_SIZE + 4 * tile_indice ));
wanted_size = *((uint32_t*) (index_header + ROK4_IMAGE_HEADER_SIZE + 4 * tiles_number + 4 * tile_indice ));
delete[] index_header;
}

if ( wanted_size == 0 ) {
Expand All @@ -205,11 +206,13 @@ const uint8_t* StoreDataSource::get_data ( size_t &tile_size ) {

// Lecture de la tuile
data = new uint8_t[wanted_size];
if (context->read(data, offset, wanted_size, name) < 0) {

try {
context->read(data, offset, wanted_size, name);
} catch (StorageException& err) {
delete[] data;
data = NULL;
BOOST_LOG_TRIVIAL(error) << "Erreur lors de la lecture de la tuile dans l'objet " << full_name ;
return NULL;
throw;
}

tile_size = wanted_size;
Expand Down
6 changes: 6 additions & 0 deletions src/datasource/StoreDataSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ class StoreDataSource : public DataSource {
* Dans le cas d'une lecture partielle, on lit la position de la donnée (#posoff), la taille de la donnée (#possize), et on lit la tuile.
* \param[out] tile_size Taille utile dans le buffer pointé en sortie
* \return Un pointeur vers la donnée
* \throw NotFoundStorageException
* \throw UnreachableStorageException
* \throw ForbiddenStorageException
** \~english
* \brief Get the data from the source
* \details If data is already read (#data is not null), it's returned without re-reading.
Expand All @@ -193,6 +196,9 @@ class StoreDataSource : public DataSource {
* For partially reading, We read tile's position (#posoff), tile's size (#possize), then we read the data.
* \param[out] tile_size Real size of data in the returned pointed buffer
* \return Data pointer
* \throw NotFoundStorageException
* \throw UnreachableStorageException
* \throw ForbiddenStorageException
*/
virtual const uint8_t* get_data ( size_t &tile_size );

Expand Down
Loading
Loading