private static void ReadModule(DocumentInputStream dis, String name, ModuleMap modules) { Module module = modules.Get(name); // TODO Refactor this to fetch dir then do the rest if (module == null) { // no DIR stream with offsets yet, so store the compressed bytes for later module = new Module(); modules.Put(name, module); module.Read(dis); } else { if (module.offset == null) { //This should not happen. bug 59858 throw new IOException("Module offset for '" + name + "' was never Read."); } // we know the offset already, so decompress immediately on-the-fly long skippedBytes = dis.Skip(module.offset.Value); if (skippedBytes != module.offset) { throw new IOException("tried to skip " + module.offset + " bytes, but actually skipped " + skippedBytes + " bytes"); } InputStream stream = new RLEDecompressingInputStream(dis); module.Read(stream); stream.Close(); } }
/** * Reads module from DIR node in input stream and Adds it to the modules map for decompression later * on the second pass through this function, the module will be decompressed * * Side-effects: Adds a new module to the module map or Sets the buf field on the module * to the decompressed stream contents (the VBA code for one module) * * @param in the Run-length encoded input stream to read from * @param streamName the stream name of the module * @param modules a map to store the modules * @throws IOException */ private static void ReadModule(RLEDecompressingInputStream in1, String streamName, ModuleMap modules) { int moduleOffset = in1.ReadInt(); Module module = modules.Get(streamName); if (module == null) { // First time we've seen the module. Add it to the ModuleMap and decompress it later module = new Module(); module.offset = moduleOffset; modules.Put(streamName, module); // Would Adding module.Read(in1) here be correct? } else { // Decompress a previously found module and store the decompressed result into module.buf InputStream stream = new RLEDecompressingInputStream( new MemoryStream(module.buf, moduleOffset, module.buf.Length - moduleOffset) ); module.Read(stream); stream.Close(); } }
private static void CheckRLEDecompression(String expected, byte[] RunLengthEncodedData) { Stream compressedStream = new MemoryStream(RunLengthEncodedData); MemoryStream out1 = new MemoryStream(); try { InputStream stream = new RLEDecompressingInputStream(compressedStream); try { IOUtils.Copy(stream, out1); } finally { out1.Close(); stream.Close(); } } catch (IOException e) { //throw new Exception(e); throw e; } String expanded; try { //expanded = out1.ToString(StringUtil.UTF8.Name()); expanded = Encoding.UTF8.GetString(out1.ToArray()); } catch (EncoderFallbackException e) { //throw new Exception(e); throw e; } Assert.AreEqual(expected, expanded); }
/** * Reads VBA Project modules from a VBA Project directory located at * <tt>macroDir</tt> into <tt>modules</tt>. * * @since 3.15-beta2 */ protected void ReadMacros(DirectoryNode macroDir, ModuleMap modules) { foreach (Entry entry in macroDir) { if (!(entry is DocumentNode)) { continue; } String name = entry.Name; DocumentNode document = (DocumentNode)entry; DocumentInputStream dis = new DocumentInputStream(document); try { if ("dir".Equals(name, StringComparison.OrdinalIgnoreCase)) { // process DIR RLEDecompressingInputStream in1 = new RLEDecompressingInputStream(dis); String streamName = null; int recordId = 0; try { while (true) { recordId = in1.ReadShort(); if (EOF == recordId || VERSION_INDEPENDENT_TERMINATOR == recordId) { break; } int recordLength = in1.ReadInt(); switch (recordId) { case PROJECTVERSION: TrySkip(in1, 6); break; case PROJECTCODEPAGE: int codepage = in1.ReadShort(); ModuleMap.charset = Encoding.GetEncoding(codepage); //Charset.ForName("Cp" + codepage); break; case STREAMNAME: streamName = ReadString(in1, recordLength, ModuleMap.charset); break; case MODULEOFFSET: ReadModule(in1, streamName, modules); break; default: TrySkip(in1, recordLength); break; } } } catch (IOException e) { throw new IOException( "Error occurred while Reading macros at section id " + recordId + " (" + HexDump.ShortToHex(recordId) + ")", e); } finally { in1.Close(); } } else if (!name.StartsWith("__SRP", StringComparison.OrdinalIgnoreCase) && !name.StartsWith("_VBA_PROJECT", StringComparison.OrdinalIgnoreCase)) { // process module, skip __SRP and _VBA_PROJECT since these do not contain macros ReadModule(dis, name, modules); } } finally { dis.Close(); } } }