|
public void calculateFileSizeAndDigest(OutputStream os) |
|
throws DigiDocException |
|
{ |
|
if(m_logger.isDebugEnabled()){ |
|
m_logger.debug("calculateFileSizeAndDigest(" + getId() + ") body: " + |
|
((m_body != null) ? "OK" : "NULL") + " base64: " + m_bodyIsBase64 + |
|
" DF cache: " + ((m_fDfCache != null) ? m_fDfCache.getAbsolutePath() : "NULL")); |
|
} |
|
if(m_contentType.equals(CONTENT_BINARY)) { |
|
byte[] digest = null; |
|
try { |
|
MessageDigest sha = MessageDigest.getInstance("SHA-256"); |
|
String longFileName = m_fileName; |
|
m_fileName = new File(m_fileName).getName(); |
|
FileInputStream fis = new FileInputStream(longFileName); |
|
byte[] data = new byte[4096]; |
|
int nRead = 0; |
|
long lSize = 0; |
|
while((nRead = fis.read(data)) > 0) { |
|
sha.update(data, 0, nRead); |
|
lSize += nRead; |
|
} |
|
digest = sha.digest(); |
|
setSize(lSize); |
|
} catch(Exception ex) { |
|
m_logger.error("Error calculating bdoc digest: " + ex); |
|
} |
|
setDigest(digest); |
|
|
|
if(m_logger.isDebugEnabled()) |
|
m_logger.debug("DataFile: \'" + getId() + "\' length: " + |
|
getSize() + " digest: " + Base64Util.encode(digest)); |
|
return; |
|
} |
|
|
|
MessageDigest sha = null; |
|
boolean bUse64ByteLines = true; |
|
String use64Flag = ConfigManager.instance().getProperty("DATAFILE_USE_64BYTE_LINES"); |
|
if(use64Flag != null && use64Flag.equalsIgnoreCase("FALSE")) |
|
bUse64ByteLines = false; |
|
try { |
|
sha = MessageDigest.getInstance("SHA-1"); // TODO: fix digest type |
|
// if DataFile's digest has already been initialized |
|
// and body in memory, e.g. has been read from digidoc |
|
// then write directly to output stream and don't calculate again |
|
if(m_origDigestValue != null && m_body != null && os != null) { |
|
os.write(xmlHeader()); |
|
if(m_logger.isDebugEnabled()) |
|
m_logger.debug("write df header1: " + xmlHeader()); |
|
os.write(m_body); |
|
os.write(xmlTrailer()); |
|
return; |
|
} |
|
String longFileName = m_fileName; |
|
File fIn = new File(m_fileName); |
|
FileInputStream fis = null; |
|
m_fileName = fIn.getName(); |
|
if(fIn.canRead()) { |
|
fis = new FileInputStream(longFileName); |
|
if(m_logger.isDebugEnabled()) |
|
m_logger.debug("Read file: " + longFileName); |
|
} |
|
if(m_fDfCache != null) { |
|
fis = new FileInputStream(m_fDfCache); |
|
if(m_logger.isDebugEnabled()) |
|
m_logger.debug("Read cache: " + m_fDfCache); |
|
} |
|
byte[] tmp1=null,tmp2=null,tmp3=null; |
|
ByteArrayOutputStream sbDig = new ByteArrayOutputStream(); |
|
sbDig.write(xmlHeader()); |
|
// add trailer and canonicalize |
|
tmp3 = xmlTrailer(); |
|
sbDig.write(tmp3); |
|
tmp1 = canonicalizeXml(sbDig.toByteArray()); |
|
// now remove the end tag again and calculate digest of the start tag only |
|
tmp2 = new byte[tmp1.length - tmp3.length]; |
|
System.arraycopy(tmp1, 0, tmp2, 0, tmp2.length); |
|
sha.update(tmp2); |
|
if(os != null) { |
|
os.write(xmlHeader()); |
|
} |
|
// reset the collecting buffer and other temp buffers |
|
sbDig = new ByteArrayOutputStream(); |
|
tmp1 = tmp2 = tmp3 = null; |
|
// content must be read from file |
|
if(m_body == null) { |
|
byte[] buf = new byte[block_size]; |
|
byte[] b64leftover = null; |
|
int fRead = 0, b64left = 0; |
|
ByteArrayOutputStream content = null; |
|
if(m_contentType.equals(CONTENT_EMBEDDED_BASE64)) { |
|
// optimization for 64 char base64 lines |
|
// convert to base64 online at a time to conserve memory |
|
// VS: DF temp file base64 decoding fix |
|
if(m_fDfCache == null) { |
|
if(bUse64ByteLines) |
|
b64leftover = new byte[65]; |
|
else |
|
content = new ByteArrayOutputStream(); |
|
} |
|
} |
|
while((fRead = fis.read(buf)) > 0 || b64left > 0) { // read input file |
|
if(m_logger.isDebugEnabled()) |
|
m_logger.debug("read: " + fRead + " bytes of input data"); |
|
if(m_contentType.equals(CONTENT_EMBEDDED_BASE64)) { |
|
// VS: DF temp file base64 decoding fix |
|
if(m_fDfCache != null) { |
|
if(os != null) |
|
os.write(buf, 0, fRead); |
|
sha.update(buf, 0, fRead); |
|
} else { |
|
if(bUse64ByteLines) { // 1 line base64 optimization |
|
b64left = calculateAndWriteBase64Block(os, sha, b64leftover, |
|
b64left, buf, fRead, fRead < block_size); |
|
} else { // no optimization |
|
content.write(buf, 0, fRead); |
|
} |
|
} |
|
} else { |
|
if(fRead < buf.length) { |
|
tmp2= new byte[fRead]; |
|
System.arraycopy(buf, 0, tmp2, 0, fRead); |
|
tmp1 = ConvertUtils.data2utf8(tmp2, m_codepage); |
|
} |
|
else |
|
tmp1 = ConvertUtils.data2utf8(buf, m_codepage); |
|
sbDig.write(tmp1); |
|
} |
|
if(m_logger.isDebugEnabled()) |
|
m_logger.debug("End using block: " + fRead + " in: " + ((fis != null) ? fis.available() : 0)); |
|
} // end reading input file |
|
if(m_contentType.equals(CONTENT_EMBEDDED_BASE64)) { |
|
// VS: DF temp file base64 decoding fix |
|
if(!bUse64ByteLines && m_fDfCache == null) |
|
sbDig.write(Base64Util.encode(content.toByteArray(), 0).getBytes()); |
|
content = null; |
|
} |
|
if(m_logger.isDebugEnabled()) |
|
m_logger.debug("End reading content"); |
|
} else { // content allready in memeory |
|
if(m_body != null) { |
|
if(bUse64ByteLines && m_contentType.equals(CONTENT_EMBEDDED_BASE64) && !m_bodyIsBase64) { |
|
calculateAndWriteBase64Block(os, sha, null, 0, m_body, m_body.length, true); |
|
m_body = Base64Util.encode(m_body).getBytes(); |
|
} else { |
|
if(m_contentType.equals(CONTENT_EMBEDDED_BASE64) && !m_bodyIsBase64) |
|
tmp1 = Base64Util.encode(m_body).getBytes(); |
|
else if(m_contentType.equals(CONTENT_EMBEDDED_BASE64) && m_bodyIsBase64) |
|
tmp1 = ConvertUtils.data2utf8(m_body, m_codepage); |
|
else |
|
tmp1 = ConvertUtils.data2utf8(m_body, m_codepage); |
|
sbDig.write(tmp1); |
|
} |
|
} |
|
} |
|
tmp1 = null; |
|
if(fis != null) |
|
fis.close(); |
|
// don't need to canonicalize base64 content ! |
|
if(m_contentType.equals(CONTENT_EMBEDDED_BASE64)) { |
|
// VS: DF temp file base64 decoding fix |
|
if(!bUse64ByteLines && m_fDfCache == null) { |
|
tmp2 = sbDig.toByteArray(); |
|
if(tmp2 != null && tmp2.length > 0) { |
|
sha.update(tmp2); |
|
if(os != null) |
|
os.write(tmp2); |
|
} |
|
} |
|
} else { |
|
// canonicalize body |
|
tmp2 = sbDig.toByteArray(); |
|
if(tmp2 != null && tmp2.length > 0) { |
|
//System.out.println("Body: \"" + tmp2 + "\""); |
|
if(tmp2[0] == '<') |
|
tmp2 = canonicalizeXml(tmp2); |
|
if(tmp2 != null && tmp2.length > 0) { |
|
sha.update(tmp2); // crash |
|
if(os != null) |
|
os.write(tmp2); |
|
} |
|
} |
|
} |
|
tmp2 = null; |
|
sbDig = null; |
|
// trailer |
|
tmp1 = xmlTrailer(); |
|
sha.update(tmp1); |
|
if(os != null) |
|
os.write(tmp1); |
|
// now calculate the digest |
|
byte[] digest = sha.digest(); |
|
setDigest(digest); |
|
if(m_logger.isDebugEnabled()) |
|
m_logger.debug("DataFile: \'" + getId() + "\' length: " + |
|
getSize() + " digest: " + Base64Util.encode(digest)); |
|
m_fileName = longFileName; |
|
} catch(Exception ex) { |
|
DigiDocException.handleException(ex, DigiDocException.ERR_READ_FILE); |
|
} |
|
} |