ansilove

ANSI and ASCII art to PNG converter in C
Log | Files | Refs | README | LICENSE

commit 3658a844965efb9e09b173a9e39a2dbabda74a74
parent c0264acab8d04ef4b1721a8522fe99101d959254
Author: Frederic Cambus <fred@statdns.com>
Date:   Fri, 29 Jun 2018 20:45:30 +0200

Use mmap(2) to map the input file into memory

Diffstat:
MTODO | 1-
Msrc/main.c | 39++++++++++++++++-----------------------
2 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/TODO b/TODO @@ -2,7 +2,6 @@ - Display mode information in summary - Use include-what-you-use to remove unnecessary headers - Use OpenBSD style(9) for function prototypes and declarations? -- Avoid reading the whole file in memory before parsing? - Allow reading from stdin? - Fix Travis CI build, need to install libansilove before building - Update documention to mention libansilove and drop GD from requirements diff --git a/src/main.c b/src/main.c @@ -12,11 +12,13 @@ #define _GNU_SOURCE #include <ansilove.h> #include <err.h> +#include <fcntl.h> #include <getopt.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/mman.h> #include <sys/stat.h> #include <unistd.h> @@ -127,6 +129,9 @@ int main(int argc, char *argv[]) { char *input = NULL, *output = NULL; + int fd; + struct stat st; + struct input inputFile; struct output outputFile; @@ -272,48 +277,32 @@ int main(int argc, char *argv[]) { inputFile.fext = fext; // load input file - FILE *input_file = fopen(input, "r"); - if (input_file == NULL) { + if ((fd = open(input, O_RDONLY)) == -1) { perror("File error"); return 1; } // get the file size (bytes) - struct stat input_file_stat; - - if (fstat(fileno(input_file), &input_file_stat)) { + if (fstat(fd, &st) == -1) { perror("Can't stat file"); return 1; } - inputFile.size = input_file_stat.st_size; - - // next up is loading our file into a dynamically allocated memory buffer + inputFile.size = st.st_size; - // allocate memory to contain the whole file - inputFile.data = (unsigned char *)malloc(sizeof (unsigned char)*inputFile.size + 1); - if (inputFile.data == NULL) { + // mmap input file into memory + inputFile.data = mmap(NULL, inputFile.size, PROT_READ, MAP_PRIVATE, fd, 0); + if (inputFile.data== MAP_FAILED) { perror("Memory error"); return 2; } - // copy the file into the buffer - if (fread(inputFile.data, 1, inputFile.size, input_file) != inputFile.size) { - perror("Reading error haha"); - return 3; - } // whole file is now loaded into inputFileBuffer - - inputFile.data[inputFile.size] = '\0'; - // adjust the file size if file contains a SAUCE record if (fileHasSAUCE) { - sauce *saucerec = sauceReadFile(input_file); + sauce *saucerec = sauceReadFileName(input); inputFile.size -= 129 - (saucerec->comments > 0 ? 5 + 64 * saucerec->comments : 0); } - // close input file, we don't need it anymore - fclose(input_file); - // create the output file by invoking the appropiate function if (!strcmp(fext, ".pcb")) { // params: input, output, font, bits, icecolors @@ -353,6 +342,10 @@ int main(int argc, char *argv[]) { if (fileIsBinary) { fprintf(stderr, "Columns: %d\n", inputFile.columns); } + + // close input file, we don't need it anymore + // TODO: munmap, with original inputFileSize + close(fd); } // either display SAUCE or tell us if there is no record