]> gitweb.factorcode.org Git - factor.git/blobdiff - core/io/encodings/encodings.factor
use radix literals
[factor.git] / core / io / encodings / encodings.factor
index 81037ca2dfb791925e988e7f52d4cf7b56615fdc..aa5d3af93e0e7ba47b6778991a4edeea93882599 100644 (file)
@@ -7,6 +7,12 @@ IN: io.encodings
 
 ! The encoding descriptor protocol
 
+GENERIC: guess-encoded-length ( string-length encoding -- byte-length )
+GENERIC: guess-decoded-length ( byte-length encoding -- string-length )
+
+M: object guess-decoded-length drop ; inline
+M: object guess-encoded-length drop ; inline
+
 GENERIC: decode-char ( stream encoding -- char/f )
 
 GENERIC: encode-char ( char stream encoding -- )
@@ -17,21 +23,23 @@ M: object encode-string [ encode-char ] 2curry each ; inline
 
 GENERIC: <decoder> ( stream encoding -- newstream )
 
-CONSTANT: replacement-char HEX: fffd
+CONSTANT: replacement-char 0xfffd
 
-TUPLE: decoder stream code cr ;
+TUPLE: decoder { stream read-only } { code read-only } { cr boolean } ;
+INSTANCE: decoder input-stream
 
 ERROR: decode-error ;
 
 GENERIC: <encoder> ( stream encoding -- newstream )
 
-TUPLE: encoder stream code ;
+TUPLE: encoder { stream read-only } { code read-only } ;
+INSTANCE: encoder output-stream
 
 ERROR: encode-error ;
 
 ! Decoding
 
-M: object <decoder> f decoder boa ;
+M: object <decoder> f decoder boa ; inline
 
 <PRIVATE
 
@@ -42,58 +50,51 @@ M: object <decoder> f decoder boa ;
 : >decoder< ( decoder -- stream encoding )
     [ stream>> ] [ code>> ] bi ; inline
 
-: fix-read1 ( stream char -- char )
+M: decoder stream-element-type
+    drop +character+ ; inline
+
+: (read1) ( decoder -- ch )
+    >decoder< decode-char ; inline
+
+: fix-cr ( decoder c -- c' )
     over cr>> [
         over cr-
-        dup CHAR: \n = [
-            drop dup stream-read1
-        ] when
-    ] when nip ; inline
+        dup CHAR: \n eq? [ drop (read1) ] [ nip ] if
+    ] [ nip ] if ; inline
 
-M: decoder stream-element-type
-    drop +character+ ;
+M: decoder stream-read1 ( decoder -- ch )
+    dup (read1) fix-cr ; inline
 
-M: decoder stream-tell stream>> stream-tell ;
+: (read-first) ( n buf decoder -- buf stream encoding n c )
+    [ rot [ >decoder< ] dip 2over decode-char ]
+    [ swap fix-cr ] bi ; inline
 
-M: decoder stream-seek stream>> stream-seek ;
+: (store-read) ( buf stream encoding n c i -- buf stream encoding n )
+    [ rot [ set-nth-unsafe ] keep ] 2curry 3dip ; inline
 
-M: decoder stream-read1
-    dup >decoder< decode-char fix-read1 ;
+: (finish-read) ( buf stream encoding n i -- i )
+    2nip 2nip ; inline
 
-: fix-read ( stream string -- string )
-    over cr>> [
-        over cr-
-        "\n" ?head [
-            over stream-read1 [ suffix ] when*
-        ] when
-    ] when nip ; inline
-
-! If we read the entire buffer, chars-read is f
-! If we hit EOF while reading, chars-read indicates how many chars were read
-: (read) ( chars-requested quot -- chars-read/f string )
-    over 0 <string> [
-        [
-            over [ swapd set-nth-unsafe f ] [ 3drop t ] if
-        ] curry compose find-integer
-    ] keep ; inline
-
-: finish-read ( n/f string -- string/f )
-    swap {
-        { [ dup zero? ] [ 2drop f ] }
-        { [ dup not   ] [ drop ] }
-        [ head ]
-    } cond ; inline
-
-M: decoder stream-read
-    over 0 = [
-        2drop f
-    ] [
-        [ nip ]
-        [ >decoder< [ decode-char ] 2curry (read) finish-read ] 2bi
-        fix-read
-    ] if ;
-
-M: decoder stream-read-partial stream-read ;
+: (read-next) ( stream encoding n i -- stream encoding n i c )
+    [ 2dup decode-char ] 2dip rot ; inline
+
+: (read-rest) ( buf stream encoding n i -- count )
+    2dup = [ (finish-read) ] [
+        (read-next) [
+            swap [ (store-read) ] [ 1 + ] bi (read-rest)
+        ] [ (finish-read) ] if*
+    ] if ; inline recursive
+
+M: decoder stream-read-unsafe
+    pick 0 = [ 3drop 0 ] [
+        (read-first) [
+            0 (store-read)
+            1 (read-rest)
+        ] [ 2drop 2drop 0 ] if*
+    ] if ; inline
+
+M: decoder stream-contents
+    (stream-contents-by-element) ;
 
 : line-ends/eof ( stream str -- str ) f like swap cr- ; inline
 
@@ -136,23 +137,23 @@ M: decoder stream-readln dup >decoder< decoder-readln handle-readln ;
 M: decoder dispose stream>> dispose ;
 
 ! Encoding
-M: object <encoder> encoder boa ;
+M: object <encoder> encoder boa ; inline
 
 : >encoder< ( encoder -- stream encoding )
     [ stream>> ] [ code>> ] bi ; inline
 
 M: encoder stream-element-type
-    drop +character+ ;
+    drop +character+ ; inline
 
 M: encoder stream-write1
-    >encoder< encode-char ;
+    >encoder< encode-char ; inline
 
 M: encoder stream-write
-    >encoder< encode-string ;
+    >encoder< encode-string ; inline
 
-M: encoder dispose stream>> dispose ;
+M: encoder dispose stream>> dispose ; inline
 
-M: encoder stream-flush stream>> stream-flush ;
+M: encoder stream-flush stream>> stream-flush ; inline
 
 INSTANCE: encoder plain-writer
 PRIVATE>