SST.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5. using Biff8Excel.Interfaces;
  6. using System.Collections.Specialized;
  7. using System.Collections;
  8. using System.Diagnostics;
  9. namespace Biff8Excel.Records
  10. {
  11. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
  12. struct RecordSST
  13. {
  14. public ushort opcode;
  15. public ushort length;
  16. public uint totalstrings;
  17. public uint stringnumber;
  18. }
  19. //SST校验(未用)
  20. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
  21. struct RecordExtSSt
  22. {
  23. public ushort opcode; // 0xFF
  24. public ushort length;
  25. public ushort npoint; // >=8 每隔多少非重复校验一次(至少为8)
  26. }
  27. //大于8224字元的内容
  28. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
  29. struct RecordCONTINUE
  30. {
  31. public ushort opcode; // 0x3C
  32. public ushort length;
  33. }
  34. internal class SST : IRecords
  35. {
  36. RecordSST sst;
  37. RecordExtSSt extsst;
  38. RecordCONTINUE scontinue;
  39. //uint m_absolut;
  40. uint m_totalstringlength;
  41. List<string> m_Strings;
  42. bool m_isContinue;
  43. uint[] m_Continue;
  44. uint[] m_ContinueStringLength;
  45. uint[] m_ContinueTotalStrings;
  46. public SST()
  47. {
  48. sst.opcode = 0xFC;
  49. extsst.opcode = 0xFF;
  50. extsst.npoint = Globals.npoint;
  51. scontinue.opcode = 0x3C;
  52. //m_totalstringlength = 0;
  53. //m_isContinue = false;
  54. }
  55. public uint[] ContinueIndex
  56. {
  57. set
  58. {
  59. m_isContinue = true;
  60. m_Continue = value;
  61. }
  62. }
  63. public uint[] ContinueStringLength
  64. {
  65. set { m_ContinueStringLength = value; }
  66. }
  67. public uint[] ContinueTotalStrings
  68. {
  69. set { m_ContinueTotalStrings = value; }
  70. }
  71. public uint TotalStringCells
  72. {
  73. set { sst.totalstrings = value; }
  74. }
  75. public List<string> SharedStrings
  76. {
  77. set
  78. {
  79. try
  80. {
  81. sst.stringnumber = (uint)value.Count;
  82. m_Strings = value;
  83. }
  84. catch
  85. {
  86. sst.stringnumber = 0;
  87. }
  88. }
  89. }
  90. public uint TotalStringsLength
  91. {
  92. set { m_totalstringlength = value; }
  93. }
  94. ////绝对偏移量
  95. //public uint absolutoffset
  96. //{
  97. // set { m_absolut = value; }
  98. //}
  99. #region IRecords 成员
  100. public byte[] GetByte()
  101. {
  102. byte[] b;
  103. uint ln = 0;
  104. //"row:{0} col:{1}",i,j
  105. //int mii = m_Strings.IndexOf("row:3450 col:10");
  106. if (m_isContinue)
  107. {
  108. sst.length = (ushort)(8 + (3 * m_Continue[0] + m_totalstringlength));
  109. // 4 bytes for reacord sst header
  110. ln = (uint)(sst.length + 4);
  111. for (int i = 0; i < m_Continue.Length; i++)
  112. {
  113. // 4 bytes for record continue header
  114. ln += (uint)(m_ContinueStringLength[i] + (3) * (m_ContinueTotalStrings[i]) + 4);
  115. }
  116. }
  117. else
  118. {
  119. // 4 bytes for record header, 8 for fields 1&2, len of all strings
  120. // + 3 bytes string length & unicode flag for each string
  121. ln = (12 + (3 * sst.stringnumber)) + m_totalstringlength;
  122. sst.length = (ushort)(ln - 4);
  123. }
  124. b = new byte[ln];
  125. Globals.GetStructToBytes(sst).CopyTo(b, 0);
  126. if (sst.stringnumber > 0)
  127. {
  128. //// 4位绝对地址,2位相对地址,2位0=8位 + 2位校验位总长度
  129. //uint extsstLen = (sst.stringnumber / Globals.npoint + 1) * 8 + 2;
  130. //extsst.length = (ushort)extsstLen;
  131. //int blen = b.Length;
  132. //b = TArray<byte>.Preserve(b, extsstLen + blen + 4);
  133. //Globals.GetByte(extsst).CopyTo(b, blen);
  134. //// extsst共6位
  135. //int ps = blen + 6;
  136. //uint absaddress = 0;
  137. uint pos = 12;
  138. uint preRound = sst.stringnumber;
  139. uint[] aftRound = new uint[2];
  140. if (m_isContinue)
  141. preRound = m_Continue[0];
  142. WriteStringsSectionToBytes(ref b, ref pos, 0, preRound);
  143. if (m_isContinue)
  144. {
  145. for (int j = 0; j < m_Continue.Length; j++)
  146. {
  147. aftRound[0] = m_Continue[j];
  148. if ((j + 1) < m_Continue.Length)
  149. aftRound[1] = m_Continue[j + 1];
  150. else
  151. aftRound[1] = sst.stringnumber;
  152. scontinue.length = (ushort)(m_ContinueStringLength[j] + (3) * (m_ContinueTotalStrings[j]));
  153. Globals.GetStructToBytes(scontinue).CopyTo(b, pos);
  154. pos += 4;
  155. WriteStringsSectionToBytes(ref b, ref pos, aftRound[0], aftRound[1]);
  156. }
  157. }
  158. }
  159. return b;
  160. }
  161. /// <summary>
  162. /// 写上一段SST内容
  163. /// </summary>
  164. /// <param name="rst">全部sst内容数组(sst + continue + extsst)</param>
  165. /// <param name="pos">相对位置</param>
  166. /// <param name="loopBegin">循环开始</param>
  167. /// <param name="loopEnd">循环节束</param>
  168. private void WriteStringsSectionToBytes(ref byte[] rst, ref uint pos, uint loopBegin, uint loopEnd)
  169. {
  170. uint lLen = 0;
  171. uint slen = 0;
  172. for (uint i = loopBegin; i < loopEnd; i++)
  173. {
  174. lLen = (ushort)m_Strings[(int)i].Length;
  175. slen = (ushort)Globals.GetDefaultBytesLength(m_Strings[(int)i]);
  176. //lLen = (ushort)Globals.GetUnicodeByteLength(m_Strings[(int)i]);
  177. BitConverter.GetBytes(lLen).CopyTo(rst, pos);
  178. //// 加校验位
  179. //if (i % Globals.npoint == 0)
  180. //{
  181. // absaddress = pos + m_absolut;
  182. // BitConverter.GetBytes(absaddress).CopyTo(b, ps);
  183. // ps += 4; // int 4
  184. // BitConverter.GetBytes(pos).CopyTo(b, ps);
  185. // ps += 4; // ushort 2 * 2个
  186. //}
  187. if (lLen != slen)
  188. {
  189. rst[pos + 2] = 1;
  190. }
  191. //rst[pos + 2] = 1;
  192. pos += 3;
  193. if (lLen > 0)
  194. {
  195. //Globals.GetUnicodeBytes(m_Strings[(int)i]).CopyTo(rst, pos);
  196. if (lLen != slen)
  197. {
  198. lLen = (ushort)(lLen * 2);
  199. Globals.GetUnicodeBytes(m_Strings[(int)i]).CopyTo(rst, pos);
  200. }
  201. else
  202. Globals.GetDefaultBytes(m_Strings[(int)i]).CopyTo(rst, pos);
  203. }
  204. pos += lLen;
  205. }
  206. }
  207. #endregion
  208. }
  209. }