CompileUnitEntry.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. namespace Mono.CompilerServices.SymbolWriter
  5. {
  6. public class CompileUnitEntry : ICompileUnit
  7. {
  8. public readonly int Index;
  9. private int DataOffset;
  10. private MonoSymbolFile file;
  11. private SourceFileEntry source;
  12. private List<SourceFileEntry> include_files;
  13. private List<NamespaceEntry> namespaces;
  14. private bool creating;
  15. public static int Size
  16. {
  17. get
  18. {
  19. return 8;
  20. }
  21. }
  22. CompileUnitEntry ICompileUnit.Entry
  23. {
  24. get
  25. {
  26. return this;
  27. }
  28. }
  29. public SourceFileEntry SourceFile
  30. {
  31. get
  32. {
  33. SourceFileEntry result;
  34. if (this.creating)
  35. {
  36. result = this.source;
  37. }
  38. else
  39. {
  40. this.ReadData();
  41. result = this.source;
  42. }
  43. return result;
  44. }
  45. }
  46. public NamespaceEntry[] Namespaces
  47. {
  48. get
  49. {
  50. this.ReadData();
  51. NamespaceEntry[] retval = new NamespaceEntry[this.namespaces.Count];
  52. this.namespaces.CopyTo(retval, 0);
  53. return retval;
  54. }
  55. }
  56. public SourceFileEntry[] IncludeFiles
  57. {
  58. get
  59. {
  60. this.ReadData();
  61. SourceFileEntry[] result;
  62. if (this.include_files == null)
  63. {
  64. result = new SourceFileEntry[0];
  65. }
  66. else
  67. {
  68. SourceFileEntry[] retval = new SourceFileEntry[this.include_files.Count];
  69. this.include_files.CopyTo(retval, 0);
  70. result = retval;
  71. }
  72. return result;
  73. }
  74. }
  75. public CompileUnitEntry(MonoSymbolFile file, SourceFileEntry source)
  76. {
  77. this.file = file;
  78. this.source = source;
  79. this.Index = file.AddCompileUnit(this);
  80. this.creating = true;
  81. this.namespaces = new List<NamespaceEntry>();
  82. }
  83. public void AddFile(SourceFileEntry file)
  84. {
  85. if (!this.creating)
  86. {
  87. throw new InvalidOperationException();
  88. }
  89. if (this.include_files == null)
  90. {
  91. this.include_files = new List<SourceFileEntry>();
  92. }
  93. this.include_files.Add(file);
  94. }
  95. public int DefineNamespace(string name, string[] using_clauses, int parent)
  96. {
  97. if (!this.creating)
  98. {
  99. throw new InvalidOperationException();
  100. }
  101. int index = this.file.GetNextNamespaceIndex();
  102. NamespaceEntry ns = new NamespaceEntry(name, index, using_clauses, parent);
  103. this.namespaces.Add(ns);
  104. return index;
  105. }
  106. //internal void WriteData(MyBinaryWriter bw)
  107. //{
  108. // this.DataOffset = (int)bw.BaseStream.Position;
  109. // bw.WriteLeb128(this.source.Index);
  110. // int count_includes = (this.include_files != null) ? this.include_files.Count : 0;
  111. // bw.WriteLeb128(count_includes);
  112. // if (this.include_files != null)
  113. // {
  114. // foreach (SourceFileEntry entry in this.include_files)
  115. // {
  116. // bw.WriteLeb128(entry.Index);
  117. // }
  118. // }
  119. // bw.WriteLeb128(this.namespaces.Count);
  120. // foreach (NamespaceEntry ns in this.namespaces)
  121. // {
  122. // ns.Write(this.file, bw);
  123. // }
  124. //}
  125. //internal void Write(BinaryWriter bw)
  126. //{
  127. // bw.Write(this.Index);
  128. // bw.Write(this.DataOffset);
  129. //}
  130. internal CompileUnitEntry(MonoSymbolFile file, MyBinaryReader reader)
  131. {
  132. this.file = file;
  133. this.Index = reader.ReadInt32();
  134. this.DataOffset = reader.ReadInt32();
  135. }
  136. private void ReadData()
  137. {
  138. if (this.creating)
  139. {
  140. throw new InvalidOperationException();
  141. }
  142. lock (this.file)
  143. {
  144. if (this.namespaces == null)
  145. {
  146. MyBinaryReader reader = this.file.BinaryReader;
  147. int old_pos = (int)reader.BaseStream.Position;
  148. reader.BaseStream.Position = (long)this.DataOffset;
  149. int source_idx = reader.ReadLeb128();
  150. this.source = this.file.GetSourceFile(source_idx);
  151. int count_includes = reader.ReadLeb128();
  152. if (count_includes > 0)
  153. {
  154. this.include_files = new List<SourceFileEntry>();
  155. for (int i = 0; i < count_includes; i++)
  156. {
  157. this.include_files.Add(this.file.GetSourceFile(reader.ReadLeb128()));
  158. }
  159. }
  160. int count_ns = reader.ReadLeb128();
  161. this.namespaces = new List<NamespaceEntry>();
  162. for (int i = 0; i < count_ns; i++)
  163. {
  164. this.namespaces.Add(new NamespaceEntry(this.file, reader));
  165. }
  166. reader.BaseStream.Position = (long)old_pos;
  167. }
  168. }
  169. }
  170. }
  171. }