github.com/shakinm/xlsReader@v0.9.12/xls/record/sst.go (about) 1 package record 2 3 import ( 4 "github.com/shakinm/xlsReader/helpers" 5 "github.com/shakinm/xlsReader/xls/structure" 6 "io" 7 ) 8 9 // SST: Shared String Table 10 11 var SSTRecord = [2]byte{0xFC, 0x00} //(FCh) 12 13 /* 14 The SST record contains string constants. 15 16 17 Record Data — BIFF8 18 Offset Name Size Contents 19 -------------------------------------------- 20 4 cstTotal 4 Total number of strings in the shared string table and 21 extended string table ( EXTSST record) 22 8 cstUnique 4 Number of unique strings in the shared string table 23 12 rgb var Array of unique unicode strings (XLUnicodeRichExtendedString). 24 25 */ 26 27 type SST struct { 28 CstTotal [4]byte 29 CstUnique [4]byte 30 RgbSrc []byte 31 Rgb []structure.XLUnicodeRichExtendedString 32 chLen int 33 ByteLen int 34 } 35 36 func (s *SST) RgbAppend(bts []byte) (err error) { 37 for _, value := range bts { 38 s.RgbSrc = append(s.RgbSrc, value) 39 } 40 41 return err 42 } 43 44 func r() (err error) { 45 if r := recover(); r != nil { 46 return io.EOF 47 } 48 return 49 } 50 51 func abs(x int) int { 52 if x < 0 { 53 return -x 54 } 55 return x 56 } 57 58 func (s *SST) Read(readType string, grbit byte, prevLen int32) () { 59 60 defer r() 61 62 if len(s.RgbSrc) == 0 { 63 return 64 } 65 oft := uint32(0) 66 for { 67 68 var _rgb structure.XLUnicodeRichExtendedString 69 var rgbSize int 70 71 cch := int(helpers.BytesToUint16(s.RgbSrc[0:2])) 72 73 if readType != "continue" { 74 grbit = s.RgbSrc[2:3][0] 75 } 76 77 if readType == "continue" && prevLen == 0 && s.ByteLen == 0 { 78 grbit = s.RgbSrc[2:3][0] 79 } 80 81 readType = "" 82 83 if cch >= (len(s.RgbSrc)-3)/(1+int(grbit&1)) || s.ByteLen > 0 { 84 85 addBytesLen := (len(s.RgbSrc) - 3) - s.ByteLen 86 87 if cch-s.chLen > addBytesLen/(1+int(grbit&1)) { 88 s.chLen = s.chLen + addBytesLen/(1+int(grbit&1)) 89 s.ByteLen = s.ByteLen + addBytesLen 90 return 91 } else { 92 93 s.ByteLen = s.ByteLen + (cch-s.chLen)*(1+int(grbit&1)) 94 s.chLen = cch 95 rgbSize = s.ByteLen 96 } 97 98 } else { 99 rgbSize = cch * (1 + int(grbit&1)) 100 } 101 102 copy(_rgb.Cch[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 103 104 _rgb.FHighByte = s.RgbSrc[iOft(&oft, 0):iOft(&oft, 1)][0] 105 106 if _rgb.FHighByte>>3&1 == 1 { // if fRichSt == 1 107 copy(_rgb.CRun[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 108 } 109 110 if _rgb.FHighByte>>2&1 == 1 { //fExtSt == 1 111 copy(_rgb.CbExtRst[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 4)]) 112 } 113 114 //offset rgbSize 115 _rgb.Rgb = make([]byte, uint32(rgbSize)) 116 copy(_rgb.Rgb[0:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, uint32(rgbSize))]) 117 118 if _rgb.FHighByte>>3&1 == 1 { // if fRichSt == 1 119 cRunSize := helpers.BytesToUint16(_rgb.CRun[:]) 120 for i := uint16(0); i <= cRunSize-1; i++ { 121 var rgRun structure.FormatRun 122 copy(rgRun.Ich[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 123 copy(rgRun.Ifnt.Ifnt[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 124 _rgb.RgRun = append(_rgb.RgRun, rgRun) 125 } 126 } 127 128 if _rgb.FHighByte>>2&1 == 1 { //fExtSt == 1 129 copy(_rgb.ExtRst.Reserved[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 130 copy(_rgb.ExtRst.Cb[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 131 132 copy(_rgb.ExtRst.Phs.Ifnt.Ifnt[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 133 copy(_rgb.ExtRst.Phs.Info[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 134 135 copy(_rgb.ExtRst.Rphssub.Crun[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 136 copy(_rgb.ExtRst.Rphssub.Cch[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 137 138 copy(_rgb.ExtRst.Rphssub.St.CchCharacters[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 139 140 rgchDataSize := helpers.BytesToUint16(_rgb.ExtRst.Rphssub.St.CchCharacters[:]) * 2 141 for i := uint16(0); i <= rgchDataSize; i++ { 142 _rgb.ExtRst.Rphssub.St.RgchData = append(_rgb.ExtRst.Rphssub.St.RgchData, s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]...) 143 } 144 145 //The number of elements in this array is rphssub.crun 146 phRunsSizeL := helpers.BytesToUint16(_rgb.ExtRst.Rphssub.Crun[:]) 147 if phRunsSizeL > 0 { 148 for i := uint16(0); i <= phRunsSizeL; i++ { 149 var phRuns structure.PhRuns 150 copy(phRuns.IchFirst[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 151 copy(phRuns.IchMom[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 152 copy(phRuns.CchMom[:], s.RgbSrc[iOft(&oft, 0):iOft(&oft, 2)]) 153 154 _rgb.ExtRst.Rgphruns = append(_rgb.ExtRst.Rgphruns, phRuns) 155 } 156 } 157 } 158 159 if len(s.RgbSrc) >= int(oft) { 160 s.Rgb = append(s.Rgb, _rgb) 161 s.RgbSrc = s.RgbSrc[int(oft):] 162 s.chLen = 0 163 s.ByteLen = 0 164 oft = 0 165 166 if len(s.RgbSrc) == 0 { 167 return 168 } 169 170 } else { 171 break 172 } 173 174 } 175 176 } 177 178 func iOft(offset *uint32, inc uint32) uint32 { 179 *offset = *offset + inc 180 return *offset 181 } 182 183 func (s *SST) NewSST(buf []byte) { 184 copy(s.CstTotal[:], buf[:4]) 185 copy(s.CstUnique[:], buf[4:8]) 186 s.RgbSrc = append(s.RgbSrc, buf[8:]...) 187 }