Skip to content

Commit 6538173

Browse files
committed
fix beforefieldinit flag on main class, create private impl on state-dependent types
1 parent 15e15b1 commit 6538173

File tree

1 file changed

+146
-115
lines changed
  • src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows

1 file changed

+146
-115
lines changed

src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/DataFormats.cs

Lines changed: 146 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -41,42 +41,12 @@ public static class DataFormats
4141
/// <summary>
4242
/// Gets the data format with the Windows Clipboard numeric ID and name for the specified ID.
4343
/// </summary>
44-
public static DataFormat GetDataFormat(int id) => InternalGetDataFormat(id);
44+
public static DataFormat GetDataFormat(int id) => DataFormatsImpl.GetDataFormat(id);
4545

4646
/// <summary>
4747
/// Gets the data format with the Windows Clipboard numeric ID and name for the specified data format.
4848
/// </summary>
49-
public static DataFormat GetDataFormat(string format)
50-
{
51-
ArgumentNullException.ThrowIfNull(format);
52-
53-
if (format == string.Empty)
54-
throw new ArgumentException(SR.DataObject_EmptyFormatNotAllowed);
55-
56-
// Lock the data format list to obtain the mutual-exclusion.
57-
lock (_formatListlock)
58-
{
59-
for (int i = 0; i < _formatList.Count; i++)
60-
{
61-
DataFormat formatItem = _formatList[i];
62-
63-
if (formatItem.Name.Equals(format, StringComparison.OrdinalIgnoreCase))
64-
return formatItem;
65-
}
66-
67-
// Register this format string
68-
int formatId = UnsafeNativeMethods.RegisterClipboardFormat(format);
69-
70-
if (formatId == 0)
71-
throw new System.ComponentModel.Win32Exception();
72-
73-
// Create a new format and store it
74-
DataFormat newFormat = new(format, formatId);
75-
_formatList.Add(newFormat);
76-
77-
return newFormat;
78-
}
79-
}
49+
public static DataFormat GetDataFormat(string format) => DataFormatsImpl.GetDataFormat(format);
8050

8151
#endregion Public Methods
8252

@@ -286,113 +256,174 @@ public static DataFormat GetDataFormat(string format)
286256

287257
//------------------------------------------------------
288258
//
289-
// Private Methods
259+
// Data Formats Implementation
290260
//
291261
//------------------------------------------------------
292262

293-
#region Private Methods
263+
#region Data Formats Implementation Class
294264

295265
/// <summary>
296-
/// Allows a the new format name to be specified if the requested format is not
297-
/// in the list
266+
/// Static class containing the internal format list and associated lookup methods.
298267
/// </summary>
299-
private static DataFormat InternalGetDataFormat(int id)
268+
private static class DataFormatsImpl
300269
{
301-
// Lock the data format list to obtain the mutual-exclusion.
302-
lock (_formatListlock)
270+
//------------------------------------------------------
271+
//
272+
// Static constructor
273+
//
274+
//------------------------------------------------------
275+
276+
#region Static constructor
277+
278+
/// <summary>
279+
/// Ensures that the Win32 predefined formats are setup in our format list.
280+
/// This is called anytime we need to search the list.
281+
/// </summary>
282+
static DataFormatsImpl()
303283
{
304-
DataFormat formatItem;
305-
StringBuilder sb;
306-
307-
for (int i = 0; i < _formatList.Count; i++)
284+
// Create format list for the default formats.
285+
formatList = new List<DataFormat>(19)
308286
{
309-
formatItem = _formatList[i];
287+
new(DataFormats.UnicodeText, NativeMethods.CF_UNICODETEXT),
288+
new(DataFormats.Text, NativeMethods.CF_TEXT),
289+
new(DataFormats.Bitmap, NativeMethods.CF_BITMAP),
290+
new(DataFormats.MetafilePicture, NativeMethods.CF_METAFILEPICT),
291+
new(DataFormats.EnhancedMetafile, NativeMethods.CF_ENHMETAFILE),
292+
new(DataFormats.Dif, NativeMethods.CF_DIF),
293+
new(DataFormats.Tiff, NativeMethods.CF_TIFF),
294+
new(DataFormats.OemText, NativeMethods.CF_OEMTEXT),
295+
new(DataFormats.Dib, NativeMethods.CF_DIB),
296+
new(DataFormats.Palette, NativeMethods.CF_PALETTE),
297+
new(DataFormats.PenData, NativeMethods.CF_PENDATA),
298+
new(DataFormats.Riff, NativeMethods.CF_RIFF),
299+
new(DataFormats.WaveAudio, NativeMethods.CF_WAVE),
300+
new(DataFormats.SymbolicLink, NativeMethods.CF_SYLK),
301+
new(DataFormats.FileDrop, NativeMethods.CF_HDROP),
302+
new(DataFormats.Locale, NativeMethods.CF_LOCALE)
303+
};
304+
305+
int xamlFormatId = UnsafeNativeMethods.RegisterClipboardFormat(DataFormats.Xaml);
306+
if (xamlFormatId != 0)
307+
formatList.Add(new(DataFormats.Xaml, xamlFormatId));
308+
309+
// This is the format to store trust boundary information. Essentially this is accompalished by storing
310+
// the permission set of the source application where the content comes from. During paste we compare this to
311+
// the permission set of the target application.
312+
int applicationTrustFormatId = UnsafeNativeMethods.RegisterClipboardFormat(DataFormats.ApplicationTrust);
313+
if (applicationTrustFormatId != 0)
314+
formatList.Add(new(DataFormats.ApplicationTrust, applicationTrustFormatId));
315+
316+
// RegisterClipboardFormat returns 0 on failure
317+
int inkServicesFrameworkFormatId = UnsafeNativeMethods.RegisterClipboardFormat(StrokeCollection.InkSerializedFormat);
318+
if (inkServicesFrameworkFormatId != 0)
319+
formatList.Add(new(StrokeCollection.InkSerializedFormat, inkServicesFrameworkFormatId));
320+
}
310321

311-
// OLE FORMATETC defined CLIPFORMAT as the unsigned short, so we should ignore
312-
// high 2bytes to find the matched CLIPFORMAT ID.
313-
if ((formatItem.Id & 0x0000ffff) == (id & 0x0000ffff))
314-
return formatItem;
315-
}
322+
#endregion Static Constructor
323+
324+
//------------------------------------------------------
325+
//
326+
// Private Methods
327+
//
328+
//------------------------------------------------------
316329

