using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using Biff8Excel.Interfaces; using System.Collections.Specialized; using System.Collections; using System.Diagnostics; namespace Biff8Excel.Records { [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)] struct RecordSST { public ushort opcode; public ushort length; public uint totalstrings; public uint stringnumber; } //SST校验(未用) [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)] struct RecordExtSSt { public ushort opcode; // 0xFF public ushort length; public ushort npoint; // >=8 每隔多少非重复校验一次(至少为8) } //大于8224字元的内容 [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)] struct RecordCONTINUE { public ushort opcode; // 0x3C public ushort length; } internal class SST : IRecords { RecordSST sst; RecordExtSSt extsst; RecordCONTINUE scontinue; //uint m_absolut; uint m_totalstringlength; List m_Strings; bool m_isContinue; uint[] m_Continue; uint[] m_ContinueStringLength; uint[] m_ContinueTotalStrings; public SST() { sst.opcode = 0xFC; extsst.opcode = 0xFF; extsst.npoint = Globals.npoint; scontinue.opcode = 0x3C; //m_totalstringlength = 0; //m_isContinue = false; } public uint[] ContinueIndex { set { m_isContinue = true; m_Continue = value; } } public uint[] ContinueStringLength { set { m_ContinueStringLength = value; } } public uint[] ContinueTotalStrings { set { m_ContinueTotalStrings = value; } } public uint TotalStringCells { set { sst.totalstrings = value; } } public List SharedStrings { set { try { sst.stringnumber = (uint)value.Count; m_Strings = value; } catch { sst.stringnumber = 0; } } } public uint TotalStringsLength { set { m_totalstringlength = value; } } ////绝对偏移量 //public uint absolutoffset //{ // set { m_absolut = value; } //} #region IRecords 成员 public byte[] GetByte() { byte[] b; uint ln = 0; //"row:{0} col:{1}",i,j //int mii = m_Strings.IndexOf("row:3450 col:10"); if (m_isContinue) { sst.length = (ushort)(8 + (3 * m_Continue[0] + m_totalstringlength)); // 4 bytes for reacord sst header ln = (uint)(sst.length + 4); for (int i = 0; i < m_Continue.Length; i++) { // 4 bytes for record continue header ln += (uint)(m_ContinueStringLength[i] + (3) * (m_ContinueTotalStrings[i]) + 4); } } else { // 4 bytes for record header, 8 for fields 1&2, len of all strings // + 3 bytes string length & unicode flag for each string ln = (12 + (3 * sst.stringnumber)) + m_totalstringlength; sst.length = (ushort)(ln - 4); } b = new byte[ln]; Globals.GetStructToBytes(sst).CopyTo(b, 0); if (sst.stringnumber > 0) { //// 4位绝对地址,2位相对地址,2位0=8位 + 2位校验位总长度 //uint extsstLen = (sst.stringnumber / Globals.npoint + 1) * 8 + 2; //extsst.length = (ushort)extsstLen; //int blen = b.Length; //b = TArray.Preserve(b, extsstLen + blen + 4); //Globals.GetByte(extsst).CopyTo(b, blen); //// extsst共6位 //int ps = blen + 6; //uint absaddress = 0; uint pos = 12; uint preRound = sst.stringnumber; uint[] aftRound = new uint[2]; if (m_isContinue) preRound = m_Continue[0]; WriteStringsSectionToBytes(ref b, ref pos, 0, preRound); if (m_isContinue) { for (int j = 0; j < m_Continue.Length; j++) { aftRound[0] = m_Continue[j]; if ((j + 1) < m_Continue.Length) aftRound[1] = m_Continue[j + 1]; else aftRound[1] = sst.stringnumber; scontinue.length = (ushort)(m_ContinueStringLength[j] + (3) * (m_ContinueTotalStrings[j])); Globals.GetStructToBytes(scontinue).CopyTo(b, pos); pos += 4; WriteStringsSectionToBytes(ref b, ref pos, aftRound[0], aftRound[1]); } } } return b; } /// /// 写上一段SST内容 /// /// 全部sst内容数组(sst + continue + extsst) /// 相对位置 /// 循环开始 /// 循环节束 private void WriteStringsSectionToBytes(ref byte[] rst, ref uint pos, uint loopBegin, uint loopEnd) { uint lLen = 0; uint slen = 0; for (uint i = loopBegin; i < loopEnd; i++) { lLen = (ushort)m_Strings[(int)i].Length; slen = (ushort)Globals.GetDefaultBytesLength(m_Strings[(int)i]); //lLen = (ushort)Globals.GetUnicodeByteLength(m_Strings[(int)i]); BitConverter.GetBytes(lLen).CopyTo(rst, pos); //// 加校验位 //if (i % Globals.npoint == 0) //{ // absaddress = pos + m_absolut; // BitConverter.GetBytes(absaddress).CopyTo(b, ps); // ps += 4; // int 4 // BitConverter.GetBytes(pos).CopyTo(b, ps); // ps += 4; // ushort 2 * 2个 //} if (lLen != slen) { rst[pos + 2] = 1; } //rst[pos + 2] = 1; pos += 3; if (lLen > 0) { //Globals.GetUnicodeBytes(m_Strings[(int)i]).CopyTo(rst, pos); if (lLen != slen) { lLen = (ushort)(lLen * 2); Globals.GetUnicodeBytes(m_Strings[(int)i]).CopyTo(rst, pos); } else Globals.GetDefaultBytes(m_Strings[(int)i]).CopyTo(rst, pos); } pos += lLen; } } #endregion } }