public static BitWriter Write_MC(this BitWriter writer, int value) { var bytes = new List <int>(); var isNegative = false; if (value < 0) { value *= -1; isNegative = true; } while (value > 0) { var b = value & 0b01111111; bytes.Add(b); value >>= 7; } if (bytes.Count == 0) { // ensure there's at least one byte written; this happens if `value` is zero bytes.Add(0); } // if last byte's 64 bit is set (which means it's necessary), add one more emtpy byte so it's not interpreted as a negative sign if ((bytes[bytes.Count - 1] & 0x40) != 0) { bytes.Add(0); } for (int i = 0; i < bytes.Count; i++) { var b = bytes[i]; if (i == bytes.Count - 1) { // on last byte, set the negative bit if (isNegative) { b |= 0x40; } } else { // more bytes remain, set high bit b |= 0b10000000; } writer.WriteByte((byte)b); } return(writer); }
public void CopyTo(BitWriter other) { var bits = BitCount; var bytes = this.AsBytes(); var spareBits = bits % 8; var fullBytesCount = spareBits == 0 ? bytes.Length : bytes.Length - 1; for (int i = 0; i < fullBytesCount; i++) { other.WriteByte(bytes[i]); } other.WriteBits(bytes[bytes.Length - 1], spareBits); }
public void Write(BitWriter writer, bool writingSecondHeader = false) { writer.WriteByte(RecordNumber); if (writingSecondHeader) { writer.Write_BL(Pointer); writer.Write_BL(Length); } else { writer.WriteInt(Pointer); writer.WriteInt(Length); } }
public static BitWriter Write_T(this BitWriter writer, string value) { if (value == null) { writer.Write_BS(0); return(writer); } writer.Write_BS((short)value.Length); foreach (var c in value) { writer.WriteByte((byte)c); } return(writer); }
public static BitWriter Write_H(this BitWriter writer, DwgHandleReference handle) { var bytes = new Stack <byte>(); var offset = handle.HandleOrOffset; while (offset != 0) { bytes.Push((byte)(offset & 0xFF)); offset >>= 8; } var header = (((int)handle.Code) << 4) | (bytes.Count & 0x0F); writer.WriteByte((byte)header); writer.WriteBytes(bytes); return(writer); }
public static BitWriter Write_BL(this BitWriter writer, int value) { if (value == 0) { writer.Write_BB(0b10); } else if (value >= 0 && value <= 255) { writer.Write_BB(0b01); writer.WriteByte((byte)value); } else { writer.Write_BB(0b00); writer.WriteInt(value); } return(writer); }
public static BitWriter Write_BS(this BitWriter writer, short value) { if (value == 0) { writer.Write_BB(0b10); } else if (value == 256) { writer.Write_BB(0b11); } else if (value >= 0 && value <= 255) { writer.Write_BB(0b01); writer.WriteByte((byte)value); } else { writer.Write_BB(0b00); writer.WriteShort(value); } return(writer); }
public static BitWriter Write_RC(this BitWriter writer, byte value) { writer.WriteByte(value); return(writer); }
internal void WriteSecondHeader(BitWriter writer, DwgHeaderVariables headerVariables, int pointer) { // write to memory the backtrack to fill in size and crc using (var ms = new MemoryStream()) { var tempWriter = new BitWriter(ms); tempWriter.WriteBytes(SecondHeaderStartSentinel); var sizeOffset = tempWriter.Position; tempWriter.Write_RL(0); // size, filled in later tempWriter.Write_BL(pointer); tempWriter.WriteStringAscii(Version.VersionString(), nullTerminated: false); tempWriter.WriteBytes(new byte[] { 0, 0, 0, 0, 0, 0 }); // 6 zero bytes tempWriter.WriteBits(0x00000000, 4); // 4 zero bits tempWriter.WriteBytes(new byte[] { 0, 0 }); // 2 unknown bytes tempWriter.WriteBytes(SecondHeaderMidSentinel); tempWriter.WriteByte(5); // record locator count HeaderVariablesLocator.Write(tempWriter, writingSecondHeader: true); ClassSectionLocator.Write(tempWriter, writingSecondHeader: true); ObjectMapLocator.Write(tempWriter, writingSecondHeader: true); UnknownSection_R13C3AndLaterLocator.Write(tempWriter, writingSecondHeader: true); UnknownSection_PaddingLocator.Write(tempWriter, writingSecondHeader: true); tempWriter.Write_BS(14); headerVariables.NextAvailableHandle.WriteSecondHeader(tempWriter, 0); headerVariables.BlockControlObjectHandle.WriteSecondHeader(tempWriter, 1); headerVariables.LayerControlObjectHandle.WriteSecondHeader(tempWriter, 2); headerVariables.StyleObjectControlHandle.WriteSecondHeader(tempWriter, 3); headerVariables.LineTypeObjectControlHandle.WriteSecondHeader(tempWriter, 4); headerVariables.ViewControlObjectHandle.WriteSecondHeader(tempWriter, 5); headerVariables.UcsControlObjectHandle.WriteSecondHeader(tempWriter, 6); headerVariables.ViewPortControlObjectHandle.WriteSecondHeader(tempWriter, 7); headerVariables.AppIdControlObjectHandle.WriteSecondHeader(tempWriter, 8); headerVariables.DimStyleControlObjectHandle.WriteSecondHeader(tempWriter, 9); headerVariables.ViewPortEntityHeaderControlObjectHandle.WriteSecondHeader(tempWriter, 10); headerVariables.NamedObjectsDictionaryHandle.WriteSecondHeader(tempWriter, 11); headerVariables.MLineStyleDictionaryHandle.WriteSecondHeader(tempWriter, 12); headerVariables.GroupDictionaryHandle.WriteSecondHeader(tempWriter, 13); tempWriter.WriteByte(0); // unknown tempWriter.AlignByte(); var crcOffset = tempWriter.Position; tempWriter.WriteShort(0); // CRC, filled in later if (Version == DwgVersionId.R14) { // unknown garbage bytes tempWriter.WriteBytes(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }); } tempWriter.WriteBytes(SecondHeaderEndSentinel); // get bytes of header var secondHeaderBytes = tempWriter.AsBytes(); // fill in size var sizeBytes = BitConverter.GetBytes(secondHeaderBytes.Length - SecondHeaderStartSentinel.Length - SecondHeaderEndSentinel.Length); if (!BitConverter.IsLittleEndian) { Array.Reverse(sizeBytes); } Array.Copy(sizeBytes, 0, secondHeaderBytes, sizeOffset, sizeBytes.Length); // fill in crc var crc = BitReaderExtensions.ComputeCRC(secondHeaderBytes, sizeOffset, crcOffset - sizeOffset, DwgHeaderVariables.InitialCrcValue); var crcBytes = BitConverter.GetBytes(crc); if (!BitConverter.IsLittleEndian) { Array.Reverse(crcBytes); } Array.Copy(crcBytes, 0, secondHeaderBytes, crcOffset, crcBytes.Length); // write to the real writer writer.WriteBytes(secondHeaderBytes); } }