Task: Just in time processing on a character stream

C: #include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

struct UserInput {
    char formFeed;
    char lineFeed;
    char tab;
    char space;
};

struct UserInputNode {
    struct UserInput ui;
    struct UserInputNode *next;
};

bool decode(FILE *fp, const struct UserInput ui) {
    char f = 0, l = 0, t = 0, s = 0;
    char buffer[1];

    while (fread(buffer, 1, 1, fp)) {
        char c = buffer[0];

        if (f == ui.formFeed && l == ui.lineFeed && t == ui.tab && s == ui.space) {
            if (c == '!')
                return false;
            putchar(c);
            return true;
        } else if (c == '\f') {
            f++;
            l = t = s = 0;
        } else if (c == '\n') {
            l++;
            t = s = 0;
        } else if (c == '\t') {
            t++;
            s = 0;
        } else {
            s++;
        }
    }

    return false;
}

void decodeFile(char *fileName, struct UserInputNode *uin) {
    FILE *fp;

    fp = fopen(fileName, "r");
    if (NULL == fp) {
        fprintf(stderr, "Could not find %s\n", fileName);
        return;
    }

    if (NULL == uin) {
        fprintf(stderr, "No user input detected!\n");
        return;
    }

    while (NULL != uin) {
        if (!decode(fp, uin->ui)) {
            break;
        }
        fseek(fp, 0, SEEK_SET);
        uin = uin->next;
    }
    printf("\n\n");
}

struct UserInputNode *getUserInput() {
    struct UserInputNode *uip, *temp;

    
    temp = malloc(sizeof(struct UserInputNode));
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 18;
    temp->ui.tab = 0;
    temp->ui.space = 0;
    uip = temp;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 68;
    temp->ui.tab = 0;
    temp->ui.space = 1;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 100;
    temp->ui.tab = 0;
    temp->ui.space = 32;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 114;
    temp->ui.tab = 0;
    temp->ui.space = 45;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 38;
    temp->ui.tab = 0;
    temp->ui.space = 26;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 16;
    temp->ui.tab = 0;
    temp->ui.space = 21;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 17;
    temp->ui.tab = 0;
    temp->ui.space = 59;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 11;
    temp->ui.tab = 0;
    temp->ui.space = 29;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 102;
    temp->ui.tab = 0;
    temp->ui.space = 0;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 10;
    temp->ui.tab = 0;
    temp->ui.space = 50;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 39;
    temp->ui.tab = 0;
    temp->ui.space = 42;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 33;
    temp->ui.tab = 0;
    temp->ui.space = 50;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 46;
    temp->ui.tab = 0;
    temp->ui.space = 54;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 76;
    temp->ui.tab = 0;
    temp->ui.space = 47;

    
    temp->next = malloc(sizeof(struct UserInputNode));
    temp = temp->next;
    temp->ui.formFeed = 0;
    temp->ui.lineFeed = 84;
    temp->ui.tab = 2;
    temp->ui.space = 28;

    temp->next = NULL;
    return uip;
}

void freeUserInput(struct UserInputNode *uip) {
    if (NULL == uip) {
        return;
    }

    freeUserInput(uip->next);
    uip->next = NULL;

    free(uip);
}

int main() {
    struct UserInputNode *uip;

    uip = getUserInput();
    decodeFile("theRaven.txt", uip);
    freeUserInput(uip);

    return 0;
}





Java: import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class Processing {
    private static class UserInput {
        private char formFeed;
        private char lineFeed;
        private char tab;
        private char space;

        private UserInput(char formFeed, char lineFeed, char tab, char space) {
            this.formFeed = formFeed;
            this.lineFeed = lineFeed;
            this.tab = tab;
            this.space = space;
        }

        char getFormFeed() {
            return formFeed;
        }

        char getLineFeed() {
            return lineFeed;
        }

        char getTab() {
            return tab;
        }

        char getSpace() {
            return space;
        }
    }

    private static List<UserInput> getUserInput() {
        String h = "0 18 0 0 0 68 0 1 0 100 0 32 0 114 0 45 0 38 0 26 0 16 0 21 0 17 0 59 0 11 " +
            "0 29 0 102 0 0 0 10 0 50 0 39 0 42 0 33 0 50 0 46 0 54 0 76 0 47 0 84 2 28";
        String[] s = h.split(" ");

        List<UserInput> uiList = new ArrayList<>();
        for (int idx = 0; idx + 3 < s.length; idx += 4) {
            char c0 = (char) Integer.parseInt(s[idx + 0]);
            char c1 = (char) Integer.parseInt(s[idx + 1]);
            char c2 = (char) Integer.parseInt(s[idx + 2]);
            char c3 = (char) Integer.parseInt(s[idx + 3]);

            UserInput userInput = new UserInput(c0, c1, c2, c3);
            uiList.add(userInput);
        }
        return uiList;
    }

    private static void decode(String fileName, List<UserInput> uiList) throws IOException {
        Path path = Paths.get(fileName);
        byte[] bytes = Files.readAllBytes(path);
        String text = new String(bytes, StandardCharsets.UTF_8);

        Predicate<UserInput> decode2 = (UserInput ui) -> {
            char f = 0;
            char l = 0;
            char t = 0;
            char s = 0;
            char ff = ui.getFormFeed();
            char lf = ui.getLineFeed();
            char tb = ui.getTab();
            char sp = ui.getSpace();

            for (char c : text.toCharArray()) {
                if (f == ff && l == lf && t == tb && s == sp) {
                    if (c == '!') {
                        return false;
                    }
                    System.out.print(c);
                    return true;
                }
                switch (c) {
                    case '\u000c':
                        f++;
                        l = 0;
                        t = 0;
                        s = 0;
                        break;
                    case '\n':
                        l++;
                        t = 0;
                        s = 0;
                        break;
                    case '\t':
                        t++;
                        s = 0;
                        break;
                    default:
                        s++;
                        break;
                }
            }

            return false;
        };

        for (UserInput ui : uiList) {
            if (!decode2.test(ui)) {
                break;
            }
        }
        System.out.println();
    }

    public static void main(String[] args) throws IOException {
        List<UserInput> uiList = getUserInput();
        decode("theRaven.txt", uiList);
    }
}