// simple arc creation test gpointer create_arc_thread(gpointer data) { sc_memory_context *ctx = sc_memory_context_new(sc_access_lvl_make(8, 8)); int count = GPOINTER_TO_INT(data); int result = count; for (int i = 0; i < count; ++i) { sc_addr addr = sc_memory_node_new(ctx, 0); if (SC_ADDR_IS_EMPTY(addr)) goto result; sc_addr addr2 = sc_memory_node_new(ctx, 0); if (SC_ADDR_IS_EMPTY(addr2)) goto result; sc_addr arc = sc_memory_arc_new(ctx, sc_type_arc_access, addr, addr); if (SC_ADDR_IS_EMPTY(arc)) goto result; continue; result = i + 1; break; } result: { sc_memory_context_free(ctx); } return GINT_TO_POINTER(result); }
// simple sc-links creation gpointer create_link_thread(gpointer data) { sc_memory_context *ctx = sc_memory_context_new(sc_access_lvl_make(8, 8)); int count = GPOINTER_TO_INT(data); int result = count; for (int i = 0; i < count; ++i) { sc_addr addr = sc_memory_link_new(ctx); if (SC_ADDR_IS_EMPTY(addr)) result = i + 1; } sc_memory_context_free(ctx); return GINT_TO_POINTER(result); }
sc_addr SCsTranslator::createScAddr(sElement *el) { sc_addr addr; SC_ADDR_MAKE_EMPTY(addr); if (el->type & sc_type_node) addr = sc_memory_node_new(mContext, el->type); else if (el->type & sc_type_link) { addr = sc_memory_link_new(mContext); // setup link content if (el->link_is_file) { String file_path; if (_getAbsFilePath(el->file_path, file_path)) { sc_stream *stream = sc_stream_file_new(file_path.c_str(), SC_STREAM_FLAG_READ); if (stream) { sc_memory_set_link_content(mContext, addr, stream); sc_stream_free(stream); } else { THROW_EXCEPT(Exception::ERR_FILE_NOT_FOUND, "Can't open file " + el->file_path, mParams.fileName, -1); } } else { THROW_EXCEPT(Exception::ERR_INVALID_PARAMS, "Unsupported link type " + el->file_path, mParams.fileName, -1); } } else { sc_stream *stream = sc_stream_memory_new(el->link_data.data.data(), (sc_uint)el->link_data.data.size(), SC_STREAM_FLAG_READ, SC_FALSE); sc_memory_set_link_content(mContext, addr, stream); sc_stream_free(stream); } // generate format information if (mParams.autoFormatInfo) { if (el->link_is_file) { size_t n = el->file_path.find_last_of("."); if (n != String::npos) generateFormatInfo(addr, el->file_path.substr(n + 1)); } } } else { assert(el->arc_src && el->arc_trg); if (SC_ADDR_IS_EMPTY(el->arc_src->addr) || SC_ADDR_IS_EMPTY(el->arc_trg->addr)) return addr; addr = sc_memory_arc_new(mContext, el->type, el->arc_src->addr, el->arc_trg->addr); } el->addr = addr; return addr; }
sc_addr SCsTranslator::resolveScAddr(sElement *el) { assert(SC_ADDR_IS_EMPTY(el->addr)); sc_addr addr; SC_ADDR_MAKE_EMPTY(addr); if (!el->idtf.empty()) { // try to find in system identifiers tStringAddrMap::iterator it = mSysIdtfAddrs.find(el->idtf); if (it != mSysIdtfAddrs.end()) { addr = it->second; } else { // try to find in global identifiers it = msGlobalIdtfAddrs.find(el->idtf); if (it != msGlobalIdtfAddrs.end()) addr = it->second; else { // try to find in local identifiers it = mLocalIdtfAddrs.find(el->idtf); if (it != mLocalIdtfAddrs.end()) addr = it->second; else { // resolve system identifier sc_result res = sc_helper_find_element_by_system_identifier(mContext, el->idtf.c_str(), (sc_uint32)el->idtf.size(), &addr); if (res == SC_RESULT_OK) mSysIdtfAddrs[el->idtf] = addr; } } } } if (SC_ADDR_IS_NOT_EMPTY(addr)) { sc_type t = 0; if (sc_memory_get_element_type(mContext, addr, &t) == SC_RESULT_OK) sc_memory_change_element_subtype(mContext, addr, ~sc_type_element_mask & (el->type | t)); el->addr = addr; return addr; } // generate addr addr = createScAddr(el); // store in addrs map if (!el->idtf.empty()) { switch (_getIdentifierVisibility(el->idtf)) { case IdtfSystem: sc_helper_set_system_identifier(mContext, addr, el->idtf.c_str(), (sc_uint32)el->idtf.size()); mSysIdtfAddrs[el->idtf] = addr; break; case IdtfLocal: mLocalIdtfAddrs[el->idtf] = addr; break; case IdtfGlobal: msGlobalIdtfAddrs[el->idtf] = addr; break; } } return addr; }
bool SCsTranslator::buildScText(pANTLR3_BASE_TREE tree) { int nodesCount = tree->getChildCount(tree); for (int i = 0; i < nodesCount; ++i) { pANTLR3_BASE_TREE sentenceNode = (pANTLR3_BASE_TREE)tree->getChild(tree, i); eSentenceType sentenceType = determineSentenceType(sentenceNode); switch (sentenceType) { case SentenceLevel1: processSentenceLevel1(sentenceNode); break; case SentenceLevel2_7: processSentenceLevel2_7(sentenceNode); break; case SentenceAssign: processSentenceAssign(sentenceNode); break; case SentenceEOF: break; default: THROW_EXCEPT(Exception::ERR_PARSE, "Unknown sentence type.", mParams.fileName, sentenceNode->getLine(sentenceNode)); break; } } // now generate sc-text in memory tElementSet::iterator it, itEnd = mElementSet.end(); for (it = mElementSet.begin(); it != itEnd; ++it) { sElement *el = *it; assert(el); if (el->type == sc_type_arc_pos_const_perm) { sc_type type = _getTypeBySetIdtf(el->arc_src->idtf); if (type != 0) { el->ignore = true; sc_type newType = el->arc_trg->type | type; // TODO check conflicts in sc-type if ((type & sc_type_constancy_mask) != 0) newType = (type & sc_type_constancy_mask) | (newType & ~sc_type_constancy_mask); el->arc_trg->type = newType; } } // arcs already have types if (!(el->type & sc_type_arc_mask)) determineElementType(el); } tElementSet arcs; for (it = mElementSet.begin(); it != itEnd; ++it) { sElement *el = *it; assert(el); // skip processed triples if (el->ignore) continue; sc_addr addr = resolveScAddr(el); if (SC_ADDR_IS_EMPTY(addr)) { assert(el->type & sc_type_arc_mask); arcs.insert(el); } } bool created = true; while (!arcs.empty() && created) { created = false; tElementSet createdSet; itEnd = arcs.end(); for (it = arcs.begin(); it != itEnd; ++it) { sElement *arc_el = *it; assert(arc_el->type & sc_type_arc_mask); sc_addr addr = resolveScAddr(arc_el); if (SC_ADDR_IS_EMPTY(addr)) continue; createdSet.insert(arc_el); } created = !createdSet.empty(); itEnd = createdSet.end(); for (it = createdSet.begin(); it != itEnd; ++it) arcs.erase(*it); } if (!arcs.empty()) { StringStream ss; ss << "Arcs not created: " << arcs.size(); THROW_EXCEPT(Exception::ERR_INVALID_STATE, ss.str(), mParams.fileName, -1); } return true; }
sc_result sc_helper_set_system_identifier(sc_memory_context const * ctx, sc_addr addr, const sc_char* data, sc_uint32 len) { sc_iterator5 *it5 = 0; sc_addr *results = 0; sc_uint32 results_count = 0; sc_stream *stream = 0; sc_uint32 i = 0; sc_addr idtf_addr, arc_addr; SC_ADDR_MAKE_EMPTY(idtf_addr) g_assert(sc_keynodes != 0); // check if specified system identifier already used stream = sc_stream_memory_new(data, sizeof(sc_char) * len, SC_STREAM_FLAG_READ, SC_FALSE); if (sc_memory_find_links_with_content(ctx, stream, &results, &results_count) == SC_RESULT_OK) { for (i = 0; i < results_count; i++) { it5 = sc_iterator5_a_a_f_a_f_new(ctx, 0, sc_type_arc_common | sc_type_const, results[i], sc_type_arc_pos_const_perm, sc_keynodes[SC_KEYNODE_NREL_SYSTEM_IDENTIFIER]); if (sc_iterator5_next(it5)) { // don't foget to free allocated memory before return error sc_iterator5_free(it5); sc_stream_free(stream); g_free(results); return SC_RESULT_ERROR_INVALID_PARAMS; } sc_iterator5_free(it5); } g_free(results); } // if there are no elements with specified system identitifier, then we can use it idtf_addr = sc_memory_link_new(ctx); if (sc_memory_set_link_content(ctx, idtf_addr, stream) != SC_RESULT_OK) { sc_stream_free(stream); return SC_RESULT_ERROR; } // we doesn't need link data anymore sc_stream_free(stream); // setup new system identifier arc_addr = sc_memory_arc_new(ctx, sc_type_arc_common | sc_type_const, addr, idtf_addr); if (SC_ADDR_IS_EMPTY(arc_addr)) return SC_RESULT_ERROR; arc_addr = sc_memory_arc_new(ctx, sc_type_arc_pos_const_perm, sc_keynodes[SC_KEYNODE_NREL_SYSTEM_IDENTIFIER], arc_addr); if (SC_ADDR_IS_EMPTY(arc_addr)) return SC_RESULT_ERROR; return SC_RESULT_OK; }
sc_bool _sc_iterator3_a_a_f_next(sc_iterator3 *it) { sc_addr arc_addr; SC_ADDR_MAKE_EMPTY(arc_addr) it->results[2] = it->params[2].addr; // try to find first input arc if (SC_ADDR_IS_EMPTY(it->results[1])) { sc_element *el = 0; STORAGE_CHECK_CALL(sc_storage_element_lock(it->ctx, it->params[2].addr, &el)); g_assert(el != null_ptr); arc_addr = el->first_in_arc; STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, it->params[2].addr)); }else { sc_element *el = 0; STORAGE_CHECK_CALL(sc_storage_element_lock(it->ctx, it->results[1], &el)); g_assert(el != null_ptr); arc_addr = el->arc.next_in_arc; _sc_iterator_unref_element(it->ctx, el, it->results[1]); STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, it->results[1])); } // trying to find input arc, that created before iterator, and wasn't deleted while (SC_ADDR_IS_NOT_EMPTY(arc_addr)) { sc_element *el = 0; while (el == null_ptr) STORAGE_CHECK_CALL(sc_storage_element_lock_try(it->ctx, arc_addr, s_max_iterator_lock_attempts, &el)); if (!sc_element_itref_add(sc_storage_get_element_meta(it->ctx, arc_addr))) { STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, arc_addr)); continue; } sc_addr next_in_arc = el->arc.next_in_arc; if (sc_element_is_request_deletion(el) == SC_FALSE) { sc_type arc_type = el->flags.type; sc_addr arc_begin = el->arc.begin; sc_access_levels arc_access = el->flags.access_levels; sc_access_levels begin_access; if (sc_storage_get_access_levels(it->ctx, arc_begin, &begin_access) != SC_RESULT_OK) begin_access = sc_access_lvl_make_max; STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, arc_addr)); sc_type el_type = 0; sc_storage_get_element_type(it->ctx, arc_begin, &el_type); if (sc_iterator_compare_type(arc_type, it->params[1].type) && sc_iterator_compare_type(el_type, it->params[0].type) && sc_access_lvl_check_read(it->ctx->access_levels, arc_access) && sc_access_lvl_check_read(it->ctx->access_levels, begin_access) ) { // store found result it->results[1] = arc_addr; it->results[0] = arc_begin; return SC_TRUE; } } else { _sc_iterator_unref_element(it->ctx, el, arc_addr); STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, arc_addr)); } // go to next arc arc_addr = next_in_arc; } it->finished = SC_TRUE; return SC_FALSE; }
sc_bool _sc_iterator3_f_a_a_next(sc_iterator3 *it) { sc_addr arc_addr; SC_ADDR_MAKE_EMPTY(arc_addr); if (it->finished == SC_TRUE) return SC_FALSE; it->results[0] = it->params[0].addr; // try to find first output arc if (SC_ADDR_IS_EMPTY(it->results[1])) { sc_element *el = 0; STORAGE_CHECK_CALL(sc_storage_element_lock(it->ctx, it->params[0].addr, &el)); g_assert(el != null_ptr); arc_addr = el->first_out_arc; STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, it->params[0].addr)); }else { sc_element *el = 0; STORAGE_CHECK_CALL(sc_storage_element_lock(it->ctx, it->results[1], &el)); g_assert(el != null_ptr); arc_addr = el->arc.next_out_arc; _sc_iterator_unref_element(it->ctx, el, it->results[1]); STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, it->results[1])); } // iterate throught output arcs while (SC_ADDR_IS_NOT_EMPTY(arc_addr)) { sc_element *el = 0; // lock required elements to prevent deadlock with deletion while (el == null_ptr) STORAGE_CHECK_CALL(sc_storage_element_lock_try(it->ctx, arc_addr, s_max_iterator_lock_attempts, &el)); if (!sc_element_itref_add(sc_storage_get_element_meta(it->ctx, arc_addr))) { STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, arc_addr)); continue; } sc_addr next_out_arc = el->arc.next_out_arc; if (sc_element_is_request_deletion(el) == SC_FALSE) { sc_addr arc_end = el->arc.end; sc_type arc_type = el->flags.type; sc_access_levels arc_access = el->flags.access_levels; sc_access_levels end_access; if (sc_storage_get_access_levels(it->ctx, arc_end, &end_access) != SC_RESULT_OK) end_access = sc_access_lvl_make_max; STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, arc_addr)); sc_type el_type; sc_storage_get_element_type(it->ctx, arc_end, &el_type); if (sc_iterator_compare_type(arc_type, it->params[1].type) && sc_iterator_compare_type(el_type, it->params[2].type) && sc_access_lvl_check_read(it->ctx->access_levels, arc_access) && sc_access_lvl_check_read(it->ctx->access_levels, end_access) ) { // store found result it->results[1] = arc_addr; it->results[2] = arc_end; return SC_TRUE; } } else { _sc_iterator_unref_element(it->ctx, el, arc_addr); STORAGE_CHECK_CALL(sc_storage_element_unlock(it->ctx, arc_addr)); } // go to next arc arc_addr = next_out_arc; } it->finished = SC_TRUE; return SC_FALSE; }
bool ScAddr::IsValid() const { return !SC_ADDR_IS_EMPTY(m_realAddr); }