/// <summary> /// Serializes the build table with 32 bit data. /// </summary> /// <param name="datamanipulate">Builder raw fold method implementation.</param> /// <param name="triedatamanipulate">Result trie fold method.</param> /// <returns>A new trie.</returns> public virtual Int32Trie Serialize(TrieBuilder.IDataManipulate datamanipulate, Trie.IDataManipulate triedatamanipulate) { if (datamanipulate == null) { throw new ArgumentException("Parameters can not be null"); } // fold and compact if necessary, also checks that indexLength is // within limits if (!m_isCompacted_) { // compact once without overlap to improve folding Compact(false); // fold the supplementary part of the index array Fold(datamanipulate); // compact again with overlap for minimum data array length Compact(true); m_isCompacted_ = true; } // is dataLength within limits? if (m_dataLength_ >= MAX_DATA_LENGTH_) { throw new IndexOutOfRangeException("Data length too small"); } char[] index = new char[m_indexLength_]; int[] data = new int[m_dataLength_]; // write the index (stage 1) array and the 32-bit data (stage 2) array // write 16-bit index values shifted right by INDEX_SHIFT_ for (int i = 0; i < m_indexLength_; i++) { index[i] = (char)(m_index_[i].TripleShift(INDEX_SHIFT_)); } // write 32-bit data values System.Array.Copy(m_data_, 0, data, 0, m_dataLength_); int options = SHIFT_ | (INDEX_SHIFT_ << OPTIONS_INDEX_SHIFT_); options |= OPTIONS_DATA_IS_32_BIT_; if (m_isLatin1Linear_) { options |= OPTIONS_LATIN1_IS_LINEAR_; } return(new Int32Trie(index, data, m_initialValue_, options, triedatamanipulate)); }
/// <summary> /// Serializes the build table to an output stream. /// <para/> /// Compacts the build-time trie after all values are set, and then /// writes the serialized form onto an output stream. /// <para/> /// After this, this build-time Trie can only be serialized again and/or closed; /// no further values can be added. /// <para/> /// This function is the rough equivalent of utrie_seriaize() in ICU4C. /// </summary> /// <param name="os">The output stream to which the seriaized trie will be written. /// If nul, the function still returns the size of the serialized Trie.</param> /// <param name="reduceTo16Bits">If true, reduce the data size to 16 bits. The resulting /// serialized form can then be used to create a <see cref="CharTrie"/>.</param> /// <param name="datamanipulate">Builder raw fold method implementation.</param> /// <returns>The number of bytes written to the output stream.</returns> public virtual int Serialize(Stream os, bool reduceTo16Bits, TrieBuilder.IDataManipulate datamanipulate) { if (datamanipulate == null) { throw new ArgumentException("Parameters can not be null"); } // fold and compact if necessary, also checks that indexLength is // within limits if (!m_isCompacted_) { // compact once without overlap to improve folding Compact(false); // fold the supplementary part of the index array Fold(datamanipulate); // compact again with overlap for minimum data array length Compact(true); m_isCompacted_ = true; } // is dataLength within limits? int length; if (reduceTo16Bits) { length = m_dataLength_ + m_indexLength_; } else { length = m_dataLength_; } if (length >= MAX_DATA_LENGTH_) { throw new IndexOutOfRangeException("Data length too small"); } // struct UTrieHeader { // int32_t signature; // int32_t options (a bit field) // int32_t indexLength // int32_t dataLength length = Trie.HEADER_LENGTH_ + 2 * m_indexLength_; if (reduceTo16Bits) { length += 2 * m_dataLength_; } else { length += 4 * m_dataLength_; } if (os == null) { // No output stream. Just return the length of the serialized Trie, in bytes. return(length); } DataOutputStream dos = new DataOutputStream(os); dos.WriteInt32(Trie.HEADER_SIGNATURE_); int options = Trie.INDEX_STAGE_1_SHIFT_ | (Trie.INDEX_STAGE_2_SHIFT_ << Trie.HEADER_OPTIONS_INDEX_SHIFT_); if (!reduceTo16Bits) { options |= Trie.HEADER_OPTIONS_DATA_IS_32_BIT_; } if (m_isLatin1Linear_) { options |= Trie.HEADER_OPTIONS_LATIN1_IS_LINEAR_MASK_; } dos.WriteInt32(options); dos.WriteInt32(m_indexLength_); dos.WriteInt32(m_dataLength_); /* write the index (stage 1) array and the 16/32-bit data (stage 2) array */ if (reduceTo16Bits) { /* write 16-bit index values shifted right by UTRIE_INDEX_SHIFT, after adding indexLength */ for (int i = 0; i < m_indexLength_; i++) { int v = (m_index_[i] + m_indexLength_).TripleShift(Trie.INDEX_STAGE_2_SHIFT_); dos.WriteChar(v); } /* write 16-bit data values */ for (int i = 0; i < m_dataLength_; i++) { int v = m_data_[i] & 0x0000ffff; dos.WriteChar(v); } } else { /* write 16-bit index values shifted right by UTRIE_INDEX_SHIFT */ for (int i = 0; i < m_indexLength_; i++) { int v = (m_index_[i]).TripleShift(Trie.INDEX_STAGE_2_SHIFT_); dos.WriteChar(v); } /* write 32-bit data values */ for (int i = 0; i < m_dataLength_; i++) { dos.WriteInt32(m_data_[i]); } } return(length); }