/// <summary>Try to create a deep clone of an Array or a standard clone of a scalar. /// The object may comprise arrays of any primitive type or any Object type which /// implements Cloneable. However, if the Object is some kind of collection, /// e.g., a Vector then only a shallow copy of that object is made. I.e., deep /// refers only to arrays. /// </summary> /// <param name="o">The object to be copied.</param> /*TODO: If multidimension array is passed as an input, it is getting flattened out * TODO: For normal multidimension, we get an error because NewInstance always returns Jagged array.*/ public static System.Object DeepClone(System.Object o) { if (o == null) { return(null); } if (!o.GetType().IsArray) { return(GenericClone(o)); } Array a = (Array)o; if (ArrayFuncs.IsArrayOfArrays(o)) { Array result = NewInstance(o.GetType().GetElementType(), a.Length); for (int i = 0; i < result.Length; ++i) { result.SetValue(DeepClone(a.GetValue(i)), i); } return(result); } else { int[] lengths = new int[a.Rank]; for (int i = 0; i < lengths.Length; ++i) { lengths[i] = a.GetLength(i); } Array result = ArrayFuncs.NewInstance(o.GetType().GetElementType(), lengths); Array.Copy(a, result, a.Length); return(result); } return(null); }
/// <summary>This routine provides efficient writing of arrays of any primitive type. /// The String class is also handled but it is an error to invoke this /// method with an object that is not an array of these types. If the /// array is multidimensional, then it calls itself recursively to write /// the entire array. Strings are written using the standard /// 1 byte format (i.e., as in writeBytes). /// * /// If the array is an array of objects, then writePrimitiveArray will /// be called for each element of the array. /// * /// </summary> /// <param name="o"> The object to be written. It must be an array of a primitive /// type, Object, or String.</param> public override void WriteArray(Object o) { if (!o.GetType().IsArray) { throw new IOException("Invalid object passed to BufferedDataStream.Write" + o.GetType().FullName); } Type type = o.GetType(); int rank = ((Array)o).Rank; // Is this a multidimensional array? If so process recursively. if (ArrayFuncs.GetDimensions(o).Length > 1) //if(o.GetType().GetArrayRank() > 1 || (((Array)o).GetValue(0)).GetType().IsArray) { if (ArrayFuncs.IsArrayOfArrays(o)) { IEnumerator i = ((Array)o).GetEnumerator(); for (bool ok = i.MoveNext(); ok; ok = i.MoveNext()) { WriteArray(i.Current); } } else { throw new IOException("Rectangular array write not supported."); } } else { // This is a one-d array. Process it using our special functions. Type t = o.GetType().GetElementType(); if (typeof(bool).Equals(t)) { Write((bool[])o, 0, ((bool[])o).Length); } else if (typeof(byte).Equals(t)) { Write((byte[])o, 0, ((byte[])o).Length); } else if (typeof(sbyte).Equals(t)) { Write((sbyte[])o, 0, ((sbyte[])o).Length); } else if (typeof(char).Equals(t)) { Write((char[])o, 0, ((char[])o).Length); } else if (typeof(short).Equals(t)) { Write((short[])o, 0, ((short[])o).Length); } else if (typeof(int).Equals(t)) { Write((int[])o, 0, ((int[])o).Length); } else if (typeof(long).Equals(t)) { Write((long[])o, 0, ((long[])o).Length); } else if (typeof(float).Equals(t)) { Write((float[])o, 0, ((float[])o).Length); } else if (typeof(double).Equals(t)) { Write((double[])o, 0, ((double[])o).Length); } else if (typeof(String).Equals(t)) { Write((String[])o, 0, ((String[])o).Length); } else { throw new IOException("Invalid object passed to BufferedDataStream.WriteArray: " + o.GetType().FullName); } } }
/// <summary>Read recursively over a multi-dimensional array.</summary> /// <returns> The number of bytes read.</returns> protected int primitiveArrayRecurse(Object o) { if (o == null) { return(primitiveArrayCount); } if (!o.GetType().IsArray) { throw new IOException("Invalid object passed to BufferedDataStream.ReadArray:" + o.GetType().FullName); } // Is this a multidimensional array? If so process recursively. //if(o.GetType().GetArrayRank() > 1 || ((Array)o).GetValue(0).GetType().IsArray) if (ArrayFuncs.GetDimensions(o).Length > 1) { if (ArrayFuncs.IsArrayOfArrays(o)) { IEnumerator i = ((Array)o).GetEnumerator(); for (bool ok = i.MoveNext(); ok; ok = i.MoveNext()) { primitiveArrayRecurse(i.Current); } } else { throw new IOException("Rectangular array read not supported."); } } else { // This is a one-d array. Process it using our special functions. Type t = o.GetType().GetElementType(); if (typeof(bool).Equals(t)) { primitiveArrayCount += Read((bool[])o, 0, ((bool[])o).Length); } else if (typeof(byte).Equals(t)) { primitiveArrayCount += Read((byte[])o, 0, ((byte[])o).Length); } else if (typeof(sbyte).Equals(t)) { primitiveArrayCount += Read((sbyte[])o, 0, ((sbyte[])o).Length); } else if (typeof(char).Equals(t)) { primitiveArrayCount += Read((char[])o, 0, ((char[])o).Length); } else if (typeof(short).Equals(t)) { primitiveArrayCount += Read((short[])o, 0, ((short[])o).Length); } else if (typeof(int).Equals(t)) { primitiveArrayCount += Read((int[])o, 0, ((int[])o).Length); } else if (typeof(long).Equals(t)) { primitiveArrayCount += Read((long[])o, 0, ((long[])o).Length); } else if (typeof(float).Equals(t)) { primitiveArrayCount += Read((float[])o, 0, ((float[])o).Length); } else if (typeof(double).Equals(t)) { primitiveArrayCount += Read((double[])o, 0, ((double[])o).Length); } else { throw new IOException("Invalid object passed to BufferedDataStream.ReadArray: " + o.GetType().FullName); } } return(primitiveArrayCount); }