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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
include <syserr.h>
include <mach.h>
include <knet.h>
include "fmio.h"
# FMIO_READHEADER -- Read the header of a FMIO datafile and set up the FMIO
# runtime descriptor.
procedure fmio_readheader (fm)
pointer fm #I FMIO descriptor
pointer sp, buf, dh, pti, pt, ft, ip, op
int offset, buflen, npti, p1, p2, d1, d2, b_off1, b_off2, i
int status, chan, nbytes, nwords, maxpages, szbpage
errchk syserrs, calloc, malloc, realloc
long clktime()
begin
call smark (sp)
call salloc (dh, LEN_DHSTRUCT, TY_STRUCT)
chan = FM_CHAN(fm)
# Make a guess at the size of buffer needed to hold the header.
buflen = DEF_DFHDRLEN
call malloc (buf, buflen, TY_STRUCT)
# Read the full datafile header area into BUF.
repeat {
# Get the raw data.
nbytes = buflen * (SZ_STRUCT * SZB_CHAR)
call zardbf (chan, Memi[buf], nbytes, 1)
call zawtbf (chan, status)
if (status == ERR)
call syserrs (SYS_FMRERR, FM_DFNAME(fm))
# Extract the datafile header struct.
call miiupk32 (Memi[buf], Memi[dh], LEN_DHSTRUCT, TY_STRUCT)
if (DH_MAGIC(dh) != FMIO_MAGIC)
call syserrs (SYS_FMBADMAGIC, FM_DFNAME(fm))
# Repeat if the full header was not read.
if (DH_DATASTART(dh)-1 > nbytes) {
buflen = DH_DATASTART(dh)-1 / (SZ_STRUCT * SZB_CHAR)
call realloc (buf, buflen, TY_STRUCT)
} else if (status < DH_DATASTART(dh)-1) {
call syserrs (SYS_FMTRUNC, FM_DFNAME(fm))
} else
break
}
# Compute region of file in buffer.
b_off1 = 1
b_off2 = b_off1 + buflen * SZ_STRUCT * SZB_CHAR
# Copy general header fields.
FM_DFVERSION(fm) = DH_DFVERSION(dh)
FM_SZBPAGE(fm) = DH_SZBPAGE(dh)
FM_NLFILES(fm) = DH_NLFILES(dh)
FM_DATASTART(fm) = DH_DATASTART(dh)
FM_LSYNCTIME(fm) = clktime(0)
FM_DHMODIFIED(fm) = NO
# Initialize buffer sizes.
szbpage = FM_SZBPAGE(fm)
call fmio_setbuf (fm)
if (FM_SZBPAGE(fm) != szbpage)
call syserrs (SYS_FMBLKCHSZ, FM_DFNAME(fm))
# Initialize the file table.
call calloc (ft, (FM_NLFILES(fm) + 1) * LEN_FTE, TY_STRUCT)
FM_FTOFF(fm) = DH_FTOFF(dh)
FM_FTLASTNF(fm) = DH_FTLASTNF(dh)
FM_FTABLE(fm) = ft
ip = buf + FM_FTOFF(fm) - 1
call miiupk32 (Memi[ip], Memi[ip],
(FM_NLFILES(fm) + 1) * LEN_FTEX, TY_INT)
do i = 0, FM_NLFILES(fm) {
op = ft + i * LEN_FTE
LF_FSIZE(op) = FT_FSIZE(ip)
LF_FLAGS(op) = FT_FLAGS(ip)
ip = ip + LEN_FTEX
}
# Read the page table index.
FM_PTIOFF(fm) = DH_PTIOFF(dh)
FM_PTILEN(fm) = DH_PTILEN(dh)
FM_PTINPTI(fm) = DH_PTINPTI(dh)
ip = buf + FM_PTIOFF(fm) - 1
call malloc (pti, FM_PTILEN(fm), TY_INT)
call miiupk32 (Memi[ip], Memi[pti], FM_PTILEN(fm), TY_INT)
FM_PTINDEX(fm) = pti
# Now read the page table itself, stored in the data pages.
FM_PTLEN(fm) = DH_PTLEN(dh)
FM_PTNPTE(fm) = DH_PTNPTE(dh)
FM_PTLUPTE(fm) = DH_PTNPTE(dh)
call malloc (pt, FM_PTLEN(fm), TY_SHORT)
FM_PTABLE(fm) = pt
maxpages = FM_MAXBUFSIZE(fm) / FM_SZBPAGE(fm)
if (maxpages <= 0)
maxpages = DEF_BIGBUFNP
op = pt
npti = FM_PTINPTI(fm)
for (p1=1; p1 <= npti; p1=p2) {
# Get a contiguous range of page table pages.
d1 = Memi[pti+p1-1]
for (p2=p1+1; p2 <= npti; p2=p2+1) {
d2 = Memi[pti+p2-1]
if (d2-d1 != p2-p1 || p2-p1 >= maxpages)
break
}
# Read in the pages.
nbytes = (p2 - p1) * FM_SZBPAGE(fm)
nwords = nbytes / (SZB_CHAR * SZ_SHORT)
offset = (d1-1) * FM_SZBPAGE(fm) + FM_DATASTART(fm)
# Check to see if data is in BUF before reading datafile.
if (offset >= b_off1 && (offset+nbytes) <= b_off2)
call bytmov (Memi[buf], offset, Mems[op], 1, nbytes)
else {
call zardbf (chan, Mems[op], nbytes, offset)
call zawtbf (chan, status)
if (status < nbytes)
call syserrs (SYS_FMTRUNC, FM_DFNAME(fm))
}
op = op + nwords
}
# Swap the data.
if (BYTE_SWAP2 == YES)
call bswap2 (Mems[pt], 1, Mems[pt], 1, npti * FM_SZBPAGE(fm))
call mfree (buf, TY_STRUCT)
call sfree (sp)
end
|