예제 #1
0
        //---------------------------------------------------------------------
        // Public methods
        //---------------------------------------------------------------------
        public UTF32String Prepare(UTF32String pSource, IEncodingOption pOption)
        {
            UTF32String output = null;

            if (null == pSource)
            {
                return(new UTF32String());
            }

            // Based on RFC3454:
            // Step 1 & 2: Map & Normalization
            output = this.Map(pSource, pOption);

            // Step 2: Normalization
            output = this.Normalize(output, pOption);

            // Step 3: Prohibition
            output = this.Prohibit(output, pOption);

            // Step 4: Bidi
            output = this.Bidirection(output, pOption);

            // Done
            return(output);
        }
예제 #2
0
        private UTF32String Bidirection(UTF32String pSource, IEncodingOption pOption)
        {
            int       cPoint             = 0;
            bool      bLeftToRight       = false;
            bool      bRightToLeft       = false;
            Direction LastCharDirection  = Direction.DIRECTION_NORM;
            Direction FirstCharDirection = Direction.DIRECTION_NORM;

            // check if we need to check bidi
            if (!pOption.IsOptionSet(EncodingOption.CHECK_BIDI))
            {
                return(pSource);
            }

            // get the first char direction
            FirstCharDirection = m_bidirectionMapping.GetDirection(pSource[0]);

            // for each char, checking it's direction
            for (int index = 1; index < pSource.Length; index++)
            {
                cPoint            = pSource[index];
                LastCharDirection = m_bidirectionMapping.GetDirection(cPoint);

                // check Left to right if necessary
                if (false == bLeftToRight)
                {
                    bLeftToRight = (LastCharDirection == Direction.DIRECTION_RIGHT);
                }

                // check right to left if necesssary
                if (false == bRightToLeft)
                {
                    bLeftToRight = (LastCharDirection == Direction.DIRECTION_LEFT);
                }
            }

            // Based on RFC3454 6.2, check if there are both right to left or left to right
            if (bLeftToRight && bRightToLeft)
            {
                throw new BidiCodePointException(string.Format("Invalid bidi code point found[Can't have both 'RightToLeft' and 'LeftToRight' code point]:  {0} in {1:X8}\r\n", cPoint, pSource.ToString()));
            }

            // Based on RFC3454 6.3, check if there are both right to left
            if (bRightToLeft && (FirstCharDirection != LastCharDirection))
            {
                throw new BidiCodePointException(string.Format("Invalid bidi code point found[first char and last char of string MUST be both 'RightToLeft']:  {0} in {1:X8}\r\n", cPoint, pSource.ToString()));
            }

            // Done.
            return(pSource);
        }
예제 #3
0
        private UTF32String Decode(string pSource, IEncodingOption pOption)
        {
            string      check   = null;
            UTF32String decoded = null;
            UTF32String source  = null;

            try
            {
                // Initializes
                source = new UTF32String(pSource);

                // Step #1-2
                if (!Converter.IsAllAscii(source) && (null != m_preparer))
                {
                    source = m_preparer.Prepare(source, pOption);
                }

                // Step #3-5
                if (null != m_converter)
                {
                    decoded = m_converter.Decode(source.ToUTF16(), new bool[source.Length]);
                }

                // Step #6-7
                if (pOption.IsOptionSet(EncodingOption.DECODE_DOUBLE_CHECK))
                {
                    check = this.Encode(decoded, pOption);
                    if (0 != string.Compare(check, pSource, true))
                    {
                        throw new ACEException("Decoding round trip check failed");
                    }
                }
            }
            catch (Exception e)
            {
                // Based on RFC3492, decode never fails.
                // check if we need to allow decode fail
                if (pOption.IsOptionSet(EncodingOption.ALLOW_DECODE_FAIL))
                {
                    throw e;
                }

                decoded = new UTF32String(pSource);
            }

            // Step #8
            return(decoded);
        }
예제 #4
0
        private UTF32String Prohibit(UTF32String pSource, IEncodingOption pOption)
        {
            int cPoint = 0;

            // valid?
            if (null == pSource)
            {
                return(pSource);
            }

            // for each char
            for (int index = 0; index < pSource.Length; index++)
            {
                cPoint = pSource[index];

                // check if there is any prohibited code point
                if (m_prohibitionMapping.IsProhibited(cPoint))
                {
                    throw new ProhibitedCodePointException(string.Format("Prohibited code point found: {0} in {1:X8}\r\n", cPoint, pSource.ToString()));
                }
            }

            return(pSource);
        }
예제 #5
0
 public override bool Validate(UTF32String pSource, IEncodingOption pOption)
 {
     return(true);
 }
