/* * ==================================================================== * Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://svnkit.com/license.html * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * ==================================================================== */ package org.tmatesoft.svn.core.internal.io.dav.handlers; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.internal.delta.SVNDeltaReader; import org.tmatesoft.svn.core.internal.io.dav.DAVElement; import org.tmatesoft.svn.core.internal.util.SVNBase64; import org.tmatesoft.svn.core.io.ISVNDeltaConsumer; import org.xml.sax.SAXException; /** * @author TMate Software Ltd. * @version 1.3 */ public abstract class BasicDAVDeltaHandler extends BasicDAVHandler { protected static final DAVElement TX_DELTA = DAVElement.getElement(DAVElement.SVN_NAMESPACE, "txdelta"); private boolean myIsDeltaProcessing; private SVNDeltaReader myDeltaReader; private StringBuffer myDeltaOutputStream; protected void setDeltaProcessing(boolean processing) throws SVNException { myIsDeltaProcessing = processing; if (!myIsDeltaProcessing) { myDeltaReader.reset(getCurrentPath(), getDeltaConsumer()); getDeltaConsumer().textDeltaEnd(getCurrentPath()); } else { myDeltaOutputStream.delete(0, myDeltaOutputStream.length()); } } protected void init() { myDeltaReader = new SVNDeltaReader(); myDeltaOutputStream = new StringBuffer(); super.init(); } public void characters(char[] ch, int start, int length) throws SAXException { if (myIsDeltaProcessing) { int offset = start; for (int i = start; i < start + length; i++) { if (ch[i] == '\r' || ch[i] == '\n') { myDeltaOutputStream.append(ch, offset, i - offset); offset = i + 1; if (i + 1 < (start + length) && ch[i + 1] == '\n') { offset++; i++; } } } if (offset < start + length) { myDeltaOutputStream.append(ch, offset, start + length - offset); } // decode (those dividable by 4) int stored = myDeltaOutputStream.length(); if (stored < 4) { return; } int segmentsCount = stored / 4; int remains = stored - (segmentsCount * 4); StringBuffer toDecode = new StringBuffer(); toDecode.append(myDeltaOutputStream); toDecode.delete(myDeltaOutputStream.length() - remains, myDeltaOutputStream.length()); int index = 0; while (index < toDecode.length() && Character.isWhitespace(toDecode.charAt(index))) { index++; } if (index > 0) { toDecode = toDecode.delete(0, index); } index = toDecode.length() - 1; while (index >= 0 && Character.isWhitespace(toDecode.charAt(index))) { toDecode.delete(index, toDecode.length()); index--; } byte[] buffer = allocateBuffer(toDecode.length()); try { int decodedLength = SVNBase64.base64ToByteArray(toDecode, buffer); myDeltaReader.nextWindow(buffer, 0, decodedLength, getCurrentPath(), getDeltaConsumer()); } catch (IllegalArgumentException e) { throw new SAXException(e); } catch (SVNException e) { throw new SAXException(e); } myDeltaOutputStream.delete(0, toDecode.length()); } else { super.characters(ch, start, length); } } protected abstract String getCurrentPath(); protected abstract ISVNDeltaConsumer getDeltaConsumer(); }