|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.lib.cvsclient.file; import java.io.*; import org.netbeans.lib.cvsclient.util.*; /** * File Processor that handles processing of rcs-diff response. * (aka diff -n format) The original file is read and a merge is created. * At the same time the correct line-ending is processed. * It's possible to set the processor the preffered line-ending. * The default is dependant on the platform. * * @author Milos Kleint */ public class WriteRcsDiffFilePreprocessor implements WriteTextFilePreprocessor { private static final int CHUNK_SIZE = 32768; private static final int READ_REMAINING = -2; /** * line ending that will be used when writing the final result file. */ private String lineEnding = "\n"; //default line ending.. public WriteRcsDiffFilePreprocessor() { } /** * Gets the value of lineending used when writing the resulting file. * @return Value of property lineEnding. */ public String getLineEnding() { return lineEnding; } /** * Setter for lineEnding used to write the file. * @param lineEnding New value of property lineEnding. */ public void setLineEnding(String lineEnding) { this.lineEnding = lineEnding; } /** * Processes the diff and merges it with the original file. * @param processedInput the stored diff. * @param fileToWrite the resulting file and * the original that is merged as the same time. * @throws IOException if any IO operation fails. * The original file is replaced by the merge only if no excpetion is thrown. */ public void copyTextFileToLocation(InputStream processedInput, File fileToWrite) throws IOException { // Here we read the temp file in again, doing any processing required // (for example, unzipping). We must not convert the bytes to characters // because this would corrupt files, that were written in an encoding // different from the current encoding. ReadInfo tempFileReader = null; OutputStream out = null; ReadInfo tempDiffReader = null; File tempFile = null; // BUGLOG.. assert the fileToWrite Exists.. otherwise it has no sense. try { tempDiffReader = new ReadInfo(new BufferedInputStream(processedInput)); tempFileReader = new ReadInfo(new BufferedInputStream(new FileInputStream(fileToWrite))); File cvsSubdir = new File(fileToWrite.getParent(), "CVS"); //NOI18N tempFile = File.createTempFile(".#merg", "cvs", cvsSubdir); //NOI18N out = new BufferedOutputStream(new FileOutputStream(tempFile)); int fileStart = 0; int diffCount = 0; byte[] diff = tempDiffReader.readLine(); while (diff != null && diff.length > 0) { // System.out.println("diffline=" + diff); if (diff[0] == 'd') { // now do delete.. int startLine = getStart(diff); int count = getLength(diff); // System.out.println("deleting. start =" + startLine + " count=" + count); if (startLine >= 0 && count > 0) { // read from file only if deletion is not some // from the beginning.. readToLine(startLine - 1, tempFileReader, out); readToLine(startLine - 1 + count, tempFileReader, null); // null skips the lines.. } else { // BugLog.. BugLog.getInstance().bug("wrong parsing.." + new String(diff)); throw new IOException(); // Interrupt the merging process so that the file is not corrupted. } } else if (diff[0] == 'a') { // now add lines from the diff.. int startLine = getStart(diff); int count = getLength(diff); // System.out.println("adding.. start =" + startLine + " count=" + count); if (startLine >= 0 && count > 0) { readToLine(startLine, tempFileReader, out); tempDiffReader.setLineNumber(0); readToLine(count, tempDiffReader, out); } else { // BugLog.. BugLog.getInstance().bug("wrong parsing.." + new String(diff)); throw new IOException(); // Interrupt the merging process so that the file is not corrupted. } } // now process next difference. diff = tempDiffReader.readLine(); } // read what's remaining.. readToLine(READ_REMAINING, tempFileReader, out); if (tempFile != null) { tempFileReader.close(); out.close(); if (fileToWrite.delete()) { boolean ok = tempFile.renameTo(fileToWrite); if (!ok) { /* System.out.println("fileToWrite path=" + fileToWrite.getPath()); System.out.println("fileToWrite absPath=" + fileToWrite.getAbsolutePath()); System.out.println("tempFile path=" + tempFile.getPath()); System.out.println("tempFile abs path=" + tempFile.getAbsolutePath()); System.out.println("temp read=" + tempFile.canRead() + "write=" + tempFile.canWrite()); System.out.println("filetowrite read=" + fileToWrite.canRead() + "write=" + fileToWrite.canWrite()); // System.out.println("cannot rename.."); */ throw new IOException(); } } else { throw new IOException(); } } } catch (Exception exc) { BugLog.getInstance().showException(exc); } finally { if (tempDiffReader != null) { try { tempDiffReader.close(); } catch (IOException ex) { // ignore } } if (tempFileReader != null) { try { tempFileReader.close(); } catch (IOException ex) { // ignore } } if (out != null) { try { out.close(); } catch (IOException ex) { // ignore } } } } /** * Reads lines from the reader until the specified line number is reached. * Writes the lines to the writer * @param finalLine the last line to read/write. Special value -2 reads * all that is remaining in the reader. * @param reader - does not accept null. * @param writer the writer that the read lines are written to. Accepts null. * In such a case the read lines are discarded. */ private void readToLine(int finalLine, final ReadInfo reader, final OutputStream out) throws IOException { byte[] line; while (reader.getLineNumber() < finalLine || finalLine == READ_REMAINING) { line = reader.readLine(); if (line == null) { // end of file.. return; } if (out != null) { out.write(line); out.write(getLineEnding().getBytes()); } } } private static int indexOf(byte[] bytes, byte b) { return indexOf(bytes, b, 0); } private static int indexOf(byte[] bytes, byte b, int start) { int index = -1; for (int i = start; i < bytes.length; i++) { if (bytes[i] == b) { index = i; break; } } return index; } /** * Extracts the line where the diff starts. */ private static int getStart(byte[] diffLine) { int spacePos = indexOf(diffLine, (byte) ' '); if (spacePos > 0) { String number = new String(diffLine, 1, spacePos - 1); try { int toReturn = Integer.parseInt(number); return toReturn; } catch (NumberFormatException exc) { // System.out.println("diffLine=" + diffLine); return -1; } } // System.out.println("no space in diffline=" + diffLine); return -1; } /** * Extracts the length of the diff. * For "delete" it means how many lines to delete from original. * For "add" it means how many lines are added from the diff to original file. */ private static int getLength(byte[] diffLine) { //String trimmed = diffLine.trim(); int spacePos = indexOf(diffLine, (byte) ' '); if (spacePos > 0) { int end = indexOf(diffLine, (byte) ' ', spacePos + 1); if (end < 0) end = diffLine.length; String number = new String(diffLine, spacePos + 1, end - spacePos - 1); try { int toReturn = Integer.parseInt(number); return toReturn; } catch (NumberFormatException exc) { // System.out.println("numformat exception..=" + diffLine); return -1; } } // System.out.println("no space in diffline=" + diffLine); return -1; } private static class ReadInfo { private PushbackInputStream in; private int readLength; private int startIndex; private int lineNumber; private ByteArray line; public ReadInfo(InputStream in) { this.in = new PushbackInputStream(in, 1); readLength = -1; startIndex = 0; lineNumber = 0; line = new ByteArray(); } public int getLineNumber() { return lineNumber; } public void setLineNumber(int lineNumber) { this.lineNumber = lineNumber; } /** * Reads a line. The line-termination bytes are not added. * @return null When the end of the stream is reached. */ public byte[] readLine() throws IOException { line.reset(); boolean end = false; do { int b = in.read(); if (b == -1) { end = true; break; } if (b == '\n') { lineNumber++; break; } if (b == '\r') { int next = in.read(); if (next != '\n') in.unread(next); lineNumber++; break; } line.add((byte) b); } while (true); byte[] bytes = line.getBytes(); if (end && bytes.length == 0) { bytes = null; } return bytes; /* StringBuffer toReturn = new StringBuffer(); while (true) { if (startIndex > readLength) { // System.out.println("reading.."); readLength = reader.read(cchunk); // System.out.println("read=" + readLength); startIndex = 0; } if (startIndex >= readLength) { readLength = -1; if (toReturn.length() == 0) { return null; } else { lineNumber = lineNumber + 1; return toReturn.toString(); } } // System.out.println("startindex = " + startIndex + " length=" + readLength); for (int i = startIndex; i < readLength; i++) { if (cchunk[i] == '\n') { toReturn.append(WriteRcsDiffFilePreprocessor.this.getLineEnding()); startIndex = i + 1; lineNumber = lineNumber + 1; // System.out.println("linenum=" + lineNumber); // System.out.println("line=" + toReturn.toString() + "--"); return toReturn.toString(); } else { // could be maybe made faster by appending the whole array when // read all or encountering the newline.. toReturn.append(cchunk[i]); } } startIndex = readLength; } */ } public void close() throws IOException { if (in != null) { in.close(); } } } // end of inner class.. } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.