예제 #6
0
        //---------------------------------------------------------------------
        // Private members
        //---------------------------------------------------------------------
        private UTF32String Map(UTF32String pSource, IEncodingOption pOption)
        {
            bool bAllowUnassigned = false;
            bool bNormalize       = true;
            int  cPoint           = 0;

            int[]       mPoint = null;
            UTF32String mapped = null;

            // Initializes
            mapped           = new UTF32String();
            bAllowUnassigned = (pOption != null) && pOption.IsOptionSet(EncodingOption.ALLOW_UNASSIGNED);
            bNormalize       = (pOption != null) && pOption.IsOptionSet(EncodingOption.USE_NORMALIZE);

            // valid?
            if (null == pSource)
            {
                return(mapped);
            }

            // for each char
            for (int index = 0; index < pSource.Length; index++)
            {
                // get code point
                cPoint = pSource[index];

                // check if it's unassigned
                if (bAllowUnassigned && m_unassignedMapping.IsUnassigned(cPoint))
                {
                    throw new UnassignedCodePointException(string.Format("Unassigned code point found: {0} in {1:X8}\r\n", cPoint, pSource.ToString()));
                }

                // check if there is any map nothing
                if (m_nothingMapping.IsMapNothing(cPoint))
                {
                    continue;
                }

                // check the map
                if (bNormalize)
                {
                    mPoint = m_normalizedCaseMapping.Mapping(cPoint);
                }
                else
                {
                    mPoint = m_unnormalizedCaseMapping.Mapping(cPoint);
                }

                // having mapping?
                if ((null == mPoint) || (0 == mPoint.Length))
                {
                    mPoint = new int [1] {
                        cPoint
                    }
                }
                ;

                // add the mapping to the output
                for (int mIndex = 0; mIndex < mPoint.Length; mIndex++)
                {
                    mapped.Append(mPoint[mIndex]);
                }
            }

            //Done
            return(mapped);
        }
예제 #7
0
 public UTF32String Unprepare(UTF32String pSource, IEncodingOption pOption)
 {
     // no implementation based on RFC3454. Reserved for furture extention.
     return(pSource);
 }
예제 #8
0
 private UTF32String Normalize(UTF32String pSource, IEncodingOption pOption)
 {
     return(pSource);
 }
예제 #9
0
        //---------------------------------------------------------------------
        // Private methods
        //---------------------------------------------------------------------
        private string Encode(UTF32String pSource, IEncodingOption pOption)
        {
            bool        bAllAscii = false;
            string      encoded   = null;
            UTF32String prepared  = null;

            // Step #1: set the flag, all ascii?
            bAllAscii = Converter.IsAllAscii(pSource);

            // Step #2
            if (!bAllAscii)
            {
                // check if we need to prepare the string
                if (null != m_preparer)
                {
                    prepared = m_preparer.Prepare(pSource, pOption);
                }
                else
                {
                    prepared = pSource;
                }
            }

            // Step #3: check if we need to apply the rules
            if (pOption.IsOptionSet(EncodingOption.USE_STD3_RULES))
            {
                // failed on Dns compatible?
                if (!Converter.IsAllDnsCompatible(prepared))
                {
                    throw new Std3RuleCodePointException(string.Format("The input does not conform to the STD 3 ASCII rules(DNS Compatible): {0}", prepared.ToString()));
                }

                if (0 < prepared.Length)
                {
                    // first char is hyphen?
                    if (prepared[0] == Converter.CHAR_HYPHEN)
                    {
                        throw new Std3RuleCodePointException(string.Format("The input does not conform to the STD 3 ASCII rules(Hyphen at the beginning): {0}", prepared.ToString()));
                    }

                    // last char is hyphen?
                    if (prepared[prepared.Length - 1] == Converter.CHAR_HYPHEN)
                    {
                        throw new Std3RuleCodePointException(string.Format("The input does not conform to the STD 3 ASCII rules(Hyphen at the end): {0}", prepared.ToString()));
                    }
                }
            }

            //Step #4: check if it's all ascii already
            if (!bAllAscii)
            {
                // Step #5: check if it begin with the 'prefix'
                if (m_converter.IsBeginWithPrefix(prepared))
                {
                    throw new ACEException(string.Format("The input can't begin with an ACE prefix: {0}", pSource.ToString()));
                }

                // Step #6:
                encoded = m_converter.Encode(prepared, new bool[prepared.Length]);

                //Step #7: insert the prefix
                encoded = encoded.Insert(0, m_converter.Prefix);
            }
            else
            {
                encoded = pSource.ToUTF16();
            }

            // Step #8
            if (encoded.Length > Converter.LABEL_MAX_LENGTH)
            {
                throw new ACEException(string.Format("Encoded name too long: {0}", encoded.Length));
            }

            // Done
            return(encoded);
        }
예제 #10
0
 public abstract bool            Validate(UTF32String pSource, IEncodingOption pOption);