aboutsummaryrefslogtreecommitdiff
path: root/src/save.c
blob: 379cd57cf9a925844dc5ab1c7bd32e5f3f0bb1e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "globals.h"

/* NOTE: integers are represented internally as long long ints, but in the save they are always 64 bits */

static uint64_t cksum;

#define ADD_CKSUM(x) (cksum += (x*x) + 1)

static bool write_be64(FILE *f, uint64_t n)
{
    ADD_CKSUM(n);

    n = to_be64(n);
    if(fwrite(&n, sizeof(n), 1, f) != 1)
        return false;
    return true;
}

static bool write_be32(FILE *f, uint32_t n)
{
    ADD_CKSUM(n);

    n = to_be32(n);
    if(fwrite(&n, sizeof(n), 1, f) != 1)
        return false;
    return true;
}

static bool write_be32_noupdate(FILE *f, uint32_t n)
{
    n = to_be32(n);
    if(fwrite(&n, sizeof(n), 1, f) != 1)
        return false;
    return true;
}

static bool write_be16(FILE *f, uint16_t n)
{
    ADD_CKSUM(n);

    n = to_be16(n);
    if(fwrite(&n, sizeof(n), 1, f) != 1)
        return false;
    return true;
}

static bool write_int8(FILE *f, uint8_t n)
{
    ADD_CKSUM(n);

    if(fwrite(&n, sizeof(n), 1, f) != 1)
        return false;
    return true;
}

size_t ck_write(const char *buf, size_t sz, size_t nmemb, FILE *f)
{
    for(size_t i = 0 ; i < sz * nmemb; ++i)
    {
        write_int8(f, buf[i]);
    }

    return nmemb;
}

void save_handler(struct player_t *player)
{
    output("Enter the file to save your portfolio in: ");

    char *filename = read_string();

    output("Writing data...\n");
    FILE *f = fopen(filename, "wb");

    free(filename);

    cksum = 0;

    ck_write(SAVE_MAGIC, strlen(SAVE_MAGIC), 1, f);

    write_be64(f, player->cash.cents);

    for(uint i = 0; i < player->portfolio_len; ++i)
    {
        struct stock_t *stock = player->portfolio + i;

        write_be64(f, strlen(stock->symbol));

        ck_write(stock->symbol, strlen(stock->symbol) + 1, 1, f);

        write_be64(f, stock->count);

        write_be32(f, stock->history_len);

        /* write history */
        struct history_item *hist = stock->history;
        while(hist)
        {
            write_be32(f, hist->action);
            write_be64(f, hist->count);
            write_be64(f, hist->price.cents);

            write_be16(f, hist->action_time.year);
            write_int8(f, hist->action_time.month);
            write_int8(f, hist->action_time.day);
            write_int8(f, hist->action_time.hour);
            write_int8(f, hist->action_time.minute);
            write_int8(f, hist->action_time.second);

            hist = hist->next;
        }

        write_be32_noupdate(f, cksum);
    }

    fclose(f);

    output("Done saving.\n");
}