diff src/org/tmatesoft/hg/internal/FilterByteChannel.java @ 355:f2c11fe7f3e9

Newline filter shall respect whole stream when deciding whether to process line terminators, hence added stream preview functionality
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 06 Dec 2011 12:57:21 +0100
parents d5268ca7715b
children 91d75e1bac9f
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/FilterByteChannel.java	Thu Dec 01 05:21:40 2011 +0100
+++ b/src/org/tmatesoft/hg/internal/FilterByteChannel.java	Tue Dec 06 12:57:21 2011 +0100
@@ -18,7 +18,9 @@
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import org.tmatesoft.hg.util.Adaptable;
 import org.tmatesoft.hg.util.ByteChannel;
@@ -55,6 +57,20 @@
 
 	// adapters or implemented interfaces of the original class shall not be obfuscated by filter
 	public <T> T getAdapter(Class<T> adapterClass) {
+		if (adapterClass == Preview.class) {
+			ArrayList<Preview> previewers = new ArrayList<Preview>(filters.length);
+			for (Filter f : filters) {
+				if (f instanceof Preview /*FIXME or getAdapter != null*/) {
+					previewers.add((Preview) f);
+				}
+			}
+			if (!previewers.isEmpty()) {
+				@SuppressWarnings("unchecked")
+				T rv = (T) new PreviewSupport(previewers);
+				return rv;
+			}
+			// fall through to let delegate answer
+		}
 		if (delegate instanceof Adaptable) {
 			return ((Adaptable) delegate).getAdapter(adapterClass);
 		}
@@ -63,4 +79,22 @@
 		}
 		return null;
 	}
+
+	private static class PreviewSupport implements Preview {
+		private final Preview[] participants;
+
+		public PreviewSupport(List<Preview> previewers) {
+			participants = new Preview[previewers.size()];
+			previewers.toArray(participants);
+		}
+		
+		public void preview(ByteBuffer src) {
+			final int originalPos = src.position();
+			for (Preview p : participants) {
+				p.preview(src);
+				// reset to initial state
+				src.position(originalPos);
+			}
+		}
+	}
 }