@@ -89,7 +89,9 @@ public static long SizeFromFormat(string format)
89
89
{
90
90
if ( Runtime . PyVersion < new Version ( 3 , 9 ) )
91
91
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 ;
93
95
}
94
96
95
97
/// <summary>
@@ -113,7 +115,7 @@ public IntPtr GetPointer(long[] indices)
113
115
throw new ObjectDisposedException ( nameof ( PyBuffer ) ) ;
114
116
if ( Runtime . PyVersion < new Version ( 3 , 7 ) )
115
117
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 ( ) ) ;
117
119
}
118
120
119
121
/// <summary>
@@ -126,7 +128,7 @@ public void FromContiguous(IntPtr buf, long len, BufferOrderStyle fort)
126
128
if ( Runtime . PyVersion < new Version ( 3 , 7 ) )
127
129
throw new NotSupportedException ( "FromContiguous requires at least Python 3.7" ) ;
128
130
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 )
130
132
throw PythonException . ThrowLastAsClrException ( ) ;
131
133
}
132
134
@@ -173,44 +175,60 @@ internal void FillInfo(BorrowedReference exporter, IntPtr buf, long len, bool _r
173
175
/// <summary>
174
176
/// 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.
175
177
/// </summary>
176
- public void Write ( byte [ ] buffer , int offset , int count )
178
+ public void Write ( byte [ ] buffer , int sourceOffset , int count , nint destinationOffset )
177
179
{
178
180
if ( disposedValue )
179
181
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" ) ;
180
186
if ( ReadOnly )
181
187
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 )
185
199
throw new ArgumentOutOfRangeException ( "count" , "Count is bigger than the buffer." ) ;
186
- if ( count > ( int ) _view . len )
200
+ if ( checked ( count + destinationOffset ) > _view . len )
187
201
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" ) ;
192
202
193
- Marshal . Copy ( buffer , offset , _view . buf , count ) ;
203
+ Marshal . Copy ( buffer , sourceOffset , _view . buf + destinationOffset , count ) ;
194
204
}
195
205
196
206
/// <summary>
197
207
/// 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.
198
208
/// </summary>
199
- public int Read ( byte [ ] buffer , int offset , int count ) {
209
+ public void Read ( byte [ ] buffer , int destinationOffset , int count , nint sourceOffset ) {
200
210
if ( disposedValue )
201
211
throw new ObjectDisposedException ( nameof ( PyBuffer ) ) ;
202
- if ( count > buffer . Length )
203
- throw new ArgumentOutOfRangeException ( "count" , "Count is bigger than the buffer." ) ;
204
212
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." ) ;
208
214
if ( ! this . IsContiguous ( BufferOrderStyle . C ) )
209
215
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." ) ;
210
230
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 ) ;
214
232
}
215
233
216
234
private bool disposedValue = false ; // To detect redundant calls
@@ -240,11 +258,7 @@ private void Dispose(bool disposing)
240
258
241
259
if ( _view . obj != IntPtr . Zero )
242
260
{
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 ) ;
248
262
}
249
263
250
264
Dispose ( false ) ;
0 commit comments