317-
sb = new StringBuilder(NativeMethods.MAX_PATH);
330+
#region Private Methods
318331

319-
// This can happen if windows adds a standard format that we don't know about,
320-
// so we should play it safe.
321-
if (UnsafeNativeMethods.GetClipboardFormatName(id, sb, sb.Capacity) == 0)
332+
/// <summary>
333+
/// Allows a new format name to be specified if the requested format is not in the list.
334+
/// </summary>
335+
public static DataFormat GetDataFormat(int id)
336+
{
337+
// Lock the data format list to obtain the mutual-exclusion.
338+
lock (_formatListlock)
322339
{
323-
sb.Length = 0; // Same as Clear()
324-
sb.Append("Format").Append(id);
340+
DataFormat formatItem;
341+
StringBuilder sb;
342+
343+
for (int i = 0; i < formatList.Count; i++)
344+
{
345+
formatItem = formatList[i];
346+
347+
// OLE FORMATETC defined CLIPFORMAT as the unsigned short, so we should ignore
348+
// high 2bytes to find the matched CLIPFORMAT ID.
349+
if ((formatItem.Id & 0x0000ffff) == (id & 0x0000ffff))
350+
return formatItem;
351+
}
352+
353+
sb = new StringBuilder(NativeMethods.MAX_PATH);
354+
355+
// This can happen if windows adds a standard format that we don't know about,
356+
// so we should play it safe.
357+
if (UnsafeNativeMethods.GetClipboardFormatName(id, sb, sb.Capacity) == 0)
358+
{
359+
sb.Length = 0; // Same as Clear()
360+
sb.Append("Format").Append(id);
361+
}
362+
363+
// Create a new format and store it
364+
formatItem = new(sb.ToString(), id);
365+
formatList.Add(formatItem);
366+
367+
return formatItem;
325368
}
369+
}
370+
371+
/// <summary>
372+
/// Retrieves a data format using its name or attempts to register a new one if it doesn't exist.
373+
/// </summary>
374+
public static DataFormat GetDataFormat(string format)
375+
{
376+
ArgumentNullException.ThrowIfNull(format);
377+
378+
if (format == string.Empty)
379+
throw new ArgumentException(SR.DataObject_EmptyFormatNotAllowed);
380+
381+
// Lock the data format list to obtain the mutual-exclusion.
382+
lock (_formatListlock)
383+
{
384+
for (int i = 0; i < formatList.Count; i++)
385+
{
386+
DataFormat formatItem = formatList[i];
387+
388+
if (formatItem.Name.Equals(format, StringComparison.OrdinalIgnoreCase))
389+
return formatItem;
390+
}
326391

327-
// Create a new format and store it
328-
formatItem = new(sb.ToString(), id);
329-
_formatList.Add(formatItem);
392+
// Register this format string
393+
int formatId = UnsafeNativeMethods.RegisterClipboardFormat(format);
330394

331-
return formatItem;
395+
if (formatId == 0)
396+
throw new System.ComponentModel.Win32Exception();
397+
398+
// Create a new format and store it
399+
DataFormat newFormat = new(format, formatId);
400+
formatList.Add(newFormat);
401+
402+
return newFormat;
403+
}
332404
}
333-
}
334405

