Rev 3408 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (C) 2009.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 or
* version 2 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 uk.me.parabola.imgfmt.app.mdr;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import uk.me.parabola.imgfmt.ExitException;
import uk.me.parabola.imgfmt.MapFailedException;
import uk.me.parabola.imgfmt.Utils;
import uk.me.parabola.imgfmt.app.ImgFileWriter;
/**
* The string table. This is not used by the device.
*
* There is a compressed and non-compressed version of this section.
* We are starting with the regular string version.
*
* @author Steve Ratcliffe
*/
public class Mdr15
extends MdrSection
{
private final OutputStream stringFile
;
private int nextOffset
;
private Map<String,
Integer> strings =
new HashMap<String,
Integer>();
private final Charset charset
;
private final File tempFile
;
public Mdr15
(MdrConfig config
) {
setConfig
(config
);
charset = config.
getSort().
getCharset();
try {
tempFile =
File.
createTempFile("strings",
null, config.
getOutputDir());
tempFile.
deleteOnExit();
stringFile =
new BufferedOutputStream(new FileOutputStream(tempFile
),
64 * 1024);
// reserve the string at offset 0 to be the empty string.
stringFile.
write(0);
nextOffset =
1;
} catch (IOException e
) {
throw new ExitException
("Could not create temporary file");
}
}
public int createString
(String str
) {
Integer offset = strings.
get(str
);
if (offset
!=
null)
return offset
;
int off
;
try {
off = nextOffset
;
byte[] bytes = str.
getBytes(charset
);
stringFile.
write(bytes
);
stringFile.
write(0);
// Increase offset for the length of the string and the null byte
nextOffset += bytes.
length +
1;
} catch (IOException e
) {
// Can't convert, return empty string instead.
off =
0;
}
strings.
put(str, off
);
return off
;
}
/**
* Tidy up after reading files.
* Close the temporary file, and release the string table which is no longer
* needed.
*/
public void releaseMemory
() {
strings =
null;
try {
stringFile.
close();
} catch (IOException e
) {
throw new MapFailedException
("Could not close string temporary file");
}
}
public void writeSectData
(ImgFileWriter writer
) {
FileInputStream stream =
null;
try {
stream =
new FileInputStream(tempFile
);
FileChannel channel = stream.
getChannel();
ByteBuffer buf =
ByteBuffer.
allocate(32 * 1024);
while (channel.
read(buf
) > 0) {
buf.
flip();
writer.
put(buf
);
buf.
compact();
}
} catch (IOException e
) {
throw new ExitException
("Could not write string section of index");
} finally {
Utils.
closeFile(stream
);
}
}
public int getItemSize
() {
// variable sized records.
return 0;
}
/**
* The meaning of number of items for this section is the largest string
* offset possible. We are taking the total size of the string section
* for this.
*/
public int getSizeForRecord
() {
return numberToPointerSize
(nextOffset
);
}
/**
* There is no use for this as the records are not fixed length.
*
* @return Always zero, could return the number of strings.
*/
protected int numberOfItems
() {
return 0;
}
}