1 // Copyright (c) Microsoft. All rights reserved.
2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 
4 using System;
5 using System.IO;
6 using System.Diagnostics;
7 using System.Globalization;
8 using System.Runtime.CompilerServices;
9 using System.Threading;
10 
11 #if BUILDINGAPPXTASKS
12 namespace Microsoft.Build.AppxPackage.Shared
13 #else
14 namespace Microsoft.Build.Shared
15 #endif
16 {
17     /// <summary>
18     /// This class contains methods that are useful for error checking and validation.
19     /// </summary>
20     internal static class ErrorUtilities
21     {
22         /// <summary>
23         /// Emergency escape hatch. If a customer hits a bug in the shipped product causing an internal exception,
24         /// and fortuitously it happens that ignoring the VerifyThrow allows execution to continue in a reasonable way,
25         /// then we can give them this undocumented environment variable as an immediate workaround.
26         /// </summary>
27         private static readonly bool s_throwExceptions = String.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILDDONOTTHROWINTERNAL"));
28         private static readonly bool s_enableMSBuildDebugTracing = !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILDENABLEDEBUGTRACING"));
29 
30         #region DebugTracing
DebugTraceMessage(string category, string formatstring, params object[] parameters)31         public static void DebugTraceMessage(string category, string formatstring, params object[] parameters)
32         {
33             if (s_enableMSBuildDebugTracing)
34             {
35                 if (parameters != null)
36                 {
37                     Trace.WriteLine(String.Format(CultureInfo.CurrentCulture, formatstring, parameters), category);
38                 }
39                 else
40                 {
41                     Trace.WriteLine(formatstring, category);
42                 }
43             }
44         }
45         #endregion
46 
47 #if !BUILDINGAPPXTASKS
48         #region VerifyThrow -- for internal errors
49 
50         /// <summary>
51         /// Throws InternalErrorException.
52         /// This is only for situations that would mean that there is a bug in MSBuild itself.
53         /// </summary>
ThrowInternalError(string message, params object[] args)54         internal static void ThrowInternalError(string message, params object[] args)
55         {
56             if (s_throwExceptions)
57             {
58                 throw new InternalErrorException(ResourceUtilities.FormatString(message, args));
59             }
60         }
61 
62         /// <summary>
63         /// Throws InternalErrorException.
64         /// This is only for situations that would mean that there is a bug in MSBuild itself.
65         /// </summary>
ThrowInternalError(string message, Exception innerException, params object[] args)66         internal static void ThrowInternalError(string message, Exception innerException, params object[] args)
67         {
68             if (s_throwExceptions)
69             {
70                 throw new InternalErrorException(ResourceUtilities.FormatString(message, args), innerException);
71             }
72         }
73 
74         /// <summary>
75         /// Throws InternalErrorException.
76         /// Indicates the code path followed should not have been possible.
77         /// This is only for situations that would mean that there is a bug in MSBuild itself.
78         /// </summary>
ThrowInternalErrorUnreachable()79         internal static void ThrowInternalErrorUnreachable()
80         {
81             if (s_throwExceptions)
82             {
83                 throw new InternalErrorException("Unreachable?");
84             }
85         }
86 
87         /// <summary>
88         /// Throws InternalErrorException.
89         /// Indicates the code path followed should not have been possible.
90         /// This is only for situations that would mean that there is a bug in MSBuild itself.
91         /// </summary>
ThrowIfTypeDoesNotImplementToString(object param)92         internal static void ThrowIfTypeDoesNotImplementToString(object param)
93         {
94 #if DEBUG
95             // Check it has a real implementation of ToString()
96             if (String.Equals(param.GetType().ToString(), param.ToString(), StringComparison.Ordinal))
97             {
98                 ErrorUtilities.ThrowInternalError("This type does not implement ToString() properly {0}", param.GetType().FullName);
99             }
100 #endif
101         }
102 
103         /// <summary>
104         /// Helper to throw an InternalErrorException when the specified parameter is null.
105         /// This should be used ONLY if this would indicate a bug in MSBuild rather than
106         /// anything caused by user action.
107         /// </summary>
108         /// <param name="parameter">The value of the argument.</param>
109         /// <param name="parameterName">Parameter that should not be null</param>
VerifyThrowInternalNull(object parameter, string parameterName)110         internal static void VerifyThrowInternalNull(object parameter, string parameterName)
111         {
112             if (parameter == null)
113             {
114                 ThrowInternalError("{0} unexpectedly null", parameterName);
115             }
116         }
117 
118         /// <summary>
119         /// Helper to throw an InternalErrorException when a lock on the specified object is not already held.
120         /// This should be used ONLY if this would indicate a bug in MSBuild rather than
121         /// anything caused by user action.
122         /// </summary>
123         /// <param name="locker">The object that should already have been used as a lock.</param>
VerifyThrowInternalLockHeld(object locker)124         internal static void VerifyThrowInternalLockHeld(object locker)
125         {
126 #if !CLR2COMPATIBILITY
127             if (!Monitor.IsEntered(locker))
128             {
129                 ThrowInternalError("Lock should already have been taken");
130             }
131 #endif
132         }
133 
134         /// <summary>
135         /// Helper to throw an InternalErrorException when the specified parameter is null or zero length.
136         /// This should be used ONLY if this would indicate a bug in MSBuild rather than
137         /// anything caused by user action.
138         /// </summary>
139         /// <param name="parameterValue">The value of the argument.</param>
140         /// <param name="parameterName">Parameter that should not be null or zero length</param>
VerifyThrowInternalLength(string parameterValue, string parameterName)141         internal static void VerifyThrowInternalLength(string parameterValue, string parameterName)
142         {
143             VerifyThrowInternalNull(parameterValue, parameterName);
144 
145             if (parameterValue.Length == 0)
146             {
147                 ThrowInternalError("{0} unexpectedly empty", parameterName);
148             }
149         }
150 
151         /// <summary>
152         /// Helper to throw an InternalErrorException when the specified parameter is not a rooted path.
153         /// This should be used ONLY if this would indicate a bug in MSBuild rather than
154         /// anything caused by user action.
155         /// </summary>
156         /// <param name="value">Parameter that should be a rooted path</param>
VerifyThrowInternalRooted(string value)157         internal static void VerifyThrowInternalRooted(string value)
158         {
159             if (!Path.IsPathRooted(value))
160             {
161                 ThrowInternalError("{0} unexpectedly not a rooted path", value);
162             }
163         }
164 
165         /// <summary>
166         /// This method should be used in places where one would normally put
167         /// an "assert". It should be used to validate that our assumptions are
168         /// true, where false would indicate that there must be a bug in our
169         /// code somewhere. This should not be used to throw errors based on bad
170         /// user input or anything that the user did wrong.
171         /// </summary>
172         /// <param name="condition"></param>
173         /// <param name="unformattedMessage"></param>
VerifyThrow( bool condition, string unformattedMessage )174         internal static void VerifyThrow
175         (
176             bool condition,
177             string unformattedMessage
178         )
179         {
180             if (!condition)
181             {
182                 // PERF NOTE: explicitly passing null for the arguments array
183                 // prevents memory allocation
184                 ThrowInternalError(unformattedMessage, null, null);
185             }
186         }
187 
188         /// <summary>
189         /// Overload for one string format argument.
190         /// </summary>
191         /// <param name="condition"></param>
192         /// <param name="unformattedMessage"></param>
193         /// <param name="arg0"></param>
VerifyThrow( bool condition, string unformattedMessage, object arg0 )194         internal static void VerifyThrow
195         (
196             bool condition,
197             string unformattedMessage,
198             object arg0
199         )
200         {
201             // PERF NOTE: check the condition here instead of pushing it into
202             // the ThrowInternalError() method, because that method always
203             // allocates memory for its variable array of arguments
204             if (!condition)
205             {
206                 ThrowInternalError(unformattedMessage, arg0);
207             }
208         }
209 
210         /// <summary>
211         /// Overload for two string format arguments.
212         /// </summary>
213         /// <param name="condition"></param>
214         /// <param name="unformattedMessage"></param>
215         /// <param name="arg0"></param>
216         /// <param name="arg1"></param>
VerifyThrow( bool condition, string unformattedMessage, object arg0, object arg1 )217         internal static void VerifyThrow
218         (
219             bool condition,
220             string unformattedMessage,
221             object arg0,
222             object arg1
223         )
224         {
225             // PERF NOTE: check the condition here instead of pushing it into
226             // the ThrowInternalError() method, because that method always
227             // allocates memory for its variable array of arguments
228             if (!condition)
229             {
230                 ThrowInternalError(unformattedMessage, arg0, arg1);
231             }
232         }
233 
234         /// <summary>
235         /// Overload for three string format arguments.
236         /// </summary>
237         /// <param name="condition"></param>
238         /// <param name="unformattedMessage"></param>
239         /// <param name="arg0"></param>
240         /// <param name="arg1"></param>
241         /// <param name="arg2"></param>
VerifyThrow( bool condition, string unformattedMessage, object arg0, object arg1, object arg2 )242         internal static void VerifyThrow
243         (
244             bool condition,
245             string unformattedMessage,
246             object arg0,
247             object arg1,
248             object arg2
249         )
250         {
251             // PERF NOTE: check the condition here instead of pushing it into
252             // the ThrowInternalError() method, because that method always
253             // allocates memory for its variable array of arguments
254             if (!condition)
255             {
256                 ThrowInternalError(unformattedMessage, arg0, arg1, arg2);
257             }
258         }
259 
260         /// <summary>
261         /// Overload for four string format arguments.
262         /// </summary>
263         /// <param name="condition"></param>
264         /// <param name="unformattedMessage"></param>
265         /// <param name="arg0"></param>
266         /// <param name="arg1"></param>
267         /// <param name="arg2"></param>
268         /// <param name="arg3"></param>
VerifyThrow( bool condition, string unformattedMessage, object arg0, object arg1, object arg2, object arg3 )269         internal static void VerifyThrow
270         (
271             bool condition,
272             string unformattedMessage,
273             object arg0,
274             object arg1,
275             object arg2,
276             object arg3
277         )
278         {
279             // PERF NOTE: check the condition here instead of pushing it into
280             // the ThrowInternalError() method, because that method always
281             // allocates memory for its variable array of arguments
282             if (!condition)
283             {
284                 ThrowInternalError(unformattedMessage, arg0, arg1, arg2, arg3);
285             }
286         }
287 
288         #endregion
289 
290         #region VerifyThrowInvalidOperation
291 
292         /// <summary>
293         /// Throws an InvalidOperationException with the specified resource string
294         /// </summary>
295         /// <param name="resourceName">Resource to use in the exception</param>
296         /// <param name="args">Formatting args.</param>
ThrowInvalidOperation(string resourceName, params object[] args)297         internal static void ThrowInvalidOperation(string resourceName, params object[] args)
298         {
299 #if DEBUG
300             ResourceUtilities.VerifyResourceStringExists(resourceName);
301 #endif
302             if (s_throwExceptions)
303             {
304                 throw new InvalidOperationException(ResourceUtilities.FormatResourceString(resourceName, args));
305             }
306         }
307 
308         /// <summary>
309         /// Throws an InvalidOperationException if the given condition is false.
310         /// </summary>
311         /// <param name="condition"></param>
312         /// <param name="resourceName"></param>
VerifyThrowInvalidOperation( bool condition, string resourceName )313         internal static void VerifyThrowInvalidOperation
314         (
315             bool condition,
316             string resourceName
317         )
318         {
319             if (!condition)
320             {
321                 // PERF NOTE: explicitly passing null for the arguments array
322                 // prevents memory allocation
323                 ThrowInvalidOperation(resourceName, null);
324             }
325         }
326 
327         /// <summary>
328         /// Overload for one string format argument.
329         /// </summary>
330         /// <param name="condition"></param>
331         /// <param name="resourceName"></param>
332         /// <param name="arg0"></param>
VerifyThrowInvalidOperation( bool condition, string resourceName, object arg0 )333         internal static void VerifyThrowInvalidOperation
334         (
335             bool condition,
336             string resourceName,
337             object arg0
338         )
339         {
340             // PERF NOTE: check the condition here instead of pushing it into
341             // the ThrowInvalidOperation() method, because that method always
342             // allocates memory for its variable array of arguments
343             if (!condition)
344             {
345                 ThrowInvalidOperation(resourceName, arg0);
346             }
347         }
348 
349         /// <summary>
350         /// Overload for two string format arguments.
351         /// </summary>
352         /// <param name="condition"></param>
353         /// <param name="resourceName"></param>
354         /// <param name="arg0"></param>
355         /// <param name="arg1"></param>
VerifyThrowInvalidOperation( bool condition, string resourceName, object arg0, object arg1 )356         internal static void VerifyThrowInvalidOperation
357         (
358             bool condition,
359             string resourceName,
360             object arg0,
361             object arg1
362         )
363         {
364             // PERF NOTE: check the condition here instead of pushing it into
365             // the ThrowInvalidOperation() method, because that method always
366             // allocates memory for its variable array of arguments
367             if (!condition)
368             {
369                 ThrowInvalidOperation(resourceName, arg0, arg1);
370             }
371         }
372 
373         /// <summary>
374         /// Overload for three string format arguments.
375         /// </summary>
376         /// <param name="condition"></param>
377         /// <param name="resourceName"></param>
378         /// <param name="arg0"></param>
379         /// <param name="arg1"></param>
380         /// <param name="arg2"></param>
VerifyThrowInvalidOperation( bool condition, string resourceName, object arg0, object arg1, object arg2 )381         internal static void VerifyThrowInvalidOperation
382         (
383             bool condition,
384             string resourceName,
385             object arg0,
386             object arg1,
387             object arg2
388         )
389         {
390             // PERF NOTE: check the condition here instead of pushing it into
391             // the ThrowInvalidOperation() method, because that method always
392             // allocates memory for its variable array of arguments
393             if (!condition)
394             {
395                 ThrowInvalidOperation(resourceName, arg0, arg1, arg2);
396             }
397         }
398 
399         /// <summary>
400         /// Overload for four string format arguments.
401         /// </summary>
402         /// <param name="condition"></param>
403         /// <param name="resourceName"></param>
404         /// <param name="arg0"></param>
405         /// <param name="arg1"></param>
406         /// <param name="arg2"></param>
407         /// <param name="arg3"></param>
VerifyThrowInvalidOperation( bool condition, string resourceName, object arg0, object arg1, object arg2, object arg3 )408         internal static void VerifyThrowInvalidOperation
409         (
410             bool condition,
411             string resourceName,
412             object arg0,
413             object arg1,
414             object arg2,
415             object arg3
416         )
417         {
418             // PERF NOTE: check the condition here instead of pushing it into
419             // the ThrowInvalidOperation() method, because that method always
420             // allocates memory for its variable array of arguments
421             if (!condition)
422             {
423                 ThrowInvalidOperation(resourceName, arg0, arg1, arg2, arg3);
424             }
425         }
426 
427         #endregion
428 
429         #region VerifyThrowArgument
430 
431         /// <summary>
432         /// Throws an ArgumentException that can include an inner exception.
433         ///
434         /// PERF WARNING: calling a method that takes a variable number of arguments
435         /// is expensive, because memory is allocated for the array of arguments -- do
436         /// not call this method repeatedly in performance-critical scenarios
437         /// </summary>
ThrowArgument( string resourceName, params object[] args )438         internal static void ThrowArgument
439         (
440             string resourceName,
441             params object[] args
442         )
443         {
444             ThrowArgument(null, resourceName, args);
445         }
446 
447         /// <summary>
448         /// Throws an ArgumentException that can include an inner exception.
449         ///
450         /// PERF WARNING: calling a method that takes a variable number of arguments
451         /// is expensive, because memory is allocated for the array of arguments -- do
452         /// not call this method repeatedly in performance-critical scenarios
453         /// </summary>
454         /// <remarks>
455         /// This method is thread-safe.
456         /// </remarks>
457         /// <param name="innerException">Can be null.</param>
458         /// <param name="resourceName"></param>
459         /// <param name="args"></param>
ThrowArgument( Exception innerException, string resourceName, params object[] args )460         private static void ThrowArgument
461         (
462             Exception innerException,
463             string resourceName,
464             params object[] args
465         )
466         {
467 #if DEBUG
468             ResourceUtilities.VerifyResourceStringExists(resourceName);
469 #endif
470             if (s_throwExceptions)
471             {
472                 throw new ArgumentException(ResourceUtilities.FormatResourceString(resourceName, args), innerException);
473             }
474         }
475 
476         /// <summary>
477         /// Throws an ArgumentException if the given condition is false.
478         /// </summary>
479         /// <remarks>This method is thread-safe.</remarks>
480         /// <param name="condition"></param>
481         /// <param name="resourceName"></param>
VerifyThrowArgument( bool condition, string resourceName )482         internal static void VerifyThrowArgument
483         (
484             bool condition,
485             string resourceName
486         )
487         {
488             VerifyThrowArgument(condition, null, resourceName);
489         }
490 
491         /// <summary>
492         /// Overload for one string format argument.
493         /// </summary>
494         /// <remarks>This method is thread-safe.</remarks>
495         /// <param name="condition"></param>
496         /// <param name="resourceName"></param>
497         /// <param name="arg0"></param>
VerifyThrowArgument( bool condition, string resourceName, object arg0 )498         internal static void VerifyThrowArgument
499         (
500             bool condition,
501             string resourceName,
502             object arg0
503         )
504         {
505             VerifyThrowArgument(condition, null, resourceName, arg0);
506         }
507 
508         /// <summary>
509         /// Overload for two string format arguments.
510         /// </summary>
511         /// <remarks>This method is thread-safe.</remarks>
512         /// <param name="condition"></param>
513         /// <param name="resourceName"></param>
514         /// <param name="arg0"></param>
515         /// <param name="arg1"></param>
VerifyThrowArgument( bool condition, string resourceName, object arg0, object arg1 )516         internal static void VerifyThrowArgument
517         (
518             bool condition,
519             string resourceName,
520             object arg0,
521             object arg1
522         )
523         {
524             VerifyThrowArgument(condition, null, resourceName, arg0, arg1);
525         }
526 
527         /// <summary>
528         /// Overload for three string format arguments.
529         /// </summary>
530         /// <remarks>This method is thread-safe.</remarks>
VerifyThrowArgument( bool condition, string resourceName, object arg0, object arg1, object arg2 )531         internal static void VerifyThrowArgument
532         (
533             bool condition,
534             string resourceName,
535             object arg0,
536             object arg1,
537             object arg2
538         )
539         {
540             VerifyThrowArgument(condition, null, resourceName, arg0, arg1, arg2);
541         }
542 
543         /// <summary>
544         /// Overload for four string format arguments.
545         /// </summary>
546         /// <remarks>This method is thread-safe.</remarks>
VerifyThrowArgument( bool condition, string resourceName, object arg0, object arg1, object arg2, object arg3 )547         internal static void VerifyThrowArgument
548         (
549             bool condition,
550             string resourceName,
551             object arg0,
552             object arg1,
553             object arg2,
554             object arg3
555         )
556         {
557             VerifyThrowArgument(condition, null, resourceName, arg0, arg1, arg2, arg3);
558         }
559 
560         /// <summary>
561         /// Throws an ArgumentException that includes an inner exception, if
562         /// the given condition is false.
563         /// </summary>
564         /// <remarks>This method is thread-safe.</remarks>
565         /// <param name="condition"></param>
566         /// <param name="innerException">Can be null.</param>
567         /// <param name="resourceName"></param>
VerifyThrowArgument( bool condition, Exception innerException, string resourceName )568         internal static void VerifyThrowArgument
569         (
570             bool condition,
571             Exception innerException,
572             string resourceName
573         )
574         {
575             if (!condition)
576             {
577                 // PERF NOTE: explicitly passing null for the arguments array
578                 // prevents memory allocation
579                 ThrowArgument(innerException, resourceName, null);
580             }
581         }
582 
583         /// <summary>
584         /// Overload for one string format argument.
585         /// </summary>
586         /// <remarks>This method is thread-safe.</remarks>
587         /// <param name="condition"></param>
588         /// <param name="innerException"></param>
589         /// <param name="resourceName"></param>
590         /// <param name="arg0"></param>
VerifyThrowArgument( bool condition, Exception innerException, string resourceName, object arg0 )591         internal static void VerifyThrowArgument
592         (
593             bool condition,
594             Exception innerException,
595             string resourceName,
596             object arg0
597         )
598         {
599             // PERF NOTE: check the condition here instead of pushing it into
600             // the ThrowArgument() method, because that method always allocates
601             // memory for its variable array of arguments
602             if (!condition)
603             {
604                 ThrowArgument(innerException, resourceName, arg0);
605             }
606         }
607 
608         /// <summary>
609         /// Overload for two string format arguments.
610         /// </summary>
611         /// <remarks>This method is thread-safe.</remarks>
612         /// <param name="condition"></param>
613         /// <param name="innerException"></param>
614         /// <param name="resourceName"></param>
615         /// <param name="arg0"></param>
616         /// <param name="arg1"></param>
VerifyThrowArgument( bool condition, Exception innerException, string resourceName, object arg0, object arg1 )617         internal static void VerifyThrowArgument
618         (
619             bool condition,
620             Exception innerException,
621             string resourceName,
622             object arg0,
623             object arg1
624         )
625         {
626             // PERF NOTE: check the condition here instead of pushing it into
627             // the ThrowArgument() method, because that method always allocates
628             // memory for its variable array of arguments
629             if (!condition)
630             {
631                 ThrowArgument(innerException, resourceName, arg0, arg1);
632             }
633         }
634 
635         /// <summary>
636         /// Overload for three string format arguments.
637         /// </summary>
638         /// <remarks>This method is thread-safe.</remarks>
VerifyThrowArgument( bool condition, Exception innerException, string resourceName, object arg0, object arg1, object arg2 )639         internal static void VerifyThrowArgument
640         (
641             bool condition,
642             Exception innerException,
643             string resourceName,
644             object arg0,
645             object arg1,
646             object arg2
647         )
648         {
649             // PERF NOTE: check the condition here instead of pushing it into
650             // the ThrowArgument() method, because that method always allocates
651             // memory for its variable array of arguments
652             if (!condition)
653             {
654                 ThrowArgument(innerException, resourceName, arg0, arg1, arg2);
655             }
656         }
657 
658         /// <summary>
659         /// Overload for four string format arguments.
660         /// </summary>
661         /// <remarks>This method is thread-safe.</remarks>
VerifyThrowArgument( bool condition, Exception innerException, string resourceName, object arg0, object arg1, object arg2, object arg3 )662         internal static void VerifyThrowArgument
663         (
664             bool condition,
665             Exception innerException,
666             string resourceName,
667             object arg0,
668             object arg1,
669             object arg2,
670             object arg3
671         )
672         {
673             // PERF NOTE: check the condition here instead of pushing it into
674             // the ThrowArgument() method, because that method always allocates
675             // memory for its variable array of arguments
676             if (!condition)
677             {
678                 ThrowArgument(innerException, resourceName, arg0, arg1, arg2, arg3);
679             }
680         }
681 
682         #endregion
683 
684         #region VerifyThrowArgumentXXX
685 
686         /// <summary>
687         /// Throws an argument out of range exception.
688         /// </summary>
ThrowArgumentOutOfRange(string parameterName)689         internal static void ThrowArgumentOutOfRange(string parameterName)
690         {
691             if (s_throwExceptions)
692             {
693                 throw new ArgumentOutOfRangeException(parameterName);
694             }
695         }
696 
697         /// <summary>
698         /// Throws an ArgumentOutOfRangeException using the given parameter name
699         /// if the condition is false.
700         /// </summary>
VerifyThrowArgumentOutOfRange(bool condition, string parameterName)701         internal static void VerifyThrowArgumentOutOfRange(bool condition, string parameterName)
702         {
703             if (!condition)
704             {
705                 ThrowArgumentOutOfRange(parameterName);
706             }
707         }
708 
709         /// <summary>
710         /// Throws an ArgumentNullException if the given string parameter is null
711         /// and ArgumentException if it has zero length.
712         /// </summary>
713         /// <param name="parameter"></param>
714         /// <param name="parameterName"></param>
VerifyThrowArgumentLength(string parameter, string parameterName)715         internal static void VerifyThrowArgumentLength(string parameter, string parameterName)
716         {
717             VerifyThrowArgumentNull(parameter, parameterName);
718 
719             if (parameter.Length == 0 && s_throwExceptions)
720             {
721                 throw new ArgumentException(ResourceUtilities.FormatResourceString("Shared.ParameterCannotHaveZeroLength", parameterName));
722             }
723         }
724 
725         /// <summary>
726         /// Throws an ArgumentNullException if the given string parameter is null
727         /// and ArgumentException if it has zero length.
728         /// </summary>
729         /// <param name="parameter"></param>
730         /// <param name="parameterName"></param>
VerifyThrowArgumentInvalidPath(string parameter, string parameterName)731         internal static void VerifyThrowArgumentInvalidPath(string parameter, string parameterName)
732         {
733             VerifyThrowArgumentNull(parameter, parameterName);
734 
735             if (FileUtilities.PathIsInvalid(parameter) && s_throwExceptions)
736             {
737                 throw new ArgumentException(ResourceUtilities.FormatResourceString("Shared.ParameterCannotHaveInvalidPathChars", parameterName, parameter));
738             }
739         }
740 
741         /// <summary>
742         /// Throws an ArgumentException if the string has zero length, unless it is
743         /// null, in which case no exception is thrown.
744         /// </summary>
VerifyThrowArgumentLengthIfNotNull(string parameter, string parameterName)745         internal static void VerifyThrowArgumentLengthIfNotNull(string parameter, string parameterName)
746         {
747             if (parameter != null && parameter.Length == 0 && s_throwExceptions)
748             {
749                 throw new ArgumentException(ResourceUtilities.FormatResourceString("Shared.ParameterCannotHaveZeroLength", parameterName));
750             }
751         }
752 
753         /// <summary>
754         /// Throws an ArgumentNullException if the given parameter is null.
755         /// </summary>
756         /// <remarks>This method is thread-safe.</remarks>
757         /// <param name="parameter"></param>
758         /// <param name="parameterName"></param>
VerifyThrowArgumentNull(object parameter, string parameterName)759         internal static void VerifyThrowArgumentNull(object parameter, string parameterName)
760         {
761             VerifyThrowArgumentNull(parameter, parameterName, "Shared.ParameterCannotBeNull");
762         }
763 
764         /// <summary>
765         /// Throws an ArgumentNullException if the given parameter is null.
766         /// </summary>
767         /// <remarks>This method is thread-safe.</remarks>
VerifyThrowArgumentNull(object parameter, string parameterName, string resourceName)768         internal static void VerifyThrowArgumentNull(object parameter, string parameterName, string resourceName)
769         {
770             if (parameter == null && s_throwExceptions)
771             {
772                 // Most ArgumentNullException overloads append its own rather clunky multi-line message.
773                 // So use the one overload that doesn't.
774                 throw new ArgumentNullException(
775                     ResourceUtilities.FormatResourceString(resourceName, parameterName),
776                     (Exception)null);
777             }
778         }
779 
780         /// <summary>
781         /// Verifies the given arrays are not null and have the same length
782         /// </summary>
783         /// <param name="parameter1"></param>
784         /// <param name="parameter2"></param>
785         /// <param name="parameter1Name"></param>
786         /// <param name="parameter2Name"></param>
VerifyThrowArgumentArraysSameLength(Array parameter1, Array parameter2, string parameter1Name, string parameter2Name)787         internal static void VerifyThrowArgumentArraysSameLength(Array parameter1, Array parameter2, string parameter1Name, string parameter2Name)
788         {
789             VerifyThrowArgumentNull(parameter1, parameter1Name);
790             VerifyThrowArgumentNull(parameter2, parameter2Name);
791 
792             if (parameter1.Length != parameter2.Length && s_throwExceptions)
793             {
794                 throw new ArgumentException(ResourceUtilities.FormatResourceString("Shared.ParametersMustHaveTheSameLength", parameter1Name, parameter2Name));
795             }
796         }
797 
798         #endregion
799 #endif
800     }
801 }
802