335-
/// <summary>
336-
/// Ensures that the Win32 predefined formats are setup in our format list. This
337-
/// is called anytime we need to search the list
338-
/// </summary>
339-
static DataFormats()
340-
{
341-
// Create format list for the default formats.
342-
_formatList = new List<DataFormat>(19)
343-
{
344-
new(DataFormats.UnicodeText, NativeMethods.CF_UNICODETEXT),
345-
new(DataFormats.Text, NativeMethods.CF_TEXT),
346-
new(DataFormats.Bitmap, NativeMethods.CF_BITMAP),
347-
new(DataFormats.MetafilePicture, NativeMethods.CF_METAFILEPICT),
348-
new(DataFormats.EnhancedMetafile, NativeMethods.CF_ENHMETAFILE),
349-
new(DataFormats.Dif, NativeMethods.CF_DIF),
350-
new(DataFormats.Tiff, NativeMethods.CF_TIFF),
351-
new(DataFormats.OemText, NativeMethods.CF_OEMTEXT),
352-
new(DataFormats.Dib, NativeMethods.CF_DIB),
353-
new(DataFormats.Palette, NativeMethods.CF_PALETTE),
354-
new(DataFormats.PenData, NativeMethods.CF_PENDATA),
355-
new(DataFormats.Riff, NativeMethods.CF_RIFF),
356-
new(DataFormats.WaveAudio, NativeMethods.CF_WAVE),
357-
new(DataFormats.SymbolicLink, NativeMethods.CF_SYLK),
358-
new(DataFormats.FileDrop, NativeMethods.CF_HDROP),
359-
new(DataFormats.Locale, NativeMethods.CF_LOCALE)
360-
};
361-
362-
int xamlFormatId = UnsafeNativeMethods.RegisterClipboardFormat(DataFormats.Xaml);
363-
if (xamlFormatId != 0)
364-
_formatList.Add(new(DataFormats.Xaml, xamlFormatId));
365-
366-
// This is the format to store trust boundary information. Essentially this is accompalished by storing
367-
// the permission set of the source application where the content comes from. During paste we compare this to
368-
// the permission set of the target application.
369-
int applicationTrustFormatId = UnsafeNativeMethods.RegisterClipboardFormat(DataFormats.ApplicationTrust);
370-
if (applicationTrustFormatId != 0)
371-
_formatList.Add(new(DataFormats.ApplicationTrust, applicationTrustFormatId));
372-
373-
// RegisterClipboardFormat returns 0 on failure
374-
int inkServicesFrameworkFormatId = UnsafeNativeMethods.RegisterClipboardFormat(StrokeCollection.InkSerializedFormat);
375-
if (inkServicesFrameworkFormatId != 0)
376-
_formatList.Add(new(StrokeCollection.InkSerializedFormat, inkServicesFrameworkFormatId));
377-
}
406+
#endregion Private Methods
378407

379-
#endregion Private Methods
408+
//------------------------------------------------------
409+
//
410+
// Private Fields
411+
//
412+
//------------------------------------------------------
380413

381-
//------------------------------------------------------
382-
//
383-
// Private Fields
384-
//
385-
//------------------------------------------------------
414+
#region Private Fields
386415

387-
#region Private Fields
416+
// The registered data format list.
417+
private static readonly List<DataFormat> formatList;
418+
// This object is for locking the _formatList to access safe in the multi-thread.
419+
private static readonly object _formatListlock = new();
388420

389-
// The registered data format list.
390-
private static readonly List<DataFormat> _formatList;
421+
#endregion Private Fields
422+
423+
}
391424

392-
// This object is for locking the _formatList to access safe in the multi-thread.
393-
private static readonly object _formatListlock = new();
425+
#endregion Data Formats Implementation Class
394426

395-
#endregion Private Fields
396427
}
397428

398429
#endregion DataFormats class

0 commit comments

Comments
 (0)