• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

xoofx / dotnet-releaser / 19395458028

15 Nov 2025 08:57PM UTC coverage: 56.195% (+29.7%) from 26.49%
19395458028

push

github

xoofx
Update CI to use .NET 10

843 of 1824 branches covered (46.22%)

Branch coverage included in aggregate %.

2477 of 4084 relevant lines covered (60.65%)

13800.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.48
/src/MsBuildPipeLogger.Logger/BinaryLogger/BuildEventArgsWriter.cs
1
using System;
2
using System.Collections;
3
using System.Collections.Generic;
4
using System.IO;
5
using System.Linq;
6
using Microsoft.Build.Framework;
7
using Microsoft.Build.Framework.Profiler;
8

9
namespace Microsoft.Build.Logging
10
{
11
    /// <summary>
12
    /// Serializes BuildEventArgs-derived objects into a provided BinaryWriter.
13
    /// </summary>
14
    internal class BuildEventArgsWriter
15
    {
16
        private readonly BinaryWriter _binaryWriter;
17

18
        /// <summary>
19
        /// Initializes a new instance of BuildEventArgsWriter with a BinaryWriter.
20
        /// </summary>
21
        /// <param name="binaryWriter">A BinaryWriter to write the BuildEventArgs instances to.</param>
22
        public BuildEventArgsWriter(BinaryWriter binaryWriter)
23
        {
24
            _binaryWriter = binaryWriter;
31✔
25
        }
31✔
26

27
        /// <summary>
28
        /// Write a provided instance of BuildEventArgs to the BinaryWriter.
29
        /// </summary>
30
        public void Write(BuildEventArgs e)
31
        {
32
            string type = e.GetType().Name;
63,773✔
33

34
            // the cases are ordered by most used first for performance
35
            if (e is BuildMessageEventArgs && type != "ProjectImportedEventArgs" && type != "TargetSkippedEventArgs")
63,773✔
36
            {
37
                Write((BuildMessageEventArgs)e);
40,675✔
38
            }
39
            else if (e is TaskStartedEventArgs taskStartedEventArgs)
23,098✔
40
            {
41
                Write(taskStartedEventArgs);
2,105✔
42
            }
43
            else if (e is TaskFinishedEventArgs taskFinishedEventArgs)
20,993✔
44
            {
45
                Write(taskFinishedEventArgs);
2,105✔
46
            }
47
            else if (e is TargetStartedEventArgs targetStartedEventArgs)
18,888✔
48
            {
49
                Write(targetStartedEventArgs);
2,934✔
50
            }
51
            else if (e is TargetFinishedEventArgs targetFinishedEventArgs)
15,954✔
52
            {
53
                Write(targetFinishedEventArgs);
2,934✔
54
            }
55
            else if (e is BuildErrorEventArgs buildErrorEventArgs)
13,020!
56
            {
57
                Write(buildErrorEventArgs);
×
58
            }
59
            else if (e is BuildWarningEventArgs buildWarningEventArgs)
13,020!
60
            {
61
                Write(buildWarningEventArgs);
×
62
            }
63
            else if (e is ProjectStartedEventArgs projectStartedEventArgs)
13,020✔
64
            {
65
                Write(projectStartedEventArgs);
107✔
66
            }
67
            else if (e is ProjectFinishedEventArgs projectFinishedEventArgs)
12,913✔
68
            {
69
                Write(projectFinishedEventArgs);
107✔
70
            }
71
            else if (e is BuildStartedEventArgs buildStartedEventArgs)
12,806✔
72
            {
73
                Write(buildStartedEventArgs);
31✔
74
            }
75
            else if (e is BuildFinishedEventArgs buildFinishedEventArgs)
12,775✔
76
            {
77
                Write(buildFinishedEventArgs);
31✔
78
            }
79
            else if (e is ProjectEvaluationStartedEventArgs projectEvaluationStartedEventArgs)
12,744!
80
            {
81
                Write(projectEvaluationStartedEventArgs);
×
82
            }
83
            else if (e is ProjectEvaluationFinishedEventArgs projectEvaluationFinishedEventArgs)
12,744!
84
            {
85
                Write(projectEvaluationFinishedEventArgs);
×
86
            }
87

88
            // The following cases are due to the fact that StructuredLogger.dll
89
            // only references MSBuild 14.0 .dlls. The following BuildEventArgs types
90
            // were only introduced in MSBuild 15.3 so we can't refer to them statically.
91
            // To still provide a good experience to those who are using the BinaryLogger
92
            // from StructuredLogger.dll against MSBuild 15.3 or later we need to preserve
93
            // these new events, so use reflection to create our "equivalents" of those
94
            // and populate them to be binary identical to the originals. Then serialize
95
            // our copies so that it's impossible to tell what wrote these.
96
            else if (type == "ProjectEvaluationStartedEventArgs")
12,744✔
97
            {
98
                ProjectEvaluationStartedEventArgs evaluationStarted = new ProjectEvaluationStartedEventArgs(e.Message)
49✔
99
                {
49✔
100
                    BuildEventContext = e.BuildEventContext,
49✔
101
                    ProjectFile = Reflector.GetProjectFileFromEvaluationStarted(e)
49✔
102
                };
49✔
103
                Write(evaluationStarted);
49✔
104
            }
105
            else if (type == "ProjectEvaluationFinishedEventArgs")
12,695✔
106
            {
107
                ProjectEvaluationFinishedEventArgs evaluationFinished = new ProjectEvaluationFinishedEventArgs(e.Message)
49✔
108
                {
49✔
109
                    BuildEventContext = e.BuildEventContext,
49✔
110
                    ProjectFile = Reflector.GetProjectFileFromEvaluationFinished(e)
49✔
111
                };
49✔
112
                Write(evaluationFinished);
49✔
113
            }
114
            else if (type == "ProjectImportedEventArgs")
12,646✔
115
            {
116
                BuildMessageEventArgs message = e as BuildMessageEventArgs;
9,290✔
117
                ProjectImportedEventArgs projectImported = new ProjectImportedEventArgs(message.LineNumber, message.ColumnNumber, e.Message)
9,290✔
118
                {
9,290✔
119
                    BuildEventContext = e.BuildEventContext,
9,290✔
120
                    ProjectFile = message.ProjectFile,
9,290✔
121
                    ImportedProjectFile = Reflector.GetImportedProjectFile(e),
9,290✔
122
                    UnexpandedProject = Reflector.GetUnexpandedProject(e)
9,290✔
123
                };
9,290✔
124
                Write(projectImported);
9,290✔
125
            }
126
            else if (type == "TargetSkippedEventArgs")
3,356✔
127
            {
128
                BuildMessageEventArgs message = e as BuildMessageEventArgs;
3,325✔
129
                TargetSkippedEventArgs targetSkipped = new TargetSkippedEventArgs(e.Message)
3,325✔
130
                {
3,325✔
131
                    BuildEventContext = e.BuildEventContext,
3,325✔
132
                    ProjectFile = message.ProjectFile,
3,325✔
133
                    TargetName = Reflector.GetTargetNameFromTargetSkipped(e),
3,325✔
134
                    TargetFile = Reflector.GetTargetFileFromTargetSkipped(e),
3,325✔
135
                    ParentTarget = Reflector.GetParentTargetFromTargetSkipped(e),
3,325✔
136
                    BuildReason = Reflector.GetBuildReasonFromTargetSkipped(e)
3,325✔
137
                };
3,325✔
138
                Write(targetSkipped);
3,325✔
139
            }
140
            else
141
            {
142
                // convert all unrecognized objects to message
143
                // and just preserve the message
144
                BuildMessageEventArgs buildMessageEventArgs = new BuildMessageEventArgs(
31!
145
                    e.Message,
31✔
146
                    e.HelpKeyword,
31✔
147
                    e.SenderName,
31✔
148
                    MessageImportance.Normal,
31✔
149
                    e.Timestamp)
31✔
150
                {
31✔
151
                    BuildEventContext = e.BuildEventContext ?? BuildEventContext.Invalid
31✔
152
                };
31✔
153
                Write(buildMessageEventArgs);
31✔
154
            }
155
        }
31✔
156

157
        public void WriteBlob(BinaryLogRecordKind kind, byte[] bytes)
158
        {
159
            Write(kind);
×
160
            Write(bytes.Length);
×
161
            Write(bytes);
×
162
        }
×
163

164
        private void Write(BuildStartedEventArgs e)
165
        {
166
            Write(BinaryLogRecordKind.BuildStarted);
31✔
167
            WriteBuildEventArgsFields(e);
31✔
168
            Write(e.BuildEnvironment);
31✔
169
        }
31✔
170

171
        private void Write(BuildFinishedEventArgs e)
172
        {
173
            Write(BinaryLogRecordKind.BuildFinished);
31✔
174
            WriteBuildEventArgsFields(e);
31✔
175
            Write(e.Succeeded);
31✔
176
        }
31✔
177

178
        private void Write(ProjectEvaluationStartedEventArgs e)
179
        {
180
            Write(BinaryLogRecordKind.ProjectEvaluationStarted);
49✔
181
            WriteBuildEventArgsFields(e);
49✔
182
            Write(e.ProjectFile);
49✔
183
        }
49✔
184

185
        private void Write(ProjectEvaluationFinishedEventArgs e)
186
        {
187
            Write(BinaryLogRecordKind.ProjectEvaluationFinished);
49✔
188

189
            WriteBuildEventArgsFields(e);
49✔
190
            Write(e.ProjectFile);
49✔
191

192
            Write(e.ProfilerResult.HasValue);
49✔
193
            if (e.ProfilerResult.HasValue)
49!
194
            {
195
                Write(e.ProfilerResult.Value.ProfiledLocations.Count);
×
196

197
                foreach (KeyValuePair<EvaluationLocation, ProfiledLocation> item in e.ProfilerResult.Value.ProfiledLocations)
×
198
                {
199
                    Write(item.Key);
×
200
                    Write(item.Value);
×
201
                }
202
            }
203
        }
49✔
204

205
        private void Write(ProjectStartedEventArgs e)
206
        {
207
            Write(BinaryLogRecordKind.ProjectStarted);
107✔
208
            WriteBuildEventArgsFields(e);
107✔
209

210
            if (e.ParentProjectBuildEventContext == null)
107!
211
            {
212
                Write(false);
×
213
            }
214
            else
215
            {
216
                Write(true);
107✔
217
                Write(e.ParentProjectBuildEventContext);
107✔
218
            }
219

220
            WriteOptionalString(e.ProjectFile);
107✔
221

222
            Write(e.ProjectId);
107✔
223
            Write(e.TargetNames);
107✔
224
            WriteOptionalString(e.ToolsVersion);
107✔
225

226
            if (e.GlobalProperties == null)
107!
227
            {
228
                Write(false);
×
229
            }
230
            else
231
            {
232
                Write(true);
107✔
233
                Write(e.GlobalProperties);
107✔
234
            }
235

236
            WriteProperties(e.Properties);
107✔
237

238
            WriteItems(e.Items);
107✔
239
        }
107✔
240

241
        private void Write(ProjectFinishedEventArgs e)
242
        {
243
            Write(BinaryLogRecordKind.ProjectFinished);
107✔
244
            WriteBuildEventArgsFields(e);
107✔
245
            WriteOptionalString(e.ProjectFile);
107✔
246
            Write(e.Succeeded);
107✔
247
        }
107✔
248

249
        private void Write(TargetStartedEventArgs e)
250
        {
251
            Write(BinaryLogRecordKind.TargetStarted);
2,934✔
252
            WriteBuildEventArgsFields(e);
2,934✔
253
            WriteOptionalString(e.TargetName);
2,934✔
254
            WriteOptionalString(e.ProjectFile);
2,934✔
255
            WriteOptionalString(e.TargetFile);
2,934✔
256
            WriteOptionalString(e.ParentTarget);
2,934✔
257
            Write((int)Reflector.GetBuildReasonFromTargetStarted(e));
2,934✔
258
        }
2,934✔
259

260
        private void Write(TargetFinishedEventArgs e)
261
        {
262
            Write(BinaryLogRecordKind.TargetFinished);
2,934✔
263
            WriteBuildEventArgsFields(e);
2,934✔
264
            Write(e.Succeeded);
2,934✔
265
            WriteOptionalString(e.ProjectFile);
2,934✔
266
            WriteOptionalString(e.TargetFile);
2,934✔
267
            WriteOptionalString(e.TargetName);
2,934✔
268
            WriteItemList(e.TargetOutputs);
2,934✔
269
        }
2,934✔
270

271
        private void Write(TaskStartedEventArgs e)
272
        {
273
            Write(BinaryLogRecordKind.TaskStarted);
2,105✔
274
            WriteBuildEventArgsFields(e);
2,105✔
275
            WriteOptionalString(e.TaskName);
2,105✔
276
            WriteOptionalString(e.ProjectFile);
2,105✔
277
            WriteOptionalString(e.TaskFile);
2,105✔
278
        }
2,105✔
279

280
        private void Write(TaskFinishedEventArgs e)
281
        {
282
            Write(BinaryLogRecordKind.TaskFinished);
2,105✔
283
            WriteBuildEventArgsFields(e);
2,105✔
284
            Write(e.Succeeded);
2,105✔
285
            WriteOptionalString(e.TaskName);
2,105✔
286
            WriteOptionalString(e.ProjectFile);
2,105✔
287
            WriteOptionalString(e.TaskFile);
2,105✔
288
        }
2,105✔
289

290
        private void Write(BuildErrorEventArgs e)
291
        {
292
            Write(BinaryLogRecordKind.Error);
×
293
            WriteBuildEventArgsFields(e);
×
294
            WriteOptionalString(e.Subcategory);
×
295
            WriteOptionalString(e.Code);
×
296
            WriteOptionalString(e.File);
×
297
            WriteOptionalString(e.ProjectFile);
×
298
            Write(e.LineNumber);
×
299
            Write(e.ColumnNumber);
×
300
            Write(e.EndLineNumber);
×
301
            Write(e.EndColumnNumber);
×
302
        }
×
303

304
        private void Write(BuildWarningEventArgs e)
305
        {
306
            Write(BinaryLogRecordKind.Warning);
×
307
            WriteBuildEventArgsFields(e);
×
308
            WriteOptionalString(e.Subcategory);
×
309
            WriteOptionalString(e.Code);
×
310
            WriteOptionalString(e.File);
×
311
            WriteOptionalString(e.ProjectFile);
×
312
            Write(e.LineNumber);
×
313
            Write(e.ColumnNumber);
×
314
            Write(e.EndLineNumber);
×
315
            Write(e.EndColumnNumber);
×
316
        }
×
317

318
        private void Write(BuildMessageEventArgs e)
319
        {
320
            if (e is CriticalBuildMessageEventArgs criticalBuildMessageEventArgs)
40,706!
321
            {
322
                Write(criticalBuildMessageEventArgs);
×
323
                return;
×
324
            }
325

326
            if (e is TaskCommandLineEventArgs taskCommandLineEventArgs)
40,706✔
327
            {
328
                Write(taskCommandLineEventArgs);
13✔
329
                return;
13✔
330
            }
331

332
            if (e is ProjectImportedEventArgs projectImportedEventArgs)
40,693!
333
            {
334
                Write(projectImportedEventArgs);
×
335
                return;
×
336
            }
337

338
            if (e is TargetSkippedEventArgs targetSkippedEventArgs)
40,693!
339
            {
340
                Write(targetSkippedEventArgs);
×
341
                return;
×
342
            }
343

344
            Write(BinaryLogRecordKind.Message);
40,693✔
345
            WriteMessageFields(e);
40,693✔
346
        }
40,693✔
347

348
        private void Write(ProjectImportedEventArgs e)
349
        {
350
            Write(BinaryLogRecordKind.ProjectImported);
9,290✔
351
            WriteMessageFields(e);
9,290✔
352
            Write(e.ImportIgnored);
9,290✔
353
            WriteOptionalString(e.ImportedProjectFile);
9,290✔
354
            WriteOptionalString(e.UnexpandedProject);
9,290✔
355
        }
9,290✔
356

357
        private void Write(TargetSkippedEventArgs e)
358
        {
359
            Write(BinaryLogRecordKind.TargetSkipped);
3,325✔
360
            WriteMessageFields(e);
3,325✔
361
            WriteOptionalString(e.TargetFile);
3,325✔
362
            WriteOptionalString(e.TargetName);
3,325✔
363
            WriteOptionalString(e.ParentTarget);
3,325✔
364
            Write((int)e.BuildReason);
3,325✔
365
        }
3,325✔
366

367
        private void Write(CriticalBuildMessageEventArgs e)
368
        {
369
            Write(BinaryLogRecordKind.CriticalBuildMessage);
×
370
            WriteMessageFields(e);
×
371
        }
×
372

373
        private void Write(TaskCommandLineEventArgs e)
374
        {
375
            Write(BinaryLogRecordKind.TaskCommandLine);
13✔
376
            WriteMessageFields(e);
13✔
377
            WriteOptionalString(e.CommandLine);
13✔
378
            WriteOptionalString(e.TaskName);
13✔
379
        }
13✔
380

381
        private void WriteBuildEventArgsFields(BuildEventArgs e)
382
        {
383
            BuildEventArgsFieldFlags flags = GetBuildEventArgsFieldFlags(e);
10,452✔
384
            Write((int)flags);
10,452✔
385
            WriteBaseFields(e, flags);
10,452✔
386
        }
10,452✔
387

388
        private void WriteBaseFields(BuildEventArgs e, BuildEventArgsFieldFlags flags)
389
        {
390
            if ((flags & BuildEventArgsFieldFlags.Message) != 0)
63,773✔
391
            {
392
                Write(e.Message);
63,714✔
393
            }
394

395
            if ((flags & BuildEventArgsFieldFlags.BuildEventContext) != 0)
63,773✔
396
            {
397
                Write(e.BuildEventContext);
63,693✔
398
            }
399

400
            if ((flags & BuildEventArgsFieldFlags.ThreadId) != 0)
63,773✔
401
            {
402
                Write(e.ThreadId);
63,773✔
403
            }
404

405
            if ((flags & BuildEventArgsFieldFlags.HelpHeyword) != 0)
63,773!
406
            {
407
                Write(e.HelpKeyword);
×
408
            }
409

410
            if ((flags & BuildEventArgsFieldFlags.SenderName) != 0)
63,773✔
411
            {
412
                Write(e.SenderName);
13,029✔
413
            }
414

415
            if ((flags & BuildEventArgsFieldFlags.Timestamp) != 0)
63,773✔
416
            {
417
                Write(e.Timestamp);
63,773✔
418
            }
419
        }
63,773✔
420

421
        private void WriteMessageFields(BuildMessageEventArgs e)
422
        {
423
            BuildEventArgsFieldFlags flags = GetBuildEventArgsFieldFlags(e);
53,321✔
424
            flags = GetMessageFlags(e, flags);
53,321✔
425

426
            Write((int)flags);
53,321✔
427

428
            WriteBaseFields(e, flags);
53,321✔
429

430
            if ((flags & BuildEventArgsFieldFlags.Subcategory) != 0)
53,321!
431
            {
432
                Write(e.Subcategory);
×
433
            }
434

435
            if ((flags & BuildEventArgsFieldFlags.Code) != 0)
53,321!
436
            {
437
                Write(e.Code);
×
438
            }
439

440
            if ((flags & BuildEventArgsFieldFlags.File) != 0)
53,321✔
441
            {
442
                Write(e.File);
3,498✔
443
            }
444

445
            if ((flags & BuildEventArgsFieldFlags.ProjectFile) != 0)
53,321✔
446
            {
447
                Write(e.ProjectFile);
42,976✔
448
            }
449

450
            if ((flags & BuildEventArgsFieldFlags.LineNumber) != 0)
53,321✔
451
            {
452
                Write(e.LineNumber);
19,767✔
453
            }
454

455
            if ((flags & BuildEventArgsFieldFlags.ColumnNumber) != 0)
53,321✔
456
            {
457
                Write(e.ColumnNumber);
19,767✔
458
            }
459

460
            if ((flags & BuildEventArgsFieldFlags.EndLineNumber) != 0)
53,321!
461
            {
462
                Write(e.EndLineNumber);
×
463
            }
464

465
            if ((flags & BuildEventArgsFieldFlags.EndColumnNumber) != 0)
53,321!
466
            {
467
                Write(e.EndColumnNumber);
×
468
            }
469

470
            Write((int)e.Importance);
53,321✔
471
        }
53,321✔
472

473
        private static BuildEventArgsFieldFlags GetMessageFlags(BuildMessageEventArgs e, BuildEventArgsFieldFlags flags)
474
        {
475
            if (e.Subcategory != null)
53,321!
476
            {
477
                flags |= BuildEventArgsFieldFlags.Subcategory;
×
478
            }
479

480
            if (e.Code != null)
53,321!
481
            {
482
                flags |= BuildEventArgsFieldFlags.Code;
×
483
            }
484

485
            if (e.File != null)
53,321✔
486
            {
487
                flags |= BuildEventArgsFieldFlags.File;
3,498✔
488
            }
489

490
            if (e.ProjectFile != null)
53,321✔
491
            {
492
                flags |= BuildEventArgsFieldFlags.ProjectFile;
42,976✔
493
            }
494

495
            if (e.LineNumber != 0)
53,321✔
496
            {
497
                flags |= BuildEventArgsFieldFlags.LineNumber;
19,767✔
498
            }
499

500
            if (e.ColumnNumber != 0)
53,321✔
501
            {
502
                flags |= BuildEventArgsFieldFlags.ColumnNumber;
19,767✔
503
            }
504

505
            if (e.EndLineNumber != 0)
53,321!
506
            {
507
                flags |= BuildEventArgsFieldFlags.EndLineNumber;
×
508
            }
509

510
            if (e.EndColumnNumber != 0)
53,321!
511
            {
512
                flags |= BuildEventArgsFieldFlags.EndColumnNumber;
×
513
            }
514

515
            return flags;
53,321✔
516
        }
517

518
        private static BuildEventArgsFieldFlags GetBuildEventArgsFieldFlags(BuildEventArgs e)
519
        {
520
            BuildEventArgsFieldFlags flags = BuildEventArgsFieldFlags.None;
63,773✔
521
            if (e.BuildEventContext != null)
63,773✔
522
            {
523
                flags |= BuildEventArgsFieldFlags.BuildEventContext;
63,693✔
524
            }
525

526
            if (e.HelpKeyword != null)
63,773!
527
            {
528
                flags |= BuildEventArgsFieldFlags.HelpHeyword;
×
529
            }
530

531
            if (!string.IsNullOrEmpty(e.Message))
63,773✔
532
            {
533
                flags |= BuildEventArgsFieldFlags.Message;
63,714✔
534
            }
535

536
            // no need to waste space for the default sender name
537
            if (e.SenderName != null && e.SenderName != "MSBuild")
63,773✔
538
            {
539
                flags |= BuildEventArgsFieldFlags.SenderName;
13,029✔
540
            }
541

542
            if (e.ThreadId > 0)
63,773✔
543
            {
544
                flags |= BuildEventArgsFieldFlags.ThreadId;
63,773✔
545
            }
546

547
            if (e.Timestamp != default(DateTime))
63,773✔
548
            {
549
                flags |= BuildEventArgsFieldFlags.Timestamp;
63,773✔
550
            }
551

552
            return flags;
63,773✔
553
        }
554

555
        private void WriteItemList(IEnumerable items)
556
        {
557
            if (items is IEnumerable<ITaskItem> taskItems)
2,934✔
558
            {
559
                Write(taskItems.Count());
583✔
560

561
                foreach (ITaskItem item in taskItems)
15,412✔
562
                {
563
                    Write(item);
7,123✔
564
                }
565

566
                return;
583✔
567
            }
568

569
            Write(0);
2,351✔
570
        }
2,351✔
571

572
        private void WriteItems(IEnumerable items)
573
        {
574
            if (items == null)
107!
575
            {
576
                Write(0);
×
577
                return;
×
578
            }
579

580
            DictionaryEntry[] entries = items.OfType<DictionaryEntry>()
107✔
581
                .Where(e => e.Key is string && e.Value is ITaskItem)
×
582
                .ToArray();
107✔
583
            Write(entries.Length);
107✔
584

585
            foreach (DictionaryEntry entry in entries)
214!
586
            {
587
                string key = entry.Key as string;
×
588
                ITaskItem item = entry.Value as ITaskItem;
×
589
                Write(key);
×
590
                Write(item);
×
591
            }
592
        }
107✔
593

594
        private void Write(ITaskItem item)
595
        {
596
            Write(item.ItemSpec);
7,123✔
597
            IDictionary customMetadata = item.CloneCustomMetadata();
7,123✔
598
            Write(customMetadata.Count);
7,123✔
599

600
            foreach (string metadataName in customMetadata.Keys)
208,754✔
601
            {
602
                Write(metadataName);
97,254✔
603
                Write(item.GetMetadata(metadataName));
97,254✔
604
            }
605
        }
7,123✔
606

607
        private void WriteProperties(IEnumerable properties)
608
        {
609
            if (properties == null)
107!
610
            {
611
                Write(0);
×
612
                return;
×
613
            }
614

615
            // there are no guarantees that the properties iterator won't change, so
616
            // take a snapshot and work with the readonly copy
617
            DictionaryEntry[] propertiesArray = properties.OfType<DictionaryEntry>().ToArray();
107✔
618

619
            Write(propertiesArray.Length);
107✔
620

621
            foreach (DictionaryEntry entry in propertiesArray)
214!
622
            {
623
                if (entry.Key is string && entry.Value is string)
×
624
                {
625
                    Write((string)entry.Key);
×
626
                    Write((string)entry.Value);
×
627
                }
628
                else
629
                {
630
                    // to keep the count accurate
631
                    Write(string.Empty);
×
632
                    Write(string.Empty);
×
633
                }
634
            }
635
        }
107✔
636

637
        private void Write(BuildEventContext buildEventContext)
638
        {
639
            Write(buildEventContext.NodeId);
63,800✔
640
            Write(buildEventContext.ProjectContextId);
63,800✔
641
            Write(buildEventContext.TargetId);
63,800✔
642
            Write(buildEventContext.TaskId);
63,800✔
643
            Write(buildEventContext.SubmissionId);
63,800✔
644
            Write(buildEventContext.ProjectInstanceId);
63,800✔
645
            Write(Reflector.GetEvaluationId(buildEventContext));
63,800✔
646
        }
63,800✔
647

648
        private void Write<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> keyValuePairs)
649
        {
650
            if (keyValuePairs?.Any() == true)
138!
651
            {
652
                Write(keyValuePairs.Count());
138✔
653
                foreach (KeyValuePair<TKey, TValue> kvp in keyValuePairs)
9,576✔
654
                {
655
                    Write(kvp.Key.ToString());
4,650✔
656
                    Write(kvp.Value.ToString());
4,650✔
657
                }
658
            }
659
            else
660
            {
661
                Write(false);
×
662
            }
663
        }
138✔
664

665
        private void Write(BinaryLogRecordKind kind)
666
        {
667
            Write((int)kind);
63,773✔
668
        }
63,773✔
669

670
        private void Write(int value)
671
        {
672
            Write7BitEncodedInt(_binaryWriter, value);
811,322✔
673
        }
811,322✔
674

675
        private void Write(long value)
676
        {
677
            _binaryWriter.Write(value);
×
678
        }
×
679

680
        private void Write7BitEncodedInt(BinaryWriter writer, int value)
681
        {
682
            // Write out an int 7 bits at a time.  The high bit of the byte,
683
            // when on, tells reader to continue reading more bytes.
684
            uint v = (uint)value;   // support negative numbers
811,322✔
685
            while (v >= 0x80)
1,415,376✔
686
            {
687
                writer.Write((byte)(v | 0x80));
604,054✔
688
                v >>= 7;
604,054✔
689
            }
690
            writer.Write((byte)v);
811,322✔
691
        }
811,322✔
692

693
        private void Write(byte[] bytes)
694
        {
695
            _binaryWriter.Write(bytes);
×
696
        }
×
697

698
        private void Write(bool boolean)
699
        {
700
            _binaryWriter.Write(boolean);
76,800✔
701
        }
76,800✔
702

703
        private void Write(string text)
704
        {
705
            if (text != null)
392,333!
706
            {
707
                _binaryWriter.Write(text);
392,333✔
708
            }
709
            else
710
            {
711
                _binaryWriter.Write(false);
×
712
            }
713
        }
×
714

715
        private void WriteOptionalString(string text)
716
        {
717
            if (text == null)
62,070✔
718
            {
719
                Write(false);
4,090✔
720
            }
721
            else
722
            {
723
                Write(true);
57,980✔
724
                Write(text);
57,980✔
725
            }
726
        }
57,980✔
727

728
        private void Write(DateTime timestamp)
729
        {
730
            _binaryWriter.Write(timestamp.Ticks);
63,773✔
731
            Write((int)timestamp.Kind);
63,773✔
732
        }
63,773✔
733

734
        private void Write(TimeSpan timeSpan)
735
        {
736
            _binaryWriter.Write(timeSpan.Ticks);
×
737
        }
×
738

739
        private void Write(EvaluationLocation item)
740
        {
741
            WriteOptionalString(item.ElementName);
×
742
            WriteOptionalString(item.ElementDescription);
×
743
            WriteOptionalString(item.EvaluationPassDescription);
×
744
            WriteOptionalString(item.File);
×
745
            Write((int)item.Kind);
×
746
            Write((int)item.EvaluationPass);
×
747

748
            Write(item.Line.HasValue);
×
749
            if (item.Line.HasValue)
×
750
            {
751
                Write(item.Line.Value);
×
752
            }
753

754
            Write(item.Id);
×
755
            Write(item.ParentId.HasValue);
×
756
            if (item.ParentId.HasValue)
×
757
            {
758
                Write(item.ParentId.Value);
×
759
            }
760
        }
×
761

762
        private void Write(ProfiledLocation e)
763
        {
764
            Write(e.NumberOfHits);
×
765
            Write(e.ExclusiveTime);
×
766
            Write(e.InclusiveTime);
×
767
        }
×
768
    }
769
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc