ansilove

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

sauce.c (3540B)


      1 /*
      2  * sauce.c
      3  * Ansilove 4.1.4
      4  * https://www.ansilove.org
      5  *
      6  * Copyright (c) 2011-2020 Stefan Vogt, Brian Cassidy, and Frederic Cambus
      7  * All rights reserved.
      8  *
      9  * Ansilove is licensed under the BSD 2-Clause License.
     10  * See LICENSE file for details.
     11  */
     12 
     13 #include <stdint.h>
     14 #include <stdlib.h>
     15 #include <string.h>
     16 
     17 #include "sauce.h"
     18 
     19 /* Reads SAUCE via a filename. */
     20 struct sauce *
     21 sauceReadFileName(char *fileName)
     22 {
     23 	FILE *file = fopen(fileName, "r");
     24 	if (file == NULL) {
     25 		return NULL;
     26 	}
     27 
     28 	struct sauce *record = sauceReadFile(file);
     29 	fclose(file);
     30 	return record;
     31 }
     32 
     33 /* Read SAUCE via a FILE pointer. */
     34 struct sauce *
     35 sauceReadFile(FILE *file)
     36 {
     37 	struct sauce *record;
     38 	record = malloc(sizeof *record);
     39 
     40 	if (record != NULL) {
     41 		memset(record, 0, sizeof *record);
     42 		readRecord(file, record);
     43 	}
     44 	return record;
     45 }
     46 
     47 #define READ_RECORD(record, size) \
     48 	read_status = fread(record, size, 1, file); \
     49 	if (read_status != 1) \
     50 		return;
     51 
     52 void
     53 readRecord(FILE *file, struct sauce *record)
     54 {
     55 	size_t read_status;
     56 
     57 	if (fseek(file, 0 - RECORD_SIZE, SEEK_END) != 0) {
     58 		return;
     59 	}
     60 
     61 	read_status = fread(record->ID, sizeof (record->ID) - 1, 1, file);
     62 	record->ID[sizeof (record->ID) - 1] = '\0';
     63 
     64 	if (read_status != 1 || strcmp(record->ID, SAUCE_ID) != 0) {
     65 		return;
     66 	}
     67 	READ_RECORD(record->version, sizeof(record->version) - 1);
     68 	record->version[sizeof (record->version) - 1] = '\0';
     69 	READ_RECORD(record->title, sizeof(record->title) - 1);
     70 	record->title[sizeof (record->title) - 1] = '\0';
     71 	READ_RECORD(record->author, sizeof(record->author) -1);
     72 	record->author[sizeof (record->author) - 1] = '\0';
     73 	READ_RECORD(record->group, sizeof(record->group) - 1);
     74 	record->group[sizeof (record->group) - 1] = '\0';
     75 	READ_RECORD(record->date, sizeof(record->date) - 1);
     76 	record->date[sizeof (record->date) - 1] = '\0';
     77 	READ_RECORD(&(record->fileSize), sizeof (record->fileSize));
     78 	READ_RECORD(&(record->dataType), sizeof (record->dataType));
     79 	READ_RECORD(&(record->fileType), sizeof (record->fileType));
     80 	READ_RECORD(&(record->tinfo1), sizeof (record->tinfo1));
     81 	READ_RECORD(&(record->tinfo2), sizeof (record->tinfo2));
     82 	READ_RECORD(&(record->tinfo3), sizeof (record->tinfo3));
     83 	READ_RECORD(&(record->tinfo4), sizeof (record->tinfo4));
     84 	READ_RECORD(&(record->comments), sizeof (record->comments));
     85 	READ_RECORD(&(record->flags), sizeof (record->flags));
     86 	READ_RECORD(record->tinfos, sizeof(record->tinfos) - 1);
     87 	record->tinfos[sizeof (record->tinfos) - 1] = '\0';
     88 
     89 	if (ferror(file) != 0) {
     90 		return;
     91 	}
     92 
     93 	if (record->comments > 0) {
     94 		record->comment_lines = malloc(record->comments *sizeof (*record->comment_lines));
     95 
     96 		if (record->comment_lines != NULL) {
     97 			if (readComments(file, record->comment_lines, record->comments) == -1) {
     98 				record->comments = 0;
     99 			}
    100 		}
    101 	}
    102 }
    103 
    104 int
    105 readComments(FILE *file, char **comment_lines, int32_t comments)
    106 {
    107 	int32_t i;
    108 	size_t read_status;
    109 
    110 	if (fseek(file, 0 - (RECORD_SIZE + 5 + COMMENT_SIZE *comments), SEEK_END) == 0) {
    111 		char ID[6];
    112 		read_status = fread(ID, sizeof (ID) - 1, 1, file);
    113 		if (read_status != 1)
    114 			return -1;
    115 
    116 		ID[sizeof (ID) - 1] = '\0';
    117 
    118 		if (strcmp(ID, COMMENT_ID) != 0) {
    119 			return -1;
    120 		}
    121 
    122 		for (i = 0; i < comments; i++) {
    123 			char buf[COMMENT_SIZE + 1] = "";
    124 
    125 			read_status = fread(buf, COMMENT_SIZE, 1, file);
    126 			if (read_status != 1)
    127 				return -1;
    128 
    129 			buf[COMMENT_SIZE] = '\0';
    130 
    131 			if (ferror(file) == 0) {
    132 				comment_lines[i] = strdup(buf);
    133 				if (comment_lines[i] == NULL) {
    134 					return -1;
    135 				}
    136 			} else {
    137 				return -1;
    138 			}
    139 		}
    140 		return 0;
    141 	}
    142 	return -1;
    143 }