All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ttzero.excel.entity.e3.Context Maven / Gradle / Ivy

/*
 * Copyright (c) 2019-2020, [email protected] All Rights Reserved.
 *
 * Licensed 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.ttzero.excel.entity.e3;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.ttzero.excel.entity.e3.enums.ByteOrder;
import org.ttzero.excel.manager.ExcelType;
import org.ttzero.excel.reader.ExcelReadException;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Path;
import java.util.Arrays;

/**
 * Compound Document Header
 * 

* The header is always located at the beginning of * the file, and its size is exactly {@code 512} bytes. * This implies that the first sector (with SecID 0) * always starts at file offset {@code 512}. * * @author guanquan.wang at 2019-01-29 13:31 */ public final class Context { private final Logger LOGGER = LoggerFactory.getLogger(getClass()); /** * The tmp split directory path */ public Path root; /** * The excel file channel */ public SeekableByteChannel channel; /** * Type of file, enum value of {@link ExcelType} */ public ExcelType excelType; /** * Revision number of the file format */ public short mv; /** * Version number of the file format */ public short v; /** * Byte order identifier * *

    *
  • FE FF: Little-Endian
  • *
  • FF FE: Big-Endian
  • *
*/ public ByteOrder byteOrder; /** * Size of a sector in the compound document file * in power-of-two (ssz), real sector size is sec_size = 2ssz bytes * (minimum value is 7 which means 128 bytes, most used * value is 9 which means 512 bytes) */ public int ssz; /** * Size of a short-sector in the short-stream container * stream in power-of-two (sssz), real short-sector * size is short_sec_size = 2sssz bytes * (maximum value is sector size ssz, see above, most used * value is 6 which means 64 bytes) */ public int sssz; /** * Total number of sectors used for the sector allocation table */ public int count_sat; /** * SecID of first sector of the directory stream */ public int dir_sid; /** * Minimum size of a standard stream (in bytes, minimum allowed * and most used size is {@code 4096} bytes), streams with an * actual size smaller than (and not equal to) this value are * stored as short-streams */ public int standard_size; /** * SecID of first sector of the short-sector allocation table, * or –2 (End Of Chain SecID) if not extant */ public int first_ssat_sid; /** * Total number of sectors used for the short-sector allocation table */ public int count_ssat; /** * SecID of first sector of the master sector allocation * table, or –2 (End Of Chain SecID) if no additional * sectors used */ public int first_msat_sid; /** * Total number of sectors used for the master sector allocation table */ public int count_msat; /** * First part of the master sector allocation table */ public int[] msat; /** * The short-sector allocation table */ public int[] ssat; /** * The split size. * Default size is 5, so the default block size is 16KB */ public int split; /** * The sector size */ public int sectorSize; /** * The first short-sector SecID */ public int first_short_sector; /** * The shared string block size */ public int cacheSize; /** * The shared string hot block size */ public int hotSize; /** * The Sector Identifiers Table */ public SectorAllocationTable sectorTable; public Context() { this.sectorTable = new SectorAllocationTable.SmallSectorTable(); } /** * Read specify sector data * * @param sid the sector id * @param buffer dest byte buffer * @return byte buffer */ public ByteBuffer read(int sid, ByteBuffer buffer) { /* Read 5 blocks of data at a time, so position is multiple of 0, 5, 10 ... and plus a fixed 512 bytes in header */ long position = (((long) sid) >> split << (ssz + split)) + 512; buffer.clear(); try { if (channel.position() != position) { LOGGER.debug("Sector id: {}, Position: {}, Channel position: {}", sid, position, channel.position()); channel.position(position); } channel.read(buffer); } catch (IOException e) { throw new ExcelReadException(e); } buffer.flip(); return buffer; } /** * Test the short-sector-block is adjacent * * @param sid the RootStorage sector id * @return bool */ public boolean isAdjacentShortBlock(int sid) { return first_short_sector == SectorAllocationTable.EOC || ssat.length == 0 || sid >= ssat.length; } /** * Bound check * * @return false if the record size exceeds limit */ public boolean recordBoundCheck(int from, int size, int s_size) { int n = size >> s_size; if (n == 0) return true; if ((n << s_size) < size) n++; sectorTable.moveTo(from); for ( ; --n > 0; ) { int next_sid = sectorTable.nextSecID(); if (next_sid < 0) return false; } return true; } @Override public String toString() { return "{Root: " + root + ", Type: " + excelType + ", Revision: " + mv + ", Version: " + v + ", ByteOrder: " + byteOrder + ", ssz: " + ssz + ", sssz: " + sssz + ", count_sat: " + count_sat + ", dir_sid: " + dir_sid + ", standard_size: " + standard_size + ", first_ssat_sid: " + first_ssat_sid + ", count_ssat: " + count_ssat + ", first_msat_sid: " + first_msat_sid + ", count_msat: " + count_msat + ", msat: " + Arrays.toString(msat) + ", ssat: " + Arrays.toString(ssat) + ", first_short_sector: " + first_short_sector + "}" ; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy