Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
 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);
     }
 }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
 public static BitWriter Write_RC(this BitWriter writer, byte value)
 {
     writer.WriteByte(value);
     return(writer);
 }
Example #9
0
        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);
            }
        }