Subversion Repositories display

Rev

Rev 606 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (C) 2011.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */


package test.display.check;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

import test.display.HuffmanDecoder;
import test.display.Section;
import test.util.BitReaderLR;
import uk.me.parabola.imgfmt.app.ImgFileReader;
import uk.me.parabola.log.Logger;

/**
 * Read and cache all the strings in the mdr15 section.
 *
 * Has to be read with regard to the code page that the file is written in.
 */

public class MdrStrings {
        private final ImgFileReader reader;
        private final Section mdr15;
        private final Charset charset;
        private final HuffmanDecoder decoder;
        private final boolean doubleCheck;
        private Map<Integer, String> stringTable;

        public MdrStrings(ImgFileReader reader, Section mdr15, Charset charset, HuffmanDecoder decoder, boolean doubleCheck) {
                this.reader = reader;
                this.mdr15 = mdr15;
                this.decoder = decoder;
                this.charset = charset;
                this.doubleCheck = doubleCheck;
        }

        /**
         * Get a string from the string section.
         *
         * @param off The offset in the text section.
         * @return The resultant string.
         */

        public String getTextString(int off) {
                if (stringTable == null)
                        readAllStrings();

                return stringTable.get(off);
        }

        public void readAllStrings() {
                stringTable = new HashMap<>();

                // Remember where we are
                long rem = reader.position();

                long start = mdr15.getStart();
                long end = mdr15.getEnd();
                int magic = mdr15.getMagic();
                boolean compressedStrings = (magic & 0x1) != 0;

                reader.position(start);
                byte[] buffer = new byte[1024];
                int len = 0;

                while (reader.position() < end) {
                        String text = null;
                        int off = (int) (reader.position() - start);
                        if (compressedStrings) {
                                text = decoder.decode(new BitReaderLR(reader, (int) (end - reader.position())), doubleCheck, charset);
                                if (decoder.isHuffmanDecodingFailed()) {
                                        Logger.defaultLogger.error("Huffman decoding of label at offset " + off + " failed");
                                        break;
                                }
                        } else {
                                len = 0;
                                while (text == null) {
                                        byte b = reader.get();
                                        if (b == 0) {
                                                text = new String(buffer, 0, len, charset);
                                        } else {
                                                buffer[len++] = b;
                                        }
                                }
                        }
                        stringTable.put(off, text);
                }
               

                // Return to our callers position
                reader.position(rem);
        }
}