Browse Source

new: IOStream#stream(writer) -> stream

Ranides Atterwim 10 năm trước cách đây
mục cha
commit
3073119da6

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 749 - 750
assira/src/main/java/net/ranides/assira/collection/maps/AHashMap.java


+ 5 - 9
assira/src/main/java/net/ranides/assira/io/DataBuffer.java

@@ -27,8 +27,6 @@ import net.ranides.assira.text.Charsets;
  */
 public class DataBuffer implements DataInput, DataOutput {
     
-    // @todo (assira #3) io DataBuffer implements DataInput, DataOutput
-    
     NativeArray array;
     ByteBuffer buffer;
 
@@ -38,6 +36,10 @@ public class DataBuffer implements DataInput, DataOutput {
         this.buffer = ByteBuffer.wrap(data);
     }
     
+    public ByteBuffer data() {
+        return ByteBuffer.wrap(array.$array(), 0, buffer.position());
+    }
+    
     public DataBuffer seek(int position) throws IOException {
         if(position != buffer.position(position).position()) {
             throw new IOException("EOF ?");
@@ -48,12 +50,6 @@ public class DataBuffer implements DataInput, DataOutput {
     public int seek() {
         return buffer.position();
     }
-        
-    private void unget(byte v) {
-        int n =buffer.position();
-        buffer.position(n-1);
-        buffer.put(n-1, v);
-    }
     
     @Override
     public void readFully(byte[] b) throws IOException {
@@ -146,7 +142,7 @@ public class DataBuffer implements DataInput, DataOutput {
             int p = buffer.position(); // NOPMD
             CoderResult cr = cd.decode(buffer, cb, true);
             if(cr.isError()) {
-                throw new IOException("Encoding error:" + cr.toString());
+                cr.throwException();
             }
             int end = out.endl();
             if(end >= 0) {

+ 88 - 1
assira/src/main/java/net/ranides/assira/io/IOStreams.java

@@ -7,13 +7,18 @@
 
 package net.ranides.assira.io;
 
-import java.io.ByteArrayOutputStream;
 import java.io.FilterInputStream;
 import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintStream;
+import java.io.Writer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
 import java.util.Arrays;
 import java.util.function.Consumer;
 import net.ranides.assira.events.EventListener;
@@ -95,6 +100,10 @@ public final class IOStreams {
         return tee(new StringOutput());
     }
     
+    public static OutputStream stream(Writer writer, Charset cs) {
+        return new WriterStream(writer, cs);
+    }
+    
     private static final class InputObserver extends FilterInputStream {
         
         private final EventListener<? super IOEvent> listener;
@@ -319,5 +328,83 @@ public final class IOStreams {
         void run(OutputStream os) throws IOException;
 
     }
+    
+    private static final class WriterStream extends OutputStream {
+        
+        private final CharsetDecoder cd;
+        private final Writer writer;
+        private final ByteBuffer buffer;
+
+        public WriterStream(Writer writer, Charset cs) {
+            this.cd = cs.newDecoder();
+            this.writer = writer;
+            this.buffer = ByteBuffer.allocate(128);
+        }
+        
+        @Override
+        public void write(int b) throws IOException {
+            buffer.put((byte)b);
+            if(buffer.remaining()==0) {
+                flush();
+            }
+        }
+
+        @Override
+        public void write(byte[] b, int off, int len) throws IOException {
+            if(buffer.remaining() < len) {
+                flush();
+                write(ByteBuffer.wrap(b, off, len), false);
+            }
+            buffer.put(b, off, len);
+            if(buffer.remaining()==0) {
+                flush();
+            }
+        }
+
+        @Override
+        public void flush() throws IOException {
+            buffer.flip();
+            write(buffer, false);
+            writer.flush();
+        }
+        
+        
+        @Override
+        public void close() throws IOException {
+            buffer.flip();
+            write(buffer, true);
+            writer.flush();
+            writer.close();
+            super.close();
+        }
+        
+        private void write(ByteBuffer src, boolean end) throws IOException {
+            if (0 == src.remaining()) {
+                return;
+            }
+            
+            int n = (int)(src.remaining() * cd.averageCharsPerByte());
+            CharBuffer out = CharBuffer.allocate(n);
+
+            while(true) {
+                CoderResult cr = src.hasRemaining() ?
+                    cd.decode(src, out, true) : CoderResult.UNDERFLOW;
+                if (end && cr.isUnderflow()) {
+                    cr = cd.flush(out);
+                }
+                if (cr.isUnderflow()) {
+                    break;
+                }
+                if (cr.isOverflow()) {
+                    writer.write(out.array(), 0, out.position());
+                    out.clear();
+                    continue;
+                }
+                cr.throwException();
+            }
+            src.clear();
+        }
+        
+    }
 
 }

+ 0 - 1
assira/src/main/java/net/ranides/assira/reflection/IElements.java

@@ -7,7 +7,6 @@
 package net.ranides.assira.reflection;
 
 import java.util.List;
-import java.util.Optional;
 import java.util.function.Function;
 import java.util.stream.Collector;
 import java.util.stream.Stream;

+ 0 - 1
assira/src/main/java/net/ranides/assira/text/StringIO.java

@@ -31,7 +31,6 @@ public final class StringIO {
     private StringIO() { }
     
     // @todo (assira #4) io adapter Reader -- (charset) --> InputStream
-    // @todo (assira #4) io adapter Writer -- (charset) --> OutputStream
     // nie robić jak apache commons, tylko używać Charset# newEncoder() # encode(...)
     // bo konwersja byte-by-byte po prostu jest nieprawidłowa
     // dobra, to jest jakiś crap, przecież my z "chars" do byte robimy, więc whatever ...