Skip to content

Commit 31d6783

Browse files
committed
Implement 'mmap.readline'.
1 parent c8f715b commit 31d6783

File tree

1 file changed

+29
-8
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap

1 file changed

+29
-8
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/MMapBuiltins.java

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
import com.oracle.graal.python.builtins.PythonBuiltins;
6969
import com.oracle.graal.python.builtins.objects.PNone;
7070
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
71+
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
72+
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.NoGeneralizationNode;
7173
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
7274
import com.oracle.graal.python.nodes.SpecialMethodNames;
7375
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
@@ -77,14 +79,14 @@
7779
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
7880
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
7981
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
82+
import com.oracle.graal.python.nodes.util.CastToByteNode;
8083
import com.oracle.graal.python.nodes.util.CastToIndexNode;
8184
import com.oracle.graal.python.nodes.util.ChannelNodes.ReadByteFromChannelNode;
8285
import com.oracle.graal.python.nodes.util.ChannelNodes.ReadFromChannelNode;
8386
import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage;
8487
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
8588
import com.oracle.truffle.api.dsl.Cached;
8689
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
87-
import com.oracle.truffle.api.dsl.ImportStatic;
8890
import com.oracle.truffle.api.dsl.NodeFactory;
8991
import com.oracle.truffle.api.dsl.Specialization;
9092
import com.oracle.truffle.api.dsl.TypeSystemReference;
@@ -290,24 +292,43 @@ PBytes read(PMMap self, Object n,
290292
abstract static class ReadlineNode extends PythonBuiltinNode {
291293

292294
@Specialization
293-
@TruffleBoundary
294-
Object readline(PMMap self) {
295+
Object readline(PMMap self,
296+
@Cached("createAppend()") SequenceStorageNodes.AppendNode appendNode) {
295297

296298
try {
297299
ByteBuffer buf = ByteBuffer.allocate(4096);
298300
SeekableByteChannel channel = self.getChannel();
301+
ByteSequenceStorage res = new ByteSequenceStorage(16);
299302
// search for newline char
300-
int nread;
301-
while ((nread = channel.read(buf)) > 0) {
302-
for (int i = 0; i < buf.remaining(); i++) {
303-
303+
outer: while (readIntoBuffer(channel, buf) > 0) {
304+
buf.flip();
305+
while (buf.hasRemaining()) {
306+
byte b = buf.get();
307+
// CPython really tests for '\n' only
308+
if (b != (byte) '\n') {
309+
appendNode.execute(res, b);
310+
} else {
311+
// recover correct position (i.e. number of remaining bytes in buffer)
312+
channel.position(channel.position() - buf.remaining() - 1);
313+
break outer;
314+
}
304315
}
316+
buf.clear();
305317
}
306-
return null;
318+
return factory().createBytes(res);
307319
} catch (IOException e) {
308320
throw raise(PythonBuiltinClassType.OSError, e.getMessage());
309321
}
310322
}
323+
324+
@TruffleBoundary(allowInlining = true)
325+
private static int readIntoBuffer(SeekableByteChannel ch, ByteBuffer dst) throws IOException {
326+
return ch.read(dst);
327+
}
328+
329+
protected static SequenceStorageNodes.AppendNode createAppend() {
330+
return SequenceStorageNodes.AppendNode.create(() -> NoGeneralizationNode.create(CastToByteNode.INVALID_BYTE_VALUE));
331+
}
311332
}
312333

313334
@Builtin(name = "seek", fixedNumOfPositionalArgs = 1)

0 commit comments

Comments
 (0)