1
+ // Copyright 2025 Confluent Inc.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // Refer to LICENSE for more information.
16
+
17
+ using System ;
18
+ using System . IO ;
19
+
20
+ namespace Confluent . SchemaRegistry . Serdes ;
21
+
22
+ /// <summary>
23
+ /// A read-only <see cref="Stream"/> implementation over a <see cref="ReadOnlyMemory{Byte}"/>.
24
+ /// This class is needed to avoid calling <c>ToArray()</c> on <see cref="ReadOnlyMemory{Byte}"/>
25
+ /// when passing data to APIs (such as Avro's <c>BinaryDecoder</c>) that require a <see cref="Stream"/>.
26
+ /// </summary>
27
+ internal class ReadOnlyMemoryStream : Stream
28
+ {
29
+ private readonly ReadOnlyMemory < byte > data ;
30
+
31
+ public ReadOnlyMemoryStream ( ReadOnlyMemory < byte > data )
32
+ {
33
+ this . data = data ;
34
+ }
35
+
36
+ public override void Flush ( )
37
+ {
38
+ }
39
+
40
+ public override int Read ( byte [ ] buffer , int offset , int count )
41
+ {
42
+ if ( buffer == null )
43
+ throw new ArgumentNullException ( nameof ( buffer ) ) ;
44
+ if ( offset < 0 || count < 0 || offset + count > buffer . Length )
45
+ throw new ArgumentOutOfRangeException ( ) ;
46
+
47
+ var remaining = data . Length - ( int ) Position ;
48
+ if ( remaining <= 0 )
49
+ return 0 ;
50
+
51
+ var toRead = Math . Min ( count , remaining ) ;
52
+ data . Slice ( ( int ) Position , toRead ) . Span . CopyTo ( buffer . AsSpan ( offset , toRead ) ) ;
53
+ Position += toRead ;
54
+ return toRead ;
55
+ }
56
+
57
+ public override long Seek ( long offset , SeekOrigin origin )
58
+ {
59
+ switch ( origin )
60
+ {
61
+ case SeekOrigin . Begin :
62
+ Position = offset ;
63
+ break ;
64
+ case SeekOrigin . Current :
65
+ Position += offset ;
66
+ break ;
67
+ case SeekOrigin . End :
68
+ Position = Length + offset ;
69
+ break ;
70
+ default :
71
+ throw new ArgumentOutOfRangeException ( nameof ( origin ) , origin , null ) ;
72
+ }
73
+
74
+ if ( Position < 0 || Position > Length )
75
+ throw new IOException ( "Seek operation resulted in an invalid position." ) ;
76
+
77
+ return Position ;
78
+ }
79
+
80
+ public override void SetLength ( long value )
81
+ {
82
+ throw new NotSupportedException ( ) ;
83
+ }
84
+
85
+ public override void Write ( byte [ ] buffer , int offset , int count )
86
+ {
87
+ throw new NotSupportedException ( ) ;
88
+ }
89
+
90
+ public override bool CanRead => true ;
91
+ public override bool CanSeek => true ;
92
+ public override bool CanWrite => false ;
93
+ public override long Length => data . Length ;
94
+ public override long Position { get ; set ; }
95
+ }
0 commit comments