Example usage for org.apache.commons.collections4.bidimap TreeBidiMap put

List of usage examples for org.apache.commons.collections4.bidimap TreeBidiMap put

Introduction

In this page you can find the example usage for org.apache.commons.collections4.bidimap TreeBidiMap put.

Prototype

public V put(final K key, final V value) 

Source Link

Document

Puts the key-value pair into the map, replacing any previous pair.

Usage

From source file:org.apache.poi.hpsf.Section.java

/**
 * Creates a {@link Section} instance from a byte array.
 *
 * @param src Contains the complete property set stream.
 * @param offset The position in the stream that points to the
 * section's format ID.//from ww w .j  ava2  s . c  o m
 *
 * @exception UnsupportedEncodingException if the section's codepage is not
 * supported.
 */
public Section(final byte[] src, final int offset) throws UnsupportedEncodingException {
    /*
     * Read the format ID.
     */
    formatID = new ClassID(src, offset);

    /*
     * Read the offset from the stream's start and positions to
     * the section header.
     */
    int offFix = (int) LittleEndian.getUInt(src, offset + ClassID.LENGTH);

    // some input files have a invalid (padded?) offset, which need to be fixed
    // search for beginning of size field
    if (src[offFix] == 0) {
        for (int i = 0; i < 3 && src[offFix] == 0; i++, offFix++)
            ;
        // cross check with propertyCount field and the property list field
        for (int i = 0; i < 3
                && (src[offFix + 3] != 0 || src[offFix + 7] != 0 || src[offFix + 11] != 0); i++, offFix--)
            ;
    }

    this._offset = offFix;

    LittleEndianByteArrayInputStream leis = new LittleEndianByteArrayInputStream(src, offFix);

    /*
     * Read the section length.
     */
    int size = (int) Math.min(leis.readUInt(), src.length - _offset);

    /*
     * Read the number of properties.
     */
    final int propertyCount = (int) leis.readUInt();

    /*
     * Read the properties. The offset is positioned at the first
     * entry of the property list. There are two problems:
     *
     * 1. For each property we have to find out its length. In the
     *    property list we find each property's ID and its offset relative
     *    to the section's beginning. Unfortunately the properties in the
     *    property list need not to be in ascending order, so it is not
     *    possible to calculate the length as
     *    (offset of property(i+1) - offset of property(i)). Before we can
     *    that we first have to sort the property list by ascending offsets.
     *
     * 2. We have to read the property with ID 1 before we read other
     *    properties, at least before other properties containing strings.
     *    The reason is that property 1 specifies the codepage. If it is
     *    1200, all strings are in Unicode. In other words: Before we can
     *    read any strings we have to know whether they are in Unicode or
     *    not. Unfortunately property 1 is not guaranteed to be the first in
     *    a section.
     *
     *    The algorithm below reads the properties in two passes: The first
     *    one looks for property ID 1 and extracts the codepage number. The
     *    seconds pass reads the other properties.
     */
    /* Pass 1: Read the property list. */
    final TreeBidiMap<Long, Long> offset2Id = new TreeBidiMap<Long, Long>();
    for (int i = 0; i < propertyCount; i++) {
        /* Read the property ID. */
        long id = (int) leis.readUInt();

        /* Offset from the section's start. */
        long off = (int) leis.readUInt();

        offset2Id.put(off, id);
    }

    Long cpOffset = offset2Id.getKey((long) PropertyIDMap.PID_CODEPAGE);

    /* Look for the codepage. */
    int codepage = -1;
    if (cpOffset != null) {
        /* Read the property's value type. It must be VT_I2. */
        leis.setReadIndex((int) (this._offset + cpOffset));
        final long type = leis.readUInt();

        if (type != Variant.VT_I2) {
            throw new HPSFRuntimeException("Value type of property ID 1 is not VT_I2 but " + type + ".");
        }

        /* Read the codepage number. */
        codepage = leis.readUShort();
        setCodepage(codepage);
    }

    /* Pass 2: Read all properties - including the codepage property,
     * if available. */
    for (Map.Entry<Long, Long> me : offset2Id.entrySet()) {
        long off = me.getKey();
        long id = me.getValue();

        if (id == PropertyIDMap.PID_CODEPAGE) {
            continue;
        }

        int pLen = propLen(offset2Id, off, size);
        leis.setReadIndex((int) (this._offset + off));

        if (id == PropertyIDMap.PID_DICTIONARY) {
            leis.mark(100000);
            if (!readDictionary(leis, pLen, codepage)) {
                // there was an error reading the dictionary, maybe because the pid (0) was used wrong
                // try reading a property instead
                leis.reset();
                try {
                    // fix id
                    id = Math.max(PropertyIDMap.PID_MAX, offset2Id.inverseBidiMap().lastKey()) + 1;
                    setProperty(new MutableProperty(id, leis, pLen, codepage));
                } catch (RuntimeException e) {
                    LOG.log(POILogger.INFO, "Dictionary fallback failed - ignoring property");
                }
            }
            ;
        } else {
            setProperty(new MutableProperty(id, leis, pLen, codepage));
        }
    }

    sectionBytes.write(src, (int) _offset, size);
    padSectionBytes();
}