From c133c4185b7a5962095dcda2122bbf011e39d94b Mon Sep 17 00:00:00 2001
From: j-twite <jonathan.twite@student.uclouvain.be>
Date: Tue, 14 Apr 2020 00:17:31 +0200
Subject: [PATCH] fileFeature

---
 fileFeatures.h | 104 ++++++++++++++++++++-----------------------------
 prime_divs.c   |  60 ++++++++++++++++++++++++++++
 2 files changed, 103 insertions(+), 61 deletions(-)
 create mode 100644 prime_divs.c

diff --git a/fileFeatures.h b/fileFeatures.h
index 39acef6..bd9b457 100644
--- a/fileFeatures.h
+++ b/fileFeatures.h
@@ -10,78 +10,60 @@
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <math.h>
 
-/**
- *  A SAVOIR pour la conversion de char en int:
- * Si 'x' ∈ ['0', '1', '2', ..., '9'] alors
- * alors (int) x = x - '0'
- */
-// Mes fonctions:
 
-long readLine(int file, char *buff);
-long parseLong(char *buff, int index);
-long ipow(int base, int exp);
-// bizarrement, quand j'appelle la fonction pow de la librairie math.h,
-// on me retourne des erreurs donc j'ai refait une implementation
+//functions:
+int factorize(char *file_in_memory, FILE *fileOutput);
+int factAndWrite(FILE *out, int n);
+int ipow(int base, int exp);
 
-/**
- * @param #file le fichier a read qu'on a prealablement charge (on ne charge pas le fichier ici)
- * @param #buff un char[x>=20] qui collecte les digits lus byte par byte
- * @return la ligne lue dans file sous forme numérique
- */
-long readline(int file, char buff[]) {
-    if(file == 0)  {
-        puts("End of file.");
-        return 0;
-    }
-
-    if (file <= 0) {
-        printf("Trying to read into %d directory.", file);
-        close(file);
-        return -1;
-    } else if (buff == NULL) {      // char doit être
-        puts("Trying to store values into NULL buffer.");
-        return -2;
-    }
-    int byteReader = read(file, &(*buff), 1);           // In order to call the read() iteratively, we have to call it once before
-    if (buff[0] > '9') {
-        puts("Illegal argument.");
-        return -3;
-    } else if(buff[0] < '0') {
-        puts("End of file");
-        return 0;
-    }
-    int i = 1;
-    while (byteReader = read(file, &buff[i], 1) > 0) {  // while datas are still remaining
-        if (buff[i] == '\n') {                                 // if this is the end of line
-            return parseLong(buff, i);                         // return the long value
-        } else if (buff[i] > '9' || buff[i] < '0') {           // if the readed value isn't a digit
-            printf("Illegal argument (%d)..", i);                     // stop the program
-            return -3;
-        } else                                                 // otherwise keep iterating
+// iterate through a mapped file and write each number found and factorize them
+// the program stop if file_in_memory contains anything else than a digit or a '\n'
+int factorize(char *file_in_memory, FILE *fileOutput) {
+    int start = 0;
+    int size = strlen(file_in_memory);
+    int i = 0;
+    while (i < size) {
+        if (file_in_memory[i] == '\n' && i > start) {   // if we are at the end of the line
+            int k = 0;
+            for (int j = i - 1; j >= start; j--)        // iterate from right to left
+                k += ((file_in_memory[j] - '0') *ipow(10, i - j - 1)); // record each digit into k
+            factAndWrite(fileOutput, k);                // write and factorize k into fileOutput
+            start = i += 1;
+        }
+        else if ((file_in_memory[i] > '9' || file_in_memory[i] < '0') && file_in_memory[i] != '\n') {
+            perror("Not a digit.");
+            return -2;
+        }
+        else
             i++;
     }
-    return byteReader;
+    return 0;
 }
 
-/**
- * @param #buff la ligne lue dans le fichier
- * @param index qui signifie les n premiers digits à lire
- * @return la ligne lue dans file sous forme numérique
- */
-long parseLong(char *buff, int index) {
-    if (buff == NULL)
-        return -1;
-    long k = 0;
-    for (int i = index - 1 ; i >= 0; i--) {
-        k += (buff[i] - '0') * ipow(10, index - (i + 1)) ;
+// * write n and its factorization in the file @out *
+int factAndWrite(FILE *out, int n) {
+    int x = n;
+    fprintf(out, "%d", n);
+    while (n % 2 == 0) {
+            fprintf(out, " 2");
+            n /= 2;
     }
-    return k;
+    for (int i = 3; x >= i*i; i+=2)
+        while (n % i == 0) {
+            fprintf(out, " %d", i);
+            n /= i;
+        }
+    if(n > 1 && n < x)    
+        fprintf(out, " %d", n);
+    fprintf(out, " \n");
+    return 0;
 }
 
 
-long ipow(int base, int exp) {
-    long result = 1;
+int ipow(int base, int exp) {
+    int result = 1;
     for (;;) {
         if (exp & 1)
             result *= base;
diff --git a/prime_divs.c b/prime_divs.c
new file mode 100644
index 0000000..a18db11
--- /dev/null
+++ b/prime_divs.c
@@ -0,0 +1,60 @@
+//
+// Created by jtwite on 28.03.20.
+//
+#include <sys/mman.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <string.h>
+#include "fileFeatures.h"
+
+
+// int max value: 2 147 483 647
+// long max value: 9223372 036 854 775 807
+
+
+// char *filepath = "/home/jtwite/Desktop/test";
+
+// Remplacez-le contenu par le chemin relatif du fichier que vous souhaitez tester.
+
+
+
+int main(int argc, char *argv[])
+{
+    struct timeval stop, start;
+    gettimeofday(&start, NULL);
+
+    printf("argv[1]: %s\n", argv[1]);
+    printf("argv[2]: %s\n", argv[2]);
+
+    //open the file
+    int fileInput = open(argv[1], O_RDONLY);
+    if (fileInput <= 0)
+        exit(1);
+
+    // get the fileInput size
+    struct stat sb;
+    fstat(fileInput, &sb);
+    char *file_in_memory = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fileInput, 0);
+    close(fileInput);
+    // Create a new file struct in which the output is writen
+    FILE *fileOutput = fopen(argv[2], "w");
+    if(fileOutput == NULL)
+        exit(-2);
+    //go through the mapped file to get numbers and write them in fileOutput
+
+    factorize(file_in_memory, fileOutput);
+
+    //close everything
+    munmap(file_in_memory, sb.st_size);
+
+    fclose(fileOutput);
+
+    gettimeofday(&stop, NULL);
+    printf("took %lu µs\n", (stop.tv_sec - start.tv_sec) * 1000000 + stop.tv_usec - start.tv_usec);
+
+    return 0;
+}
-- 
GitLab