This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |