2005-08-02 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / corlib / System.Runtime.Serialization.Formatters.Binary / ObjectReader.cs
index 9e62e49f7169c2211a874f49dc2555d963a3f2e6..54f581618a2f757dbd880b12421b1e6eef34a0d1 100644 (file)
@@ -56,7 +56,9 @@ namespace System.Runtime.Serialization.Formatters.Binary
 \r
                object _lastObject = null;\r
                long _lastObjectID = 0;\r
-               long _rootObjectID = 0;\r
+               long _rootObjectID = 0;
+               byte[] arrayBuffer;
+               int ArrayBufferLength = 4096;\r
 \r
                class TypeMetadata\r
                {\r
@@ -368,12 +370,26 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                }\r
 \r
                                case TypeCode.Byte: {\r
-                                       val = reader.ReadBytes (length);\r
+                                       byte[] arr = new byte [length];\r
+                                       int pos = 0;\r
+                                       while (pos < length) {\r
+                                               int nr = reader.Read (arr, pos, length - pos);\r
+                                               if (nr == 0) break;\r
+                                               pos += nr;\r
+                                       }\r
+                                       val = arr;\r
                                        break;\r
                                }\r
 \r
                                case TypeCode.Char: {\r
-                                       val = reader.ReadChars (length);\r
+                                       char[] arr = new char [length];\r
+                                       int pos = 0;\r
+                                       while (pos < length) {\r
+                                               int nr = reader.Read (arr, pos, length - pos);\r
+                                               if (nr == 0) break;\r
+                                               pos += nr;\r
+                                       }\r
+                                       val = arr;\r
                                        break;\r
                                }\r
 \r
@@ -386,70 +402,97 @@ namespace System.Runtime.Serialization.Formatters.Binary
 \r
                                case TypeCode.Decimal: {\r
                                        Decimal[] arr = new Decimal [length];\r
-                                       for (int n = 0; n < length; n++) arr [n] = Decimal.Parse (reader.ReadString(), CultureInfo.InvariantCulture);\r
+                                       for (int n = 0; n < length; n++) arr [n] = reader.ReadDecimal();\r
                                        val = arr;\r
                                        break;\r
                                }\r
 \r
                                case TypeCode.Double: {\r
-                                       Double[] arr = new Double [length];\r
-                                       for (int n = 0; n < length; n++) arr [n] = reader.ReadDouble();\r
+                                       Double[] arr = new Double [length];
+                                       if (length > 2)\r
+                                               BlockRead (reader, arr, 8);
+                                       else\r
+                                               for (int n = 0; n < length; n++) arr [n] = reader.ReadDouble();\r
                                        val = arr;\r
                                        break;\r
                                }\r
 \r
                                case TypeCode.Int16: {\r
                                        short[] arr = new short [length];\r
-                                       for (int n = 0; n < length; n++) arr [n] = reader.ReadInt16();\r
+                                       if (length > 2)\r
+                                               BlockRead (reader, arr, 2);
+                                       else
+                                               for (int n = 0; n < length; n++) arr [n] = reader.ReadInt16();\r
                                        val = arr;\r
                                        break;\r
                                }\r
 \r
                                case TypeCode.Int32: {\r
                                        int[] arr = new int [length];\r
-                                       for (int n = 0; n < length; n++) arr [n] = reader.ReadInt32();\r
+                                       if (length > 2)\r
+                                               BlockRead (reader, arr, 4);
+                                       else
+                                               for (int n = 0; n < length; n++) arr [n] = reader.ReadInt32();\r
                                        val = arr;\r
                                        break;\r
                                }\r
 \r
                                case TypeCode.Int64: {\r
-                                       long[] arr = new long [length];\r
-                                       for (int n = 0; n < length; n++) arr [n] = reader.ReadInt64();\r
+                                       long[] arr = new long [length];
+                                       if (length > 2)\r
+                                               BlockRead (reader, arr, 8);
+                                       else\r
+                                               for (int n = 0; n < length; n++) arr [n] = reader.ReadInt64();\r
                                        val = arr;\r
                                        break;\r
                                }\r
 \r
                                case TypeCode.SByte: {\r
                                        sbyte[] arr = new sbyte [length];\r
-                                       for (int n = 0; n < length; n++) arr [n] = reader.ReadSByte();\r
+                                       if (length > 2)\r
+                                               BlockRead (reader, arr, 1);
+                                       else\r
+                                               for (int n = 0; n < length; n++) arr [n] = reader.ReadSByte();\r
                                        val = arr;\r
                                        break;\r
                                }\r
 \r
                                case TypeCode.Single: {\r
                                        float[] arr = new float [length];\r
-                                       for (int n = 0; n < length; n++) arr [n] = reader.ReadSingle();\r
+                                       if (length > 2)\r
+                                               BlockRead (reader, arr, 4);
+                                       else\r
+                                               for (int n = 0; n < length; n++) arr [n] = reader.ReadSingle();\r
                                        val = arr;\r
                                        break;\r
                                }\r
 \r
                                case TypeCode.UInt16: {\r
                                        ushort[] arr = new ushort [length];\r
-                                       for (int n = 0; n < length; n++) arr [n] = reader.ReadUInt16();\r
+                                       if (length > 2)\r
+                                               BlockRead (reader, arr, 2);
+                                       else\r
+                                               for (int n = 0; n < length; n++) arr [n] = reader.ReadUInt16();\r
                                        val = arr;\r
                                        break;\r
                                }\r
 \r
                                case TypeCode.UInt32: {\r
                                        uint[] arr = new uint [length];\r
-                                       for (int n = 0; n < length; n++) arr [n] = reader.ReadUInt32();\r
+                                       if (length > 2)\r
+                                               BlockRead (reader, arr, 4);
+                                       else\r
+                                               for (int n = 0; n < length; n++) arr [n] = reader.ReadUInt32();\r
                                        val = arr;\r
                                        break;\r
                                }\r
 \r
                                case TypeCode.UInt64: {\r
                                        ulong[] arr = new ulong [length];\r
-                                       for (int n = 0; n < length; n++) arr [n] = reader.ReadUInt64();\r
+                                       if (length > 2)\r
+                                               BlockRead (reader, arr, 8);
+                                       else\r
+                                               for (int n = 0; n < length; n++) arr [n] = reader.ReadUInt64();\r
                                        val = arr;\r
                                        break;\r
                                }\r
@@ -474,6 +517,33 @@ namespace System.Runtime.Serialization.Formatters.Binary
                        }                       \r
                }\r
 \r
+               private void BlockRead (BinaryReader reader, Array array, int dataSize)\r
+               {
+                       int totalSize = Buffer.ByteLength (array);
+                       
+                       if (arrayBuffer == null || (totalSize > arrayBuffer.Length && arrayBuffer.Length != ArrayBufferLength))
+                               arrayBuffer = new byte [totalSize <= ArrayBufferLength ? totalSize : ArrayBufferLength];
+                       
+                       int pos = 0;
+                       while (totalSize > 0) {
+                               int size = totalSize < arrayBuffer.Length ? totalSize : arrayBuffer.Length;
+                               int ap = 0;
+                               do {
+                                       int nr = reader.Read (arrayBuffer, ap, size - ap);\r
+                                       if (nr == 0) break;\r
+                                       ap += nr;
+                               } while (ap < size);
+                               
+                               if (!BitConverter.IsLittleEndian && dataSize > 1)
+                                       BinaryCommon.SwapBytes (arrayBuffer, size, dataSize);
+
+                               Buffer.BlockCopy (arrayBuffer, 0, array, pos, size);
+                               totalSize -= size;
+                               pos += size;
+                       }
+               }
+               
+\r
                private void ReadArrayOfObject (BinaryReader reader, out long objectId, out object array)\r
                {\r
                        ReadSimpleArray (reader, typeof (object), out objectId, out array);\r