diff src/org/tmatesoft/hg/internal/DataAccessProvider.java @ 534:243202f1bda5

Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Mon, 04 Feb 2013 18:00:55 +0100
parents 2743641f2f12
children dd4f6311af52
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/DataAccessProvider.java	Wed Jan 30 15:48:36 2013 +0100
+++ b/src/org/tmatesoft/hg/internal/DataAccessProvider.java	Mon Feb 04 18:00:55 2013 +0100
@@ -21,7 +21,10 @@
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.nio.ByteBuffer;
 import java.nio.MappedByteBuffer;
 import java.nio.channels.FileChannel;
@@ -72,7 +75,7 @@
 		return mapioBoundary == 0 ? Integer.MAX_VALUE : mapioBoundary;
 	}
 
-	public DataAccess create(File f) {
+	public DataAccess createReader(File f) {
 		if (!f.exists()) {
 			return new DataAccess();
 		}
@@ -96,6 +99,22 @@
 		}
 		return new DataAccess(); // non-null, empty.
 	}
+	
+	public DataSerializer createWriter(File f, boolean createNewIfDoesntExist) {
+		if (!f.exists() && !createNewIfDoesntExist) {
+			return new DataSerializer();
+		}
+		try {
+			return new StreamDataSerializer(context.getLog(), new FileOutputStream(f));
+		} catch (final FileNotFoundException ex) {
+			context.getLog().dump(getClass(), Error, ex, null);
+			return new DataSerializer() {
+				public void write(byte[] data, int offset, int length) throws IOException {
+					throw ex;
+				}
+			};
+		}
+	}
 
 	private static class MemoryMapFileAccess extends DataAccess {
 		private FileChannel fileChannel;
@@ -374,4 +393,57 @@
 			}
 		}
 	}
+
+	public/*XXX, private, once HgCloneCommand stops using it */ static class StreamDataSerializer extends DataSerializer {
+		private final OutputStream out;
+		private final LogFacility log;
+		private byte[] buffer;
+	
+		public StreamDataSerializer(LogFacility logFacility, OutputStream os) {
+			assert os != null;
+			out = os;
+			log = logFacility;
+		}
+		
+		@Override
+		public void write(byte[] data, int offset, int length) throws IOException {
+			out.write(data, offset, length);
+		}
+	
+		@Override
+		public void writeInt(int... values) throws IOException {
+			ensureBufferSize(4*values.length); // sizeof(int)
+			int idx = 0;
+			for (int v : values) {
+				DataSerializer.bigEndian(v, buffer, idx);
+				idx += 4;
+			}
+			out.write(buffer, 0, idx);
+		}
+		
+		@Override
+		public void writeByte(byte... values) throws IOException {
+			if (values.length == 1) {
+				out.write(values[0]);
+			} else {
+				out.write(values, 0, values.length);
+			}
+		}
+		
+		private void ensureBufferSize(int bytesNeeded) {
+			if (buffer == null || buffer.length < bytesNeeded) {
+				buffer = new byte[bytesNeeded];
+			}
+		}
+	
+		@Override
+		public void done() {
+			try {
+				out.flush();
+				out.close();
+			} catch (IOException ex) {
+				log.dump(getClass(), Error, ex, "Failure to close stream");
+			}
+		}
+	}
 }