# Spécifications du module Gestion de Fichiers
###### tags: `specs`
Ce qu'il faut sauvegarder:
- Nom du graphe + version (nom du fichier sauvegardé)
- Sommets : POINT, numéro, étiquette, vecteur -> bool: int 1, float 0
- Arcs : numero, étiquette, sommet depart, sommet fin, vecteur
- Graphe : nbSommets, étiquette, liste arc/sommet (précédement écrit)
## Introduction
Le module de gestion de fichiers présent dans l'application, permet de gérer les fichiers soit en le sauvegardant, en le chargeant ou bien en le supprimant. Ce module utilise la bibliothèque RapidJSON détaillée ci dessous.
## La bibliothèque
Nous souhaitons avoir un langage de format de données textuelles permettant de rendre lisible les fichiers de sauvegarde par l'utilisateur.
Pour permettre à l'utilisateur de lire les fichiers de sauvegarde ou les faire lire par un autre programme nous devons avoir un langage de description suffisament clair pour être lu par un humain, mais suffisament utilisé et avec des règles d'écritures fortes pour permettre à l'utilisateur de pouvoir s'en servir avec d'autres programmes.
Le JSON nous est donc apparu comme une évidence, en effet, ce langage est doté d'une syntaxe claire et lisible, il est très utilisé et de nombreuses bibliothèques dans plusieurs langages existent, permettant ainsi à nos fichiers de sauvegarde d'être ré-exploitable. Sa syntaxe suit également des règles suffisament fortes pour communiquer efficacement et sans ambiguité.
Comme dit précédemment le JSON bénéficie de très nombreuses bibliothèques et cela dans un large panel de langages différent, le C++ n'échappe pas à la règle. Si on regarde sur le site officiel du [JSON](https://www.json.org/json-en.html) on peut voir près de 23 bibliothèques différentes rien que pour le C++. Certaines sont prévus pour des objectifs précis tel que les Arduinos.
Rapidement nous nous sommes intéressés à la bibliothèque RapidJSON car au vue de la taille potentielle des objets que nous voulons stocker, manipuler la vitesse n'est pas un paramètre à prendre à la légère.
Nous l'avons comparé à d'autres bibliothèque et **RapidJSON** est bien l'une des plus rapide, en effet son efficacité est comparable à celle de la fonction `strlen()`.
Bibliothèque de parsing et génération de JSON : **RapidJson**, http://rapidjson.org/
## La sauvegarde
```c++
int save(string path = NULL, Graphe G){
/*
Entrée : string path de valeur par défaut NULL permettant d'utiliser par
défaut le chemin retourné par G.getPath(). S'il est différent de NULL
on est dans le cas du sauvegarder sous ou d'un nouveau document car l'on
spécifie un chemin de sauvegarde. Et Graphe G est passée pour permettre
son parsing et sauvegarde.
Retourne un code d'erreur ou de réussite.
La fonction va parser l'objet G et va écrire le fichier placé en
paramètre ou en attribut. L'objet sera écrit comme décrit dans la partie
Exemple d'un fichier JSON.
*/
}
TEST_CASE("Test du nom du fichier", "[graphe]"){
/*
Test pour savoir si le nom du fichier est equivalent a celui du graphe
*/
TEST_CASE("Test du chemin du fichier", "[graphe]"){
/*
Test pour savoir si le path du fichier est equivalent a celui du graphe
*/
```
### **Exemple d'un fichier JSON :**
Description d'un graphe *"_name"* ayant deux sommets, S0 et S1 et deux arcs :
>A0 : 0 -> 1
>A1 : 1 -> 0
```json
{
"nom":
"_name",
"version":
0.0.0,
"list_arc":
[
{
"id":0,
"etiquette": "_etiquette",
"ID_depart": 0,
"ID_arrivee": 1,
"Charge_utile": [...]
},
{
"id":1,
"etiquette": "_etiquette",
"ID_depart": 1,
"ID_arrivee": 0,
"Charge_utile": [...]
}
],
"list_sommet":
[
{
"posX":0,
"posY":0,
"id": 0,
"etiquette": "_etiquette",
"liste_ID_Arc":
[
0
],
"Charge_utile": [...]
},
{
"posX":0,
"posY":0,
"id": 1,
"etiquette": "_etiquette",
"liste_ID_Arc":
[
1
],
"Charge_utile": [...]
}
],
"path": "/path/name"
}
```
Dans le fichier JSON on va retrouver le nom et la version du graphe mais aussi :
- La liste de ses arcs, qui est un vecteur d'arcs en c++, qui est ici un tableau de map, chaque map symbolisant un arc, avec pour chaque map :
- l'ID de chaque arc
- Leur étiquette
- L'ID du sommet de départ
- L'ID du sommet d'arrivée
- Et la "charge utile" qui est un vecteur, symbolisé ici en tableau, embarquant les valeurs utiles pour des algorithmes, tel que le poids, le flot maximum etc...
- La liste de ses sommets, qui est un vecteur de sommets en c++, qui est ici un tableau de map, chaque map symbolisant un sommet, avec pour chaque map :
- Les positions X et Y de chaque sommet dans l'espace de dessin
- L'ID de chaque sommet
- L'étiquette de chaque sommet
- La liste d'ID des arcs sortants du sommet. Dans le code source il s'agit d'un vecteur d'entier, c'est ici donc un tableau.
- Et la "charge utile" qui est un vecteur, symbolisé ici en tableau, embarquant les valeurs utiles pour des algorithmes.
- Le chemin du fichier de sauvegarde
## Le chargement
```cpp
Graphe load(string path){
/*
Entrée : String path, chemin du fichier
Sortie : Le graphe présent dans le fichier
Cette fonction permet de parser le fichier JSON où était sauvegardé un
graphe lors d'une précédente session et de le charger.
*/
}
Bool verif_file(Document d){
/*
* Entrée : Document d décrivant le fichier JSON parsé
* Sortie : Booleen validant ou invalidant un fichier
*
* Fonction qui va se charger de vérifier que le document JSON correpond à l'archétype de notre docment de sauvegarde.
* Si oui, renvoie 1 sinon 0.
* */
}
TEST_CASE("Test de validité du fichier", "[]"){
/*
Permet de vérifier que la fonction valide les documents qui doivent l'être (respectant le document de sauvegarde type décrit plus haut) et invalide ceux ne le respectant pas.
*/
TEST_CASE("Test de chargement de fichier", "[]"){
/*
* Vérifie que la fonction charge bien un graphe présent dans un fichier de test.
* */
}
```
## La suppression
```c++
int delete(string path){
/*
Entrée : String path, chemin du fichier .
Sortie : Le fichier est supprimé. Renvoie un code de réussite. Dans le cas contraire un code d'erreur.
*/
}
TEST_CASE("Test de suppression du fichier", "[]"){
/*
Test pour savoir si le nom du fichier existe encore après sa suppression
*/