Quellcode durchsuchen

new: StrBuilder#replace
new: StrBuilder#insert

Ranides Atterwim vor 9 Jahren
Ursprung
Commit
378dea8bf8

+ 86 - 10
assira/src/main/java/net/ranides/assira/text/StrBuilder.java

@@ -9,16 +9,17 @@ package net.ranides.assira.text;
 import java.io.Reader;
 import java.io.Serializable;
 import java.io.Writer;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.Iterator;
+import java.util.*;
 import java.util.function.Function;
 import java.util.function.IntFunction;
+import java.util.function.Supplier;
+
 import net.ranides.assira.collection.arrays.ArrayAllocator;
 import net.ranides.assira.collection.arrays.ArrayUtils;
 import net.ranides.assira.collection.arrays.NativeArray;
 import net.ranides.assira.collection.arrays.NativeArrayAllocator;
 import net.ranides.assira.collection.arrays.NativeArrayUtils;
+import net.ranides.assira.generic.LazyReference;
 import net.ranides.assira.generic.ValueUtils;
 import net.ranides.assira.math.MathUtils;
 
@@ -43,6 +44,8 @@ public final class StrBuilder implements CharSequence, Appendable, Serializable
     private char[] buffer;
     
     private int size;
+
+    private final Supplier<Formatter> formatter = LazyReference.unique(() -> new Formatter(this));
     
     Deque<BuilderState> options = new ArrayDeque<>(); // StrBuilderOptions.DEFAULT;
     
@@ -86,16 +89,11 @@ public final class StrBuilder implements CharSequence, Appendable, Serializable
     }
 
     public StrBuilder trim() {
-        if (buffer.length > length()) {
-            char[] old = buffer;
-            buffer = new char[length()];
-            System.arraycopy(old, 0, buffer, 0, size);
-        }
-        return this;
+        return trim(size);
     }
     
     public StrBuilder trim(int n) {
-        if (buffer.length > n) {
+        if (buffer.length > n && buffer.length!=Math.max(n,size)) {
             buffer = ArrayAllocator.trim(buffer, Math.max(n,size));
         }
         return this;
@@ -389,6 +387,84 @@ public final class StrBuilder implements CharSequence, Appendable, Serializable
         }
 		return this;
 	}
+
+    public StrBuilder replace(int begin, int end, CharSequence value) {
+        if(value == null) {
+            value = options.peek().blank();
+        }
+        if(value == null) {
+            value = "";
+        }
+        int d = value.length() - (end - begin);
+        if(d>0) {
+            insertBytes(begin, d);
+        } else {
+            removeBytes(begin, -d);
+        }
+        copy(begin, value, 0, value.length());
+        return this;
+    }
+
+    public StrBuilder replace(int begin, int end, char[] value) {
+        if(value == null) {
+            return replace(begin, end, options.peek().blank());
+        }
+        int d = value.length - (end - begin);
+        if(d>0) {
+            insertBytes(begin, d);
+        } else {
+            removeBytes(begin, -d);
+        }
+        copy(begin, value, 0, value.length);
+        return this;
+    }
+
+    public StrBuilder insert(int offset, CharSequence value) {
+        insertBytes(offset, value.length());
+        copy(offset, value, 0, value.length());
+        return this;
+    }
+
+    public StrBuilder insert(int offset, char[] value) {
+        insertBytes(offset, value.length);
+        copy(offset, value, 0, value.length);
+        return this;
+    }
+
+    private StrBuilder copy(int offset, CharSequence value, int begin, int end) {
+        for(int i=begin; i<end; i++, offset++) {
+            buffer[offset] = value.charAt(i);
+        }
+        return this;
+    }
+
+    private StrBuilder copy(int offset, char[] value, int begin, int end) {
+        System.arraycopy(value, begin, buffer, offset, end-begin);
+        return this;
+    }
+
+    private StrBuilder removeBytes(int offset, int count) {
+        moveBytes(offset+count, offset, size - (offset+count));
+        size -= count;
+        return this;
+    }
+
+    private StrBuilder insertBytes(int offset, int count) {
+        reserve(size + count);
+        moveBytes(offset, offset + count, size - offset);
+        size += count;
+        return this;
+    }
+
+    private StrBuilder moveBytes(int src, int target, int count) {
+        System.arraycopy(buffer, src, buffer, target, count);
+        return this;
+    }
+
+	public StrBuilder printf(String format, Object... arguments) {
+        formatter.get().format(Locale.getDefault(), format, arguments);
+        return this;
+    }
     
     @Override
     public boolean equals(Object object) {

+ 47 - 1
assira/src/test/java/net/ranides/assira/text/StrBuilderTest.java

@@ -479,7 +479,53 @@ public class StrBuilderTest {
 			.run();
         assertTrue(true);
     }
-    
+
+    @Test
+    public void testPrint() {
+        StrBuilder sb = new StrBuilder();
+        sb.append("nums = ");
+        sb.printf("%02x/%02x", 0x23, 0xA);
+        sb.append(" ");
+        sb.printf("vars = %04x", 0x79);
+        sb.append(" ");
+        sb.open("{","}"," ");
+        for(int i=0x51; i<0x55; i++) {
+            sb.item().printf("%03x", i);
+        }
+        sb.close();
+        assertEquals("nums = 23/0a vars = 0079 {051 052 053 054}", sb.toString());
+    }
+
+    @Test
+    public void testReplaceInsert() {
+        StrBuilder sb = new StrBuilder();
+        sb.append("heRUworld?___:)");
+        sb.replace(2,4, "llo ");
+        sb.replace(11,16, "! ;");
+
+        assertEquals("hello world! ;)", sb.toString());
+
+        sb.insert(6, "[7]");
+        sb.insert(18, " [9]");
+        sb.append(" end.");
+        assertEquals("hello [7]world! ;) [9] end.",sb.toString());
+    }
+
+    @Test
+    public void testReplaceInsert_chars() {
+        StrBuilder sb = new StrBuilder();
+        sb.append("heRUworld?___:)");
+        sb.replace(2,4, "llo ".toCharArray());
+        sb.replace(11,16, "! ;".toCharArray());
+
+        assertEquals("hello world! ;)", sb.toString());
+
+        sb.insert(6, "[7]".toCharArray());
+        sb.insert(18, " [9]".toCharArray());
+        sb.append(" end.".toCharArray());
+        assertEquals("hello [7]world! ;) [9] end.",sb.toString());
+    }
+
     @Test
     public void testHashcode() {
         assertEquals(Arrays.hashCode("Hello".toCharArray()), new StrBuilder(32).append("Hello").hashCode());