//--------------------------------------------------------------------- // 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); }
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); }
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); }
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); }
public override bool Validate(UTF32String pSource, IEncodingOption pOption) { return(true); }
//--------------------------------------------------------------------- // 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); }
public UTF32String Unprepare(UTF32String pSource, IEncodingOption pOption) { // no implementation based on RFC3454. Reserved for furture extention. return(pSource); }
private UTF32String Normalize(UTF32String pSource, IEncodingOption pOption) { return(pSource); }
//--------------------------------------------------------------------- // 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); }
public abstract bool Validate(UTF32String pSource, IEncodingOption pOption);