@@ -212,6 +212,97 @@ public void ToBEBytes(byte[] buffer, int offset = 0)
212212 typeof ( Action < Array , int , Array , int , int > ) ,
213213 typeof ( Buffer ) . GetMethod ( "InternalBlockCopy" , BindingFlags . NonPublic | BindingFlags . Static ) )
214214 as Action < Array , int , Array , int , int > ;
215+
216+ #region Combine byte arrays & segments
217+ public static byte [ ] Combine ( ArraySegment < byte > a , ArraySegment < byte > b )
218+ {
219+ byte [ ] combinedArray = new byte [ a . Count + b . Count ] ;
220+ BlockCopy ( a . Array , a . Offset , combinedArray , 0 , a . Count ) ;
221+ BlockCopy ( b . Array , b . Offset , combinedArray , a . Count , b . Count ) ;
222+ return combinedArray ;
223+ } // Combine(two byte array segments)
224+
225+ public static byte [ ] Combine ( byte [ ] a , byte [ ] b ) { return Combine ( a . AsArraySegment ( ) , b . AsArraySegment ( ) ) ; } // Combine(two byte arrays)
226+
227+ public static byte [ ] Combine ( ArraySegment < byte > a , ArraySegment < byte > b , ArraySegment < byte > c )
228+ {
229+ byte [ ] combinedArray = new byte [ a . Count + b . Count + c . Count ] ;
230+ BlockCopy ( a . Array , a . Offset , combinedArray , 0 , a . Count ) ;
231+ BlockCopy ( b . Array , b . Offset , combinedArray , a . Count , b . Count ) ;
232+ BlockCopy ( c . Array , c . Offset , combinedArray , a . Count + b . Count , c . Count ) ;
233+ return combinedArray ;
234+ } // Combine(three byte array segments)
235+
236+ public static byte [ ] Combine ( byte [ ] a , byte [ ] b , byte [ ] c ) { return Combine ( a . AsArraySegment ( ) , b . AsArraySegment ( ) , c . AsArraySegment ( ) ) ; } // Combine(three byte arrays)
237+
238+ public static byte [ ] Combine ( params byte [ ] [ ] arrays )
239+ {
240+ int combinedArrayLength = 0 , combinedArrayOffset = 0 ;
241+ for ( int i = 0 ; i < arrays . Length ; ++ i ) combinedArrayLength += arrays [ i ] . Length ;
242+ byte [ ] array , combinedArray = new byte [ combinedArrayLength ] ;
243+
244+ for ( int i = 0 ; i < arrays . Length ; ++ i )
245+ {
246+ array = arrays [ i ] ;
247+ BlockCopy ( array , 0 , combinedArray , combinedArrayOffset , array . Length ) ;
248+ combinedArrayOffset += array . Length ;
249+ }
250+ return combinedArray ;
251+ } // Combine(params byte[][])
252+
253+ public static byte [ ] Combine ( params ArraySegment < byte > [ ] arraySegments )
254+ {
255+ int combinedArrayLength = 0 , combinedArrayOffset = 0 ;
256+ for ( int i = 0 ; i < arraySegments . Length ; ++ i ) combinedArrayLength += arraySegments [ i ] . Count ;
257+ byte [ ] combinedArray = new byte [ combinedArrayLength ] ;
258+
259+ for ( int i = 0 ; i < arraySegments . Length ; ++ i )
260+ {
261+ var segment = arraySegments [ i ] ;
262+ BlockCopy ( segment . Array , segment . Offset , combinedArray , combinedArrayOffset , segment . Count ) ;
263+ combinedArrayOffset += segment . Count ;
264+ }
265+ return combinedArray ;
266+ } // Combine(params ArraySegment<byte>[])
267+ #endregion
268+
269+ #region Xor
270+ [ StructLayout ( LayoutKind . Explicit ) ]
271+ struct Union
272+ {
273+ [ FieldOffset ( 0 ) ]
274+ public byte [ ] Bytes ;
275+
276+ [ FieldOffset ( 0 ) ]
277+ public long [ ] Longs ;
278+ } // struct Union
279+
280+ public static void Xor ( byte [ ] dest , int destOffset , byte [ ] left , int leftOffset , byte [ ] right , int rightOffset , int byteCount )
281+ {
282+ int i = 0 ;
283+ if ( ( destOffset & 7 ) == 0 && ( leftOffset & 7 ) == 0 && ( rightOffset & 7 ) == 0 ) // all offsets must be multiples of 8 for long-sized xor
284+ {
285+ Union destUnion = new Union { Bytes = dest } , leftUnion = new Union { Bytes = left } , rightBuffer = new Union { Bytes = right } ;
286+ int longDestOffset = destOffset >> 3 , longLeftOffset = leftOffset >> 3 , longRightOffset = rightOffset >> 3 , longCount = byteCount >> 3 ;
287+ for ( ; i < longCount ; ++ i ) destUnion . Longs [ longDestOffset + i ] = leftUnion . Longs [ longLeftOffset + i ] ^ rightBuffer . Longs [ longRightOffset + i ] ;
288+ i = longCount << 3 ;
289+ }
290+ for ( ; i < byteCount ; ++ i ) dest [ destOffset + i ] = ( byte ) ( left [ leftOffset + i ] ^ right [ rightOffset + i ] ) ;
291+ } // Xor()
292+
293+ public static void Xor ( byte [ ] dest , int destOffset , byte [ ] left , int leftOffset , int byteCount )
294+ {
295+ int i = 0 ;
296+ if ( ( destOffset & 7 ) == 0 && ( leftOffset & 7 ) == 0 ) // all offsets must be multiples of 8 for long-sized xor
297+ {
298+ Union destUnion = new Union { Bytes = dest } , leftUnion = new Union { Bytes = left } ;
299+ int longDestOffset = destOffset >> 3 , longLeftOffset = leftOffset >> 3 , longCount = byteCount >> 3 ;
300+ for ( ; i < longCount ; ++ i ) destUnion . Longs [ longDestOffset + i ] ^= leftUnion . Longs [ longLeftOffset + i ] ;
301+ i = longCount << 3 ;
302+ }
303+ for ( ; i < byteCount ; ++ i ) dest [ destOffset + i ] ^= left [ leftOffset + i ] ;
304+ } // Xor()
305+ #endregion
215306 } // class Utils
216307
217308 public static class ArraySegmentExtensions
0 commit comments