correctly handle LFOData structures
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1178083 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3607c2fc74
commit
19e92a8e6a
@ -19,6 +19,7 @@ package org.apache.poi.util;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* a utility class for handling little-endian numbers, which the 80x86 world is
|
* a utility class for handling little-endian numbers, which the 80x86 world is
|
||||||
@ -97,7 +98,6 @@ public class LittleEndian implements LittleEndianConsts {
|
|||||||
return (b3 << 24) + (b2 << 16) + (b1 << 8) + (b0 << 0);
|
return (b3 << 24) + (b2 << 16) + (b1 << 8) + (b0 << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get an int value from the beginning of a byte array
|
* get an int value from the beginning of a byte array
|
||||||
*
|
*
|
||||||
@ -254,6 +254,25 @@ public class LittleEndian implements LittleEndianConsts {
|
|||||||
putInt(data, 0, value);
|
putInt(data, 0, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put int into output stream
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* the int (32-bit) value
|
||||||
|
* @param outputStream
|
||||||
|
* output stream
|
||||||
|
* @throws IOException
|
||||||
|
* if an I/O error occurs
|
||||||
|
*/
|
||||||
|
public static void putInt( int value, OutputStream outputStream )
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) );
|
||||||
|
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
|
||||||
|
outputStream.write( (byte) ( ( value >>> 16 ) & 0xFF ) );
|
||||||
|
outputStream.write( (byte) ( ( value >>> 24 ) & 0xFF ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* put an unsigned int value into a byte array
|
* put an unsigned int value into a byte array
|
||||||
*
|
*
|
||||||
@ -281,6 +300,25 @@ public class LittleEndian implements LittleEndianConsts {
|
|||||||
putUInt(data, 0, value);
|
putUInt(data, 0, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put unsigned int into output stream
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* the int (32-bit) value
|
||||||
|
* @param outputStream
|
||||||
|
* output stream
|
||||||
|
* @throws IOException
|
||||||
|
* if an I/O error occurs
|
||||||
|
*/
|
||||||
|
public static void putUInt( long value, OutputStream outputStream )
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) );
|
||||||
|
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
|
||||||
|
outputStream.write( (byte) ( ( value >>> 16 ) & 0xFF ) );
|
||||||
|
outputStream.write( (byte) ( ( value >>> 24 ) & 0xFF ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* put a long value into a byte array
|
* put a long value into a byte array
|
||||||
*
|
*
|
||||||
|
67
src/scratchpad/src/org/apache/poi/hwpf/model/LFOData.java
Normal file
67
src/scratchpad/src/org/apache/poi/hwpf/model/LFOData.java
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package org.apache.poi.hwpf.model;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.poi.hwpf.model.io.HWPFOutputStream;
|
||||||
|
import org.apache.poi.util.Internal;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The LFOData structure contains the Main Document CP of the corresponding LFO,
|
||||||
|
* as well as an array of LVL override data.
|
||||||
|
*
|
||||||
|
* @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
class LFOData
|
||||||
|
{
|
||||||
|
private int _cp;
|
||||||
|
|
||||||
|
private ListFormatOverrideLevel[] _rgLfoLvl;
|
||||||
|
|
||||||
|
LFOData( byte[] buf, int startOffset, int cLfolvl )
|
||||||
|
{
|
||||||
|
int offset = startOffset;
|
||||||
|
|
||||||
|
_cp = LittleEndian.getInt( buf, offset );
|
||||||
|
offset += LittleEndian.INT_SIZE;
|
||||||
|
|
||||||
|
_rgLfoLvl = new ListFormatOverrideLevel[cLfolvl];
|
||||||
|
for ( int x = 0; x < cLfolvl; x++ )
|
||||||
|
{
|
||||||
|
_rgLfoLvl[x] = new ListFormatOverrideLevel( buf, offset );
|
||||||
|
offset += _rgLfoLvl[x].getSizeInBytes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getCp()
|
||||||
|
{
|
||||||
|
return _cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListFormatOverrideLevel[] getRgLfoLvl()
|
||||||
|
{
|
||||||
|
return _rgLfoLvl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSizeInBytes()
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
result += LittleEndian.INT_SIZE;
|
||||||
|
|
||||||
|
for ( ListFormatOverrideLevel lfolvl : _rgLfoLvl )
|
||||||
|
result += lfolvl.getSizeInBytes();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeTo( HWPFOutputStream tableStream ) throws IOException
|
||||||
|
{
|
||||||
|
LittleEndian.putInt( _cp, tableStream );
|
||||||
|
for ( ListFormatOverrideLevel lfolvl : _rgLfoLvl )
|
||||||
|
{
|
||||||
|
tableStream.write( lfolvl.toByteArray() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
42
src/scratchpad/src/org/apache/poi/hwpf/model/LFOLVLBase.java
Normal file
42
src/scratchpad/src/org/apache/poi/hwpf/model/LFOLVLBase.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hwpf.model;
|
||||||
|
|
||||||
|
import org.apache.poi.hwpf.model.types.LFOLVLBaseAbstractType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The LFOLVL structure contains information that is used to override the
|
||||||
|
* formatting information of a corresponding LVL.
|
||||||
|
* <p>
|
||||||
|
* Class and fields descriptions are quoted from Microsoft Office Word 97-2007
|
||||||
|
* Binary File Format and [MS-DOC] - v20110608 Word (.doc) Binary File Format
|
||||||
|
*
|
||||||
|
* @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary
|
||||||
|
* File Format Specification [*.doc] and [MS-DOC] - v20110608 Word
|
||||||
|
* (.doc) Binary File Format
|
||||||
|
*/
|
||||||
|
class LFOLVLBase extends LFOLVLBaseAbstractType
|
||||||
|
{
|
||||||
|
LFOLVLBase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LFOLVLBase( byte[] buf, int offset )
|
||||||
|
{
|
||||||
|
fillFields( buf, offset );
|
||||||
|
}
|
||||||
|
}
|
@ -22,27 +22,34 @@ import org.apache.poi.util.Internal;
|
|||||||
@Internal
|
@Internal
|
||||||
public final class ListFormatOverride
|
public final class ListFormatOverride
|
||||||
{
|
{
|
||||||
|
|
||||||
private ListFormatOverrideLevel[] _levelOverrides;
|
|
||||||
|
|
||||||
private LFO _lfo;
|
private LFO _lfo;
|
||||||
|
|
||||||
|
private LFOData _lfoData;
|
||||||
|
|
||||||
public ListFormatOverride( byte[] buf, int offset )
|
public ListFormatOverride( byte[] buf, int offset )
|
||||||
{
|
{
|
||||||
_lfo = new LFO( buf, offset );
|
_lfo = new LFO( buf, offset );
|
||||||
_levelOverrides = new ListFormatOverrideLevel[_lfo.getClfolvl()];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListFormatOverride( int lsid )
|
public ListFormatOverride( int lsid )
|
||||||
{
|
{
|
||||||
_lfo = new LFO();
|
_lfo = new LFO();
|
||||||
_lfo.setLsid( lsid );
|
_lfo.setLsid( lsid );
|
||||||
_levelOverrides = new ListFormatOverrideLevel[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListFormatOverrideLevel[] getLevelOverrides()
|
public ListFormatOverrideLevel[] getLevelOverrides()
|
||||||
{
|
{
|
||||||
return _levelOverrides;
|
return _lfoData.getRgLfoLvl();
|
||||||
|
}
|
||||||
|
|
||||||
|
LFO getLfo()
|
||||||
|
{
|
||||||
|
return _lfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
LFOData getLfoData()
|
||||||
|
{
|
||||||
|
return _lfoData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLsid()
|
public int getLsid()
|
||||||
@ -52,14 +59,12 @@ public final class ListFormatOverride
|
|||||||
|
|
||||||
public ListFormatOverrideLevel getOverrideLevel( int level )
|
public ListFormatOverrideLevel getOverrideLevel( int level )
|
||||||
{
|
{
|
||||||
|
|
||||||
ListFormatOverrideLevel retLevel = null;
|
ListFormatOverrideLevel retLevel = null;
|
||||||
|
for ( int x = 0; x < getLevelOverrides().length; x++ )
|
||||||
for ( int x = 0; x < _levelOverrides.length; x++ )
|
|
||||||
{
|
{
|
||||||
if ( _levelOverrides[x].getLevelNum() == level )
|
if ( getLevelOverrides()[x].getLevelNum() == level )
|
||||||
{
|
{
|
||||||
retLevel = _levelOverrides[x];
|
retLevel = getLevelOverrides()[x];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retLevel;
|
return retLevel;
|
||||||
@ -70,6 +75,11 @@ public final class ListFormatOverride
|
|||||||
return _lfo.getClfolvl();
|
return _lfo.getClfolvl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setLfoData( LFOData _lfoData )
|
||||||
|
{
|
||||||
|
this._lfoData = _lfoData;
|
||||||
|
}
|
||||||
|
|
||||||
public void setLsid( int lsid )
|
public void setLsid( int lsid )
|
||||||
{
|
{
|
||||||
_lfo.setLsid( lsid );
|
_lfo.setLsid( lsid );
|
||||||
@ -77,7 +87,7 @@ public final class ListFormatOverride
|
|||||||
|
|
||||||
public void setOverride( int index, ListFormatOverrideLevel lfolvl )
|
public void setOverride( int index, ListFormatOverrideLevel lfolvl )
|
||||||
{
|
{
|
||||||
_levelOverrides[index] = lfolvl;
|
getLevelOverrides()[index] = lfolvl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] toByteArray()
|
public byte[] toByteArray()
|
||||||
|
@ -14,110 +14,108 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
package org.apache.poi.hwpf.model;
|
package org.apache.poi.hwpf.model;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import org.apache.poi.util.BitField;
|
|
||||||
import org.apache.poi.util.BitFieldFactory;
|
|
||||||
import org.apache.poi.util.Internal;
|
import org.apache.poi.util.Internal;
|
||||||
import org.apache.poi.util.LittleEndian;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The LFOLVL structure contains information that is used to override the
|
||||||
|
* formatting information of a corresponding LVL.
|
||||||
|
* <p>
|
||||||
|
* Class and fields descriptions are quoted from Microsoft Office Word 97-2007
|
||||||
|
* Binary File Format and [MS-DOC] - v20110608 Word (.doc) Binary File Format
|
||||||
|
*/
|
||||||
@Internal
|
@Internal
|
||||||
public final class ListFormatOverrideLevel
|
public final class ListFormatOverrideLevel
|
||||||
{
|
{
|
||||||
private static final int BASE_SIZE = 8;
|
private LFOLVLBase _base;
|
||||||
|
private ListLevel _lvl;
|
||||||
|
|
||||||
int _iStartAt;
|
public ListFormatOverrideLevel( byte[] buf, int offset )
|
||||||
byte _info;
|
|
||||||
private static BitField _ilvl = BitFieldFactory.getInstance(0xf);
|
|
||||||
private static BitField _fStartAt = BitFieldFactory.getInstance(0x10);
|
|
||||||
private static BitField _fFormatting = BitFieldFactory.getInstance(0x20);
|
|
||||||
byte[] _reserved = new byte[3];
|
|
||||||
ListLevel _lvl;
|
|
||||||
|
|
||||||
public ListFormatOverrideLevel(byte[] buf, int offset)
|
|
||||||
{
|
|
||||||
_iStartAt = LittleEndian.getInt(buf, offset);
|
|
||||||
offset += LittleEndian.INT_SIZE;
|
|
||||||
_info = buf[offset++];
|
|
||||||
System.arraycopy(buf, offset, _reserved, 0, _reserved.length);
|
|
||||||
offset += _reserved.length;
|
|
||||||
|
|
||||||
if (_fFormatting.getValue(_info) > 0)
|
|
||||||
{
|
{
|
||||||
_lvl = new ListLevel(buf, offset);
|
_base = new LFOLVLBase( buf, offset );
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ListLevel getLevel()
|
if ( _base.isFFormatting() )
|
||||||
{
|
{
|
||||||
return _lvl;
|
_lvl = new ListLevel( buf, offset );
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLevelNum()
|
|
||||||
{
|
|
||||||
return _ilvl.getValue(_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFormatting()
|
|
||||||
{
|
|
||||||
return _fFormatting.getValue(_info) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isStartAt()
|
|
||||||
{
|
|
||||||
return _fStartAt.getValue(_info) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSizeInBytes()
|
|
||||||
{
|
|
||||||
return (_lvl == null ? BASE_SIZE : BASE_SIZE + _lvl.getSizeInBytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if (obj == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ListFormatOverrideLevel lfolvl = (ListFormatOverrideLevel)obj;
|
|
||||||
boolean lvlEquality = false;
|
|
||||||
if (_lvl != null)
|
|
||||||
{
|
|
||||||
lvlEquality = _lvl.equals(lfolvl._lvl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lvlEquality = lfolvl._lvl == null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return lvlEquality && lfolvl._iStartAt == _iStartAt && lfolvl._info == _info &&
|
public boolean equals( Object obj )
|
||||||
Arrays.equals(lfolvl._reserved, _reserved);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] toByteArray()
|
|
||||||
{
|
|
||||||
byte[] buf = new byte[getSizeInBytes()];
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
LittleEndian.putInt(buf, _iStartAt);
|
|
||||||
offset += LittleEndian.INT_SIZE;
|
|
||||||
buf[offset++] = _info;
|
|
||||||
System.arraycopy(_reserved, 0, buf, offset, 3);
|
|
||||||
offset += 3;
|
|
||||||
|
|
||||||
if (_lvl != null)
|
|
||||||
{
|
{
|
||||||
byte[] levelBuf = _lvl.toByteArray();
|
if ( obj == null )
|
||||||
System.arraycopy(levelBuf, 0, buf, offset, levelBuf.length);
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ListFormatOverrideLevel lfolvl = (ListFormatOverrideLevel) obj;
|
||||||
|
boolean lvlEquality = false;
|
||||||
|
if ( _lvl != null )
|
||||||
|
{
|
||||||
|
lvlEquality = _lvl.equals( lfolvl._lvl );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lvlEquality = lfolvl._lvl == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lvlEquality && lfolvl._base.equals( _base );
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
public int getIStartAt()
|
||||||
}
|
{
|
||||||
|
return _base.getIStartAt();
|
||||||
|
}
|
||||||
|
|
||||||
public int getIStartAt() {
|
public ListLevel getLevel()
|
||||||
return _iStartAt;
|
{
|
||||||
}
|
return _lvl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevelNum()
|
||||||
|
{
|
||||||
|
return _base.getILvl();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSizeInBytes()
|
||||||
|
{
|
||||||
|
return _lvl == null ? LFOLVLBase.getSize() : LFOLVLBase.getSize()
|
||||||
|
+ _lvl.getSizeInBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + _base.hashCode();
|
||||||
|
result = prime * result + ( _lvl != null ? _lvl.hashCode() : 0 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFormatting()
|
||||||
|
{
|
||||||
|
return _base.isFFormatting();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStartAt()
|
||||||
|
{
|
||||||
|
return _base.isFStartAt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] toByteArray()
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
byte[] buf = new byte[getSizeInBytes()];
|
||||||
|
_base.serialize( buf, offset );
|
||||||
|
offset += LFOLVLBase.getSize();
|
||||||
|
|
||||||
|
if ( _lvl != null )
|
||||||
|
{
|
||||||
|
byte[] levelBuf = _lvl.toByteArray();
|
||||||
|
System.arraycopy( levelBuf, 0, buf, offset, levelBuf.length );
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,6 @@ package org.apache.poi.hwpf.model;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.apache.poi.hwpf.model.types.LVLFAbstractType;
|
|
||||||
|
|
||||||
import org.apache.poi.util.BitField;
|
|
||||||
import org.apache.poi.util.Internal;
|
import org.apache.poi.util.Internal;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ import org.apache.poi.util.POILogger;
|
|||||||
public final class ListTables
|
public final class ListTables
|
||||||
{
|
{
|
||||||
private static final int LIST_DATA_SIZE = 28;
|
private static final int LIST_DATA_SIZE = 28;
|
||||||
private static final int LIST_FORMAT_OVERRIDE_SIZE = 16;
|
|
||||||
private static POILogger log = POILogFactory.getLogger(ListTables.class);
|
private static POILogger log = POILogFactory.getLogger(ListTables.class);
|
||||||
|
|
||||||
ListMap _listMap = new ListMap();
|
ListMap _listMap = new ListMap();
|
||||||
@ -53,7 +52,7 @@ public final class ListTables
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListTables(byte[] tableStream, int lstOffset, int lfoOffset)
|
public ListTables(byte[] tableStream, int lstOffset, final int lfoOffset)
|
||||||
{
|
{
|
||||||
// get the list data
|
// get the list data
|
||||||
int length = LittleEndian.getShort(tableStream, lstOffset);
|
int length = LittleEndian.getShort(tableStream, lstOffset);
|
||||||
@ -75,28 +74,51 @@ public final class ListTables
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now get the list format overrides. The size is an int unlike the LST size
|
|
||||||
length = LittleEndian.getInt(tableStream, lfoOffset);
|
|
||||||
lfoOffset += LittleEndian.INT_SIZE;
|
|
||||||
int lfolvlOffset = lfoOffset + (LIST_FORMAT_OVERRIDE_SIZE * length);
|
|
||||||
for (int x = 0; x < length; x++)
|
|
||||||
{
|
|
||||||
ListFormatOverride lfo = new ListFormatOverride(tableStream, lfoOffset);
|
|
||||||
lfoOffset += LIST_FORMAT_OVERRIDE_SIZE;
|
|
||||||
int num = lfo.numOverrides();
|
|
||||||
for (int y = 0; y < num; y++)
|
|
||||||
{
|
|
||||||
while(tableStream[lfolvlOffset] == -1)
|
|
||||||
{
|
{
|
||||||
lfolvlOffset++;
|
/*
|
||||||
|
* The PlfLfo structure contains the list format override data for
|
||||||
|
* the document. -- Page 424 of 621. [MS-DOC] -- v20110315 Word
|
||||||
|
* (.doc) Binary File Format
|
||||||
|
*/
|
||||||
|
int offset = lfoOffset;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* lfoMac (4 bytes): An unsigned integer that specifies the count of
|
||||||
|
* elements in both the rgLfo and rgLfoData arrays. -- Page 424 of
|
||||||
|
* 621. [MS-DOC] -- v20110315 Word (.doc) Binary File Format
|
||||||
|
*/
|
||||||
|
long lfoMac = LittleEndian.getUInt( tableStream, offset );
|
||||||
|
offset += LittleEndian.INT_SIZE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An array of LFO structures. The number of elements in this array
|
||||||
|
* is specified by lfoMac. -- Page 424 of 621. [MS-DOC] -- v20110315
|
||||||
|
* Word (.doc) Binary File Format
|
||||||
|
*/
|
||||||
|
for ( int x = 0; x < lfoMac; x++ )
|
||||||
|
{
|
||||||
|
ListFormatOverride lfo = new ListFormatOverride( tableStream,
|
||||||
|
offset );
|
||||||
|
offset += LFO.getSize();
|
||||||
|
_overrideList.add( lfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An array of LFOData that is parallel to rgLfo. The number of
|
||||||
|
* elements that are contained in this array is specified by lfoMac.
|
||||||
|
* -- Page 424 of 621. [MS-DOC] -- v20110315 Word (.doc) Binary File
|
||||||
|
* Format
|
||||||
|
*/
|
||||||
|
for ( int x = 0; x < lfoMac; x++ )
|
||||||
|
{
|
||||||
|
ListFormatOverride lfo = _overrideList.get( x );
|
||||||
|
LFOData lfoData = new LFOData( tableStream, offset,
|
||||||
|
lfo.numOverrides() );
|
||||||
|
lfo.setLfoData( lfoData );
|
||||||
|
offset += lfoData.getSizeInBytes();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ListFormatOverrideLevel lfolvl = new ListFormatOverrideLevel(tableStream, lfolvlOffset);
|
|
||||||
lfo.setOverride(y, lfolvl);
|
|
||||||
lfolvlOffset += lfolvl.getSizeInBytes();
|
|
||||||
}
|
|
||||||
_overrideList.add(lfo);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public int addList(ListData lst, ListFormatOverride override)
|
public int addList(ListData lst, ListFormatOverride override)
|
||||||
{
|
{
|
||||||
@ -135,32 +157,21 @@ public final class ListTables
|
|||||||
tableStream.write(levelBuf.toByteArray());
|
tableStream.write(levelBuf.toByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeListOverridesTo(HWPFOutputStream tableStream)
|
public void writeListOverridesTo( HWPFOutputStream tableStream )
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
|
||||||
|
|
||||||
// use this stream as a buffer for the levels since their size varies.
|
|
||||||
ByteArrayOutputStream levelBuf = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
int size = _overrideList.size();
|
|
||||||
|
|
||||||
byte[] intHolder = new byte[4];
|
|
||||||
LittleEndian.putInt(intHolder, size);
|
|
||||||
tableStream.write(intHolder);
|
|
||||||
|
|
||||||
for (int x = 0; x < size; x++)
|
|
||||||
{
|
{
|
||||||
ListFormatOverride lfo = _overrideList.get(x);
|
LittleEndian.putUInt( _overrideList.size(), tableStream );
|
||||||
tableStream.write(lfo.toByteArray());
|
|
||||||
ListFormatOverrideLevel[] lfolvls = lfo.getLevelOverrides();
|
|
||||||
for (int y = 0; y < lfolvls.length; y++)
|
|
||||||
{
|
|
||||||
levelBuf.write(lfolvls[y].toByteArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tableStream.write(levelBuf.toByteArray());
|
|
||||||
|
|
||||||
}
|
for ( ListFormatOverride lfo : _overrideList )
|
||||||
|
{
|
||||||
|
tableStream.write( lfo.getLfo().serialize() );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( ListFormatOverride lfo : _overrideList )
|
||||||
|
{
|
||||||
|
lfo.getLfoData().writeTo( tableStream );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ListFormatOverride getOverride(int lfoIndex)
|
public ListFormatOverride getOverride(int lfoIndex)
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,290 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hwpf.model.types;
|
||||||
|
|
||||||
|
import org.apache.poi.util.BitField;
|
||||||
|
import org.apache.poi.util.Internal;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The LFOLVL structure contains information that is used to override the formatting
|
||||||
|
information of a corresponding LVL. <p>Class and fields descriptions are quoted from
|
||||||
|
Microsoft Office Word 97-2007 Binary File Format and [MS-DOC] - v20110608 Word (.doc) Binary
|
||||||
|
File Format
|
||||||
|
|
||||||
|
* <p>
|
||||||
|
* NOTE: This source is automatically generated please do not modify this file. Either subclass or
|
||||||
|
* remove the record in src/types/definitions.
|
||||||
|
* <p>
|
||||||
|
* This class is internal. It content or properties may change without notice
|
||||||
|
* due to changes in our knowledge of internal Microsoft Word binary structures.
|
||||||
|
|
||||||
|
* @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary File Format
|
||||||
|
Specification [*.doc] and [MS-DOC] - v20110608 Word (.doc) Binary File Format
|
||||||
|
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public abstract class LFOLVLBaseAbstractType
|
||||||
|
{
|
||||||
|
|
||||||
|
protected int field_1_iStartAt;
|
||||||
|
protected int field_2_flags;
|
||||||
|
/**/private static final BitField iLvl = new BitField(0x0000000F);
|
||||||
|
/**/private static final BitField fStartAt = new BitField(0x00000010);
|
||||||
|
/**/private static final BitField fFormatting = new BitField(0x00000020);
|
||||||
|
/**/private static final BitField grfhic = new BitField(0x00003FC0);
|
||||||
|
/**/private static final BitField unused1 = new BitField(0x1FFFC000);
|
||||||
|
/**/private static final BitField unused2 = new BitField(0xE0000000);
|
||||||
|
|
||||||
|
protected LFOLVLBaseAbstractType()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fillFields( byte[] data, int offset )
|
||||||
|
{
|
||||||
|
field_1_iStartAt = LittleEndian.getInt( data, 0x0 + offset );
|
||||||
|
field_2_flags = LittleEndian.getInt( data, 0x4 + offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void serialize( byte[] data, int offset )
|
||||||
|
{
|
||||||
|
LittleEndian.putInt( data, 0x0 + offset, field_1_iStartAt );
|
||||||
|
LittleEndian.putInt( data, 0x4 + offset, field_2_flags );
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] serialize()
|
||||||
|
{
|
||||||
|
final byte[] result = new byte[ getSize() ];
|
||||||
|
serialize( result, 0 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size of record
|
||||||
|
*/
|
||||||
|
public static int getSize()
|
||||||
|
{
|
||||||
|
return 0 + 4 + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals( Object obj )
|
||||||
|
{
|
||||||
|
if ( this == obj )
|
||||||
|
return true;
|
||||||
|
if ( obj == null )
|
||||||
|
return false;
|
||||||
|
if ( getClass() != obj.getClass() )
|
||||||
|
return false;
|
||||||
|
LFOLVLBaseAbstractType other = (LFOLVLBaseAbstractType) obj;
|
||||||
|
if ( field_1_iStartAt != other.field_1_iStartAt )
|
||||||
|
return false;
|
||||||
|
if ( field_2_flags != other.field_2_flags )
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + field_1_iStartAt;
|
||||||
|
result = prime * result + field_2_flags;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("[LFOLVLBase]\n");
|
||||||
|
builder.append(" .iStartAt = ");
|
||||||
|
builder.append(" (").append(getIStartAt()).append(" )\n");
|
||||||
|
builder.append(" .flags = ");
|
||||||
|
builder.append(" (").append(getFlags()).append(" )\n");
|
||||||
|
builder.append(" .iLvl = ").append(getILvl()).append('\n');
|
||||||
|
builder.append(" .fStartAt = ").append(isFStartAt()).append('\n');
|
||||||
|
builder.append(" .fFormatting = ").append(isFFormatting()).append('\n');
|
||||||
|
builder.append(" .grfhic = ").append(getGrfhic()).append('\n');
|
||||||
|
builder.append(" .unused1 = ").append(getUnused1()).append('\n');
|
||||||
|
builder.append(" .unused2 = ").append(getUnused2()).append('\n');
|
||||||
|
|
||||||
|
builder.append("[/LFOLVLBase]\n");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If fStartAt is set to 0x1, this is a signed integer that specifies the start-at value that overrides lvlf.iStartAt of the corresponding LVL. This value MUST be less than or equal to 0x7FFF and MUST be greater than or equal to zero. If both fStartAt and fFormatting are set to 0x1, or if fStartAt is set to 0x0, this value is undefined and MUST be ignored.
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public int getIStartAt()
|
||||||
|
{
|
||||||
|
return field_1_iStartAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If fStartAt is set to 0x1, this is a signed integer that specifies the start-at value that overrides lvlf.iStartAt of the corresponding LVL. This value MUST be less than or equal to 0x7FFF and MUST be greater than or equal to zero. If both fStartAt and fFormatting are set to 0x1, or if fStartAt is set to 0x0, this value is undefined and MUST be ignored.
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public void setIStartAt( int field_1_iStartAt )
|
||||||
|
{
|
||||||
|
this.field_1_iStartAt = field_1_iStartAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the flags field for the LFOLVLBase record.
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public int getFlags()
|
||||||
|
{
|
||||||
|
return field_2_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the flags field for the LFOLVLBase record.
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public void setFlags( int field_2_flags )
|
||||||
|
{
|
||||||
|
this.field_2_flags = field_2_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the iLvl field value.
|
||||||
|
* An unsigned integer that specifies the zero-based level of the list that this overrides. This LFOLVL overrides the LVL that specifies the level formatting of this level of the LSTF that is specified by the lsid field of the LFO to which this LFOLVL corresponds. This value MUST be less than or equal to 0x08
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public void setILvl( byte value )
|
||||||
|
{
|
||||||
|
field_2_flags = iLvl.setValue(field_2_flags, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An unsigned integer that specifies the zero-based level of the list that this overrides. This LFOLVL overrides the LVL that specifies the level formatting of this level of the LSTF that is specified by the lsid field of the LFO to which this LFOLVL corresponds. This value MUST be less than or equal to 0x08
|
||||||
|
* @return the iLvl field value.
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public byte getILvl()
|
||||||
|
{
|
||||||
|
return ( byte )iLvl.getValue(field_2_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the fStartAt field value.
|
||||||
|
* A bit that specifies whether this LFOLVL overrides the start-at value of the level.
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public void setFStartAt( boolean value )
|
||||||
|
{
|
||||||
|
field_2_flags = fStartAt.setBoolean(field_2_flags, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bit that specifies whether this LFOLVL overrides the start-at value of the level.
|
||||||
|
* @return the fStartAt field value.
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public boolean isFStartAt()
|
||||||
|
{
|
||||||
|
return fStartAt.isSet(field_2_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the fFormatting field value.
|
||||||
|
* A bit that specifies whether lvl is an LVL that overrides the corresponding LVL
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public void setFFormatting( boolean value )
|
||||||
|
{
|
||||||
|
field_2_flags = fFormatting.setBoolean(field_2_flags, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bit that specifies whether lvl is an LVL that overrides the corresponding LVL
|
||||||
|
* @return the fFormatting field value.
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public boolean isFFormatting()
|
||||||
|
{
|
||||||
|
return fFormatting.isSet(field_2_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the grfhic field value.
|
||||||
|
* A grfhic that specifies the HTML incompatibilities of the overriding level formatting
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public void setGrfhic( short value )
|
||||||
|
{
|
||||||
|
field_2_flags = grfhic.setValue(field_2_flags, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A grfhic that specifies the HTML incompatibilities of the overriding level formatting
|
||||||
|
* @return the grfhic field value.
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public short getGrfhic()
|
||||||
|
{
|
||||||
|
return ( short )grfhic.getValue(field_2_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the unused1 field value.
|
||||||
|
* This MUST be ignored
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public void setUnused1( short value )
|
||||||
|
{
|
||||||
|
field_2_flags = unused1.setValue(field_2_flags, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This MUST be ignored
|
||||||
|
* @return the unused1 field value.
|
||||||
|
* @deprecated This field should not be used according to specification
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
@Deprecated
|
||||||
|
public short getUnused1()
|
||||||
|
{
|
||||||
|
return ( short )unused1.getValue(field_2_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the unused2 field value.
|
||||||
|
* This MUST be ignored
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public void setUnused2( byte value )
|
||||||
|
{
|
||||||
|
field_2_flags = unused2.setValue(field_2_flags, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This MUST be ignored
|
||||||
|
* @return the unused2 field value.
|
||||||
|
* @deprecated This field should not be used according to specification
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
@Deprecated
|
||||||
|
public byte getUnused2()
|
||||||
|
{
|
||||||
|
return ( byte )unused2.getValue(field_2_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // END OF CLASS
|
46
src/types/definitions/LFOLVLBase_type.xml
Normal file
46
src/types/definitions/LFOLVLBase_type.xml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
====================================================================
|
||||||
|
-->
|
||||||
|
<record fromfile="true" name="LFOLVLBase" package="org.apache.poi.hwpf.model.types">
|
||||||
|
<suffix>AbstractType</suffix>
|
||||||
|
<description>The LFOLVL structure contains information that is used to override the formatting
|
||||||
|
information of a corresponding LVL. <p>Class and fields descriptions are quoted from
|
||||||
|
Microsoft Office Word 97-2007 Binary File Format and [MS-DOC] - v20110608 Word (.doc) Binary
|
||||||
|
File Format
|
||||||
|
</description>
|
||||||
|
<author>Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary File Format
|
||||||
|
Specification [*.doc] and [MS-DOC] - v20110608 Word (.doc) Binary File Format
|
||||||
|
</author>
|
||||||
|
<fields>
|
||||||
|
<field type="int" size="4" name="iStartAt"
|
||||||
|
description="If fStartAt is set to 0x1, this is a signed integer that specifies the start-at value that overrides lvlf.iStartAt of the corresponding LVL. This value MUST be less than or equal to 0x7FFF and MUST be greater than or equal to zero. If both fStartAt and fFormatting are set to 0x1, or if fStartAt is set to 0x0, this value is undefined and MUST be ignored"/>
|
||||||
|
<field type="int" size="4" name="flags">
|
||||||
|
<bit mask="0x0000000F" name="iLvl"
|
||||||
|
description="An unsigned integer that specifies the zero-based level of the list that this overrides. This LFOLVL overrides the LVL that specifies the level formatting of this level of the LSTF that is specified by the lsid field of the LFO to which this LFOLVL corresponds. This value MUST be less than or equal to 0x08"/>
|
||||||
|
<bit mask="0x00000010" name="fStartAt"
|
||||||
|
description="A bit that specifies whether this LFOLVL overrides the start-at value of the level."/>
|
||||||
|
<bit mask="0x00000020" name="fFormatting"
|
||||||
|
description="A bit that specifies whether lvl is an LVL that overrides the corresponding LVL"/>
|
||||||
|
<bit mask="0x00003FC0" name="grfhic"
|
||||||
|
description="A grfhic that specifies the HTML incompatibilities of the overriding level formatting"/>
|
||||||
|
<bit mask="0x1FFFC000" name="unused1" deprecated="true" description="This MUST be ignored"/>
|
||||||
|
<bit mask="0xE0000000" name="unused2" deprecated="true" description="This MUST be ignored"/>
|
||||||
|
</field>
|
||||||
|
</fields>
|
||||||
|
</record>
|
Loading…
Reference in New Issue
Block a user