zhao
2021-06-24 02ca96debc6056275d58e55d97f7885a195542d0
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
using System;
using System.Collections.Generic;
using System.Text;
 
namespace HH.WMS.Utils.ExcelLibrary.CompoundDocumentFormat
{
    /// <summary>
    /// The master sector allocation table (MSAT) is an array of SecIDs of all sectors
    /// used by the sector allocation table (SAT).
    /// </summary>
    public class MasterSectorAllocation
    {
        CompoundDocument Document;
 
        int NumberOfSecIDs;
 
        int CurrentMSATSector;
 
        int SecIDCapacity;
 
        List<Int32> MasterSectorAllocationTable;
 
        public MasterSectorAllocation(CompoundDocument document)
        {
            this.Document = document;
            this.NumberOfSecIDs = document.Header.NumberOfSATSectors;
            this.CurrentMSATSector = document.Header.FirstSectorIDofMasterSectorAllocationTable;
            this.SecIDCapacity = document.SectorSize / 4 - 1;
            InitializeMasterSectorAllocationTable();
        }
 
        private void InitializeMasterSectorAllocationTable()
        {
            this.MasterSectorAllocationTable = new List<int>(NumberOfSecIDs);
            SelectSIDs(Document.Header.MasterSectorAllocationTable);
            int msid = Document.Header.FirstSectorIDofMasterSectorAllocationTable;
            while (msid != SID.EOC)
            {
                CurrentMSATSector = msid;
                int[] SIDs = Document.ReadSectorDataAsIntegers(msid);
                SelectSIDs(SIDs);
                msid = SIDs[SIDs.Length - 1];
            }
        }
 
        private void SelectSIDs(int[] SIDs)
        {
            for (int i = 0; i < SIDs.Length; i++)
            {
                int sid = SIDs[i];
                if (MasterSectorAllocationTable.Count < NumberOfSecIDs)
                {
                    MasterSectorAllocationTable.Add(sid);
                }
                else
                {
                    break;
                }
            }
        }
 
        public int GetSATSectorID(int SATSectorIndex)
        {
            if (SATSectorIndex < NumberOfSecIDs)
            {
                return MasterSectorAllocationTable[SATSectorIndex];
            }
            else if (SATSectorIndex == NumberOfSecIDs)
            {
                return AllocateSATSector();
            }
            else
            {
                throw new ArgumentOutOfRangeException("SATSectorIndex");
            }
        }
 
        public int AllocateSATSector()
        {
            int[] sids = new Int32[SecIDCapacity + 1];
            for (int i = 0; i < sids.Length; i++)
            {
                sids[i] = SID.Free;
            }
            int secID = Document.AllocateNewSector(sids);
            MasterSectorAllocationTable.Add(secID);
            NumberOfSecIDs++;
            int SATSectorIndex = NumberOfSecIDs - 1;
            if (NumberOfSecIDs <= 109)
            {
                Document.Header.MasterSectorAllocationTable[SATSectorIndex] = secID;
                Document.Write(76 + SATSectorIndex * 4, secID);
            }
            else
            {
                if (CurrentMSATSector == SID.EOC)
                {
                    CurrentMSATSector = AllocateMSATSector();
                    Document.Header.FirstSectorIDofMasterSectorAllocationTable = CurrentMSATSector;
                }
                int index = (SATSectorIndex - 109) % SecIDCapacity;
                Document.WriteInSector(CurrentMSATSector, index * 4, secID);
                if (index == SecIDCapacity - 1)
                {
                    int newMSATSector = AllocateMSATSector();
                    Document.WriteInSector(CurrentMSATSector, SecIDCapacity * 4, newMSATSector);
                    CurrentMSATSector = newMSATSector;
                }
            }
            Document.SectorAllocation.LinkSectorID(secID, SID.SAT);
            Document.Header.NumberOfSATSectors++;
            return secID;
        }
 
        public int AllocateMSATSector()
        {
            int[] secIDs = new int[SecIDCapacity + 1];
            for (int i = 0; i < SecIDCapacity; i++)
            {
                secIDs[i] = SID.Free;
            }
            secIDs[SecIDCapacity] = SID.EOC;
 
            int newMSATSector = Document.AllocateNewSector(secIDs);
 
            Document.SectorAllocation.LinkSectorID(newMSATSector, SID.MSAT);
            Document.Header.NumberOfMasterSectors++;
 
            return newMSATSector;
        }
    }
}