bool XmlNodeReader::Read() const { switch (get_ReadState()) { case Ext::ReadState::EndOfFile: case Ext::ReadState::Error: case Ext::ReadState::Closed: return false; case Ext::ReadState::Initial: m_linkedNode = m_cur = m_startNode; m_readState = Ext::ReadState::Interactive; return bool(m_cur); } // TRC(4, int(m_cur.NodeType) << " " << &m_cur.R << " StartNode type: " << int(m_startNode.NodeType) << " " << &m_startNode.R); MoveToElement(); if (XmlNode firstChild = !m_bEndElement ? m_cur.FirstChild : XmlNode()) { ++m_depth; m_linkedNode = m_cur = firstChild; return true; } if (m_cur == m_startNode) { if (!(m_bEndElement = !IsEmptyElement() && !m_bEndElement)) { m_cur = XmlNode(); m_readState = ReadState::EndOfFile; } m_linkedNode = m_cur; return m_bEndElement; } XmlNodeType curType = m_cur.NodeType; if (!m_bEndElement && !IsEmptyElement() && curType==XmlNodeType::Element) return m_bEndElement = true; if (XmlNode next = m_cur.NextSibling) { m_linkedNode = m_cur = next; return !(m_bEndElement = false); } XmlNode parent; if (curType != XmlNodeType::Document) { parent = m_cur.ParentNode; // TRC(4, "Parent: " << int(parent.NodeType) << " " << &parent.R); } if (m_bEndElement = parent && parent!=m_startNode) { m_cur = parent; --m_depth; } else { m_cur = nullptr; m_readState = ReadState::EndOfFile; } m_linkedNode = m_cur; return m_bEndElement; }
static int ResizeHashArray (TRI_hash_array_t* array) { TRI_hash_index_element_t* oldTable; uint64_t oldAlloc; uint64_t j; int res; oldTable = array->_table; oldAlloc = array->_nrAlloc; res = AllocateTable(array, 2 * array->_nrAlloc + 1); if (res != TRI_ERROR_NO_ERROR) { return res; } array->_nrUsed = 0; #ifdef TRI_INTERNAL_STATS array->_nrResizes++; #endif for (j = 0; j < oldAlloc; j++) { if (! IsEmptyElement(array, &oldTable[j])) { AddNewElement(array, &oldTable[j]); } } TRI_Free(TRI_UNKNOWN_MEM_ZONE, oldTable); return TRI_ERROR_NO_ERROR; }
static void AddNewElement (TRI_hash_array_t* array, TRI_hash_index_element_t* element) { uint64_t hash; uint64_t i; // ........................................................................... // compute the hash // ........................................................................... hash = HashElement(array, element); // ........................................................................... // search the table // ........................................................................... i = hash % array->_nrAlloc; while (! IsEmptyElement(array, &array->_table[i])) { i = (i + 1) % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS array->_nrProbesR++; #endif } // ........................................................................... // add a new element to the associative array // memcpy ok here since are simply moving array items internally // ........................................................................... memcpy(&array->_table[i], element, sizeof(TRI_hash_index_element_t)); array->_nrUsed++; }
TRI_hash_index_element_t* TRI_FindByElementHashArray (TRI_hash_array_t* array, TRI_hash_index_element_t* element) { TRI_hash_index_element_t* element2; element2 = TRI_LookupByElementHashArray(array, element); if (! IsEmptyElement(array, element2) && IsEqualElementElement(array, element2, element)) { return element2; } return NULL; }
TRI_hash_index_element_t* TRI_FindByKeyHashArray (TRI_hash_array_t* array, TRI_index_search_value_t* key) { TRI_hash_index_element_t* element; element = TRI_LookupByKeyHashArray(array, key); if (! IsEmptyElement(array, element) && IsEqualKeyElement(array, key, element)) { return element; } return NULL; }
TRI_vector_pointer_t TRI_LookupByElementHashArrayMulti (TRI_hash_array_t* array, TRI_hash_index_element_t* element) { TRI_vector_pointer_t result; uint64_t hash; uint64_t i; // ........................................................................... // initialise the vector which will hold the result if any // ........................................................................... TRI_InitVectorPointer(&result, TRI_UNKNOWN_MEM_ZONE); // ........................................................................... // compute the hash // ........................................................................... hash = HashElement(array, element); i = hash % array->_nrAlloc; // ........................................................................... // update statistics // ........................................................................... #ifdef TRI_INTERNAL_STATS array->_nrFinds++; #endif // ........................................................................... // search the table // ........................................................................... while (! IsEmptyElement(array, &array->_table[i])) { if (IsEqualElementElement(array, element, &array->_table[i])) { TRI_PushBackVectorPointer(&result, &array->_table[i]); } #ifdef TRI_INTERNAL_STATS else { array->_nrProbesF++; } #endif i = (i + 1) % array->_nrAlloc; } // ........................................................................... // return whatever we found -- which could be an empty vector list if nothing // matches. Note that we allow multiple elements (compare with pointer impl). // ........................................................................... return result; }
UnicodeString XMLReader::ReadString() { if (mNodeType == kElement) { if (IsEmptyElement()) return UnicodeString(); Read(); } UnicodeString result; while ((mNodeType == kText) || (mNodeType == kWhitespace) || (mNodeType == kSignificantWhitespace) || (mNodeType == kCDATA)) { result += mValue; Read(); } return result; }
void XmlNodeReader::Skip() const { if (ReadState == ReadState::Interactive) { MoveToElement (); if (NodeType != XmlNodeType::Element || IsEmptyElement()) Read(); else { for (int depth=Depth; Read() && depth<Depth; ) ; if (NodeType == XmlNodeType::EndElement) Read (); } } }
TRI_hash_index_element_t* TRI_LookupByElementHashArray (TRI_hash_array_t* array, TRI_hash_index_element_t* element) { uint64_t hash; uint64_t i; // ........................................................................... // compute the hash // ........................................................................... hash = HashElement(array, element); i = hash % array->_nrAlloc; // ........................................................................... // update statistics // ........................................................................... #ifdef TRI_INTERNAL_STATS array->_nrFinds++; #endif // ........................................................................... // search the table // ........................................................................... while (! IsEmptyElement(array, &array->_table[i]) && ! IsEqualElementElement(array, element, &array->_table[i])) { i = (i + 1) % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS array->_nrProbesF++; #endif } // ........................................................................... // return whatever we found // ........................................................................... return &array->_table[i]; }
bool XMLReader::IsNotEmptyElementRead() { bool result = ! IsEmptyElement(); Read(); return result; }
void Parse() { ReadNextNode(); WriteElement(); int nDepth = GetDepth(); if (!IsEmptyElement()) { XmlNodeType eNodeType = XmlNodeType_None; int nCurDepth = -1; // У закрывающего тэга глубина на 1 больше, чем у открывающего while (true) { if (1 != xmlTextReaderRead(reader)) break; int nTempType = xmlTextReaderNodeType(reader); if (-1 == nTempType) break; eNodeType = (XmlNodeType)nTempType; nCurDepth = GetDepth(); if (eNodeType == XmlNodeType_Text || eNodeType == XmlNodeType_Whitespace || eNodeType == XmlNodeType_SIGNIFICANT_WHITESPACE) { m_pCurrentNode->m_sText += GetText(); } else if (eNodeType == XmlNodeType_CDATA) { m_pCurrentNode->m_sText += GetText(); } else if (eNodeType == XmlNodeType_Element) { WriteElement(); } else if (eNodeType == XmlNodeType_EndElement) { m_list.pop_back(); if (0 != m_list.size()) { std::list<CXmlNodeBase*>::iterator iter = m_list.end(); --iter; m_pCurrentNode = *iter; } else { m_pCurrentNode = m_pNode; } } nCurDepth = GetDepth(); if (nCurDepth < nDepth) break; if (XmlNodeType_EndElement == eNodeType && nCurDepth == nDepth) break; } } }
int TRI_RemoveKeyHashArray (TRI_hash_array_t* array, TRI_index_search_value_t* key) { uint64_t hash; uint64_t i; uint64_t k; bool found; void* arrayElement; // ........................................................................... // compute the hash // ........................................................................... hash = HashKey(array, key); i = hash % array->_nrAlloc; // ........................................................................... // update statistics // ........................................................................... #ifdef TRI_INTERNAL_STATS array->_nrRems++; #endif // ........................................................................... // search the table // ........................................................................... while (! IsEmptyElement(array, &array->_table[i]) && ! IsEqualKeyElement(array, key, &array->_table[i])) { i = (i + 1) % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS array->_nrProbesD++; #endif } arrayElement = &array->_table[i]; // ........................................................................... // if we did not find such an item return false // ........................................................................... found = ! IsEmptyElement(array, arrayElement); if (! found) { return TRI_RESULT_KEY_NOT_FOUND; } // ........................................................................... // remove item // ........................................................................... DestroyElement(array, arrayElement); array->_nrUsed--; // ........................................................................... // and now check the following places for items to move here // ........................................................................... k = (i + 1) % array->_nrAlloc; while (! IsEmptyElement(array, &array->_table[k])) { uint64_t j = HashElement(array, &array->_table[k]) % array->_nrAlloc; if ((i < k && !(i < j && j <= k)) || (k < i && !(i < j || j <= k))) { array->_table[i] = array->_table[k]; ClearElement(array, &array->_table[k]); i = k; } k = (k + 1) % array->_nrAlloc; } // ........................................................................... // return success // ........................................................................... return TRI_ERROR_NO_ERROR; }
int TRI_RemoveElementHashArray (TRI_hash_array_t* array, TRI_hash_index_element_t* element) { uint64_t hash; uint64_t i; uint64_t k; bool found; void* arrayElement; // ........................................................................... // compute the hash // ........................................................................... hash = HashElement(array, element); i = hash % array->_nrAlloc; // ........................................................................... // update statistics // ........................................................................... #ifdef TRI_INTERNAL_STATS array->_nrRems++; #endif // ........................................................................... // search the table // ........................................................................... while (! IsEmptyElement(array, &array->_table[i]) && ! IsEqualElementElement(array, element, &array->_table[i])) { i = (i + 1) % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS array->_nrProbesD++; #endif } arrayElement = &array->_table[i]; // ........................................................................... // if we did not find such an item return false // ........................................................................... found = ! IsEmptyElement(array, arrayElement); if (! found) { return TRI_RESULT_ELEMENT_NOT_FOUND; } // ........................................................................... // remove item - destroy any internal memory associated with the element structure // ........................................................................... DestroyElement(array, arrayElement); array->_nrUsed--; // ........................................................................... // and now check the following places for items to move closer together // so that there are no gaps in the array // ........................................................................... k = (i + 1) % array->_nrAlloc; while (! IsEmptyElement(array, &array->_table[k])) { uint64_t j = HashElement(array, &array->_table[k]) % array->_nrAlloc; if ((i < k && !(i < j && j <= k)) || (k < i && !(i < j || j <= k))) { array->_table[i] = array->_table[k]; ClearElement(array, &array->_table[k]); i = k; } k = (k + 1) % array->_nrAlloc; } return TRI_ERROR_NO_ERROR; }
int TRI_InsertElementHashArrayMulti (TRI_hash_array_t* array, TRI_hash_index_element_t* element, bool overwrite) { uint64_t hash; uint64_t i; bool found; int res; TRI_hash_index_element_t* arrayElement; // ........................................................................... // compute the hash // ........................................................................... hash = HashElement(array, element); i = hash % array->_nrAlloc; // ........................................................................... // update statistics // ........................................................................... #ifdef TRI_INTERNAL_STATS array->_nrAdds++; #endif // ........................................................................... // search the table // ........................................................................... while (! IsEmptyElement(array, &array->_table[i]) && ! IsEqualElementElement(array, element, &array->_table[i])) { i = (i + 1) % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS array->_nrProbesA++; #endif } arrayElement = &array->_table[i]; // ........................................................................... // If we found an element, return. While we allow duplicate entries in the // hash table, we do not allow duplicate elements. Elements would refer to the // (for example) an actual row in memory. This is different from the // TRI_InsertElementMultiArray function below where we only have keys to // differentiate between elements. // ........................................................................... found = ! IsEmptyElement(array, arrayElement); if (found) { if (overwrite) { // destroy the underlying element since we are going to stomp on top if it DestroyElement(array, arrayElement); *arrayElement = *element; } else { DestroyElement(array, element); } return TRI_RESULT_ELEMENT_EXISTS; } // ........................................................................... // add a new element to the associative array // ........................................................................... *arrayElement = *element; array->_nrUsed++; // ........................................................................... // if we were adding and the table is more than half full, extend it // ........................................................................... if (array->_nrAlloc < 2 * array->_nrUsed) { res = ResizeHashArray(array); if (res != TRI_ERROR_NO_ERROR) { return res; } } return TRI_ERROR_NO_ERROR; }
int TRI_InsertKeyHashArrayMulti (TRI_hash_array_t* array, TRI_index_search_value_t* key, TRI_hash_index_element_t* element, bool overwrite) { uint64_t hash; uint64_t i; int res; TRI_hash_index_element_t* arrayElement; // ........................................................................... // compute the hash // ........................................................................... hash = HashKey(array, key); i = hash % array->_nrAlloc; // ........................................................................... // update statistics // ........................................................................... #ifdef TRI_INTERNAL_STATS array->_nrAdds++; #endif // ........................................................................... // search the table // ........................................................................... while (! IsEmptyElement(array, &array->_table[i])) { i = (i + 1) % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS array->_nrProbesA++; #endif } arrayElement = &array->_table[i]; // ........................................................................... // We do not look for an element (as opposed to the function above). So whether // or not there exists a duplicate we do not care. // ........................................................................... // ........................................................................... // add a new element to the associative array // ........................................................................... *arrayElement = * element; array->_nrUsed++; // ........................................................................... // if we were adding and the table is more than half full, extend it // ........................................................................... if (array->_nrAlloc < 2 * array->_nrUsed) { res = ResizeHashArray(array); if (res != TRI_ERROR_NO_ERROR) { return res; } } return TRI_ERROR_NO_ERROR; }
int TRI_InsertKeyHashArray (TRI_hash_array_t* array, TRI_index_search_value_t* key, TRI_hash_index_element_t* element, bool overwrite) { uint64_t hash; uint64_t i; bool found; int res; TRI_hash_index_element_t* arrayElement; // ........................................................................... // compute the hash // ........................................................................... hash = HashKey(array, key); i = hash % array->_nrAlloc; // ........................................................................... // update statistics // ........................................................................... #ifdef TRI_INTERNAL_STATS array->_nrAdds++; #endif // ........................................................................... // search the table // ........................................................................... while (! IsEmptyElement(array, &array->_table[i]) && ! IsEqualKeyElement(array, key, &array->_table[i])) { i = (i + 1) % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS array->_nrProbesA++; #endif } arrayElement = &array->_table[i]; // ........................................................................... // if we found an element, return // ........................................................................... found = ! IsEmptyElement(array, arrayElement); if (found) { if (overwrite) { // destroy the underlying element since we are going to stomp on top if it DestroyElement(array, arrayElement); *arrayElement = *element; } else { DestroyElement(array, element); } return TRI_RESULT_KEY_EXISTS; } // ........................................................................... // add a new element to the associative array // ........................................................................... *arrayElement = *element; array->_nrUsed++; // ........................................................................... // we are adding and the table is more than half full, extend it // ........................................................................... if (array->_nrAlloc < 2 * array->_nrUsed) { res = ResizeHashArray(array); if (res != TRI_ERROR_NO_ERROR) { return res; } } return TRI_ERROR_NO_ERROR; }
bool XmlCallbackReader::Parse(IContentHandler * pContentHandler) { bool bShouldContinue = true; if (pContentHandler) mpContentHandler = pContentHandler; if (mpContentHandler) mpContentHandler->StartDocument(); while (bShouldContinue && Read() ) { if (mpContentHandler) { const XmlReader::NodeType nodeType = GetNodeType(); switch (nodeType) { case Element: bShouldContinue = mpContentHandler->StartElement( mpTokenName, mAttributeArray.data(), mAttributeArray.size() / 2 ); if (bShouldContinue && IsEmptyElement()) bShouldContinue = mpContentHandler->EndElement( mpTokenName ); break; case EndElement: bShouldContinue = mpContentHandler->EndElement( mpTokenName ); break; case CharacterData: bShouldContinue = mpContentHandler->Characters( mpTokenValue, (size_t)mValueLength ); break; case Comment: bShouldContinue = mpContentHandler->Comment( mpTokenValue, (size_t)mValueLength ); break; case ProcessingInstruction: // As it stands now, the attribute list of the processing instruction is passed as a single unparsed string (mpTokenValue); bShouldContinue = mpContentHandler->ProcessingInstruction( mpTokenName, mpTokenValue ); break; case EntityRef: bShouldContinue = mpContentHandler->SkippedEntity( mpTokenName ); break; case None: case Document: case Prologue: case DocTypeDecl: case EntityDecl: case ElementDecl: case AttListDecl: case NotationDecl: // To do: We should do something about these types so the user can at least see them. break; } } } if (mResultCode == kSuccess) { if (mpContentHandler) mpContentHandler->EndDocument(); return true; } return false; }