@@ -89,7 +89,9 @@ public static long SizeFromFormat(string format)
8989 {
9090 if ( Runtime . PyVersion < new Version ( 3 , 9 ) )
9191 throw new NotSupportedException ( "SizeFromFormat requires at least Python 3.9" ) ;
92- return ( long ) Runtime . PyBuffer_SizeFromFormat ( format ) ;
92+ nint result = Runtime . PyBuffer_SizeFromFormat ( format ) ;
93+ if ( result == - 1 ) throw PythonException . ThrowLastAsClrException ( ) ;
94+ return result ;
9395 }
9496
9597 /// <summary>
@@ -113,7 +115,7 @@ public IntPtr GetPointer(long[] indices)
113115 throw new ObjectDisposedException ( nameof ( PyBuffer ) ) ;
114116 if ( Runtime . PyVersion < new Version ( 3 , 7 ) )
115117 throw new NotSupportedException ( "GetPointer requires at least Python 3.7" ) ;
116- return Runtime . PyBuffer_GetPointer ( ref _view , indices . Select ( x => ( IntPtr ) x ) . ToArray ( ) ) ;
118+ return Runtime . PyBuffer_GetPointer ( ref _view , indices . Select ( x => checked ( ( nint ) x ) ) . ToArray ( ) ) ;
117119 }
118120
119121 /// <summary>
@@ -126,7 +128,7 @@ public void FromContiguous(IntPtr buf, long len, BufferOrderStyle fort)
126128 if ( Runtime . PyVersion < new Version ( 3 , 7 ) )
127129 throw new NotSupportedException ( "FromContiguous requires at least Python 3.7" ) ;
128130
129- if ( Runtime . PyBuffer_FromContiguous ( ref _view , buf , ( IntPtr ) len , OrderStyleToChar ( fort , false ) ) < 0 )
131+ if ( Runtime . PyBuffer_FromContiguous ( ref _view , buf , checked ( ( nint ) len ) , OrderStyleToChar ( fort , false ) ) < 0 )
130132 throw PythonException . ThrowLastAsClrException ( ) ;
131133 }
132134
@@ -173,44 +175,60 @@ internal void FillInfo(BorrowedReference exporter, IntPtr buf, long len, bool _r
173175 /// <summary>
174176 /// Writes a managed byte array into the buffer of a python object. This can be used to pass data like images from managed to python.
175177 /// </summary>
176- public void Write ( byte [ ] buffer , int offset , int count )
178+ public void Write ( byte [ ] buffer , int sourceOffset , int count , nint destinationOffset )
177179 {
178180 if ( disposedValue )
179181 throw new ObjectDisposedException ( nameof ( PyBuffer ) ) ;
182+ if ( _view . ndim != 1 )
183+ throw new NotImplementedException ( "Multidimensional arrays, scalars and objects without a buffer are not supported." ) ;
184+ if ( ! this . IsContiguous ( BufferOrderStyle . C ) )
185+ throw new NotImplementedException ( "Only continuous buffers are supported" ) ;
180186 if ( ReadOnly )
181187 throw new InvalidOperationException ( "Buffer is read-only" ) ;
182- if ( ( long ) _view . len > int . MaxValue )
183- throw new NotSupportedException ( "Python buffers bigger than int.MaxValue are not supported." ) ;
184- if ( count > buffer . Length )
188+ if ( buffer is null )
189+ throw new ArgumentNullException ( nameof ( buffer ) ) ;
190+
191+ if ( sourceOffset < 0 )
192+ throw new IndexOutOfRangeException ( $ "{ nameof ( sourceOffset ) } is negative") ;
193+ if ( destinationOffset < 0 )
194+ throw new IndexOutOfRangeException ( $ "{ nameof ( destinationOffset ) } is negative") ;
195+ if ( count < 0 )
196+ throw new ArgumentOutOfRangeException ( nameof ( count ) , count , "Value must be >= 0" ) ;
197+
198+ if ( checked ( count + sourceOffset ) > buffer . Length )
185199 throw new ArgumentOutOfRangeException ( "count" , "Count is bigger than the buffer." ) ;
186- if ( count > ( int ) _view . len )
200+ if ( checked ( count + destinationOffset ) > _view . len )
187201 throw new ArgumentOutOfRangeException ( "count" , "Count is bigger than the python buffer." ) ;
188- if ( _view . ndim != 1 )
189- throw new NotSupportedException ( "Multidimensional arrays, scalars and objects without a buffer are not supported." ) ;
190- if ( ! this . IsContiguous ( BufferOrderStyle . C ) )
191- throw new NotImplementedException ( "Only continuous buffers are supported" ) ;
192202
193- Marshal . Copy ( buffer , offset , _view . buf , count ) ;
203+ Marshal . Copy ( buffer , sourceOffset , _view . buf + destinationOffset , count ) ;
194204 }
195205
196206 /// <summary>
197207 /// Reads the buffer of a python object into a managed byte array. This can be used to pass data like images from python to managed.
198208 /// </summary>
199- public int Read ( byte [ ] buffer , int offset , int count ) {
209+ public void Read ( byte [ ] buffer , int destinationOffset , int count , nint sourceOffset ) {
200210 if ( disposedValue )
201211 throw new ObjectDisposedException ( nameof ( PyBuffer ) ) ;
202- if ( count > buffer . Length )
203- throw new ArgumentOutOfRangeException ( "count" , "Count is bigger than the buffer." ) ;
204212 if ( _view . ndim != 1 )
205- throw new NotSupportedException ( "Multidimensional arrays, scalars and objects without a buffer are not supported." ) ;
206- if ( _view . len . ToInt64 ( ) > int . MaxValue )
207- throw new NotSupportedException ( "Python buffers bigger than int.MaxValue are not supported." ) ;
213+ throw new NotImplementedException ( "Multidimensional arrays, scalars and objects without a buffer are not supported." ) ;
208214 if ( ! this . IsContiguous ( BufferOrderStyle . C ) )
209215 throw new NotImplementedException ( "Only continuous buffers are supported" ) ;
216+ if ( buffer is null )
217+ throw new ArgumentNullException ( nameof ( buffer ) ) ;
218+
219+ if ( sourceOffset < 0 )
220+ throw new IndexOutOfRangeException ( $ "{ nameof ( sourceOffset ) } is negative") ;
221+ if ( destinationOffset < 0 )
222+ throw new IndexOutOfRangeException ( $ "{ nameof ( destinationOffset ) } is negative") ;
223+ if ( count < 0 )
224+ throw new ArgumentOutOfRangeException ( nameof ( count ) , count , "Value must be >= 0" ) ;
225+
226+ if ( checked ( count + destinationOffset ) > buffer . Length )
227+ throw new ArgumentOutOfRangeException ( "count" , "Count is bigger than the buffer." ) ;
228+ if ( checked ( count + sourceOffset ) > _view . len )
229+ throw new ArgumentOutOfRangeException ( "count" , "Count is bigger than the python buffer." ) ;
210230
211- int copylen = count < ( int ) _view . len ? count : ( int ) _view . len ;
212- Marshal . Copy ( _view . buf , buffer , offset , copylen ) ;
213- return copylen ;
231+ Marshal . Copy ( _view . buf + sourceOffset , buffer , destinationOffset , count ) ;
214232 }
215233
216234 private bool disposedValue = false ; // To detect redundant calls
@@ -240,11 +258,7 @@ private void Dispose(bool disposing)
240258
241259 if ( _view . obj != IntPtr . Zero )
242260 {
243- Finalizer . Instance . AddFinalizedObject ( ref _view . obj , _exporter . run
244- #if TRACE_ALLOC
245- , _exporter . Traceback
246- #endif
247- ) ;
261+ Finalizer . Instance . AddFinalizedBuffer ( ref _view ) ;
248262 }
249263
250264 Dispose ( false ) ;
0 commit comments