Permalink
Browse files

cap error output to avoid running out of memory

  • Loading branch information...
1 parent 6caec8f commit 80b0ad5ba22636f753c7b8a5e61b21ca48faff4c @JPMoresmau committed Mar 11, 2013
@@ -137,7 +137,7 @@ available at http://www.eclipse.org/legal/epl-v10.html.
id="net.sf.eclipsefp.haskell.util"
download-size="0"
install-size="0"
- version="2.5.1"
+ version="2.5.2"
unpack="false"/>
<plugin
@@ -10,7 +10,6 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
-import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -30,6 +29,7 @@
import net.sf.eclipsefp.haskell.browser.items.Module;
import net.sf.eclipsefp.haskell.browser.items.Packaged;
import net.sf.eclipsefp.haskell.browser.util.BrowserText;
+import net.sf.eclipsefp.haskell.util.CappedStringWriter;
import net.sf.eclipsefp.haskell.util.DispatchWriter;
import net.sf.eclipsefp.haskell.util.FileUtil;
import net.sf.eclipsefp.haskell.util.LangUtil;
@@ -63,7 +63,7 @@
private boolean logError;
- private StringWriter lastErrW=new StringWriter();
+ private CappedStringWriter lastErrW=new CappedStringWriter(10000);
private DispatchWriter allErrWs=new DispatchWriter();
public StreamBrowserServer(IPath serverExecutable,boolean logError) throws Exception {
@@ -178,7 +178,7 @@ public boolean sendAndReceiveBoolean(JSONObject input)
private void sendCommand(String command) throws IOException{
log(">> " + command);
- lastErrW.getBuffer().setLength(0);
+ lastErrW.clear();
in.write(command + "\n");
in.flush();
}
@@ -21,6 +21,7 @@ public static Test suite() {
suite.addTest( new JUnit4TestAdapter(CommandLineUtilTest.class ));
suite.addTestSuite( FileUtilTest.class );
+ suite.addTest( new JUnit4TestAdapter(CappedStringWriterTest.class ));
return suite;
}
}
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2013 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.util;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+/**
+ * Tests for CappedStringWriter
+ * @author JP Moresmau
+ *
+ */
+public class CappedStringWriterTest {
+
+ @Test
+ public void testNormal() throws IOException{
+ CappedStringWriter w=new CappedStringWriter(100);
+ w.write("toto");
+ w.write("titi");
+ Assert.assertEquals("tototiti", w.toString());
+ }
+
+ @Test
+ public void testClear() throws IOException{
+ CappedStringWriter w=new CappedStringWriter(4);
+ w.write("toto");
+ w.clear();
+ w.write("titi");
+ Assert.assertEquals("titi", w.toString());
+ w=new CappedStringWriter(4);
+ w.write("toto");
+ w.clear();
+ w.write("tutu");
+ w.write("titi");
+ Assert.assertEquals("titi", w.toString());
+ }
+
+
+ @Test
+ public void testNull() throws IOException{
+ CappedStringWriter w=new CappedStringWriter(100);
+ w.write("toto");
+ w.write((String)null);
+ assertEquals("toto", w.toString());
+ }
+
+ @Test
+ public void testLimit() throws IOException{
+ CappedStringWriter w=new CappedStringWriter(4);
+ w.write("toto");
+ w.write("titi");
+ assertEquals("titi", w.toString());
+ }
+
+ @Test
+ public void testLimitMiddle() throws IOException{
+ CappedStringWriter w=new CappedStringWriter(6);
+ w.write("toto");
+ w.write("titi");
+ assertEquals("titi", w.toString());
+ }
+
+ @Test
+ public void testLimitMiddleAll() throws IOException{
+ CappedStringWriter w=new CappedStringWriter(2);
+ w.write("toto");
+ w.write("titi");
+ assertEquals("", w.toString());
+ }
+
+ @Test
+ public void testPerf() throws IOException{
+ CappedStringWriter w=new CappedStringWriter(100);
+ StringBuilder sb=new StringBuilder();
+ for (int a=0;a<100;a++){
+ sb.append("a");
+ }
+ String s=sb.toString();
+ assertEquals(100, s.length());
+ for (int a=0;a<10000;a++){
+ w.write(s);
+ }
+ assertEquals(s,w.toString());
+ }
+}
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: net.sf.eclipsefp.haskell.util
-Bundle-Version: 2.5.1
+Bundle-Version: 2.5.2
Bundle-Activator: net.sf.eclipsefp.haskell.util.Activator
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources,
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2013 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.util;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.LinkedList;
+
+/**
+ * A string writer that only keeps n max characters, discarding the first received characters
+ * @author JP Moresmau
+ *
+ */
+public class CappedStringWriter extends Writer {
+ private int maxSize;
+ private LinkedList<String> ls=new LinkedList<String>();
+ private int size;
+
+ public CappedStringWriter(int max){
+ maxSize=max;
+ lock=ls;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.Writer#write(char[], int, int)
+ */
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ synchronized (lock) {
+ ls.add(new String(cbuf,off,len));
+ size+=len;
+ checkSize();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.Writer#write(java.lang.String)
+ */
+ @Override
+ public void write(String str) throws IOException {
+ synchronized (lock) {
+ if (str!=null){
+ ls.add(str);
+ size+=str.length();
+ checkSize();
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.Writer#write(java.lang.String, int, int)
+ */
+ @Override
+ public void write(String str, int off, int len) throws IOException {
+ write(str.substring(off, off+len));
+ }
+
+ private void checkSize(){
+ while (size>maxSize){
+ String s=ls.removeFirst();
+ size-=s.length();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.Writer#flush()
+ */
+ @Override
+ public void flush() throws IOException {
+ // noop
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.Writer#close()
+ */
+ @Override
+ public void close() throws IOException {
+ // noop
+
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ synchronized (lock) {
+ StringBuilder sb=new StringBuilder(size);
+ for (String s:ls){
+ sb.append(s);
+ }
+ return sb.toString();
+ }
+ }
+
+ public void clear(){
+ synchronized (lock) {
+ ls.clear();
+ size=0;
+ }
+
+ }
+}

0 comments on commit 80b0ad5

Please sign in to comment.