summaryrefslogtreecommitdiff
path: root/command_line/CmdLine/Src/OSLib/FileHandles.c
blob: 69b4b11557d6ee9c6b8bc480fdde7c6d46abbca3 (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
120
121
122
123
124
125
126
127
128
#include "oslib.h"
#include <errno.h>

static int OS_LoadFileHandle(OSFileHandle *hand) {
    int err;
    int ref;
    UInt32 sz;
    void *buffer;

    hand->loaded = 0;

    err = OS_Open(&hand->spec, OSReadOnly, &ref);
    if (!err) {
        err = OS_GetSize(ref, &sz);
        if (!err) {
            err = OS_ResizeHandle(&hand->hand, sz);
            if (!err) {
                buffer = OS_LockHandle(&hand->hand);
                err = OS_Read(ref, buffer, &sz);
                if (!err) {
                    hand->loaded = 1;
                    hand->changed = 0;
                }
                OS_UnlockHandle(&hand->hand);
            }
        }
        OS_Close(ref);
    }

    return err;
}

static int OS_WriteFileHandle(OSFileHandle *hand) {
    int err;
    int ref;
    UInt32 sz;
    void *buffer;

    if (!hand->loaded && !hand->changed)
        return 0;

    OS_Delete(&hand->spec);
    err = OS_Create(&hand->spec, &OS_TEXTTYPE);
    if (!err) {
        err = OS_Open(&hand->spec, OSReadWrite, &ref);
        if (!err) {
            err = OS_GetHandleSize(&hand->hand, &sz);
            if (!err) {
                buffer = OS_LockHandle(&hand->hand);
                err = OS_Write(ref, buffer, &sz);
                if (!err)
                    hand->changed = 0;
                OS_UnlockHandle(&hand->hand);
                OS_Close(ref);
            }
        }
    }

    return err;
}

int OS_NewFileHandle(const OSSpec *spec, OSHandle *src, Boolean writeable, OSFileHandle *hand) {
    int err;

    if (!writeable && src)
        return EACCES;

    hand->spec = *spec;
    hand->writeable = writeable;

    if (!src) {
        err = OS_NewHandle(0, &hand->hand);
        if (err)
            return err;
        err = OS_LoadFileHandle(hand);
    } else {
        err = OS_CopyHandle(src, &hand->hand);
        if (err)
            return err;
        hand->changed = 1;
        hand->loaded = 1;
    }

    return err;
}

int OS_LockFileHandle(OSFileHandle *hand, Ptr *ptr, UInt32 *size) {
    *size = 0;

    if (!OS_ValidHandle(&hand->hand))
        return ENOMEM;

    *ptr = OS_LockHandle(&hand->hand);
    OS_GetHandleSize(&hand->hand, size);
    return 0;
}

int OS_UnlockFileHandle(OSFileHandle *hand) {
    if (!OS_ValidHandle(&hand->hand))
        return ENOMEM;

    OS_UnlockHandle(&hand->hand);
    return 0;
}

int OS_FreeFileHandle(OSFileHandle *hand) {
    int err;

    if (hand->writeable && hand->changed) {
        err = OS_WriteFileHandle(hand);
        if (err)
            return err;
    }

    if (!OS_ValidHandle(&hand->hand))
        return ENOMEM;

    err = OS_FreeHandle(&hand->hand);
    if (err)
        return err;

    hand->loaded = 0;
    return 0;
}

void OS_GetFileHandleSpec(const OSFileHandle *hand, OSSpec *spec) {
    *spec = hand->spec;
}