ansilove

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

sauce.c (3584B)


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