Skip to content

Commit

Permalink
checkin
Browse files Browse the repository at this point in the history
  • Loading branch information
thatstoasty committed Aug 13, 2024
1 parent 05d9901 commit f14c578
Show file tree
Hide file tree
Showing 18 changed files with 81 additions and 90 deletions.
79 changes: 27 additions & 52 deletions gojo/bufio/bufio.mojo
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from collections import InlineList
from utils import Span
import ..io
from ..builtins import copy, panic
from ..builtins.bytes import index_byte
Expand All @@ -17,10 +18,10 @@ alias ERR_NEGATIVE_WRITE = "bufio: writer returned negative count from write"

# buffered input
# TODO: Uncomment write_to and write_buf once the bug with the trait's Span argument is fixed.
struct Reader[R: io.Reader, size: Int = MIN_READ_BUFFER_SIZE](Sized, io.Reader, io.ByteReader, io.ByteScanner):
struct Reader[R: io.Reader](Sized, io.Reader, io.ByteReader, io.ByteScanner):
"""Implements buffering for an io.Reader object."""

var buf: InlineList[UInt8, size]
var buf: List[UInt8]
var reader: R # reader provided by the client
var read_pos: Int
var write_pos: Int # buf read and write positions
Expand All @@ -31,16 +32,13 @@ struct Reader[R: io.Reader, size: Int = MIN_READ_BUFFER_SIZE](Sized, io.Reader,
fn __init__(
inout self,
owned reader: R,
buf: InlineList[UInt8, size] = InlineList[UInt8, size](),
capacity: Int = io.BUFFER_SIZE,
read_pos: Int = 0,
write_pos: Int = 0,
last_byte: Int = -1,
last_rune_size: Int = -1,
):
self.buf = InlineList[UInt8, size]()
for element in buf:
self.buf.append(element[])

self.buf = List[UInt8](capacity=capacity)
self.reader = reader^
self.read_pos = read_pos
self.write_pos = write_pos
Expand All @@ -49,10 +47,7 @@ struct Reader[R: io.Reader, size: Int = MIN_READ_BUFFER_SIZE](Sized, io.Reader,
self.err = Error()

fn __moveinit__(inout self, owned existing: Self):
self.buf = InlineList[UInt8, size]()
for element in existing.buf:
self.buf.append(element[])

self.buf = existing.buf^
self.reader = existing.reader^
self.read_pos = existing.read_pos
self.write_pos = existing.write_pos
Expand Down Expand Up @@ -83,16 +78,15 @@ struct Reader[R: io.Reader, size: Int = MIN_READ_BUFFER_SIZE](Sized, io.Reader,

fn as_bytes_slice(ref [_]self) -> Span[UInt8, __lifetime_of(self)]:
"""Returns the internal data as a Span[UInt8]."""
return Span[UInt8, __lifetime_of(self)](array=self.buf._array)
return Span[UInt8, __lifetime_of(self)](self.buf)

fn reset(inout self, buf: InlineList[UInt8, size], owned reader: R):
fn reset(inout self, owned reader: R):
"""Discards any buffered data, resets all state, and switches
the buffered reader to read from r.
Calling reset on the zero value of [Reader] initializes the internal buffer
to the default size.
Calling self.reset(b) (that is, resetting a [Reader] to itself) does nothing."""
self = Reader[R, size](
buf=buf,
self = Reader[R](
reader=reader^,
last_byte=-1,
last_rune_size=-1,
Expand All @@ -119,12 +113,10 @@ struct Reader[R: io.Reader, size: Int = MIN_READ_BUFFER_SIZE](Sized, io.Reader,
# Read new data: try a limited number of times.
var i: Int = MAX_CONSECUTIVE_EMPTY_READS
while i > 0:
# TODO: Using temp until slicing can return a Reference, does reading directly into a Span of self.buf work?
# Maybe we need to read into the end of the buffer.
var span = self.as_bytes_slice()
# var span = self.as_bytes_slice()
var bytes_read: Int
var err: Error
bytes_read, err = self.reader._read(span, len(self.buf))
bytes_read, err = self.reader.read(self.buf)
if bytes_read < 0:
panic(ERR_NEGATIVE_READ)

Expand Down Expand Up @@ -632,7 +624,7 @@ struct Reader[R: io.Reader, size: Int = MIN_READ_BUFFER_SIZE](Sized, io.Reader,
# return Int(bytes_written), Error()


fn new_reader[R: io.Reader, size: Int = MIN_READ_BUFFER_SIZE](owned reader: R) -> Reader[R, size]:
fn new_reader[R: io.Reader](owned reader: R) -> Reader[R]:
"""Returns a new [Reader] whose buffer has at least the specified
size. If the argument io.Reader is already a [Reader] with large enough
size, it returns the underlying [Reader].
Expand All @@ -646,43 +638,37 @@ fn new_reader[R: io.Reader, size: Int = MIN_READ_BUFFER_SIZE](owned reader: R) -
Returns:
The new [Reader].
"""
var r = Reader[R, size](reader^)
var r = Reader[R](reader^)
return r^


# buffered output
struct Writer[W: io.Writer, size: Int = io.BUFFER_SIZE](
Sized, io.Writer, io.ByteWriter, io.StringWriter, io.ReaderFrom
):
struct Writer[W: io.Writer](Sized, io.Writer, io.ByteWriter, io.StringWriter, io.ReaderFrom):
"""Implements buffering for an [io.Writer] object.
# If an error occurs writing to a [Writer], no more data will be
# accepted and all subsequent writes, and [Writer.flush], will return the error.
# After all data has been written, the client should call the
# [Writer.flush] method to guarantee all data has been forwarded to
# the underlying [io.Writer]."""

var buf: InlineList[UInt8, size]
var buf: List[UInt8]
var bytes_written: Int
var writer: W
var err: Error

fn __init__(
inout self,
owned writer: W,
buf: InlineList[UInt8, size] = InlineList[UInt8, size](),
capacity: Int = io.BUFFER_SIZE,
bytes_written: Int = 0,
):
self.buf = InlineList[UInt8, size]()
for element in buf:
self.buf.append(element[])
self.buf = List[UInt8](capacity=capacity)
self.bytes_written = bytes_written
self.writer = writer^
self.err = Error()

fn __moveinit__(inout self, owned existing: Self):
self.buf = InlineList[UInt8, size]()
for element in existing.buf:
self.buf.append(element[])
self.buf = existing.buf^
self.bytes_written = existing.bytes_written
self.writer = existing.writer^
self.err = existing.err^
Expand All @@ -693,7 +679,7 @@ struct Writer[W: io.Writer, size: Int = io.BUFFER_SIZE](

fn as_bytes_slice(ref [_]self) -> Span[UInt8, __lifetime_of(self)]:
"""Returns the internal data as a Span[UInt8]."""
return Span[UInt8, __lifetime_of(self)](array=self.buf._array)
return Span[UInt8, __lifetime_of(self)](self.buf)

fn reset(inout self, owned writer: W):
"""Discards any unflushed buffered data, clears any error, and
Expand All @@ -705,15 +691,6 @@ struct Writer[W: io.Writer, size: Int = io.BUFFER_SIZE](
Args:
writer: The writer to write to.
"""
# # If a Writer w is passed to new_writer, new_writer will return w.
# # Different layers of code may do that, and then later pass w
# # to reset. Avoid infinite recursion in that case.
# if self == writer:
# return

# if self.buf == nil:
# self.buf = make(InlineList[UInt8, io.BUFFER_SIZE], io.BUFFER_SIZE)

self.err = Error()
self.bytes_written = 0
self.writer = writer^
Expand All @@ -739,17 +716,18 @@ struct Writer[W: io.Writer, size: Int = io.BUFFER_SIZE](
# TODO: Temp copying of elements until I figure out a better pattern or slice refs are added
var temp = self.as_bytes_slice()[bytes_written : self.bytes_written]
for i in range(len(temp)):
if i > len(temp):
self.buf[i] = temp[i]
else:
self.buf.append(temp[i])
self.buf[i] = temp[i]
# if i > len(temp):
# self.buf[i] = temp[i]
# else:
# self.buf.append(temp[i])

self.bytes_written -= bytes_written
self.err = err
return err

# Reset the buffer
self.buf = InlineList[UInt8, size]()
self.buf = List[UInt8](capacity=io.BUFFER_SIZE)
self.bytes_written = 0
return err

Expand Down Expand Up @@ -929,7 +907,7 @@ struct Writer[W: io.Writer, size: Int = io.BUFFER_SIZE](
return total_bytes_written, Error()


fn new_writer[W: io.Writer, size: Int = io.BUFFER_SIZE](owned writer: W) -> Writer[W, size]:
fn new_writer[W: io.Writer](owned writer: W) -> Writer[W]:
"""Returns a new [Writer] whose buffer has at least the specified
size. If the argument io.Writer is already a [Writer] with large enough
size, it returns the underlying [Writer]."""
Expand All @@ -938,10 +916,7 @@ fn new_writer[W: io.Writer, size: Int = io.BUFFER_SIZE](owned writer: W) -> Writ
# if ok and self.buf.capacity >= size:
# return b

constrained[size > 0, "bufio: invalid buffer size. Must be greater than 0."]()

return Writer[W, size](
buf=InlineList[UInt8, size](),
return Writer[W](
writer=writer^,
bytes_written=0,
)
Expand Down
5 changes: 3 additions & 2 deletions gojo/bufio/scan.mojo
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from utils import StringSlice, Span
from memory import memcpy
import ..io
from ..builtins import copy, panic
from ..builtins.bytes import index_byte
from ..builtins import copy, panic, index_byte
from .bufio import MAX_CONSECUTIVE_EMPTY_READS


Expand Down
2 changes: 2 additions & 0 deletions gojo/builtins/bytes.mojo
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from utils import Span

alias Byte = UInt8


Expand Down
3 changes: 2 additions & 1 deletion gojo/bytes/buffer.mojo
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from utils import StringSlice, Span
from memory import memcpy
import ..io
from ..builtins import copy, panic, index_byte
from algorithm.memory import parallel_memcpy


alias Rune = Int32
Expand Down
1 change: 1 addition & 0 deletions gojo/bytes/reader.mojo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from utils import Span
from ..builtins import copy, panic
import ..io

Expand Down
1 change: 1 addition & 0 deletions gojo/io/__init__.mojo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from utils import Span
from .io import write_string, read_at_least, read_full, read_all, BUFFER_SIZE
from .file import FileWrapper
from .std import STDWriter
Expand Down
1 change: 1 addition & 0 deletions gojo/net/fd.mojo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from utils import Span
import ..io
from ..syscall import (
recv,
Expand Down
3 changes: 2 additions & 1 deletion gojo/net/socket.mojo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from utils import Span
from ..syscall import (
sockaddr,
sockaddr_in,
Expand Down Expand Up @@ -384,7 +385,7 @@ struct Socket(FileDescriptorBase):
0,
)
if bytes_sent == -1:
return Error("Failed to send message, wrote" + String(total_bytes_sent) + "bytes before failing.")
return Error("Failed to send message, wrote" + str(total_bytes_sent) + "bytes before failing.")
total_bytes_sent += bytes_sent
attempts += 1

Expand Down
1 change: 1 addition & 0 deletions gojo/net/tcp.mojo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from utils import Span
from collections import InlineList
from ..syscall import SocketOptions
from .address import NetworkType, split_host_port, join_host_port, BaseAddr, resolve_internet_addr, HostPort
Expand Down
3 changes: 2 additions & 1 deletion gojo/net/udp.mojo
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from collections import InlineList
from collections import InlineArray, InlineList
from utils import Span
from ..syscall import SocketOptions, SocketType
from .address import NetworkType, split_host_port, join_host_port, BaseAddr, resolve_internet_addr
from .socket import Socket
Expand Down
3 changes: 3 additions & 0 deletions gojo/strings/builder.mojo
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from collections import InlineArray
from utils import StringSlice, Span
from memory import memcpy
import ..io


Expand Down
1 change: 1 addition & 0 deletions gojo/strings/reader.mojo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from utils import StringSlice, Span
import ..io
from ..builtins import copy, panic

Expand Down
4 changes: 1 addition & 3 deletions gojo/syscall/net.mojo
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
from utils.static_tuple import StaticTuple
from . import c_char, c_int, c_ushort, c_uint, c_size_t, c_ssize_t
from .file import O_CLOEXEC, O_NONBLOCK
from utils.static_tuple import StaticTuple

alias IPPROTO_IPV6 = 41
alias IPV6_V6ONLY = 26
alias EPROTONOSUPPORT = 93

# Adapted from https://github.com/gabrieldemarmiesse/mojo-stdlib-extensions/ . Huge thanks to Gabriel!


struct FD:
alias STDIN = 0
Expand Down
3 changes: 3 additions & 0 deletions gojo/unicode/utf8/table.mojo
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from collections import InlineArray


@register_passable("trivial")
struct Interval:
var first: UInt32
Expand Down
1 change: 1 addition & 0 deletions gojo/unicode/utf8/width.mojo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from collections import InlineArray
from .table import Interval, narrow, combining, doublewidth, ambiguous, emoji, nonprint


Expand Down
44 changes: 22 additions & 22 deletions tests/test_bufio.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,32 @@ fn test_read():
test.assert_equal(to_string(dest), "Hello World!")


# fn test_read_all():
# var test = MojoTest("Testing bufio.Reader with io.read_all")
# # fn test_read_all():
# # var test = MojoTest("Testing bufio.Reader with io.read_all")

# var s: String = "0123456789"
# var buf = buffer.new_reader(s)
# var reader = Reader(buf^)
# var result = read_all(reader)
# var bytes = result[0]
# bytes.append(0)
# test.assert_equal(String(bytes), "0123456789")
# # var s: String = "0123456789"
# # var buf = buffer.new_reader(s)
# # var reader = Reader(buf^)
# # var result = read_all(reader)
# # var bytes = result[0]
# # bytes.append(0)
# # test.assert_equal(String(bytes), "0123456789")


# fn test_write_to():
# var test = MojoTest("Testing bufio.Reader.write_to")
# # fn test_write_to():
# # var test = MojoTest("Testing bufio.Reader.write_to")

# var buf = buffer.new_buffer("0123456789")
# var reader = Reader(buf^)
# # var buf = buffer.new_buffer("0123456789")
# # var reader = Reader(buf^)

# # Create a new writer containing the content "Hello World"
# var writer = buffer.new_buffer("Hello World")
# # # Create a new writer containing the content "Hello World"
# # var writer = buffer.new_buffer("Hello World")

# # Write the content of the reader to the writer
# _ = reader.write_to(writer)
# # # Write the content of the reader to the writer
# # _ = reader.write_to(writer)

# # Check if the content of the writer is "Hello World0123456789"
# test.assert_equal(str(writer), "Hello World0123456789")
# # # Check if the content of the writer is "Hello World0123456789"
# # test.assert_equal(str(writer), "Hello World0123456789")


fn test_read_and_unread_byte():
Expand Down Expand Up @@ -141,7 +141,7 @@ fn test_several_writes():
var test = MojoTest("Testing several bufio.Writer.write")

# Create a new List[UInt8] Buffer Writer and use it to create the buffered Writer
var buf = buffer.new_buffer()
var buf = buffer.Buffer(capacity=4096)
var writer = Writer(buf^)

# Write the content from src to the buffered writer's internal buffer and flush it to the List[UInt8] Buffer Writer.
Expand Down Expand Up @@ -226,8 +226,8 @@ fn test_read_from():
# TODO: Add big file read/write to make sure buffer usage is correct
fn main():
test_read()
# test_read_all()
# test_write_to()
# # test_read_all()
# # test_write_to()
test_read_and_unread_byte()
test_read_slice()
test_peek()
Expand Down
2 changes: 1 addition & 1 deletion tests/test_bytes_buffer.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn test_read_string():
var s: String = "Hello World!"
var buf = new_buffer(s)
var result = buf.read_string(ord("o"))
test.assert_equal(String(result[0]), String("Hello"))
test.assert_equal(result[0], String("Hello"))


fn test_next():
Expand Down
Loading

0 comments on commit f14c578

Please sign in to comment.