Skip to content

Commit 7b79b2f

Browse files
committed
First pass at nqp::getcfh on JVM.
1 parent b4e00e5 commit 7b79b2f

File tree

5 files changed

+83
-0
lines changed

5 files changed

+83
-0
lines changed

src/vm/jvm/QAST/Compiler.nqp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,6 +1898,7 @@ QAST::OperationsJAST.map_classlib_core_op('sayfh', $TYPE_OPS, 'sayfh', [$RT_OBJ,
18981898
QAST::OperationsJAST.map_classlib_core_op('readlinefh', $TYPE_OPS, 'readlinefh', [$RT_OBJ], $RT_STR, :tc);
18991899
QAST::OperationsJAST.map_classlib_core_op('readlineintfh', $TYPE_OPS, 'readlineintfh', [$RT_OBJ, $RT_STR], $RT_STR, :tc);
19001900
QAST::OperationsJAST.map_classlib_core_op('readallfh', $TYPE_OPS, 'readallfh', [$RT_OBJ], $RT_STR, :tc);
1901+
QAST::OperationsJAST.map_classlib_core_op('getcfh', $TYPE_OPS, 'getcfh', [$RT_OBJ], $RT_STR, :tc);
19011902
QAST::OperationsJAST.map_classlib_core_op('eoffh', $TYPE_OPS, 'eoffh', [$RT_OBJ], $RT_INT, :tc);
19021903
QAST::OperationsJAST.map_classlib_core_op('closefh', $TYPE_OPS, 'closefh', [$RT_OBJ], $RT_OBJ, :tc);
19031904

src/vm/jvm/runtime/org/perl6/nqp/io/IIOSyncReadable.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ public interface IIOSyncReadable {
66
public String slurp(ThreadContext tc);
77
public String readline(ThreadContext tc);
88
public byte[] read(ThreadContext tc, int bytes);
9+
public String getc(ThreadContext tc);
910
public boolean eof(ThreadContext tc);
1011
}

src/vm/jvm/runtime/org/perl6/nqp/io/StandardReadHandle.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,23 @@ public synchronized String readline(ThreadContext tc) {
8383
}
8484
}
8585

86+
public synchronized String getc(ThreadContext tc) {
87+
try {
88+
if (br == null)
89+
br = new BufferedReader(new InputStreamReader(is, cs));
90+
int read = br.read();
91+
if (read == -1) {
92+
eof = true;
93+
return "";
94+
}
95+
else {
96+
return String.valueOf(read);
97+
}
98+
} catch (IOException e) {
99+
throw ExceptionHandling.dieInternal(tc, e);
100+
}
101+
}
102+
86103
public synchronized String readlineInteractive(ThreadContext tc, String prompt) {
87104
try {
88105
if (cr == null)

src/vm/jvm/runtime/org/perl6/nqp/io/SyncHandle.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import java.nio.charset.Charset;
88
import java.nio.charset.CharsetDecoder;
99
import java.nio.charset.CharsetEncoder;
10+
import java.nio.charset.CoderResult;
11+
import java.nio.charset.MalformedInputException;
1012
import java.util.ArrayList;
1113

1214
import org.perl6.nqp.runtime.ExceptionHandling;
@@ -133,6 +135,53 @@ private String decodeBuffers(ArrayList<ByteBuffer> buffers, int total) throws IO
133135
return dec.decode(allBytes).toString();
134136
}
135137

138+
public synchronized String getc(ThreadContext tc) {
139+
try {
140+
int maxBytes = (int)enc.maxBytesPerChar();
141+
ByteBuffer toDecode = ByteBuffer.allocate(maxBytes);
142+
CharBuffer decoded = CharBuffer.allocate(1);
143+
for (int i = 0; i < maxBytes; i++) {
144+
/* Ensure we have a read buffer available. */
145+
if (readBuffer == null) {
146+
readBuffer = ByteBuffer.allocate(32768);
147+
if (chan.read(readBuffer) == -1) {
148+
/* End of file. */
149+
eof = true;
150+
if (i == 0) {
151+
/* Fine, just no char. */
152+
return "";
153+
}
154+
else {
155+
/* Malformed; following will likely throw. */
156+
toDecode.position(0);
157+
dec.decode(toDecode, decoded, true).throwException();
158+
return decoded.toString();
159+
}
160+
}
161+
readBuffer.flip();
162+
}
163+
164+
/* Get a character from the read buffer. */
165+
toDecode.position(i);
166+
toDecode.put(readBuffer.get());
167+
if (readBuffer.remaining() == 0)
168+
readBuffer = null;
169+
170+
/* Try to decode; if we fail, try another byte. */
171+
toDecode.position(0);
172+
CoderResult cr = dec.decode(toDecode, decoded, false);
173+
if (!cr.isError()) {
174+
decoded.rewind();
175+
return decoded.toString();
176+
}
177+
}
178+
throw new MalformedInputException(maxBytes);
179+
}
180+
catch (IOException e) {
181+
throw ExceptionHandling.dieInternal(tc, e);
182+
}
183+
}
184+
136185
public boolean eof(ThreadContext tc) {
137186
return eof;
138187
}

src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,21 @@ public static String readallfh(SixModelObject obj, ThreadContext tc) {
611611
}
612612
}
613613

614+
public static String getcfh(SixModelObject obj, ThreadContext tc) {
615+
if (obj instanceof IOHandleInstance) {
616+
IOHandleInstance h = (IOHandleInstance)obj;
617+
if (h.handle instanceof IIOSyncReadable)
618+
return ((IIOSyncReadable)h.handle).getc(tc);
619+
else
620+
throw ExceptionHandling.dieInternal(tc,
621+
"This handle does not support getc");
622+
}
623+
else {
624+
throw ExceptionHandling.dieInternal(tc,
625+
"getcfh requires an object with the IOHandle REPR");
626+
}
627+
}
628+
614629
public static long eoffh(SixModelObject obj, ThreadContext tc) {
615630
if (obj instanceof IOHandleInstance) {
616631
IOHandleInstance h = (IOHandleInstance)obj;

0 commit comments

Comments
 (0)