2 using System.Collections.Generic;
5 using SharpCompress.Archive;
6 using SharpCompress.Common;
7 using SharpCompress.IO;
9 namespace SharpCompress
11 internal static class Utility
13 public static ReadOnlyCollection<T> ToReadOnly<T>(this IEnumerable<T> items)
15 return new ReadOnlyCollection<T>(items.ToList());
19 /// Performs an unsigned bitwise right shift with the specified number
21 /// <param name="number">Number to operate on</param>
22 /// <param name="bits">Ammount of bits to shift</param>
23 /// <returns>The resulting number from the shift operation</returns>
24 public static int URShift(int number, int bits)
27 return number >> bits;
29 return (number >> bits) + (2 << ~bits);
33 /// Performs an unsigned bitwise right shift with the specified number
35 /// <param name="number">Number to operate on</param>
36 /// <param name="bits">Ammount of bits to shift</param>
37 /// <returns>The resulting number from the shift operation</returns>
38 public static int URShift(int number, long bits)
40 return URShift(number, (int)bits);
44 /// Performs an unsigned bitwise right shift with the specified number
46 /// <param name="number">Number to operate on</param>
47 /// <param name="bits">Ammount of bits to shift</param>
48 /// <returns>The resulting number from the shift operation</returns>
49 public static long URShift(long number, int bits)
52 return number >> bits;
54 return (number >> bits) + (2L << ~bits);
58 /// Performs an unsigned bitwise right shift with the specified number
60 /// <param name="number">Number to operate on</param>
61 /// <param name="bits">Ammount of bits to shift</param>
62 /// <returns>The resulting number from the shift operation</returns>
63 public static long URShift(long number, long bits)
65 return URShift(number, (int)bits);
69 /// Fills the array with an specific value from an specific index to an specific index.
71 /// <param name="array">The array to be filled.</param>
72 /// <param name="fromindex">The first index to be filled.</param>
73 /// <param name="toindex">The last index to be filled.</param>
74 /// <param name="val">The value to fill the array with.</param>
75 public static void Fill<T>(T[] array, int fromindex, int toindex, T val) where T : struct
77 if (array.Length == 0)
79 throw new NullReferenceException();
81 if (fromindex > toindex)
83 throw new ArgumentException();
85 if ((fromindex < 0) || ((System.Array)array).Length < toindex)
87 throw new IndexOutOfRangeException();
89 for (int index = (fromindex > 0) ? fromindex-- : fromindex; index < toindex; index++)
96 /// Fills the array with an specific value.
98 /// <param name="array">The array to be filled.</param>
99 /// <param name="val">The value to fill the array with.</param>
100 public static void Fill<T>(T[] array, T val) where T : struct
102 Fill(array, 0, array.Length, val);
105 public static void SetSize(this List<byte> list, int count)
107 if (count > list.Count)
109 for (int i = list.Count; i < count; i++)
116 byte[] temp = new byte[count];
117 list.CopyTo(temp, 0);
123 /// <summary> Read a int value from the byte array at the given position (Big Endian)
126 /// <param name="array">the array to read from
128 /// <param name="pos">the offset
130 /// <returns> the value
132 public static int readIntBigEndian(byte[] array, int pos)
135 temp |= array[pos] & 0xff;
137 temp |= array[pos + 1] & 0xff;
139 temp |= array[pos + 2] & 0xff;
141 temp |= array[pos + 3] & 0xff;
145 /// <summary> Read a short value from the byte array at the given position (little
149 /// <param name="array">the array to read from
151 /// <param name="pos">the offset
153 /// <returns> the value
155 public static short readShortLittleEndian(byte[] array, int pos)
157 return BitConverter.ToInt16(array, pos);
160 /// <summary> Read an int value from the byte array at the given position (little
164 /// <param name="array">the array to read from
166 /// <param name="pos">the offset
168 /// <returns> the value
170 public static int readIntLittleEndian(byte[] array, int pos)
172 return BitConverter.ToInt32(array, pos);
175 /// <summary> Write an int value into the byte array at the given position (Big endian)
178 /// <param name="array">the array
180 /// <param name="pos">the offset
182 /// <param name="value">the value to write
184 public static void writeIntBigEndian(byte[] array, int pos, int value)
186 array[pos] = (byte)((Utility.URShift(value, 24)) & 0xff);
187 array[pos + 1] = (byte)((Utility.URShift(value, 16)) & 0xff);
188 array[pos + 2] = (byte)((Utility.URShift(value, 8)) & 0xff);
189 array[pos + 3] = (byte)((value) & 0xff);
192 /// <summary> Write a short value into the byte array at the given position (little
196 /// <param name="array">the array
198 /// <param name="pos">the offset
200 /// <param name="value">the value to write
202 #if PORTABLE || NETFX_CORE
203 public static void WriteLittleEndian(byte[] array, int pos, short value)
205 byte[] newBytes = BitConverter.GetBytes(value);
206 Array.Copy(newBytes, 0, array, pos, newBytes.Length);
209 public static unsafe void WriteLittleEndian(byte[] array, int pos, short value)
211 fixed (byte* numRef = &(array[pos]))
213 *((short*)numRef) = value;
218 /// <summary> Increment a short value at the specified position by the specified amount
221 public static void incShortLittleEndian(byte[] array, int pos, short incrementValue)
223 short existingValue = BitConverter.ToInt16(array, pos);
224 existingValue += incrementValue;
225 WriteLittleEndian(array, pos, existingValue);
226 //int c = Utility.URShift(((array[pos] & 0xff) + (dv & 0xff)), 8);
227 //array[pos] = (byte)(array[pos] + (dv & 0xff));
228 //if ((c > 0) || ((dv & 0xff00) != 0))
230 // array[pos + 1] = (byte)(array[pos + 1] + ((Utility.URShift(dv, 8)) & 0xff) + c);
234 /// <summary> Write an int value into the byte array at the given position (little
238 /// <param name="array">the array
240 /// <param name="pos">the offset
242 /// <param name="value">the value to write
244 #if PORTABLE || NETFX_CORE
245 public static void WriteLittleEndian(byte[] array, int pos, int value)
247 byte[] newBytes = BitConverter.GetBytes(value);
248 Array.Copy(newBytes, 0, array, pos, newBytes.Length);
251 public static unsafe void WriteLittleEndian(byte[] array, int pos, int value)
253 fixed (byte* numRef = &(array[pos]))
255 *((int*)numRef) = value;
260 public static void Initialize<T>(this T[] array, Func<T> func)
262 for (int i = 0; i < array.Length; i++)
268 public static void AddRange<T>(this ICollection<T> destination, IEnumerable<T> source)
270 foreach (T item in source)
272 destination.Add(item);
276 public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
278 foreach (T item in items)
284 public static IEnumerable<T> AsEnumerable<T>(this T item)
289 public static void CheckNotNull(this object obj, string name)
293 throw new ArgumentNullException(name);
297 public static void CheckNotNullOrEmpty(this string obj, string name)
299 obj.CheckNotNull(name);
302 throw new ArgumentException("String is empty.");
306 public static void Skip(this Stream source, long advanceAmount)
308 byte[] buffer = new byte[32 * 1024];
313 readCount = buffer.Length;
314 if (readCount > advanceAmount)
316 readCount = (int)advanceAmount;
318 read = source.Read(buffer, 0, readCount);
323 advanceAmount -= read;
324 if (advanceAmount == 0)
331 public static void SkipAll(this Stream source)
333 byte[] buffer = new byte[32 * 1024];
336 } while (source.Read(buffer, 0, buffer.Length) == buffer.Length);
340 public static byte[] UInt32ToBigEndianBytes(uint x)
344 (byte) ((x >> 24) & 0xff),
345 (byte) ((x >> 16) & 0xff),
346 (byte) ((x >> 8) & 0xff),
351 public static DateTime DosDateToDateTime(UInt16 iDate, UInt16 iTime)
353 int year = iDate / 512 + 1980;
354 int month = iDate % 512 / 32;
355 int day = iDate % 512 % 32;
356 int hour = iTime / 2048;
357 int minute = iTime % 2048 / 32;
358 int second = iTime % 2048 % 32 * 2;
360 if (iDate == UInt16.MaxValue || month == 0 || day == 0)
367 if (iTime == UInt16.MaxValue)
369 hour = minute = second = 0;
375 dt = new DateTime(year, month, day, hour, minute, second);
384 public static uint DateTimeToDosTime(this DateTime? dateTime)
386 if (dateTime == null)
391 (dateTime.Value.Second / 2) | (dateTime.Value.Minute << 5) | (dateTime.Value.Hour << 11) |
392 (dateTime.Value.Day << 16) | (dateTime.Value.Month << 21) |
393 ((dateTime.Value.Year - 1980) << 25));
397 public static DateTime DosDateToDateTime(UInt32 iTime)
399 return DosDateToDateTime((UInt16)(iTime / 65536),
400 (UInt16)(iTime % 65536));
403 public static DateTime DosDateToDateTime(Int32 iTime)
405 return DosDateToDateTime((UInt32)iTime);
408 public static long TransferTo(this Stream source, Stream destination)
410 byte[] array = new byte[81920];
413 while ((count = source.Read(array, 0, array.Length)) != 0)
416 destination.Write(array, 0, count);
421 public static bool ReadFully(this Stream stream, byte[] buffer)
425 while ((read = stream.Read(buffer, total, buffer.Length - total)) > 0)
428 if (total >= buffer.Length)
433 return (total >= buffer.Length);
436 public static string TrimNulls(this string source)
438 return source.Replace('\0', ' ').Trim();
441 public static bool BinaryEquals(this byte[] source, byte[] target)
443 if (source.Length != target.Length)
447 for (int i = 0; i < source.Length; ++i)
449 if (source[i] != target[i])
457 #if PORTABLE || NETFX_CORE
458 public static void CopyTo(this byte[] array, byte[] destination, int index)
460 Array.Copy(array, 0, destination, index, array.Length);
463 public static long HostToNetworkOrder(long host)
465 return (int)((long)HostToNetworkOrder((int)host)
466 & unchecked((long)(unchecked((ulong)-1))) << 32
467 | ((long)HostToNetworkOrder((int)((int)host >> 32)) & unchecked((long)(unchecked((ulong)-1)))));
469 public static int HostToNetworkOrder(int host)
471 return (int)((int)(HostToNetworkOrder((short)host) & -1) << 16 | (HostToNetworkOrder((short)(host >> 16)) & -1));
473 public static short HostToNetworkOrder(short host)
475 return (short)((int)(host & 255) << 8 | ((int)host >> 8 & 255));
477 public static long NetworkToHostOrder(long network)
479 return HostToNetworkOrder(network);
481 public static int NetworkToHostOrder(int network)
483 return HostToNetworkOrder(network);
485 public static short NetworkToHostOrder(short network)
487 return HostToNetworkOrder(network);