Esempio n. 1
0
        /// <summary>
        /// Writes the boolean value to the stream
        /// </summary>
        /// <param name="value">The value to write</param>
        /// <param name="tag">The tag for the value</param>
        /// <param name="scope">The scope for the value</param>
        public async Task WriteAsync(bool value, int tag, EncodingScope scope)
        {
            await EncodeHeaderAsync(tag, scope, true);
            await EncodeLengthAsync(1);

            _target.WriteByte(value ? (byte)0xFF : (byte)0x0);
        }
Esempio n. 2
0
        /// <summary>
        /// Writes a string value to the stream
        /// </summary>
        /// <param name="value">The value to write</param>
        /// <param name="tag">The tag for the value</param>
        /// <param name="scope">The scope for the value</param>
        public async Task WriteAsync(string value, int tag, EncodingScope scope)
        {
            var buffer = System.Text.Encoding.UTF8.GetBytes(value);

            await EncodeHeaderAsync(tag, scope, true);
            await EncodeLengthAsync(buffer.Length);

            await _target.WriteAsync(buffer, 0, buffer.Length);
        }
Esempio n. 3
0
        /// <summary>
        /// Writes the integer value to the stream
        /// </summary>
        /// <param name="value">The value to write</param>
        /// <param name="tag">The tag for the value</param>
        /// <param name="scope">The scope for the value</param>
        public async Task WriteAsync(int value, int tag, EncodingScope scope)
        {
            // Write the header
            await EncodeHeaderAsync(tag, scope, true);

            // Calculate the bits required to write this value
            var bits = value.MSB() + 1;
            var len  = bits >> 3;
            var rem  = bits & 0x7;

            // Will we require extra bitss?
            if (rem > 0)
            {
                len++;
            }

            // Write the length
            await EncodeLengthAsync(len);

            // Write the value
            if (len == 0)
            {
                _target.WriteByte((byte)value);
            }
            else
            {
                // Write the value
                var n   = bits >> 3;
                var idx = 0;

                // 4 bytes for an integer max
                var contents = new byte[4];
                var rShift   = bits - rem;

                // Handle overflow
                if (rem > 0)
                {
                    contents[idx++] = (byte)((value >> rShift) & 0xFF);
                }

                // Write remainder
                for (var i = n - 1; i > 0; --i)
                {
                    contents[idx++] = (byte)((value >> ((rShift -= 8))) & 0xFF);
                }

                // Write the last bits
                if (bits > 7)
                {
                    contents[idx++] = (byte)(value & 0xFF);
                }

                // Write the portion of the buffer used
                await _target.WriteAsync(contents, 0, idx);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Encodes the header information to the stream
        /// </summary>
        /// <param name="tag">The tag value</param>
        /// <param name="scope">The current scope</param>
        /// <param name="isPrimitive">Flag for if the contents are primitive</param>
        /// <returns></returns>
        async Task EncodeHeaderAsync(int tag, EncodingScope scope, bool isPrimitive)
        {
            // Create the tag header
            var header = (int)scope << 6;

            header |= (isPrimitive ? 0 : 1) << 5;

            // Safe to write entire tag
            if (tag < 31)
            {
                _target.WriteByte((byte)(header | tag));
            }
            else
            {
                // Check the number of bits used to represent the number
                var bits = tag.MSB() + 1;

                // Can't go over 6 bytes but 8 feels better for alignment
                var contents = new byte[8];
                var idx      = 0;

                // Header + indicator
                contents[idx++] = (byte)(header | 0x1F);

                // Get the number of bits to the left remaining
                var rem    = bits % 7;
                var rShift = bits - rem;
                if (rem > 0)
                {
                    contents[idx++] = (byte)(0x80 | (((tag >> rShift) & 0x7F)));
                }

                // Write middle bytes
                for (var n = bits / 7 - 1; n > 0; --n)
                {
                    contents[idx++] = (byte)(0x80 | (((tag >> (rShift -= 7)) & 0x7F)));
                }

                // Write any remaining bits
                if (bits > 6)
                {
                    contents[idx++] = (byte)(tag & 0x7F);
                }

                // Write the portion of the buffer used
                await _target.WriteAsync(contents, 0, idx);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Copies the writer to this as a complex object
        /// </summary>
        /// <param name="writer">The writer to copy</param>
        /// <param name="tag">The tag to use for the object</param>
        /// <param name="scope">The scope to use for the object</param>
        public async Task WriteAsync(LDAPWriter writer, int tag, EncodingScope scope)
        {
            await EncodeHeaderAsync(tag, scope, false);

            // Get the underlying stream
            var s = writer._target;

            // Reset the stream if possible for copying
            if (s.Position != 0 && s.CanSeek)
            {
                s.Seek(0, SeekOrigin.Begin);
            }
            else if (s.Length - s.Position <= 0)
            {
                throw new LDAPProtocolException("Stream has data that cannot be recovered");
            }

            // Write the number of bytes available in the stream
            await EncodeLengthAsync((int)(s.Length - s.Position));

            // Copy the streams
            await s.CopyToAsync(_target);
        }
Esempio n. 6
0
 /// <summary>
 /// Writes a null value to the stream
 /// </summary>
 /// <param name="tag">The tag to use</param>
 /// <param name="scope">The scope for the value</param>
 public async Task WriteNullAsync(int tag, EncodingScope scope)
 {
     await EncodeHeaderAsync(tag, scope, true);
     await EncodeLengthAsync(0);
 }