...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package comdoc
18
19 import (
20 "bytes"
21 "encoding/binary"
22 )
23
24
25
26
27
28
29 func (r *ComDoc) readMSAT() error {
30 msat := r.Header.MSAT[:]
31 nextSector := r.Header.MSATNextSector
32 count := r.SectorSize / 4
33 values := make([]SecID, count)
34 for nextSector >= 0 {
35 if err := r.readSectorStruct(nextSector, values); err != nil {
36 return err
37 }
38 msat = append(msat, values[:count-1]...)
39 nextSector = values[count-1]
40 }
41 r.MSAT = msat
42 return nil
43 }
44
45
46 func (r *ComDoc) allocSectorTables() (satList, msatList []SecID) {
47
48 for i, j := range r.SAT {
49 if j == SecIDSAT || j == SecIDMSAT {
50 r.SAT[i] = SecIDFree
51 }
52 }
53
54 satPerSector := r.SectorSize / 4
55 msatPerSector := satPerSector - 1
56 for {
57 if len(r.SAT)%satPerSector != 0 {
58 panic("irregularly sized sector table")
59 }
60 satSectors := len(r.SAT) / satPerSector
61
62 msatSectors := (satSectors - msatInHeader + msatPerSector - 1) / msatPerSector
63
64 oldSize := len(r.SAT)
65 freeList := r.makeFreeSectors(satSectors+msatSectors, false)
66 if oldSize == len(r.SAT) {
67 msatList = freeList[:msatSectors]
68 satList = freeList[msatSectors:]
69 break
70 }
71
72
73 }
74
75 for _, i := range msatList {
76 r.SAT[i] = SecIDMSAT
77 }
78 for _, i := range satList {
79 r.SAT[i] = SecIDSAT
80 }
81 return satList, msatList
82 }
83
84
85
86 func (r *ComDoc) writeMSAT(satSectors, msatSectors []SecID) error {
87 satPerSector := r.SectorSize / 4
88 msatPerSector := satPerSector - 1
89 msatCount := msatInHeader + len(msatSectors)*msatPerSector
90 msat := make([]SecID, msatCount)
91 copy(msat, satSectors)
92 for i := len(satSectors); i < msatCount; i++ {
93 msat[i] = SecIDFree
94 }
95 copy(r.Header.MSAT[:], msat)
96 msat = msat[msatInHeader:]
97 buf := bytes.NewBuffer(r.sectorBuf)
98 nextSector := SecIDEndOfChain
99 chunk := make([]SecID, r.SectorSize/4)
100 for i := len(msatSectors) - 1; i >= 0; i-- {
101 sector := msatSectors[i]
102 j := i * msatPerSector
103 copy(chunk, msat[j:])
104 msat = msat[:j]
105 chunk[msatPerSector] = nextSector
106 nextSector = sector
107
108 buf.Reset()
109 binary.Write(buf, binary.LittleEndian, chunk)
110 if err := r.writeSector(sector, buf.Bytes()); err != nil {
111 return err
112 }
113 }
114 r.Header.MSATNextSector = nextSector
115 r.MSAT = msat
116 return nil
117 }
118
View as plain text