Merge pull request #2977 from BrzVlad/fix-major-log2
[mono.git] / mcs / class / referencesource / mscorlib / system / runtime / serialization / formatters / binary / binaryutilclasses.cs
1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 //
5 // ==--==
6 /*============================================================
7  **
8  ** Class: CommonClasses
9  **
10  **
11  ** Purpose: utility classes
12  **
13  **
14  ===========================================================*/
15
16
17 // All classes and methods in here are only for the internal use by the XML and Binary Formatters.
18 // They are public so that the XMLFormatter can address them. Eventually they will
19 // be signed so that they can't be used by external applications.
20
21 namespace System.Runtime.Serialization.Formatters.Binary
22 {
23     using System;
24     using System.Collections;
25     using System.Reflection;
26     using System.Text;
27     using System.Globalization;
28     using System.Runtime.Serialization.Formatters;
29     using System.Runtime.Remoting;
30     using System.Runtime.Remoting.Messaging;
31     using System.Runtime.InteropServices;
32     using System.Runtime.Serialization;
33     using System.Diagnostics;
34
35     // The ParseRecord class holds the parsed XML information. There is a
36     // ParsedRecord for each XML Element
37     internal sealed class ParseRecord 
38 #if _DEBUG
39                                         : ITrace
40 #endif                                        
41     {
42 // disable csharp compiler warning #0414: field assigned unused value
43 #pragma warning disable 0414
44         internal static int parseRecordIdCount = 1;
45
46         internal int PRparseRecordId = 0;
47 #pragma warning restore 0414
48
49         // Enums
50         internal InternalParseTypeE PRparseTypeEnum = InternalParseTypeE.Empty;
51         internal InternalObjectTypeE PRobjectTypeEnum = InternalObjectTypeE.Empty;
52         internal InternalArrayTypeE PRarrayTypeEnum = InternalArrayTypeE.Empty;
53         internal InternalMemberTypeE PRmemberTypeEnum = InternalMemberTypeE.Empty;
54         internal InternalMemberValueE PRmemberValueEnum = InternalMemberValueE.Empty;
55         internal InternalObjectPositionE PRobjectPositionEnum = InternalObjectPositionE.Empty;
56
57         // Object
58         internal String PRname;
59
60         // Value
61         internal String PRvalue;
62         internal Object PRvarValue;
63
64         // dt attribute
65         internal String PRkeyDt;
66         internal Type PRdtType;
67         internal InternalPrimitiveTypeE PRdtTypeCode;
68 // disable csharp compiler warning #0414: field assigned unused value
69 #pragma warning disable 0414
70         internal bool PRisVariant = false; // Used by Binary
71         internal bool PRisEnum = false;
72 #pragma warning restore 0414
73
74         // Object ID
75         internal long PRobjectId;
76
77         // Reference ID
78         internal long PRidRef;
79
80         // Array
81
82         // Array Element Type
83         internal String PRarrayElementTypeString;
84         internal Type PRarrayElementType;
85         internal bool PRisArrayVariant = false;
86         internal InternalPrimitiveTypeE PRarrayElementTypeCode;
87
88         // Parsed array information
89         internal int PRrank;
90         internal int[] PRlengthA;
91 // disable csharp compiler warning #0414: field assigned unused value
92 #pragma warning disable 0414
93         internal int[] PRpositionA;
94         internal int[] PRlowerBoundA;
95         internal int[] PRupperBoundA;
96 #pragma warning restore 0414
97
98         // Array map for placing array elements in array
99         internal int[] PRindexMap;
100         internal int PRmemberIndex;
101         internal int PRlinearlength;
102         internal int[] PRrectangularMap;
103         internal bool   PRisLowerBound;
104
105         // SerializedStreamHeader information
106 // disable csharp compiler warning #0414: field assigned unused value
107 #pragma warning disable 0414
108         internal long PRtopId;
109         internal long PRheaderId;
110 #pragma warning restore 0414
111
112
113         // MemberInfo accumulated during parsing of members
114
115         internal ReadObjectInfo PRobjectInfo;
116
117         // ValueType Fixup needed
118         internal bool PRisValueTypeFixup = false;
119
120         // Created object
121         internal Object PRnewObj;
122         internal Object[] PRobjectA; //optimization, will contain object[]
123         internal PrimitiveArray PRprimitiveArray; // for Primitive Soap arrays, optimization
124         internal bool PRisRegistered; // Used when registering nested classes
125         internal Object[] PRmemberData; // member data is collected here before populating
126         internal SerializationInfo  PRsi;
127
128         internal int PRnullCount; // Count of consecutive nulls within an array
129
130
131         internal ParseRecord()
132         {
133         }
134
135
136 #if _DEBUG
137         // Get a String describing the ParseRecord
138         // ITrace
139         public String Trace()
140         {
141             return "ParseRecord"+PRparseRecordId+" ParseType "+ ((Enum)PRparseTypeEnum).ToString() +" name "+PRname+" keyDt "+Util.PString(PRkeyDt);
142         }
143 #endif
144
145         // Initialize ParseRecord. Called when reusing.
146         internal void Init()
147         {
148             // Enums
149             PRparseTypeEnum = InternalParseTypeE.Empty;
150             PRobjectTypeEnum = InternalObjectTypeE.Empty;
151             PRarrayTypeEnum = InternalArrayTypeE.Empty;
152             PRmemberTypeEnum = InternalMemberTypeE.Empty;
153             PRmemberValueEnum = InternalMemberValueE.Empty;
154             PRobjectPositionEnum = InternalObjectPositionE.Empty;
155
156             // Object
157             PRname = null;
158
159             // Value
160             PRvalue = null;
161
162             // dt attribute
163             PRkeyDt = null;
164             PRdtType = null;
165             PRdtTypeCode = InternalPrimitiveTypeE.Invalid;
166             PRisEnum = false;
167
168             // Object ID
169             PRobjectId = 0;
170
171             // Reference ID
172             PRidRef = 0;
173
174             // Array
175
176             // Array Element Type
177             PRarrayElementTypeString = null;
178             PRarrayElementType = null;
179             PRisArrayVariant = false;
180             PRarrayElementTypeCode = InternalPrimitiveTypeE.Invalid;
181
182
183             // Parsed array information
184             PRrank = 0;
185             PRlengthA = null;
186             PRpositionA = null;
187             PRlowerBoundA = null;
188             PRupperBoundA = null;
189
190             // Array map for placing array elements in array
191             PRindexMap = null;
192             PRmemberIndex = 0;
193             PRlinearlength = 0;
194             PRrectangularMap = null;
195             PRisLowerBound = false;
196
197             // SerializedStreamHeader information
198             PRtopId = 0;
199             PRheaderId = 0;
200
201             // ValueType Fixup needed
202             PRisValueTypeFixup = false;
203
204             PRnewObj = null;
205             PRobjectA = null;
206             PRprimitiveArray = null;
207             PRobjectInfo = null;
208             PRisRegistered = false;
209             PRmemberData = null;
210             PRsi = null;
211
212             PRnullCount = 0;
213         }
214
215 #if _DEBUG        // Dump ParseRecord.
216         [Conditional("SER_LOGGING")]
217         internal void Dump()
218         {
219             SerTrace.Log("ParseRecord Dump ",PRparseRecordId);
220             SerTrace.Log("Enums");
221             Util.NVTrace("ParseType",((Enum)PRparseTypeEnum).ToString());
222             Util.NVTrace("ObjectType",((Enum)PRobjectTypeEnum).ToString());
223             Util.NVTrace("ArrayType",((Enum)PRarrayTypeEnum).ToString());
224             Util.NVTrace("MemberType",((Enum)PRmemberTypeEnum).ToString());
225             Util.NVTrace("MemberValue",((Enum)PRmemberValueEnum).ToString());
226             Util.NVTrace("ObjectPosition",((Enum)PRobjectPositionEnum).ToString());
227             SerTrace.Log("Basics");
228             Util.NVTrace("Name",PRname);
229             Util.NVTrace("Value ",PRvalue);
230             Util.NVTrace("varValue ",PRvarValue);
231             if (PRvarValue != null)
232                 Util.NVTrace("varValue type",PRvarValue.GetType());
233
234             Util.NVTrace("keyDt",PRkeyDt);
235             Util.NVTrace("dtType",PRdtType);
236             Util.NVTrace("code",((Enum)PRdtTypeCode).ToString());
237             Util.NVTrace("objectID",PRobjectId);
238             Util.NVTrace("idRef",PRidRef);
239             Util.NVTrace("isEnum",PRisEnum);
240             SerTrace.Log("Array ");
241             Util.NVTrace("arrayElementTypeString",PRarrayElementTypeString);
242             Util.NVTrace("arrayElementType",PRarrayElementType);
243             Util.NVTrace("arrayElementTypeCode",((Enum)PRarrayElementTypeCode).ToString());
244             Util.NVTrace("isArrayVariant",PRisArrayVariant);
245             Util.NVTrace("rank",PRrank);
246             Util.NVTrace("dimensions", Util.PArray(PRlengthA));
247             Util.NVTrace("position", Util.PArray(PRpositionA));
248             Util.NVTrace("lowerBoundA", Util.PArray(PRlowerBoundA));
249             Util.NVTrace("upperBoundA", Util.PArray(PRupperBoundA));
250             SerTrace.Log("Header ");
251             Util.NVTrace("nullCount", PRnullCount);
252
253             SerTrace.Log("New Object");
254             if (PRnewObj != null)
255                 Util.NVTrace("newObj", PRnewObj);
256         }
257 #endif
258     }
259
260 #if _DEBUG
261     internal interface ITrace
262     {
263         String Trace();
264     }
265 #endif
266
267     // Implements a stack used for parsing
268     internal sealed class SerStack
269     {
270         internal Object[] objects = new Object[5];
271         internal String stackId;
272         internal int top = -1;
273 // disable csharp compiler warning #0414: field assigned unused value
274 #pragma warning disable 0414
275         internal int next = 0;
276 #pragma warning restore 0414
277
278         internal SerStack()
279         {
280             stackId = "System";
281         }
282
283         internal SerStack(String stackId) {
284             this.stackId = stackId;
285         }
286
287         // Push the object onto the stack
288         internal void Push(Object obj) {
289 #if _DEBUG        
290             SerTrace.Log(this, "Push ",stackId," ",((obj is ITrace)?((ITrace)obj).Trace():""));
291 #endif
292             if (top == (objects.Length -1))
293             {
294                 IncreaseCapacity();
295             }
296             objects[++top] = obj;
297         }
298
299         // Pop the object from the stack
300         internal Object Pop() {
301             if (top < 0)
302                 return null;
303
304             Object obj = objects[top];
305             objects[top--] = null;
306 #if _DEBUG        
307             SerTrace.Log(this, "Pop ",stackId," ",((obj is ITrace)?((ITrace)obj).Trace():""));
308 #endif
309             return obj;
310         }
311
312         internal void IncreaseCapacity() {
313             int size = objects.Length * 2;
314             Object[] newItems = new Object[size];
315             Array.Copy(objects, 0, newItems, 0, objects.Length);
316             objects = newItems;
317         }
318
319         // Gets the object on the top of the stack
320         internal Object Peek() {
321             if (top < 0)
322                 return null;
323 #if _DEBUG        
324             SerTrace.Log(this, "Peek ",stackId," ",((objects[top] is ITrace)?((ITrace)objects[top]).Trace():""));
325 #endif
326             return objects[top];
327         }
328
329         // Gets the second entry in the stack.
330         internal Object PeekPeek() {
331             if (top < 1)
332                 return null;
333 #if _DEBUG            
334             SerTrace.Log(this, "PeekPeek ",stackId," ",((objects[top - 1] is ITrace)?((ITrace)objects[top - 1]).Trace():""));
335 #endif
336             return objects[top - 1];
337         }
338
339         // The number of entries in the stack
340         internal int Count() {
341             return top + 1;
342         }
343
344         // The number of entries in the stack
345         internal bool IsEmpty() {
346             if (top > 0)
347                 return false;
348             else
349                 return true;
350         }
351
352         [Conditional("SER_LOGGING")]
353         internal void Dump()
354         {
355             for (int i=0; i<Count(); i++)
356             {
357                 Object obj = objects[i];
358 #if _DEBUG                
359                 SerTrace.Log(this, "Stack Dump ",stackId," "+((obj is ITrace)?((ITrace)obj).Trace():""));
360 #endif
361             }
362         }
363     }
364
365
366     // Implements a Growable array
367
368     [Serializable]
369     internal sealed class SizedArray : ICloneable
370     {
371         internal Object[] objects = null;
372         internal Object[] negObjects = null;
373
374         internal SizedArray()
375         {
376             objects = new Object[16];
377             negObjects = new Object[4];
378         }
379
380         internal SizedArray(int length)
381         {
382             objects = new Object[length];
383             negObjects = new Object[length];
384         }
385
386         private SizedArray(SizedArray sizedArray)
387         {
388             objects = new Object[sizedArray.objects.Length];
389             sizedArray.objects.CopyTo(objects, 0);
390             negObjects = new Object[sizedArray.negObjects.Length];
391             sizedArray.negObjects.CopyTo(negObjects, 0);
392         }
393
394         public Object Clone()
395         {
396             return new SizedArray(this);
397         }
398
399         internal Object this[int index]
400         {
401             get
402             {
403                 if (index < 0)
404                 {
405                     if (-index > negObjects.Length - 1)
406                         return null;
407                     return negObjects[-index];
408                 }
409                 else
410                 {
411                     if (index > objects.Length - 1)
412                         return null;
413                     return objects[index];
414                 }
415             }
416             set
417             {
418                 if (index < 0)
419                 {
420                     if (-index > negObjects.Length-1 )
421                     {
422                         IncreaseCapacity(index);
423                     }
424                     negObjects[-index] = value;
425
426                 }
427                 else
428                 {
429                     if (index > objects.Length-1 )
430                     {
431                         IncreaseCapacity(index);
432                     }
433                     if (objects[index] != null)
434                     {
435                         //Console.WriteLine("SizedArray Setting a non-zero "+index+" "+value);
436                     }
437                     objects[index] = value;
438                 }
439             }
440         }
441
442         internal void IncreaseCapacity(int index)
443         {
444             try
445             {
446                 if (index < 0)
447                 {
448                     int size = Math.Max(negObjects.Length * 2, (-index)+1);
449                     Object[] newItems = new Object[size];
450                     Array.Copy(negObjects, 0, newItems, 0, negObjects.Length);
451                     negObjects = newItems;
452                 }
453                 else
454                 {
455                     int size = Math.Max(objects.Length * 2, index+1);
456                     Object[] newItems = new Object[size];
457                     Array.Copy(objects, 0, newItems, 0, objects.Length);
458                     objects = newItems;
459                 }
460             }
461             catch (Exception)
462             {
463                 throw new SerializationException(Environment.GetResourceString("Serialization_CorruptedStream"));
464             }
465         }
466
467     }
468
469     [Serializable]
470     internal sealed class IntSizedArray : ICloneable
471     {
472         internal int[] objects = new int[16];
473         internal int[] negObjects = new int[4];
474
475         public IntSizedArray()
476         {
477         }
478
479         private IntSizedArray(IntSizedArray sizedArray)
480         {
481             objects = new int[sizedArray.objects.Length];
482             sizedArray.objects.CopyTo(objects, 0);
483             negObjects = new int[sizedArray.negObjects.Length];
484             sizedArray.negObjects.CopyTo(negObjects, 0);
485         }
486
487         public Object Clone()
488         {
489             return new IntSizedArray(this);
490         }
491
492
493         internal int this[int index]
494         {
495             get
496             {
497                 if (index < 0)
498                 {
499                     if (-index > negObjects.Length-1 )
500                         return 0;
501                     return negObjects[-index];
502                 }
503                 else
504                 {
505                     if (index > objects.Length-1 )
506                         return 0;
507                     return objects[index];
508                 }
509             }
510             set
511             {
512                 if (index < 0)
513                 {
514                     if (-index > negObjects.Length-1 )
515                     {
516                         IncreaseCapacity(index);
517                     }
518                     negObjects[-index] = value;
519
520                 }
521                 else
522                 {
523                     if (index > objects.Length-1 )
524                     {
525                         IncreaseCapacity(index);
526                     }
527                     objects[index] = value;
528                 }
529             }
530         }
531
532         internal void IncreaseCapacity(int index)
533         {
534             try
535             {
536                 if (index < 0)
537                 {
538                     int size = Math.Max(negObjects.Length * 2, (-index)+1);
539                     int[] newItems = new int[size];
540                     Array.Copy(negObjects, 0, newItems, 0, negObjects.Length);
541                     negObjects = newItems;
542                 }
543                 else
544                 {
545                     int size = Math.Max(objects.Length * 2, index+1);
546                     int[] newItems = new int[size];
547                     Array.Copy(objects, 0, newItems, 0, objects.Length);
548                     objects = newItems;
549                 }
550             }
551             catch (Exception)
552             {
553                 throw new SerializationException(Environment.GetResourceString("Serialization_CorruptedStream"));
554             }
555         }
556     }
557
558     internal sealed class NameCache
559     {
560         static System.Collections.Concurrent.ConcurrentDictionary<string, object> ht = new System.Collections.Concurrent.ConcurrentDictionary<string, object>();
561         String name = null;
562
563         internal Object GetCachedValue(String name)
564         {
565             this.name = name;
566             object value;
567             return ht.TryGetValue(name, out value) ? value : null;
568         }
569
570         internal void SetCachedValue(Object value)
571         {
572             ht[name] = value;
573         }
574     }
575
576 #if _DEBUG
577     // Utilities
578     internal static class Util
579     {
580         // Replaces a null string with an empty string
581         internal static String PString(String value)
582         {
583             if (value == null)
584                 return "";
585             else
586                 return value;
587         }
588
589         // Converts an object to a string and checks for nulls
590
591         internal static String PString(Object value)
592         {
593             if (value == null)
594                 return "";
595             else
596                 return value.ToString();
597         }
598
599         // Converts a single int array to a string
600
601         internal static String PArray(int[] array)
602         {
603             if (array != null)
604             {
605                 StringBuilder sb = new StringBuilder(10);
606                 sb.Append("[");
607                 for (int i=0; i<array.Length; i++)
608                 {
609                     sb.Append(array[i]);
610                     if (i != array.Length -1)
611                         sb.Append(",");
612                 }
613                 sb.Append("]");
614                 return sb.ToString();
615             }
616             else
617                 return "";
618         }
619
620         // Traces an name value pair
621
622         [Conditional("SER_LOGGING")]
623         internal static void NVTrace(String name, String value)
624         {
625             SerTrace.Log("  "+name+((value == null)?" = null":" = "+value));
626         }
627
628         // Traces an name value pair
629         [Conditional("SER_LOGGING")]
630         internal static void NVTrace(String name, Object value)
631         {
632             SerTrace.Log("  "+name+((value == null)?" = null":" = "+value.ToString()));
633         }
634
635         // Traces an name value pair
636
637         [Conditional("_LOGGING")]
638         internal static void NVTraceI(String name, String value)
639         {
640             BCLDebug.Trace("Binary", "  "+name+((value == null)?" = null":" = "+value));
641         }
642
643         // Traces an name value pair
644         [Conditional("_LOGGING")]
645         internal static void NVTraceI(String name, Object value)
646         {
647             BCLDebug.Trace("Binary", "  "+name+((value == null)?" = null":" = "+value.ToString()));
648         }
649     }
650 #endif
651
652
653     // Used to fixup value types. Only currently used for valuetypes which are array items.
654     internal sealed class ValueFixup
655     {
656         internal ValueFixupEnum valueFixupEnum = ValueFixupEnum.Empty;
657         internal Array arrayObj;
658         internal int[] indexMap;
659         internal Object header = null;
660         internal Object memberObject;
661         internal static volatile MemberInfo valueInfo;
662         internal ReadObjectInfo objectInfo;
663         internal String memberName;
664
665         internal ValueFixup(Array arrayObj, int[] indexMap)
666         {
667 #if _DEBUG
668             SerTrace.Log(this, "Array Constructor ",arrayObj);
669 #endif
670             valueFixupEnum = ValueFixupEnum.Array;
671             this.arrayObj = arrayObj;
672             this.indexMap = indexMap;
673         }
674
675         internal ValueFixup(Object memberObject, String memberName, ReadObjectInfo objectInfo)
676         {
677 #if _DEBUG
678             SerTrace.Log(this, "Member Constructor ",memberObject);
679 #endif
680             valueFixupEnum = ValueFixupEnum.Member;
681             this.memberObject = memberObject;
682             this.memberName = memberName;
683             this.objectInfo = objectInfo;
684         }
685
686         [System.Security.SecurityCritical]  // auto-generated
687         internal void Fixup(ParseRecord record, ParseRecord parent) {
688             Object obj = record.PRnewObj;
689 #if _DEBUG
690             SerTrace.Log(this, "Fixup ",obj," ",((Enum)valueFixupEnum).ToString());
691 #endif
692             switch (valueFixupEnum)
693             {
694             case ValueFixupEnum.Array:
695                 arrayObj.SetValue(obj, indexMap);
696                 break;
697             case ValueFixupEnum.Header:
698                 Type type = typeof(Header);
699                 if (valueInfo == null)
700                 {
701                     MemberInfo[] valueInfos = type.GetMember("Value");
702                     if (valueInfos.Length != 1)
703                         throw new SerializationException(Environment.GetResourceString("Serialization_HeaderReflection",valueInfos.Length));
704                     valueInfo = valueInfos[0];
705                 }
706                 FormatterServices.SerializationSetValue(valueInfo, header, obj);
707                 break;
708             case ValueFixupEnum.Member:
709                 SerTrace.Log(this, "Fixup Member new object value ",obj," memberObject ",memberObject);
710
711                 if (objectInfo.isSi)
712                 {
713                     SerTrace.Log(this, "Recording a fixup on member: ", memberName,
714                                  " in object id", parent.PRobjectId, " Required Object ", record.PRobjectId);
715                     objectInfo.objectManager.RecordDelayedFixup(parent.PRobjectId, memberName, record.PRobjectId);
716 //                          Console.WriteLine("SerializationInfo: Main Object ({0}): {1}. SubObject ({2}): {3}", parent.PRobjectId,
717 //                                            objectInfo.obj, record.PRobjectId, obj);
718                 }
719                 else
720                 {
721                     MemberInfo memberInfo = objectInfo.GetMemberInfo(memberName);
722                     SerTrace.Log(this, "Recording a fixup on member:", memberInfo, " in object id ",
723                                  parent.PRobjectId," Required Object", record.PRobjectId);
724                     if (memberInfo != null)
725                         objectInfo.objectManager.RecordFixup(parent.PRobjectId, memberInfo, record.PRobjectId);
726 //                          Console.WriteLine("MemberFixup: Main Object({0}): {1}. SubObject({2}): {3}", parent.PRobjectId,
727 //                                            objectInfo.obj.GetType(), record.PRobjectId, obj.GetType());
728
729                 }
730                 break;
731             }
732         }
733
734 #if _DEBUG
735         public String Trace()
736         {
737             return "ValueFixup"+((Enum)valueFixupEnum).ToString();
738         }
739 #endif
740     }
741
742     // Class used to transmit Enums from the XML and Binary Formatter class to the ObjectWriter and ObjectReader class
743     internal sealed class InternalFE
744     {
745         internal FormatterTypeStyle FEtypeFormat;
746         internal FormatterAssemblyStyle FEassemblyFormat;
747         internal TypeFilterLevel FEsecurityLevel;        
748         internal InternalSerializerTypeE FEserializerTypeEnum;
749     }
750
751
752     internal sealed class NameInfo
753     {
754         internal String NIFullName; // Name from SerObjectInfo.GetType
755         internal long NIobjectId;
756         internal long NIassemId;
757         internal InternalPrimitiveTypeE NIprimitiveTypeEnum = InternalPrimitiveTypeE.Invalid;
758         internal Type NItype;
759         internal bool NIisSealed;
760         internal bool NIisArray;
761         internal bool NIisArrayItem;
762         internal bool NItransmitTypeOnObject;
763         internal bool NItransmitTypeOnMember;
764         internal bool NIisParentTypeOnObject;
765         internal InternalArrayTypeE NIarrayEnum;
766
767         internal NameInfo()
768         {
769         }
770
771
772         internal void Init()
773         {
774             NIFullName = null;
775             NIobjectId = 0;
776             NIassemId = 0;
777             NIprimitiveTypeEnum = InternalPrimitiveTypeE.Invalid;
778             NItype = null;
779             NIisSealed = false;
780             NItransmitTypeOnObject = false;
781             NItransmitTypeOnMember = false;
782             NIisParentTypeOnObject = false;
783             NIisArray = false;
784             NIisArrayItem = false;
785             NIarrayEnum = InternalArrayTypeE.Empty;
786             NIsealedStatusChecked = false;
787         }
788
789 #if _DEBUG
790         [Conditional("SER_LOGGING")]
791         internal void Dump(String value)
792         {
793             Util.NVTrace("name", NIFullName);
794             Util.NVTrace("objectId", NIobjectId);
795             Util.NVTrace("assemId", NIassemId);
796             Util.NVTrace("primitiveTypeEnum", ((Enum)NIprimitiveTypeEnum).ToString());
797             Util.NVTrace("type", NItype);
798             Util.NVTrace("isSealed", NIisSealed);
799             Util.NVTrace("transmitTypeOnObject", NItransmitTypeOnObject);
800             Util.NVTrace("transmitTypeOnMember", NItransmitTypeOnMember);
801             Util.NVTrace("isParentTypeOnObject", NIisParentTypeOnObject);
802             Util.NVTrace("isArray", NIisArray);
803             Util.NVTrace("isArrayItem", NIisArrayItem);
804             Util.NVTrace("arrayEnum", ((Enum)NIarrayEnum).ToString());
805         }
806 #endif
807         private bool NIsealedStatusChecked = false;
808         public bool IsSealed
809         {
810             get {
811                 if (!NIsealedStatusChecked)
812                 {
813                     NIisSealed = NItype.IsSealed;
814                     NIsealedStatusChecked = true;
815                 }
816                 return NIisSealed;
817             }
818         }
819
820         public String NIname
821         {
822             get {
823                 if (this.NIFullName == null)
824                     this.NIFullName = NItype.FullName;
825
826                 return this.NIFullName;
827             }
828             set {
829                 this.NIFullName = value;
830             }
831         }
832     }
833
834     internal sealed class PrimitiveArray
835     {
836         InternalPrimitiveTypeE code;
837         Boolean[] booleanA = null;
838         Char[] charA = null;
839         Double[] doubleA = null;
840         Int16[] int16A = null;
841         Int32[] int32A = null;
842         Int64[] int64A = null;
843         SByte[] sbyteA = null;
844         Single[] singleA = null;
845         UInt16[] uint16A = null;
846         UInt32[] uint32A = null;
847         UInt64[] uint64A = null;
848
849
850         internal PrimitiveArray(InternalPrimitiveTypeE code, Array array)
851         {
852             Init(code, array);
853         }
854
855         internal void Init(InternalPrimitiveTypeE code, Array array)
856         {
857             this.code = code;
858             switch (code)
859             {
860             case InternalPrimitiveTypeE.Boolean:
861                 booleanA = (Boolean[])array;
862                 break;
863             case InternalPrimitiveTypeE.Char:
864                 charA = (Char[])array;
865                 break;
866             case InternalPrimitiveTypeE.Double:
867                 doubleA = (Double[])array;
868                 break;
869             case InternalPrimitiveTypeE.Int16:
870                 int16A = (Int16[])array;
871                 break;
872             case InternalPrimitiveTypeE.Int32:
873                 int32A = (Int32[])array;
874                 break;
875             case InternalPrimitiveTypeE.Int64:
876                 int64A = (Int64[])array;
877                 break;
878             case InternalPrimitiveTypeE.SByte:
879                 sbyteA = (SByte[])array;
880                 break;
881             case InternalPrimitiveTypeE.Single:
882                 singleA = (Single[])array;
883                 break;
884             case InternalPrimitiveTypeE.UInt16:
885                 uint16A = (UInt16[])array;
886                 break;
887             case InternalPrimitiveTypeE.UInt32:
888                 uint32A = (UInt32[])array;
889                 break;
890             case InternalPrimitiveTypeE.UInt64:
891                 uint64A = (UInt64[])array;
892                 break;
893             }
894         }
895         
896         internal void SetValue(String value, int index)
897         {
898             switch (code)
899             {
900             case InternalPrimitiveTypeE.Boolean:
901                 booleanA[index] = Boolean.Parse(value);
902                 break;
903             case InternalPrimitiveTypeE.Char:
904                 if ((value[0] == '_') && (value.Equals("_0x00_")))
905                     charA[index] = Char.MinValue;
906                 else
907                     charA[index] = Char.Parse(value);
908                 break;
909             case InternalPrimitiveTypeE.Double:
910                 doubleA[index] = Double.Parse(value, CultureInfo.InvariantCulture);
911                 break;
912             case InternalPrimitiveTypeE.Int16:
913                 int16A[index] = Int16.Parse(value, CultureInfo.InvariantCulture);
914                 break;
915             case InternalPrimitiveTypeE.Int32:
916                 int32A[index] = Int32.Parse(value, CultureInfo.InvariantCulture);
917                 break;
918             case InternalPrimitiveTypeE.Int64:
919                 int64A[index] = Int64.Parse(value, CultureInfo.InvariantCulture);
920                 break;
921             case InternalPrimitiveTypeE.SByte:
922                 sbyteA[index] = SByte.Parse(value, CultureInfo.InvariantCulture);
923                 break;
924             case InternalPrimitiveTypeE.Single:
925                 singleA[index] = Single.Parse(value, CultureInfo.InvariantCulture);
926                 break;
927             case InternalPrimitiveTypeE.UInt16:
928                 uint16A[index] = UInt16.Parse(value, CultureInfo.InvariantCulture);
929                 break;
930             case InternalPrimitiveTypeE.UInt32:
931                 uint32A[index] = UInt32.Parse(value, CultureInfo.InvariantCulture);
932                 break;
933             case InternalPrimitiveTypeE.UInt64:
934                 uint64A[index] = UInt64.Parse(value, CultureInfo.InvariantCulture);
935                 break;
936             }
937         }
938     }
939 }
940