Ignore:
Timestamp:
6/18/2010 6:53:20 AM (2 years ago)
Author:
lowjoel
Message:

Refactor a function which parses null-delimited string arrays.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser/Eraser.Util/NativeMethods/Kernel.cs

    r2178 r2179  
    599599                //Do we have enough space for all the text 
    600600                if (written != 0) 
    601                     break; 
     601                    return ParseNullDelimitedArray(buffer, (int)written); 
    602602                else if (Marshal.GetLastWin32Error() == Win32ErrorCode.InsufficientBuffer) 
    603603                    continue; 
     
    605605                    throw Win32ErrorCode.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); 
    606606            } 
    607  
    608             List<string> result = new List<string>(); 
    609             for (int lastIndex = 0, i = 0; i != buffer.Length; ++i) 
    610             { 
    611                 if (buffer[i] == '\0') 
    612                 { 
    613                     //If there are no mount points for this volume, the string will only 
    614                     //have one NULL 
    615                     if (i - lastIndex == 0) 
    616                         break; 
    617  
    618                     //Resolve the DOS name to the device name 
    619                     result.Add(new string(buffer, lastIndex, i - lastIndex)); 
    620  
    621                     lastIndex = i + 1; 
    622                     if (buffer[lastIndex] == '\0') 
    623                         break; 
    624                 } 
    625             } 
    626  
    627             return result.ToArray(); 
    628607        } 
    629608 
     
    11671146        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    11681147        [return: MarshalAs(UnmanagedType.Bool)] 
    1169         public static extern bool GetVolumePathNamesForVolumeName(string lpszVolumeName, 
     1148        private static extern bool GetVolumePathNamesForVolumeName(string lpszVolumeName, 
    11701149            [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] char[] lpszVolumePathNames, 
    11711150            uint cchBufferLength, out uint lpcchReturnLength); 
     1151 
     1152        /// <summary> 
     1153        /// Retrieves a list of path names for the specified volume name. 
     1154        /// </summary> 
     1155        /// <param name="lpszVolumeName">The volume name.</param> 
     1156        public static string[] GetVolumePathNamesForVolumeName(string lpszVolumeName) 
     1157        { 
     1158            uint returnLength = 0; 
     1159            char[] pathNamesBuffer = new char[NativeMethods.MaxPath]; 
     1160            while (!NativeMethods.GetVolumePathNamesForVolumeName(lpszVolumeName, 
     1161                pathNamesBuffer, (uint)pathNamesBuffer.Length, out returnLength)) 
     1162            { 
     1163                int errorCode = Marshal.GetLastWin32Error(); 
     1164                switch (errorCode) 
     1165                { 
     1166                    case Win32ErrorCode.NotReady: 
     1167                        //The drive isn't ready yet: just return an empty list. 
     1168                        return new string[0]; 
     1169                    case Win32ErrorCode.MoreData: 
     1170                        pathNamesBuffer = new char[pathNamesBuffer.Length * 2]; 
     1171                        break; 
     1172                    default: 
     1173                        throw Win32ErrorCode.GetExceptionForWin32Error(errorCode); 
     1174                } 
     1175            } 
     1176 
     1177            return ParseNullDelimitedArray(pathNamesBuffer, (int)returnLength); 
     1178        } 
    11721179 
    11731180        public const int MaxPath = 260; 
     
    12441251        [DllImport("Kernel32.dll", SetLastError = true)] 
    12451252        public static extern IntPtr LocalFree(IntPtr hMem); 
     1253 
     1254        /// <summary> 
     1255        /// Parses a null-delimited array into a string array. 
     1256        /// </summary> 
     1257        /// <param name="buffer">The buffer to parse.</param> 
     1258        /// <param name="length">The valid length of the array.</param> 
     1259        /// <returns>The array found in the buffer</returns> 
     1260        private static string[] ParseNullDelimitedArray(char[] buffer, int length) 
     1261        { 
     1262            List<string> result = new List<string>(); 
     1263            for (int lastIndex = 0, i = 0; i != length; ++i) 
     1264            { 
     1265                if (buffer[i] == '\0') 
     1266                { 
     1267                    //If the string formed is empty, there are no elements left. 
     1268                    if (i - lastIndex == 0) 
     1269                        break; 
     1270 
     1271                    result.Add(new string(buffer, lastIndex, i - lastIndex)); 
     1272 
     1273                    lastIndex = i + 1; 
     1274                    if (buffer[lastIndex] == '\0') 
     1275                        break; 
     1276                } 
     1277            } 
     1278 
     1279            return result.ToArray(); 
     1280        } 
    12461281    } 
    12471282} 
Note: See TracChangeset for help on using the changeset viewer.