moat-lib-ring 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- moat_lib_ring-0.1.0/LICENSE.txt +14 -0
- moat_lib_ring-0.1.0/Makefile +14 -0
- moat_lib_ring-0.1.0/PKG-INFO +75 -0
- moat_lib_ring-0.1.0/README.md +55 -0
- moat_lib_ring-0.1.0/debian/.gitignore +7 -0
- moat_lib_ring-0.1.0/debian/changelog +11 -0
- moat_lib_ring-0.1.0/debian/control +18 -0
- moat_lib_ring-0.1.0/debian/rules +13 -0
- moat_lib_ring-0.1.0/pyproject.toml +34 -0
- moat_lib_ring-0.1.0/setup.cfg +4 -0
- moat_lib_ring-0.1.0/src/moat/lib/ring/__init__.py +4 -0
- moat_lib_ring-0.1.0/src/moat/lib/ring/aio.py +66 -0
- moat_lib_ring-0.1.0/src/moat/lib/ring/ring.py +108 -0
- moat_lib_ring-0.1.0/src/moat_lib_ring.egg-info/PKG-INFO +75 -0
- moat_lib_ring-0.1.0/src/moat_lib_ring.egg-info/SOURCES.txt +16 -0
- moat_lib_ring-0.1.0/src/moat_lib_ring.egg-info/dependency_links.txt +1 -0
- moat_lib_ring-0.1.0/src/moat_lib_ring.egg-info/requires.txt +1 -0
- moat_lib_ring-0.1.0/src/moat_lib_ring.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
The code in this repository, and all MoaT submodules it refers to,
|
|
2
|
+
is part of the MoaT project.
|
|
3
|
+
|
|
4
|
+
Unless a submodule's LICENSE.txt states otherwise, all included files are
|
|
5
|
+
licensed under the LGPL V3, as published by the FSF at
|
|
6
|
+
https://www.gnu.org/licenses/lgpl-3.0.html .
|
|
7
|
+
|
|
8
|
+
In addition to the LGPL's terms, the author(s) respectfully ask all users of
|
|
9
|
+
this code to contribute any bug fixes or enhancements. Also, please link back to
|
|
10
|
+
https://M-o-a-T.org.
|
|
11
|
+
|
|
12
|
+
Thank you.
|
|
13
|
+
|
|
14
|
+
Copyright © 2021 ff.: the MoaT contributor(s), as per the git changelog(s).
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/make -f
|
|
2
|
+
|
|
3
|
+
PACKAGE = moat-lib-ring
|
|
4
|
+
MAKEINCL ?= $(shell python3 -mmoat src path)/make/py
|
|
5
|
+
|
|
6
|
+
ifneq ($(wildcard $(MAKEINCL)),)
|
|
7
|
+
include $(MAKEINCL)
|
|
8
|
+
# availabe via http://github.com/smurfix/sourcemgr
|
|
9
|
+
|
|
10
|
+
else
|
|
11
|
+
%:
|
|
12
|
+
@echo "Please fix 'python3 -mmoat src path'."
|
|
13
|
+
@exit 1
|
|
14
|
+
endif
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: moat-lib-ring
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A character-based ring buffer
|
|
5
|
+
Maintainer-email: Matthias Urlichs <matthias@urlichs.de>
|
|
6
|
+
Project-URL: homepage, https://m-o-a-t.org
|
|
7
|
+
Project-URL: repository, https://github.com/M-o-a-T/moat
|
|
8
|
+
Keywords: MoaT
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Framework :: AnyIO
|
|
11
|
+
Classifier: Framework :: Trio
|
|
12
|
+
Classifier: Framework :: AsyncIO
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE.txt
|
|
18
|
+
Requires-Dist: anyio~=4.0
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# moat-lib-ring
|
|
23
|
+
A simple opinionated character-based ring buffer.
|
|
24
|
+
|
|
25
|
+
This buffer, well, buffers. It's async compatible and can handle writes
|
|
26
|
+
overruns either by delaying the writer or by only keeping the newest data.
|
|
27
|
+
|
|
28
|
+
Usage is very simple:
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from moat.lib.ring import RingBuffer
|
|
32
|
+
|
|
33
|
+
# Create buffer
|
|
34
|
+
ring = RingBuffer(200)
|
|
35
|
+
|
|
36
|
+
# write to it
|
|
37
|
+
nbytes = ring.write(b'Hello', drop=True)
|
|
38
|
+
assert nbytes == 5
|
|
39
|
+
|
|
40
|
+
# read from it
|
|
41
|
+
buf = bytearray(2)
|
|
42
|
+
assert ring.readinto(buf) == 2
|
|
43
|
+
assert buf == 'He'
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Overflow handling
|
|
48
|
+
|
|
49
|
+
If you set `drop=True`, which is the default, then writing to the buffer
|
|
50
|
+
will always succeed and return the length of the bytestring.
|
|
51
|
+
The last bufsize-1 bytes will be preserved. The first byte you read will be
|
|
52
|
+
a null byte, to signal that data was lost.
|
|
53
|
+
|
|
54
|
+
`drop=False` means that writing will stall instead of destroying data: `write`
|
|
55
|
+
will return a smaller length than requested. The caller is responsible for
|
|
56
|
+
waiting until there is free space.
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## Locking
|
|
60
|
+
|
|
61
|
+
This code doesn't know if it's called from a thread or not.
|
|
62
|
+
If required, please add your own.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## Async operation
|
|
66
|
+
|
|
67
|
+
`moat.lib.ring.aio` provides an async version of this code.
|
|
68
|
+
|
|
69
|
+
In the async version, writing always waits until all bytes have been
|
|
70
|
+
delivered to the buffer.
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# Threaded operation
|
|
74
|
+
|
|
75
|
+
TODO. Requires a lock and thread-based events (or conditions).
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
|
|
2
|
+
# moat-lib-ring
|
|
3
|
+
A simple opinionated character-based ring buffer.
|
|
4
|
+
|
|
5
|
+
This buffer, well, buffers. It's async compatible and can handle writes
|
|
6
|
+
overruns either by delaying the writer or by only keeping the newest data.
|
|
7
|
+
|
|
8
|
+
Usage is very simple:
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
from moat.lib.ring import RingBuffer
|
|
12
|
+
|
|
13
|
+
# Create buffer
|
|
14
|
+
ring = RingBuffer(200)
|
|
15
|
+
|
|
16
|
+
# write to it
|
|
17
|
+
nbytes = ring.write(b'Hello', drop=True)
|
|
18
|
+
assert nbytes == 5
|
|
19
|
+
|
|
20
|
+
# read from it
|
|
21
|
+
buf = bytearray(2)
|
|
22
|
+
assert ring.readinto(buf) == 2
|
|
23
|
+
assert buf == 'He'
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Overflow handling
|
|
28
|
+
|
|
29
|
+
If you set `drop=True`, which is the default, then writing to the buffer
|
|
30
|
+
will always succeed and return the length of the bytestring.
|
|
31
|
+
The last bufsize-1 bytes will be preserved. The first byte you read will be
|
|
32
|
+
a null byte, to signal that data was lost.
|
|
33
|
+
|
|
34
|
+
`drop=False` means that writing will stall instead of destroying data: `write`
|
|
35
|
+
will return a smaller length than requested. The caller is responsible for
|
|
36
|
+
waiting until there is free space.
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## Locking
|
|
40
|
+
|
|
41
|
+
This code doesn't know if it's called from a thread or not.
|
|
42
|
+
If required, please add your own.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## Async operation
|
|
46
|
+
|
|
47
|
+
`moat.lib.ring.aio` provides an async version of this code.
|
|
48
|
+
|
|
49
|
+
In the async version, writing always waits until all bytes have been
|
|
50
|
+
delivered to the buffer.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Threaded operation
|
|
54
|
+
|
|
55
|
+
TODO. Requires a lock and thread-based events (or conditions).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
moat-lib-ring (0.1.0-4) unstable; urgency=medium
|
|
2
|
+
|
|
3
|
+
* New release for 25.6.6
|
|
4
|
+
|
|
5
|
+
-- Matthias Urlichs <matthias@urlichs.de> Wed, 10 Dec 2025 11:29:56 +0100
|
|
6
|
+
|
|
7
|
+
moat-lib-ring (0.1.0-1) unstable; urgency=medium
|
|
8
|
+
|
|
9
|
+
* Initial release.
|
|
10
|
+
|
|
11
|
+
-- Matthias Urlichs <matthias@urlichs.de> Mon, 01 Dec 2025 13:18:41 +0100
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Source: moat-lib-ring
|
|
2
|
+
Maintainer: "Matthias Urlichs" <matthias@urlichs.de>
|
|
3
|
+
Section: python
|
|
4
|
+
Priority: optional
|
|
5
|
+
Build-Depends: dh-python, python3-all, debhelper (>= 13),
|
|
6
|
+
python3-setuptools,
|
|
7
|
+
python3-wheel,
|
|
8
|
+
Standards-Version: 3.9.6
|
|
9
|
+
Homepage: https://m-o-a-t.org
|
|
10
|
+
X-DH-Compat: 13
|
|
11
|
+
|
|
12
|
+
Package: python3-moat-lib-ring
|
|
13
|
+
Architecture: all
|
|
14
|
+
Depends: ${misc:Depends}, ${python3:Depends},
|
|
15
|
+
python3-anyio (>= 3.0),
|
|
16
|
+
Description: A simple ring buffer
|
|
17
|
+
This is an efficient character-based ring buffer. It can either stall when the buffer
|
|
18
|
+
is full, or keep only the last n-1 bytes (adding a null byte to signal overflow).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/make -f
|
|
2
|
+
|
|
3
|
+
# This file was automatically generated by toml2deb
|
|
4
|
+
# Thu, 16 Jul 2020 13:15:17 +0200
|
|
5
|
+
export PYBUILD_NAME=moat-lib-ring
|
|
6
|
+
%:
|
|
7
|
+
dh $@ --with python3 --buildsystem=pybuild
|
|
8
|
+
|
|
9
|
+
override_dh_usrlocal:
|
|
10
|
+
if test -d debian/python3-moat-lib-ring/usr/local/bin/ ; then \
|
|
11
|
+
mkdir -p debian/python3-moat-lib-ring/usr/bin; \
|
|
12
|
+
mv debian/python3-moat-lib-ring/usr/local/bin/* debian/python3-moat-lib-ring/usr/bin; \
|
|
13
|
+
fi
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
build-backend = "setuptools.build_meta"
|
|
3
|
+
requires = ["wheel","setuptools"]
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
classifiers = [
|
|
7
|
+
"Development Status :: 4 - Beta",
|
|
8
|
+
"Framework :: AnyIO",
|
|
9
|
+
"Framework :: Trio",
|
|
10
|
+
"Framework :: AsyncIO",
|
|
11
|
+
"Programming Language :: Python :: 3",
|
|
12
|
+
"Intended Audience :: Developers",
|
|
13
|
+
]
|
|
14
|
+
dependencies = [
|
|
15
|
+
"anyio ~= 4.0",
|
|
16
|
+
]
|
|
17
|
+
keywords = ["MoaT"]
|
|
18
|
+
requires-python = ">=3.8"
|
|
19
|
+
name = "moat-lib-ring"
|
|
20
|
+
maintainers = [{email = "matthias@urlichs.de",name = "Matthias Urlichs"}]
|
|
21
|
+
description='A character-based ring buffer'
|
|
22
|
+
readme = "README.md"
|
|
23
|
+
version = "0.1.0"
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
homepage = "https://m-o-a-t.org"
|
|
27
|
+
repository = "https://github.com/M-o-a-T/moat"
|
|
28
|
+
|
|
29
|
+
[tool.setuptools]
|
|
30
|
+
[tool.setuptools.packages.find]
|
|
31
|
+
where = ["src"]
|
|
32
|
+
|
|
33
|
+
[tool.setuptools.package-data]
|
|
34
|
+
"*" = ["*.yaml"]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Async front-end for the characer-based ring buffer.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from moat.lib.compat import Event
|
|
8
|
+
|
|
9
|
+
from .ring import RingBuffer as _RingBuf
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class RingBuffer(_RingBuf):
|
|
13
|
+
"""
|
|
14
|
+
This ring buffer can hold a predetermined number of bytes.
|
|
15
|
+
|
|
16
|
+
This is the async version.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
_w_evt: Event | None = None
|
|
20
|
+
_r_evt: Event | None = None
|
|
21
|
+
|
|
22
|
+
def __init__(self, length: int):
|
|
23
|
+
super().__init__(length)
|
|
24
|
+
|
|
25
|
+
async def write(self, buf: bytes) -> int:
|
|
26
|
+
"""
|
|
27
|
+
Adds the bytes in `buf` to the end of the buffer.
|
|
28
|
+
"""
|
|
29
|
+
if not buf:
|
|
30
|
+
return 0
|
|
31
|
+
|
|
32
|
+
buf_len = len(buf)
|
|
33
|
+
n = 0
|
|
34
|
+
|
|
35
|
+
while True:
|
|
36
|
+
nb = super().write(buf, drop=False)
|
|
37
|
+
n += nb
|
|
38
|
+
if self._r_evt is not None:
|
|
39
|
+
self._r_evt.set()
|
|
40
|
+
self._r_evt = None
|
|
41
|
+
if n == buf_len:
|
|
42
|
+
return buf_len
|
|
43
|
+
buf = memoryview(buf)[nb:]
|
|
44
|
+
if self._w_evt is None:
|
|
45
|
+
self._w_evt = Event()
|
|
46
|
+
await self._w_evt.wait()
|
|
47
|
+
|
|
48
|
+
async def readinto(self, buf: bytearray) -> int:
|
|
49
|
+
"""
|
|
50
|
+
Copies as many bytes as will fit (or are available, whichever is
|
|
51
|
+
smaller) into the buffer and advance the read counter.
|
|
52
|
+
"""
|
|
53
|
+
if len(buf) == 0:
|
|
54
|
+
return 0
|
|
55
|
+
n = super().readinto(buf)
|
|
56
|
+
while n == 0:
|
|
57
|
+
if self._r_evt is None:
|
|
58
|
+
self._r_evt = Event()
|
|
59
|
+
await self._r_evt.wait()
|
|
60
|
+
n = super().readinto(buf)
|
|
61
|
+
|
|
62
|
+
if self._w_evt is not None:
|
|
63
|
+
self._w_evt.set()
|
|
64
|
+
self._w_evt = None
|
|
65
|
+
|
|
66
|
+
return n
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Characer-based ring buffer.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RingBuffer:
|
|
9
|
+
"""
|
|
10
|
+
This ring buffer can hold a predetermined number of bytes.
|
|
11
|
+
|
|
12
|
+
Old data are overwritten when the reader doesn't keep up.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, length: int):
|
|
16
|
+
"""
|
|
17
|
+
Sets up a ring buffer of size `len` (i.e. holds zero to len-1 bytes).
|
|
18
|
+
"""
|
|
19
|
+
self._buf = bytearray(length)
|
|
20
|
+
self._read_pos = 0 # Position to read from
|
|
21
|
+
self._count = 0 # Number of bytes available
|
|
22
|
+
|
|
23
|
+
def n_free(self):
|
|
24
|
+
"free space in buffer"
|
|
25
|
+
return len(self._buf) - self._count
|
|
26
|
+
|
|
27
|
+
def n_avail(self):
|
|
28
|
+
"bytes in buffer"
|
|
29
|
+
return self._count
|
|
30
|
+
|
|
31
|
+
__len__ = n_avail
|
|
32
|
+
|
|
33
|
+
def __repr__(self):
|
|
34
|
+
return f"<Ring:{self._count}/{len(self._buf)}>"
|
|
35
|
+
|
|
36
|
+
def write(self, buf: bytes, drop: bool = True) -> int:
|
|
37
|
+
"""
|
|
38
|
+
Adds the bytes in `buf` to the end of the buffer.
|
|
39
|
+
|
|
40
|
+
If the buffer is full and `drop` is set (the default), discards as
|
|
41
|
+
many old bytes as necessary and replaces the first byte with a
|
|
42
|
+
0x00. Otherwise only write as much as will fit.
|
|
43
|
+
"""
|
|
44
|
+
if not buf:
|
|
45
|
+
return 0
|
|
46
|
+
|
|
47
|
+
buf_len = len(self._buf)
|
|
48
|
+
res = write_len = len(buf)
|
|
49
|
+
|
|
50
|
+
# If writing more than buffer can hold, only write last buf_len bytes
|
|
51
|
+
if drop and write_len > buf_len:
|
|
52
|
+
buf = memoryview(buf)[write_len - buf_len :]
|
|
53
|
+
write_len = buf_len
|
|
54
|
+
|
|
55
|
+
# Check if we'll overflow
|
|
56
|
+
overflow = max(0, self._count + write_len - buf_len)
|
|
57
|
+
if overflow > 0:
|
|
58
|
+
# Advance read position to discard old bytes
|
|
59
|
+
if drop:
|
|
60
|
+
self._read_pos = (self._read_pos + overflow) % buf_len
|
|
61
|
+
self._count -= overflow
|
|
62
|
+
else:
|
|
63
|
+
res = write_len = buf_len - self._count
|
|
64
|
+
overflow = 0
|
|
65
|
+
buf = memoryview(buf)[:write_len]
|
|
66
|
+
|
|
67
|
+
# Write data, handling wraparound
|
|
68
|
+
write_pos = (self._read_pos + self._count) % buf_len
|
|
69
|
+
space_to_end = buf_len - write_pos
|
|
70
|
+
if write_len <= space_to_end:
|
|
71
|
+
# Simple case: no wraparound
|
|
72
|
+
self._buf[write_pos : write_pos + write_len] = buf
|
|
73
|
+
else:
|
|
74
|
+
# Wraparound case: split the write
|
|
75
|
+
self._buf[write_pos:buf_len] = buf[:space_to_end]
|
|
76
|
+
self._buf[0 : write_len - space_to_end] = buf[space_to_end:]
|
|
77
|
+
|
|
78
|
+
self._count += write_len
|
|
79
|
+
|
|
80
|
+
# Replace the oldest byte with 0x00 if we had overflow
|
|
81
|
+
if overflow > 0:
|
|
82
|
+
self._buf[self._read_pos] = 0x00
|
|
83
|
+
|
|
84
|
+
return res
|
|
85
|
+
|
|
86
|
+
def readinto(self, buf: bytearray) -> int:
|
|
87
|
+
"""
|
|
88
|
+
Copies as many bytes as will fit (or are available, whichever is
|
|
89
|
+
smaller) into the buffer and advance the read counter.
|
|
90
|
+
"""
|
|
91
|
+
read_len = min(len(buf), self._count)
|
|
92
|
+
if read_len == 0:
|
|
93
|
+
return 0
|
|
94
|
+
|
|
95
|
+
buf_len = len(self._buf)
|
|
96
|
+
space_to_end = buf_len - self._read_pos
|
|
97
|
+
|
|
98
|
+
if read_len <= space_to_end:
|
|
99
|
+
# Simple case: no wraparound
|
|
100
|
+
buf[:read_len] = self._buf[self._read_pos : self._read_pos + read_len]
|
|
101
|
+
else:
|
|
102
|
+
# Wraparound case: split the read
|
|
103
|
+
buf[:space_to_end] = self._buf[self._read_pos : buf_len]
|
|
104
|
+
buf[space_to_end:read_len] = self._buf[0 : read_len - space_to_end]
|
|
105
|
+
|
|
106
|
+
self._read_pos = (self._read_pos + read_len) % buf_len
|
|
107
|
+
self._count -= read_len
|
|
108
|
+
return read_len
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: moat-lib-ring
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A character-based ring buffer
|
|
5
|
+
Maintainer-email: Matthias Urlichs <matthias@urlichs.de>
|
|
6
|
+
Project-URL: homepage, https://m-o-a-t.org
|
|
7
|
+
Project-URL: repository, https://github.com/M-o-a-T/moat
|
|
8
|
+
Keywords: MoaT
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Framework :: AnyIO
|
|
11
|
+
Classifier: Framework :: Trio
|
|
12
|
+
Classifier: Framework :: AsyncIO
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE.txt
|
|
18
|
+
Requires-Dist: anyio~=4.0
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# moat-lib-ring
|
|
23
|
+
A simple opinionated character-based ring buffer.
|
|
24
|
+
|
|
25
|
+
This buffer, well, buffers. It's async compatible and can handle writes
|
|
26
|
+
overruns either by delaying the writer or by only keeping the newest data.
|
|
27
|
+
|
|
28
|
+
Usage is very simple:
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from moat.lib.ring import RingBuffer
|
|
32
|
+
|
|
33
|
+
# Create buffer
|
|
34
|
+
ring = RingBuffer(200)
|
|
35
|
+
|
|
36
|
+
# write to it
|
|
37
|
+
nbytes = ring.write(b'Hello', drop=True)
|
|
38
|
+
assert nbytes == 5
|
|
39
|
+
|
|
40
|
+
# read from it
|
|
41
|
+
buf = bytearray(2)
|
|
42
|
+
assert ring.readinto(buf) == 2
|
|
43
|
+
assert buf == 'He'
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Overflow handling
|
|
48
|
+
|
|
49
|
+
If you set `drop=True`, which is the default, then writing to the buffer
|
|
50
|
+
will always succeed and return the length of the bytestring.
|
|
51
|
+
The last bufsize-1 bytes will be preserved. The first byte you read will be
|
|
52
|
+
a null byte, to signal that data was lost.
|
|
53
|
+
|
|
54
|
+
`drop=False` means that writing will stall instead of destroying data: `write`
|
|
55
|
+
will return a smaller length than requested. The caller is responsible for
|
|
56
|
+
waiting until there is free space.
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## Locking
|
|
60
|
+
|
|
61
|
+
This code doesn't know if it's called from a thread or not.
|
|
62
|
+
If required, please add your own.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## Async operation
|
|
66
|
+
|
|
67
|
+
`moat.lib.ring.aio` provides an async version of this code.
|
|
68
|
+
|
|
69
|
+
In the async version, writing always waits until all bytes have been
|
|
70
|
+
delivered to the buffer.
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# Threaded operation
|
|
74
|
+
|
|
75
|
+
TODO. Requires a lock and thread-based events (or conditions).
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
LICENSE.txt
|
|
2
|
+
Makefile
|
|
3
|
+
README.md
|
|
4
|
+
pyproject.toml
|
|
5
|
+
debian/.gitignore
|
|
6
|
+
debian/changelog
|
|
7
|
+
debian/control
|
|
8
|
+
debian/rules
|
|
9
|
+
src/moat/lib/ring/__init__.py
|
|
10
|
+
src/moat/lib/ring/aio.py
|
|
11
|
+
src/moat/lib/ring/ring.py
|
|
12
|
+
src/moat_lib_ring.egg-info/PKG-INFO
|
|
13
|
+
src/moat_lib_ring.egg-info/SOURCES.txt
|
|
14
|
+
src/moat_lib_ring.egg-info/dependency_links.txt
|
|
15
|
+
src/moat_lib_ring.egg-info/requires.txt
|
|
16
|
+
src/moat_lib_ring.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
anyio~=4.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
moat
|