internal void Write(MonoSymbolFile file, MyBinaryWriter bw)
{
int start = (int) bw.BaseStream.Position;
bool last_is_hidden = false;
int last_line = 1, last_offset = 0, last_file = 1;
for (int i = 0; i < LineNumbers.Length; i++) {
int line_inc = LineNumbers [i].Row - last_line;
int offset_inc = LineNumbers [i].Offset - last_offset;
if (SuppressDuplicates && (i+1 < LineNumbers.Length)) {
if (LineNumbers [i+1].Equals (LineNumbers [i]))
continue;
}
if (LineNumbers [i].File != last_file) {
bw.Write (DW_LNS_set_file);
bw.WriteLeb128 (LineNumbers [i].File);
last_file = LineNumbers [i].File;
}
if (LineNumbers [i].IsHidden != last_is_hidden) {
bw.Write ((byte) 0);
bw.Write ((byte) 1);
bw.Write (DW_LNE_MONO_negate_is_hidden);
last_is_hidden = LineNumbers [i].IsHidden;
}
#if DEBUGGER_SOURCE
if (LineNumbers [i].SourceRange != null) {
bw.Write ((byte) 0);
long tmp_offset = bw.BaseStream.Position;
bw.Write ((byte) 0);
bw.Write (DW_LNE_MONO_set_source_range);
/*
* Use a private extended opcode to encode source ranges.
*
* Instead of only having one integer "line number", we now have a struct
* containing 'StartLine', 'EndLine', 'StartColumn' and 'EndColumn'.
*/
SourceRangeEntry range = (SourceRangeEntry) LineNumbers [i].SourceRange;
/*
* We use some optimization here: since the start and end lines are usually
* close together, we use relative values, so we can encode it as a single-byte
* even for large source files.
*/
bw.WriteLeb128 (range.StartLine - last_line);
bw.WriteLeb128 (range.EndLine - range.StartLine);
bw.WriteLeb128 (range.StartColumn);
bw.WriteLeb128 (range.EndColumn);
long tmp_size = bw.BaseStream.Position - tmp_offset - 1;
long tmp_end = bw.BaseStream.Position;
bw.BaseStream.Position = tmp_offset;
bw.Write ((byte) tmp_size);
bw.BaseStream.Position = tmp_end;
}
#endif
if (offset_inc >= MaxAddressIncrement) {
if (offset_inc < 2 * MaxAddressIncrement) {
bw.Write (DW_LNS_const_add_pc);
offset_inc -= MaxAddressIncrement;
} else {
bw.Write (DW_LNS_advance_pc);
bw.WriteLeb128 (offset_inc);
offset_inc = 0;
}
}
if ((line_inc < LineBase) || (line_inc >= LineBase + LineRange)) {
bw.Write (DW_LNS_advance_line);
bw.WriteLeb128 (line_inc);
if (offset_inc != 0) {
bw.Write (DW_LNS_advance_pc);
bw.WriteLeb128 (offset_inc);
}
bw.Write (DW_LNS_copy);
} else {
byte opcode;
opcode = (byte) (line_inc - LineBase + (LineRange * offset_inc) +
OpcodeBase);
bw.Write (opcode);
}
last_line = LineNumbers [i].Row;
last_offset = LineNumbers [i].Offset;
}
bw.Write ((byte) 0);
bw.Write ((byte) 1);
bw.Write (DW_LNE_end_sequence);
file.ExtendedLineNumberSize += (int) bw.BaseStream.Position - start;
}