Пример #1
0
        private static byte[] DecodingByteArrayHelper(SafeBerHandle berElement, char fmt, ref int error)
        {
            error = 0;
            IntPtr result      = IntPtr.Zero;
            berval binaryValue = new berval();

            byte[] byteArray = null;

            // can't use SafeBerval here as CLR creates a SafeBerval which points to a different memory location, but when doing memory
            // deallocation, wldap has special check. So have to use IntPtr directly here.
            error = BerPal.ScanNextPtr(berElement, new string(fmt, 1), ref result);

            try
            {
                if (!BerPal.IsBerDecodeError(error))
                {
                    if (result != IntPtr.Zero)
                    {
                        Marshal.PtrToStructure(result, binaryValue);

                        byteArray = new byte[binaryValue.bv_len];
                        Marshal.Copy(binaryValue.bv_val, byteArray, 0, binaryValue.bv_len);
                    }
                }
                else
                {
                    Debug.WriteLine("ber_scanf for format character 'O' failed");
                }
            }
            finally
            {
                if (result != IntPtr.Zero)
                {
                    BerPal.FreeBerval(result);
                }
            }

            return(byteArray);
        }
Пример #2
0
        public static byte[] Encode(string format, params object[] value)
        {
            if (format == null)
            {
                throw new ArgumentNullException(nameof(format));
            }

            // no need to turn on invalid encoding detection as we just do string->byte[] conversion.
            UTF8Encoding utf8Encoder = new UTF8Encoding();

            byte[] encodingResult = null;
            // value is allowed to be null in certain scenario, so if it is null, just set it to empty array.
            if (value == null)
            {
                value = Array.Empty <object>();
            }

            Debug.WriteLine("Begin encoding\n");

            // allocate the berelement
            SafeBerHandle berElement = new SafeBerHandle();

            int valueCount = 0;
            int error      = 0;

            for (int formatCount = 0; formatCount < format.Length; formatCount++)
            {
                char fmt = format[formatCount];
                if (fmt == '{' || fmt == '}' || fmt == '[' || fmt == ']' || fmt == 'n')
                {
                    // no argument needed
                    error = BerPal.PrintEmptyArgument(berElement, new string(fmt, 1));
                }
                else if (fmt == 't' || fmt == 'i' || fmt == 'e')
                {
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (!(value[valueCount] is int))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be int\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    // one int argument
                    error = BerPal.PrintInt(berElement, new string(fmt, 1), (int)value[valueCount]);

                    // increase the value count
                    valueCount++;
                }
                else if (fmt == 'b')
                {
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (!(value[valueCount] is bool))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be boolean\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    // one int argument
                    error = BerPal.PrintInt(berElement, new string(fmt, 1), (bool)value[valueCount] ? 1 : 0);

                    // increase the value count
                    valueCount++;
                }
                else if (fmt == 's')
                {
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (value[valueCount] != null && !(value[valueCount] is string))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be string, but receiving value has type of ");
                        Debug.WriteLine(value[valueCount].GetType());
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    // one string argument
                    byte[] tempValue = null;
                    if (value[valueCount] != null)
                    {
                        tempValue = utf8Encoder.GetBytes((string)value[valueCount]);
                    }
                    error = EncodingByteArrayHelper(berElement, tempValue, 'o');

                    // increase the value count
                    valueCount++;
                }
                else if (fmt == 'o' || fmt == 'X')
                {
                    // we need to have one arguments
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (value[valueCount] != null && !(value[valueCount] is byte[]))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be byte[], but receiving value has type of ");
                        Debug.WriteLine(value[valueCount].GetType());
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    byte[] tempValue = (byte[])value[valueCount];
                    error = EncodingByteArrayHelper(berElement, tempValue, fmt);

                    valueCount++;
                }
                else if (fmt == 'v')
                {
                    // we need to have one arguments
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (value[valueCount] != null && !(value[valueCount] is string[]))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be string[], but receiving value has type of ");
                        Debug.WriteLine(value[valueCount].GetType());
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    string[] stringValues = (string[])value[valueCount];
                    byte[][] tempValues   = null;
                    if (stringValues != null)
                    {
                        tempValues = new byte[stringValues.Length][];
                        for (int i = 0; i < stringValues.Length; i++)
                        {
                            string s = stringValues[i];
                            if (s == null)
                            {
                                tempValues[i] = null;
                            }
                            else
                            {
                                tempValues[i] = utf8Encoder.GetBytes(s);
                            }
                        }
                    }

                    error = EncodingMultiByteArrayHelper(berElement, tempValues, 'V');

                    valueCount++;
                }
                else if (fmt == 'V')
                {
                    // we need to have one arguments
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (value[valueCount] != null && !(value[valueCount] is byte[][]))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be byte[][], but receiving value has type of ");
                        Debug.WriteLine(value[valueCount].GetType());
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    byte[][] tempValue = (byte[][])value[valueCount];

                    error = EncodingMultiByteArrayHelper(berElement, tempValue, fmt);

                    valueCount++;
                }
                else
                {
                    Debug.WriteLine("Format string contains undefined character: ");
                    Debug.WriteLine(new string(fmt, 1));
                    throw new ArgumentException(SR.BerConverterUndefineChar);
                }

                // process the return value
                if (error == -1)
                {
                    Debug.WriteLine("ber_printf failed\n");
                    throw new BerConversionException();
                }
            }

            // get the binary value back
            berval binaryValue = new berval();
            IntPtr flattenptr  = IntPtr.Zero;

            try
            {
                // can't use SafeBerval here as CLR creates a SafeBerval which points to a different memory location, but when doing memory
                // deallocation, wldap has special check. So have to use IntPtr directly here.
                error = BerPal.FlattenBerElement(berElement, ref flattenptr);

                if (error == -1)
                {
                    Debug.WriteLine("ber_flatten failed\n");
                    throw new BerConversionException();
                }

                if (flattenptr != IntPtr.Zero)
                {
                    Marshal.PtrToStructure(flattenptr, binaryValue);
                }

                if (binaryValue == null || binaryValue.bv_len == 0)
                {
                    encodingResult = Array.Empty <byte>();
                }
                else
                {
                    encodingResult = new byte[binaryValue.bv_len];

                    Marshal.Copy(binaryValue.bv_val, encodingResult, 0, binaryValue.bv_len);
                }
            }
            finally
            {
                if (flattenptr != IntPtr.Zero)
                {
                    BerPal.FreeBerval(flattenptr);
                }
            }

            return(encodingResult);
        }