PageRenderTime 83ms CodeModel.GetById 17ms RepoModel.GetById 3ms app.codeStats 0ms

/src/org/apache/poi/hwpf/model/PlfLfo.java

https://github.com/minstrelsy/SimpleAndroidDocView
Java | 221 lines | 139 code | 28 blank | 54 comment | 24 complexity | b5d9339ca4853e5e226395f421624c70 MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * ====================================================================
  3. * Licensed to the Apache Software Foundation (ASF) under one or more
  4. * contributor license agreements. See the NOTICE file distributed with
  5. * this work for additional information regarding copyright ownership.
  6. * The ASF licenses this file to You under the Apache License, Version 2.0
  7. * (the "License"); you may not use this file except in compliance with
  8. * the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. * ====================================================================
  18. */
  19. package org.apache.poi.hwpf.model;
  20. import java.io.IOException;
  21. import java.util.Arrays;
  22. import java.util.NoSuchElementException;
  23. import org.apache.poi.hwpf.model.io.HWPFOutputStream;
  24. import org.apache.poi.util.ArrayUtil;
  25. import org.apache.poi.util.LittleEndian;
  26. import org.apache.poi.util.POILogFactory;
  27. import org.apache.poi.util.POILogger;
  28. /**
  29. * The PlfLfo structure contains the list format override data for the document.
  30. * <p>
  31. * Documentation quoted from Page 424 of 621. [MS-DOC] -- v20110315 Word (.doc)
  32. * Binary File Format
  33. *
  34. * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
  35. */
  36. public class PlfLfo
  37. {
  38. private static POILogger log = POILogFactory.getLogger( PlfLfo.class );
  39. /**
  40. * An unsigned integer that specifies the count of elements in both the
  41. * rgLfo and rgLfoData arrays.
  42. */
  43. private int _lfoMac;
  44. private LFO[] _rgLfo;
  45. private LFOData[] _rgLfoData;
  46. PlfLfo( byte[] tableStream, int fcPlfLfo, int lcbPlfLfo )
  47. {
  48. /*
  49. * The PlfLfo structure contains the list format override data for the
  50. * document. -- Page 424 of 621. [MS-DOC] -- v20110315 Word (.doc)
  51. * Binary File Format
  52. */
  53. int offset = fcPlfLfo;
  54. /*
  55. * lfoMac (4 bytes): An unsigned integer that specifies the count of
  56. * elements in both the rgLfo and rgLfoData arrays. -- Page 424 of 621.
  57. * [MS-DOC] -- v20110315 Word (.doc) Binary File Format
  58. */
  59. long lfoMacLong = LittleEndian.getUInt( tableStream, offset );
  60. offset += LittleEndian.INT_SIZE;
  61. if ( lfoMacLong > Integer.MAX_VALUE )
  62. {
  63. throw new UnsupportedOperationException(
  64. "Apache POI doesn't support rgLfo/rgLfoData size large than "
  65. + Integer.MAX_VALUE + " elements" );
  66. }
  67. this._lfoMac = (int) lfoMacLong;
  68. _rgLfo = new LFO[_lfoMac];
  69. _rgLfoData = new LFOData[_lfoMac];
  70. /*
  71. * An array of LFO structures. The number of elements in this array is
  72. * specified by lfoMac. -- Page 424 of 621. [MS-DOC] -- v20110315 Word
  73. * (.doc) Binary File Format
  74. */
  75. for ( int x = 0; x < _lfoMac; x++ )
  76. {
  77. LFO lfo = new LFO( tableStream, offset );
  78. offset += LFO.getSize();
  79. _rgLfo[x] = lfo;
  80. }
  81. /*
  82. * An array of LFOData that is parallel to rgLfo. The number of elements
  83. * that are contained in this array is specified by lfoMac. -- Page 424
  84. * of 621. [MS-DOC] -- v20110315 Word (.doc) Binary File Format
  85. */
  86. for ( int x = 0; x < _lfoMac; x++ )
  87. {
  88. LFOData lfoData = new LFOData( tableStream, offset,
  89. _rgLfo[x].getClfolvl() );
  90. offset += lfoData.getSizeInBytes();
  91. _rgLfoData[x] = lfoData;
  92. }
  93. if ( ( offset - fcPlfLfo ) != lcbPlfLfo )
  94. {
  95. log.log( POILogger.WARN, "Actual size of PlfLfo is "
  96. + ( offset - fcPlfLfo ) + " bytes, but expected "
  97. + lcbPlfLfo );
  98. }
  99. }
  100. void add( LFO lfo, LFOData lfoData )
  101. {
  102. final int newLfoMac = _lfoMac + 1;
  103. _rgLfo = ArrayUtil.copyOf( _rgLfo, new LFO[newLfoMac] );
  104. _rgLfo[_lfoMac + 1] = lfo;
  105. _rgLfoData = ArrayUtil.copyOf( _rgLfoData, new LFOData[_lfoMac + 1] );
  106. _rgLfoData[_lfoMac + 1] = lfoData;
  107. this._lfoMac = newLfoMac;
  108. }
  109. @Override
  110. public boolean equals( Object obj )
  111. {
  112. if ( this == obj )
  113. return true;
  114. if ( obj == null )
  115. return false;
  116. if ( getClass() != obj.getClass() )
  117. return false;
  118. PlfLfo other = (PlfLfo) obj;
  119. if ( _lfoMac != other._lfoMac )
  120. return false;
  121. if ( !Arrays.equals( _rgLfo, other._rgLfo ) )
  122. return false;
  123. if ( !Arrays.equals( _rgLfoData, other._rgLfoData ) )
  124. return false;
  125. return true;
  126. }
  127. /**
  128. * An unsigned integer that specifies the count of elements in both the
  129. * rgLfo and rgLfoData arrays.
  130. */
  131. public int getLfoMac()
  132. {
  133. return _lfoMac;
  134. }
  135. public int getIlfoByLsid( int lsid )
  136. {
  137. for ( int i = 0; i < _lfoMac; i++ )
  138. {
  139. if ( _rgLfo[i].getLsid() == lsid )
  140. {
  141. return i + 1;
  142. }
  143. }
  144. throw new NoSuchElementException( "LFO with lsid " + lsid
  145. + " not found" );
  146. }
  147. public LFO getLfo( int ilfo ) throws NoSuchElementException
  148. {
  149. if ( ilfo <= 0 || ilfo > _lfoMac )
  150. {
  151. throw new NoSuchElementException( "LFO with ilfo " + ilfo
  152. + " not found. lfoMac is " + _lfoMac );
  153. }
  154. return _rgLfo[ilfo - 1];
  155. }
  156. public LFOData getLfoData( int ilfo ) throws NoSuchElementException
  157. {
  158. if ( ilfo <= 0 || ilfo > _lfoMac )
  159. {
  160. throw new NoSuchElementException( "LFOData with ilfo " + ilfo
  161. + " not found. lfoMac is " + _lfoMac );
  162. }
  163. return _rgLfoData[ilfo - 1];
  164. }
  165. @Override
  166. public int hashCode()
  167. {
  168. final int prime = 31;
  169. int result = 1;
  170. result = prime * result + _lfoMac;
  171. result = prime * result + Arrays.hashCode( _rgLfo );
  172. result = prime * result + Arrays.hashCode( _rgLfoData );
  173. return result;
  174. }
  175. void writeTo( FileInformationBlock fib, HWPFOutputStream outputStream )
  176. throws IOException
  177. {
  178. final int offset = outputStream.getOffset();
  179. fib.setFcPlfLfo( offset );
  180. LittleEndian.putUInt( _lfoMac, outputStream );
  181. byte[] bs = new byte[LFO.getSize() * _lfoMac];
  182. for ( int i = 0; i < _lfoMac; i++ )
  183. {
  184. _rgLfo[i].serialize( bs, i * LFO.getSize() );
  185. }
  186. outputStream.write( bs, 0, LFO.getSize() * _lfoMac );
  187. for ( int i = 0; i < _lfoMac; i++ )
  188. {
  189. _rgLfoData[i].writeTo( outputStream );
  190. }
  191. fib.setLcbPlfLfo( outputStream.getOffset() - offset );
  192. }
  193. }