public CDIItem ReadItem() { long nextIndex = Index; // Read the CDIBaseInfo header byte version = ReadByte(); if (version != CDIVERSION) { throw new FormatException("Got unexpected CDIBaseInfo version at " + Index); } byte kind = ReadByte(); SkipPadding(4); uint size = ReadUInt32(); nextIndex += size; CDIItem item = null; // Read kind-specific data switch ((CDIKind)kind) { case CDIKind.UsingInfo: ushort cUsings = ReadUInt16(); CDIUsing cdiUsing = new CDIUsing(); cdiUsing.countOfUsing = new int[cUsings]; for (ushort j = 0; j < cUsings; j++) { cdiUsing.countOfUsing[j] = ReadUInt16(); } SkipPadding(4); item = cdiUsing; break; case CDIKind.ForwardInfo: uint tokenToForwardTo = ReadUInt32(); CDIForward fwd = new CDIForward(); fwd.tokenToForwardTo = Util.AsToken((int)tokenToForwardTo); item = fwd; break; case CDIKind.ForwardToModuleInfo: uint token = ReadUInt32(); CDIForwardModule modFwd = new CDIForwardModule(); modFwd.tokenOfModuleInfo = Util.AsToken((int)token); item = modFwd; break; case CDIKind.IteratorLocals: int cBuckets = ReadInt32(); if (cBuckets < 0) { throw new FormatException("Unexpected negative iteratorLocal bucket count at " + BaseStream.Position); } CDIIteratorLocals iterLocals = new CDIIteratorLocals(); iterLocals.buckets = new CDIIteratorLocalBucket[cBuckets]; for (int j = 0; j < cBuckets; j++) { CDIIteratorLocalBucket b = new CDIIteratorLocalBucket(); b.ilOffsetStart = ReadInt32(); b.ilOffsetEnd = ReadInt32(); iterLocals.buckets[j] = b; } item = iterLocals; break; case CDIKind.ForwardIterator: CDIForwardIterator fwdIter = new CDIForwardIterator(); fwdIter.iteratorClassName = ReadString(); SkipPadding(4); item = fwdIter; break; default: CDIUnknown u = new CDIUnknown(); u.kind = kind; byte[] bytes = ReadBytes(checked ((int)(nextIndex - Index))); u.bytes = Util.ToHexString(bytes); item = u; break; } if (Index != nextIndex) { throw new FormatException(String.Format("Expected CDI item to end at index {0}, but ended at {1} instead", nextIndex, Index)); } item.version = version; return(item); }
private void WriteItem(CDIItem item) { long startPos = BaseStream.Position; uint length = 2 * sizeof(int); Write((byte)item.version); if (item is CDIUsing) { CDIUsing cdiUsing = (CDIUsing)item; Write((byte)CDIKind.UsingInfo); WritePadding(4); length = AlignUp(8 + ((uint)cdiUsing.countOfUsing.Length + 1) * sizeof(ushort), 4); Write(length); Write(checked ((ushort)cdiUsing.countOfUsing.Length)); foreach (ushort u in cdiUsing.countOfUsing) { Write(u); } WritePadding(4); } else if (item is CDIForward) { CDIForward cdiFwd = (CDIForward)item; Write((byte)CDIKind.ForwardInfo); WritePadding(4); length = 12; Write(length); Write(Util.ToInt32(cdiFwd.tokenToForwardTo, 16)); } else if (item is CDIForwardModule) { CDIForwardModule cdiFwdMod = (CDIForwardModule)item; Write((byte)CDIKind.ForwardToModuleInfo); WritePadding(4); length = 12; Write(length); Write(Util.ToInt32(cdiFwdMod.tokenOfModuleInfo, 16)); } else if (item is CDIIteratorLocals) { CDIIteratorLocals cdiIterLocals = (CDIIteratorLocals)item; Write((byte)CDIKind.IteratorLocals); WritePadding(4); length = (uint)(12 + cdiIterLocals.buckets.Length * 2 * sizeof(uint)); Write(length); Write(cdiIterLocals.buckets.Length); foreach (CDIIteratorLocalBucket b in cdiIterLocals.buckets) { Write(b.ilOffsetStart); Write(b.ilOffsetEnd); } } else if (item is CDIForwardIterator) { CDIForwardIterator cdiIter = (CDIForwardIterator)item; Write((byte)CDIKind.ForwardIterator); WritePadding(4); length = AlignUp(8 + 2 * ((uint)cdiIter.iteratorClassName.Length + 1), 4); Write(length); WriteString(cdiIter.iteratorClassName); WritePadding(4); } else if (item is CDIUnknown) { CDIUnknown cdiUnknown = (CDIUnknown)item; Write((byte)cdiUnknown.kind); WritePadding(4); byte[] bytes = Util.ToByteArray(cdiUnknown.bytes); length = 8 + (uint)bytes.Length; Write(length); Write(bytes); } else { Debug.Assert(false, "Unexpected CDIItem type"); } Debug.Assert(BaseStream.Position == startPos + length, "Didn't write the length we promised"); }