List of usage examples for org.apache.poi.util RLEDecompressingInputStream close
@Override
public void close() throws IOException
From source file:com.pnf.plugin.ole.parser.vba.VBAMacroExtractor.java
License:Apache License
/** * Extracts all macros from all modules of the provided input stream. The stream is assumed to * be in POIFS format (i.e. XLS file itself or vbaProject.bin from OOXML files) * //from w w w . ja v a 2s .c om * @param in * @return * @throws IOException */ @SuppressWarnings("resource") public static Map<String, String> extractMacros(InputStream dirIn, Map<String, DocumentStream> streams) { try { class ModuleMap extends HashMap<String, VbaModule> { private static final long serialVersionUID = 1L; Charset charset = Charset.forName("Cp1252"); // default charset } final ModuleMap modules = new ModuleMap(); // process DIR RLEDecompressingInputStream in = null; try { in = new RLEDecompressingInputStream(dirIn); } catch (ArrayIndexOutOfBoundsException e) { return null; } String streamName = null; while (true) { int id = in.readShort(); if (id == -1 || id == 0x0010) { break; // EOF or TERMINATOR } int len = in.readInt(); switch (id) { case 0x0009: // PROJECTVERSION in.skip(6); break; case 0x0003: // PROJECTCODEPAGE int codepage = in.readShort(); modules.charset = Charset.forName("Cp" + codepage); break; case 0x001A: // STREAMNAME byte[] streamNameBuf = new byte[len]; int count = in.read(streamNameBuf); streamName = new String(streamNameBuf, 0, count, modules.charset); break; case 0x0031: // MODULEOFFSET int moduleOffset = in.readInt(); VbaModule module = modules.get(streamName); if (module != null) { ByteArrayOutputStream out = new ByteArrayOutputStream(); RLEDecompressingInputStream stream = new RLEDecompressingInputStream( new ByteArrayInputStream(module.buf, moduleOffset, module.buf.length - moduleOffset)); IOUtils.copy(stream, out); stream.close(); out.close(); module.buf = out.toByteArray(); } else { module = new VbaModule(); module.offset = moduleOffset; modules.put(streamName, module); } break; default: in.skip(len); break; } } in.close(); String attrib = "Attribu"; byte[] temp = new byte[attrib.length()]; Map<String, String> moduleSources = new HashMap<String, String>(); for (String s : streams.keySet()) { ByteBuffer buff = streams.get(s).getBuffer(); VbaModule module = modules.get(s); if (module != null) { // Read module using data we already collected read(module, buff); } else { // Otherwise, attempt to locate "Attribute" reserved word and use that as the basis for the module offset try { int total = buff.remaining(); int pos = 0; boolean found = false; while (pos + temp.length < total && !found) { buff.position(pos); buff.get(temp); found = attrib.equals(new String(temp)); if (!found) pos++; buff.rewind(); } if (found) { VbaModule m = new VbaModule(); m.offset = pos - 4; // for [01 00 b0 b7] bytes modules.put(s, m); read(m, buff); } } catch (Throwable t) { // Discard any errors since this is a last resort } } } for (Map.Entry<String, VbaModule> entry : modules.entrySet()) { VbaModule module = entry.getValue(); if (module != null && module.buf != null && module.buf.length > 0) { // Skip empty modules moduleSources.put(entry.getKey(), new String(module.buf, modules.charset)); } } return moduleSources; } catch (IOException e) { return null; } }