/// <summary> /// Get the ordering priority of the previous contracting character in the /// string. </summary> /// <param name="ch"> the starting character of a contracting character token </param> /// <returns> the next contracting character's ordering. Returns NULLORDER /// if the end of string is reached. </returns> private int PrevContractChar(int ch) { // This function is identical to nextContractChar(), except that we've // switched things so that the next() and previous() calls on the Normalizer // are switched and so that we skip entry pairs with the fwd flag turned on // rather than off. Notice that we still use append() and startsWith() when // working on the fragment. This is because the entry pairs that are used // in reverse iteration have their names reversed already. List <EntryPair> list = Ordering.GetContractValues(ch); EntryPair pair = list[0]; int order = pair.Value; pair = list[list.Count - 1]; int maxLength = pair.EntryName.Length(); NormalizerBase tempText = (NormalizerBase)Text_Renamed.clone(); tempText.next(); Key.Length = 0; int c = tempText.previous(); while (maxLength > 0 && c != NormalizerBase.DONE) { if (Character.IsSupplementaryCodePoint(c)) { Key.Append(Character.ToChars(c)); maxLength -= 2; } else { Key.Append((char)c); --maxLength; } c = tempText.previous(); } String fragment = Key.ToString(); maxLength = 1; for (int i = list.Count - 1; i > 0; i--) { pair = list[i]; if (pair.Fwd) { continue; } if (fragment.StartsWith(pair.EntryName) && pair.EntryName.Length() > maxLength) { maxLength = pair.EntryName.Length(); order = pair.Value; } } while (maxLength > 1) { c = Text_Renamed.previous(); maxLength -= Character.CharCount(c); } return(order); }
/// <summary> /// If the given string has been specified as a contracting string /// in this collation table, return its ordering. /// Otherwise return UNMAPPED. /// </summary> private int GetContractOrder(String groupChars) { int result = RBCollationTables.UNMAPPED; if (ContractTable != null) { int ch = groupChars.CodePointAt(0); /* * char ch0 = groupChars.charAt(0); * int ch = Character.isHighSurrogate(ch0)? * Character.toCodePoint(ch0, groupChars.charAt(1)):ch0; */ List <EntryPair> entryTable = GetContractValues(ch); if (entryTable != null) { int index = RBCollationTables.GetEntry(entryTable, groupChars, true); if (index != RBCollationTables.UNMAPPED) { EntryPair pair = entryTable[index]; result = pair.Value; } } } return(result); }
internal static int GetEntry(List <EntryPair> list, String name, bool fwd) { for (int i = 0; i < list.Count; i++) { EntryPair pair = list[i]; if (pair.Fwd == fwd && pair.EntryName.Equals(name)) { return(i); } } return(UNMAPPED); }
private int GetCharOrder(int ch) { int order = Mapping.elementAt(ch); if (order >= RBCollationTables.CONTRACTCHARINDEX) { List <EntryPair> groupList = GetContractValuesImpl(order - RBCollationTables.CONTRACTCHARINDEX); EntryPair pair = groupList[0]; order = pair.Value; } return(order); }
/// <summary> /// Get the ordering priority of the next contracting character in the /// string. </summary> /// <param name="ch"> the starting character of a contracting character token </param> /// <returns> the next contracting character's ordering. Returns NULLORDER /// if the end of string is reached. </returns> private int NextContractChar(int ch) { // First get the ordering of this single character, // which is always the first element in the list List <EntryPair> list = Ordering.GetContractValues(ch); EntryPair pair = list[0]; int order = pair.Value; // find out the length of the longest contracting character sequence in the list. // There's logic in the builder code to make sure the longest sequence is always // the last. pair = list[list.Count - 1]; int maxLength = pair.EntryName.Length(); // (the Normalizer is cloned here so that the seeking we do in the next loop // won't affect our real position in the text) NormalizerBase tempText = (NormalizerBase)Text_Renamed.clone(); // extract the next maxLength characters in the string (we have to do this using the // Normalizer to ensure that our offsets correspond to those the rest of the // iterator is using) and store it in "fragment". tempText.previous(); Key.Length = 0; int c = tempText.next(); while (maxLength > 0 && c != NormalizerBase.DONE) { if (Character.IsSupplementaryCodePoint(c)) { Key.Append(Character.ToChars(c)); maxLength -= 2; } else { Key.Append((char)c); --maxLength; } c = tempText.next(); } String fragment = Key.ToString(); // now that we have that fragment, iterate through this list looking for the // longest sequence that matches the characters in the actual text. (maxLength // is used here to keep track of the length of the longest sequence) // Upon exit from this loop, maxLength will contain the length of the matching // sequence and order will contain the collation-element value corresponding // to this sequence maxLength = 1; for (int i = list.Count - 1; i > 0; i--) { pair = list[i]; if (!pair.Fwd) { continue; } if (fragment.StartsWith(pair.EntryName) && pair.EntryName.Length() > maxLength) { maxLength = pair.EntryName.Length(); order = pair.Value; } } // seek our current iteration position to the end of the matching sequence // and return the appropriate collation-element value (if there was no matching // sequence, we're already seeked to the right position and order already contains // the correct collation-element value for the single character) while (maxLength > 1) { c = Text_Renamed.next(); maxLength -= Character.CharCount(c); } return(order); }
/// <summary> /// Adds the contracting string into the collation table. /// </summary> private void AddContractOrder(String groupChars, int anOrder, bool fwd) { if (ContractTable == null) { ContractTable = new List <>(INITIALTABLESIZE); } //initial character int ch = groupChars.CodePointAt(0); /* * char ch0 = groupChars.charAt(0); * int ch = Character.isHighSurrogate(ch0)? * Character.toCodePoint(ch0, groupChars.charAt(1)):ch0; */ // See if the initial character of the string already has a contract table. int entry = Mapping.elementAt(ch); List <EntryPair> entryTable = GetContractValuesImpl(entry - RBCollationTables.CONTRACTCHARINDEX); if (entryTable == null) { // We need to create a new table of contract entries for this base char int tableIndex = RBCollationTables.CONTRACTCHARINDEX + ContractTable.Count; entryTable = new List <>(INITIALTABLESIZE); ContractTable.Add(entryTable); // Add the initial character's current ordering first. then // update its mapping to point to this contract table entryTable.Add(new EntryPair(groupChars.Substring(0, Character.CharCount(ch)), entry)); Mapping.setElementAt(ch, tableIndex); } // Now add (or replace) this string in the table int index = RBCollationTables.GetEntry(entryTable, groupChars, fwd); if (index != RBCollationTables.UNMAPPED) { EntryPair pair = entryTable[index]; pair.Value = anOrder; } else { EntryPair pair = entryTable[entryTable.Count - 1]; // NOTE: This little bit of logic is here to speed CollationElementIterator // .nextContractChar(). This code ensures that the longest sequence in // this list is always the _last_ one in the list. This keeps // nextContractChar() from having to search the entire list for the longest // sequence. if (groupChars.Length() > pair.EntryName.Length()) { entryTable.Add(new EntryPair(groupChars, anOrder, fwd)); } else { entryTable.Insert(entryTable.Count - 1, new EntryPair(groupChars, anOrder, fwd)); } } // If this was a forward mapping for a contracting string, also add a // reverse mapping for it, so that CollationElementIterator.previous // can work right if (fwd && groupChars.Length() > 1) { AddContractFlags(groupChars); AddContractOrder((new StringBuffer(groupChars)).Reverse().ToString(), anOrder, false); } }