001: /*****************************************************************************
002: * Sun Public License Notice
003: *
004: * The contents of this file are subject to the Sun Public License Version
005: * 1.0 (the "License"). You may not use this file except in compliance with
006: * the License. A copy of the License is available at http://www.sun.com/
007: *
008: * The Original Code is the CVS Client Library.
009: * The Initial Developer of the Original Code is Robert Greig.
010: * Portions created by Robert Greig are Copyright (C) 2000.
011: * All Rights Reserved.
012: *****************************************************************************/
013:
014: /**
015: * This class is based on the original source code from the netbeans javacvs
016: * module (http://www.netbeans.org)
017: */package gruntspud;
018:
019: import gruntspud.connection.ConnectionProfile;
020:
021: import java.io.BufferedInputStream;
022: import java.io.BufferedOutputStream;
023: import java.io.File;
024: import java.io.FileInputStream;
025: import java.io.FileOutputStream;
026: import java.io.IOException;
027: import java.io.InputStream;
028: import java.io.OutputStream;
029:
030: import org.netbeans.lib.cvsclient.file.DefaultTransmitTextFilePreprocessor;
031:
032: public class GruntspudTransmitTextFilePreprocessor extends
033: DefaultTransmitTextFilePreprocessor {
034:
035: private static final int CHUNK_SIZE = 32768;
036:
037: public GruntspudTransmitTextFilePreprocessor(
038: ConnectionProfile profile) {
039: this .profile = profile;
040: }
041:
042: public String getSeparatorSequence() {
043: switch (profile.getLineEndings()) {
044: case ConnectionProfile.UNIX_LINE_ENDINGS:
045: return "\n";
046: case ConnectionProfile.WINDOWS_LINE_ENDINGS:
047: return "\r\n";
048: case ConnectionProfile.IGNORE_LINE_ENDINGS:
049: return "";
050: default:
051: return System.getProperty("line.separator");
052: }
053: }
054:
055: private String debugSequence(String seq) {
056: StringBuffer buf = new StringBuffer();
057: for (int i = 0; i < seq.length(); i++) {
058: if (buf.length() > 0) {
059: buf.append(",");
060: }
061: buf.append(Integer.toHexString(seq.charAt(i)));
062: }
063: return buf.toString();
064: }
065:
066: public void cleanup(File preprocessedTextFile) {
067: Constants.CVS_LOG.debug("Cleaning up "
068: + preprocessedTextFile.getAbsolutePath());
069: if (preprocessedTextFile != null) {
070: preprocessedTextFile.delete();
071: }
072: }
073:
074: public File getPreprocessedTextFile(File originalTextFile)
075: throws IOException {
076:
077: // must write file to temp location first because size might change
078:
079: // due to CR/LF changes
080: File preprocessedTextFile = File.createTempFile("cvs", null); // NOI18N
081:
082: String separatorSeq = getSeparatorSequence();
083: byte[] newLine = separatorSeq.getBytes();
084:
085: Constants.CVS_LOG.debug("Preprocessing "
086: + originalTextFile.getAbsolutePath() + " to "
087: + preprocessedTextFile.getAbsolutePath() + " using "
088: + debugSequence(separatorSeq));
089:
090: byte[] crlf = "\r\n".getBytes();
091: byte[] lf = "\n".getBytes();
092:
093: OutputStream out = null;
094: InputStream in = null;
095:
096: try {
097: in = new BufferedInputStream(new FileInputStream(
098: originalTextFile));
099: out = new BufferedOutputStream(new FileOutputStream(
100: preprocessedTextFile));
101:
102: byte[] fileChunk = new byte[CHUNK_SIZE];
103: byte[] fileWriteChunk = new byte[CHUNK_SIZE];
104:
105: for (int readLength = in.read(fileChunk); readLength > 0; readLength = in
106: .read(fileChunk)) {
107:
108: if (newLine.length == 0) {
109: out.write(fileChunk, 0, readLength);
110: } else {
111:
112: int writeLength = 0;
113: for (int i = 0; i < readLength;) {
114: int pos = findIndexOf(fileChunk, crlf, i);
115: int lineSepLength = crlf.length;
116: if (pos < i || pos >= readLength) {
117: pos = findIndexOf(fileChunk, lf, i);
118: lineSepLength = lf.length;
119: }
120: if (pos >= i && pos < readLength) {
121: try {
122: System.arraycopy(fileChunk, i,
123: fileWriteChunk, writeLength,
124: pos - i);
125: } catch (ArrayIndexOutOfBoundsException aiobe) {
126: Constants.CVS_LOG
127: .error("fileChunk.length="
128: + fileChunk.length
129: + " i="
130: + i
131: + " writeLength="
132: + writeLength
133: + " pos="
134: + pos
135: + " fileWriteChunk.length="
136: + fileWriteChunk.length);
137: throw aiobe;
138: }
139: writeLength += pos - i;
140: i = pos + lineSepLength;
141: for (int j = 0; j < newLine.length; j++)
142: fileWriteChunk[writeLength++] = newLine[j];
143: } else {
144: System.arraycopy(fileChunk, i,
145: fileWriteChunk, writeLength,
146: readLength - i);
147: writeLength += readLength - i;
148: i = readLength;
149: }
150: }
151: out.write(fileWriteChunk, 0, writeLength);
152:
153: }
154: }
155: return preprocessedTextFile;
156: } catch (IOException ex) {
157: if (preprocessedTextFile != null) {
158: cleanup(preprocessedTextFile);
159: }
160: throw ex;
161: } finally {
162: if (in != null) {
163: try {
164: in.close();
165: } catch (IOException ex) {
166: // ignore
167: }
168: }
169: if (out != null) {
170: try {
171: out.close();
172: } catch (IOException ex) {
173: // ignore
174: }
175: }
176: }
177: }
178:
179: private static int findIndexOf(byte[] array, byte[] pattern,
180: int start) {
181: int subPosition = 0;
182: for (int i = start; i < array.length; i++) {
183: if (array[i] == pattern[subPosition]) {
184: if (++subPosition == pattern.length) {
185: return i - subPosition + 1;
186: }
187: } else {
188: subPosition = 0;
189: }
190: }
191: return -1;
192: }
193:
194: //
195: private ConnectionProfile profile;
196: }
|