// file: $isip/class/mmedia/AnnotationGraph/angr_5.cc // version: $Id: angr_05.cc 9136 2003-05-12 22:41:59Z huang $ // // isip include files // #include "AnnotationGraph.h" // method: clear // // arguments: // Integral::CMODE cmode: (input) clear mode // // return: logical error status // // this method clears the content of the current object // bool8 AnnotationGraph::clear(Integral::CMODE cmode_a) { // declare local variables // bool8 status = false; DoubleLinkedList ancrs(DstrBase::USER); DoubleLinkedList annos(DstrBase::USER); // delete the sequence of annotations // if (getAnnotationSet(annos)) { for (bool8 more = annos.gotoFirst(); more; more = annos.gotoNext()) { deleteAnnotation(annos.getCurr()); } } // delete the set of anchors // if (getAnchorSet(ancrs)) { for (bool8 more = ancrs.gotoFirst(); more; more = ancrs.gotoNext()) { deleteAnchor(ancrs.getCurr()); } } // clear the member data // status = id_d.clear(cmode_a); status &= type_d.clear(cmode_a); status &= index_d.clear(cmode_a); status &= annoseq_d.clear(cmode_a); // delete the identifiers // if (anchorids_d != (Identifier*)NULL) { delete anchorids_d; anchorids_d = (Identifier*)NULL; } if (annotationids_d != (Identifier*)NULL) { delete annotationids_d; annotationids_d = (Identifier*)NULL; } // return the logical status // return status; } // method: sofSize // // arguments: none // // return: logical error status // // method gets the size of the graph object // int32 AnnotationGraph::sofSize() const { // declare local variables // DoubleLinkedList > ancrs; DoubleLinkedList > annos; // get the annotations and anchors associated with the graph // const_cast(this)->get(ancrs, annos); // return the sof size // return ancrs.sofSize() + annos.sofSize() + id_d.sofSize() + type_d.sofSize(); } // method: get // // arguments: // DoubleLinkedList >& ancrs: (output) list of anchors // DoubleLinkedList >& annos: (output) list // of annotations // // return: logical error status // // method get the annotations and anchors associated with the graph // bool8 AnnotationGraph::get(DoubleLinkedList >& ancrs_a, DoubleLinkedList >& annos_a) { // declare local variables // Pair ancr_pair; Triple anno_triple; DoubleLinkedList ancrs(DstrBase::USER); DoubleLinkedList annos(DstrBase::USER); // get the list of anchors // getAnchorSet(ancrs); // get the list of annotations // getAnnotationSeqByOffset(annos, 0.0, 0.0); // create a list of annotations and anchors that contain cross indexing // information in order for the annotations to reference the anchors // for (bool8 more = ancrs.gotoFirst(); more; more = ancrs.gotoNext()) { // set the index of the anchor // ancr_pair.first().assign(ancrs.getPosition()); // set the anchor object // ancr_pair.second().assign(*ancrs.getCurr()); // inset the anchor pair into the list // ancrs_a.insert(&ancr_pair); } for (bool8 more = annos.gotoFirst(); more; more = annos.gotoNext()) { // set the start index of the annotation // anno_triple.first().assign(DEF_INDEX); if (ancrs.find(annos.getCurr()->getStartAnchor())) { anno_triple.first().assign(ancrs.getPosition()); } // set the end index of the annotation // anno_triple.second().assign(DEF_INDEX); if (ancrs.find(annos.getCurr()->getEndAnchor())) { anno_triple.second().assign(ancrs.getPosition()); } // set the annotation object // anno_triple.third().assign(*annos.getCurr()); // insert the annotation pair into the list // annos_a.insert(&anno_triple); } // exit gracefully // return true; } // method: set // // arguments: // DoubleLinkedList >& ancrs: (input) list of anchors // DoubleLinkedList >& annos: (input) list // of annotations // // return: logical error status // // method get the annotations and anchors associated with the graph // bool8 AnnotationGraph::set(DoubleLinkedList >& ancrs_a, DoubleLinkedList >& annos_a) { // declare local variables // int32 index; int32 start_index; int32 end_index; String tmpstr; Anchor anchor; String anchorid; Annotation annotation; Annotation* annotation1; String annotationid; Vector keys; int32 num_anchors = ancrs_a.length(); Anchor* start_anchor = (Anchor*)NULL; Anchor* end_anchor = (Anchor*)NULL; Anchor* anchors[num_anchors]; // insert the anchors into the graph // for (bool8 more=ancrs_a.gotoFirst(); more; more=ancrs_a.gotoNext()) { // get the anchor parameters // index = ancrs_a.getCurr()->first(); anchor = ancrs_a.getCurr()->second(); tmpstr = anchor.getUnit(); // create the anchor object using the parameters // if (anchor.getAnchored()) { anchorid = createAnchor(id_d, anchor.getOffset(), tmpstr); } else { anchorid = createAnchor(id_d, tmpstr); } anchors[index] = getAnchorById(anchorid); } // insert the annotations into the graph // for (bool8 more=annos_a.gotoFirst(); more; more=annos_a.gotoNext()) { // get the annotation parameters // start_anchor = (Anchor*)NULL; end_anchor = (Anchor*)NULL; start_index = annos_a.getCurr()->first(); end_index = annos_a.getCurr()->second(); annotation = annos_a.getCurr()->third(); tmpstr = annotation.getType(); // get the start and end anchors // if (start_index != DEF_INDEX) { start_anchor = anchors[start_index]; } if (end_index != DEF_INDEX) { end_anchor = anchors[end_index]; } int32 channel_index = annotation.getChannel(); // create the annotation object using the parameters // annotationid.assign(annotation.getId()); annotationid = createAnnotation(id_d, start_anchor, end_anchor, tmpstr, channel_index); annotation1 = getById(annotationid); // set the feature map for the annotation // annotation1->setFeatureMap(annotation.getFeatureMap()); // get the features corresponding to the annotation // annotation.getFeatureNames(keys); // add the features to the annotation index // for (int32 i=0; i > ancrs; DoubleLinkedList > annos; DoubleLinkedList > ancrs1; DoubleLinkedList > annos1; // get the structure of the current graph // const_cast(this)->get(ancrs, annos); // get the structure of the input graph // const_cast(arg_a).get(ancrs1, annos1); // determine if the two graph structures are equal // status = ancrs.eq(ancrs1); status &= annos.eq(annos1); // return the logical status // return status; } // method: assign // // arguments: // const AnnotationGraph& arg: (input) annotation graph // // return: logical error status // // method assigns the input annotation graph to the current one // bool8 AnnotationGraph::assign(const AnnotationGraph& arg_a) { // declare local variables // bool8 status = false; String anchor(DEF_ANCHOR); String annotation(DEF_ANNOTATION); DoubleLinkedList > ancrs; DoubleLinkedList > annos; // clear the current contents of the graph // this->clear(); // assign the member data // status = id_d.assign(arg_a.id_d); status &= type_d.assign(arg_a.type_d); // initialize the identifiers if needed // if (anchorids_d == (Identifier*)NULL) { anchorids_d = new Identifier(id_d, anchor); } if (annotationids_d == (Identifier*)NULL) { annotationids_d = new Identifier(id_d, annotation); } // get the annotations and anchors associated with the input graph // status &= const_cast(arg_a).get(ancrs, annos); // initialize the annotations and anchors // status &= set(ancrs, annos); // return the logical status // return status; } // method: setFeature // // arguments: // String& id_a: (input) annotation id // String& fname_a: (input) feature name // String& fvalue_a: (input) feature value // // return: logical error status // // method sets the feature value of the annotation // bool8 AnnotationGraph::setFeature(String& id_a, String& fname_a, String& fvalue_a) { // insert the feature value pair to the feature map of the annotation // return setFeature(getById(id_a), fname_a, fvalue_a); } // method: existsFeature // // arguments: // String& id_a: (input) annotation id // String& fname_a: (input) feature name // // return: logical error status // // method to test if a feature exists in the annotation // bool8 AnnotationGraph::existsFeature(String& id_a, String& fname_a) { // declare local variables // bool8 status = false; Annotation* anno = (Annotation*)NULL; // get the annotation corresponding to the id // anno = getById(id_a); // determine if the feature name exists // if (anno != (Annotation*)NULL) { status = anno->existsFeature(fname_a); } // return the logical status // return status; } // method: deleteFeature // // arguments: // String& id_a: (input) annotation id // String& fname_a: (input) feature name // // return: logical error status // // method that deletes the specified feature from the annotation // bool8 AnnotationGraph::deleteFeature(String& id_a, String& fname_a) { // declare local variables // bool8 status = false; Annotation* anno = (Annotation*)NULL; // get the annotation corresponding to the id // anno = getById(id_a); // delete the feature from the indeces // if (anno != (Annotation*)NULL) { status = index_d.deleteFeature(anno, fname_a); status &= anno->deleteFeature(fname_a); } // return the logical status // return status; } // method: getFeature // // arguments: // String& id_a: (input) annotation id // String& fname_a: (input) feature name // // return: value of the corresponding feature name // // method that gets the value of specified feature in the annotation // String AnnotationGraph::getFeature(String& id_a, String& fname_a) { // declare local variables // String fvalue; Annotation* anno = (Annotation*)NULL; // get the annotation corresponding to the id // anno = getById(id_a); // retrieve the feature value // if (anno != (Annotation*)NULL) { fvalue.assign(anno->getFeature(fname_a)); } // return the feature value // return fvalue; } // method: getFeatureNames // // arguments: // String& id_a: (input) annotation id // Vector& features: (output) vector of feature names // // return: logical error status // // method that gets the value of specified feature in the annotation // bool8 AnnotationGraph::getFeatureNames(String& id_a, Vector& features_a) { // declare local variables // bool8 status = false; Annotation* anno = (Annotation*)NULL; // get the annotation corresponding to the id // anno = getById(id_a); // retrieve the feature names // if (anno != (Annotation*)NULL) { status = anno->getFeatureNames(features_a); } // return the logical status // return status; } // method: unsetFeatures // // arguments: // String& id_a: (input) annotation id // // return: logical error status // // method to unset all features in the annotation // bool8 AnnotationGraph::unsetFeatures(String& id_a) { // declare local variables // String null; Vector names; Annotation* anno = (Annotation*)NULL; // get the annotation corresponding to the id // anno = getById(id_a); // get the set of feature names // if (anno != (Annotation*)NULL) { if (!anno->getFeatureNames(names)) { return Error::handle(name(), L"getFeature", Error::ARG, __FILE__, __LINE__); } } // loop over all feature names and unset their values // null.assign(String::EMPTY); for (int i=0; i < names.length(); i++) { setFeature(anno, names(i), null); } // exit gracefully // return true; } // method: setFeature // // arguments: // Annotation* anno: (input) annotation // const String& fname_a: (input) feature name // const String& fvalue_a: (input) feature value // // return: logical error status // // method to set the specified feature of the annotation to this value // bool8 AnnotationGraph::setFeature(Annotation* anno_a, String& fname_a, String& fvalue_a) { // declare local variables // bool8 status = false; // delete the previous feature from the annotation indices // status = index_d.deleteFeature(anno_a, fname_a); if (anno_a->existsFeature(fname_a)) { status &= anno_a->deleteFeature(fname_a); } // insert the feature value pair into the indices // status &= anno_a->setFeature(fname_a, fvalue_a); status &= index_d.addFeature(anno_a, fname_a, fvalue_a); // return the logical status // return status; } // method: getAnnotationSetByFeature // // arguments: // const String& fname_a: (input) feature name // const String& fvalue_a: (input) feature value // DoubleLinkedList& annos_a: (input) annotation list // // return: logical error status // // method to set the specified feature of the annotation to this value // bool8 AnnotationGraph::getAnnotationSetByFeature(const String& fname_a, const String& fvalue_a, DoubleLinkedList& annos_a) { // declare local variables // String index; // clear the list to start with // annos_a.clear(); annos_a.setAllocationMode(DstrBase::USER); // generate the hash index // index.assign(fname_a); index.concat(fvalue_a); // get the list of annotations corresponding to the feature-value pair // if (index_d.by_feature_d.get(index) != (DoubleLinkedList*)NULL) { annos_a.assign(*index_d.by_feature_d.get(index)); } // return error // else { return Error::handle(name(), L"null pointer - no annotation for this feature and the value", Error::ARG, __FILE__, __LINE__); } // exit gracefully // return true; } // method: addAnchor // // arguments: // Anchor* ancr: (input) anchor to be added // // return: logical error status // // method to add an anchor to the graph // bool8 AnnotationGraph::addAnchor(Anchor* ancr_a) { // check for null pointer exceptions // if (anchorids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } if (annotationids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } // insert the anchor id and anchor pair to the anchor mapping // anchorids_d->addAnchorRef(ancr_a->getId(), ancr_a); // insert the anchor to the anchor set // if (!index_d.ancrset_d.contains(ancr_a)) { index_d.addAnchor(ancr_a); } // exit gracefully // return true; } // method: deleteAnchor // // arguments: // Anchor* ancr: (input) anchor to be deleted // // return: logical error status // // method to delete an anchor from the graph // bool8 AnnotationGraph::deleteAnchor(Anchor* ancr_a) { // declare local variables // HashKey hashkey; // check for null pointer exceptions // if (anchorids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } if (annotationids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } // make sure that the anchor has no incoming or outgoing arcs // hashkey.assign(ancr_a); if ((index_d.incoming_d.get(hashkey) == (DoubleLinkedList*)NULL) && (index_d.outgoing_d.get(hashkey) == (DoubleLinkedList*)NULL)) { // remove the anchor for the identifier list // anchorids_d->deleteAnchorRef(ancr_a->getId()); index_d.deleteAnchor(ancr_a); // reclaim the id from the anchor issuer // anchorids_d->reclaimId(ancr_a->getId()); // delete the anchor // delete ancr_a; // exit gracefully // return true; } // exit gracefully // return false; } // method: setAnchorOffset // // arguments: // Anchor* ancr: (input) anchor whose offset is to be changed // float32 offset: (input) anchor offset // // return: logical error status // // method that sets an anchors offset to the specified value // bool8 AnnotationGraph::setAnchorOffset(Anchor* ancr_a, float32 offset_a) { // delete anchor from indexes // index_d.deleteAnchor(ancr_a); // update the anchor // ancr_a->setOffset(offset_a); // add new anchor to indexes // index_d.addAnchor(ancr_a); // exit gracefully // return true; } // method: splitAnchor // // arguments: // Anchor* ancr: (input) anchor to be split // // return: the new anchor is returned // // method that splits an anchor a in two, creating a new anchor a' // having the same offset as the original one. anchor a has all the // incoming annotations, while anchor a' has all the outgoing annotations. // the new anchor a' is returned. // Anchor* AnnotationGraph::splitAnchor(Anchor* ancr_a) { // declare local variables // String newid; Anchor* ancr = (Anchor*)NULL; DoubleLinkedList annos(DstrBase::USER); // check for null pointer exceptions // if (anchorids_d == (Identifier*)NULL) { Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } if (annotationids_d == (Identifier*)NULL) { Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } // generate a new id for the anchor // newid.assign(anchorids_d->registerId()); // clone the anchor // ancr = new Anchor(newid, ancr_a); addAnchor(ancr); // for each outgoing arc from ancr_a, change its start node to ancr // getOutgoingAnnotationSet(ancr_a, annos); for (bool8 more = annos.gotoFirst(); more; more = annos.gotoNext()) { setStartAnchor(annos.getCurr(), ancr); } // return the new anchor // return ancr; } // method: add // // arguments: // Annotation* anno: (input) annotation to be added // // return: logical error status // // method that adds a new annotation to the graph // bool8 AnnotationGraph::add(Annotation* anno_a) { // check for null pointer exceptions // if (anchorids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } if (annotationids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } // add annotation to the annotation set // annoseq_d.insert(anno_a); // update index and the identifier issuer // index_d.add(anno_a); annotationids_d->addAnnotationRef(anno_a->getId(), anno_a); // exit gracefully // return true; } // method: createAnnotation // // arguments: // String& id_a: (input) annotation id // Anchor* anchor1_a: (input) start anchor // Anchor* anchor2_a: (input) end anchor // String& type_a: (input) annotation type // int32 channel; (input) channel // // return: annotation id // // method that create a new annotation // String AnnotationGraph::createAnnotation(String& id_a, Anchor* anchor1_a, Anchor* anchor2_a, String& type_a, int32 channel_a) { // declare local variables // String newid; Annotation* anno = (Annotation*)NULL; // check for null pointer exceptions // if (anchorids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } if (annotationids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } String nspace(annotationids_d->getNamespace(id_a)); if (nspace.eq(String::EMPTY)) { nspace.assign(id_a); } // when the is the same as the graphs id // if (id_a.eq(id_a)) { newid.assign(annotationids_d->registerId()); anno = new Annotation(newid, anchor1_a, anchor2_a, type_a, channel_a); } // when the namespace is the same as the graphs id // else if (nspace.eq(id_a)) { newid.assign(annotationids_d->registerId(id_a)); anno = new Annotation(newid, anchor1_a, anchor2_a, type_a, channel_a); } // the id is not an annotation graph or a valid annotation id // else { return Error::handle(name(), L"createAnnotation", Error::ARG, __FILE__, __LINE__); } // add the annotation to the graph // add(anno); // return the annotation id // return anno->getId(); } // method: createAnchor // // arguments: // String& id: (input) anchor id // float32 offset: (input) anchor offset // String& unit: (input) unit of the offset // // return: anchor id // // method that creates and anchor with specified offset and unit // String AnnotationGraph::createAnchor(String& id_a, String& unit_a) { // declare local variables // String newid; Anchor* ancr = (Anchor*)NULL; // check for null pointer exceptions // if (anchorids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } if (annotationids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } String nspace(anchorids_d->getNamespace(id_a)); if (nspace.eq(String::EMPTY)) { nspace.assign(id_a); } // when the id is the same as the graphs id // if (id_a.eq(id_d)) { newid.assign(anchorids_d->registerId()); ancr = new Anchor(newid, unit_a); } // when the name space is the same as the graphs id // else if (nspace.eq(id_a)) { newid.assign(anchorids_d->registerId(id_a)); ancr = new Anchor(newid, unit_a); } // the id is not an annotation graph or a valid anchor id // else { return Error::handle(name(), L"createAnchor", Error::ARG, __FILE__, __LINE__); } // add the anchor to the graph // addAnchor(ancr); // return the anchor id // return ancr->getId(); } // method: createAnchor // // arguments: // String& id: (input) anchor id // float32 offset: (input) anchor offset // String& unit: (input) unit of the offset // // return: anchor id // // method that creates and anchor with specified offset and unit // String AnnotationGraph::createAnchor(String& id_a, float32 offset_a, String& unit_a) { // declare local variables // String newid; Anchor* ancr = (Anchor*)NULL; // check for null pointer exceptions // if (anchorids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } if (annotationids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } String nspace(anchorids_d->getNamespace(id_a)); if (nspace.eq(String::EMPTY)) { nspace.assign(id_a); } // when the id is the same as the graphs id // if (id_a.eq(id_d)) { newid.assign(anchorids_d->registerId()); ancr = new Anchor(newid, offset_a, unit_a); } // when the name space is the same as the graphs id // else if (nspace.eq(id_a)) { newid.assign(anchorids_d->registerId(id_a)); ancr = new Anchor(newid, offset_a, unit_a); } // the id is not an annotation graph or a valid anchor id // else { return Error::handle(name(), L"createAnchor", Error::ARG, __FILE__, __LINE__); } // add the anchor to the graph // addAnchor(ancr); // return the anchor id // return ancr->getId(); } // method: getAnchorOffset // // arguments: // Anchor* ancr: (input) graph anchor // // return: anchor offset // // method that returns the offset of the specified anchor // float32 AnnotationGraph::getAnchorOffset(Anchor* ancr_a) { // declare local variables // float32 offset = 0.0; // determine the offset of the anchor // if ((ancr_a != (Anchor*)NULL) && (ancr_a->getAnchored())) { offset = ancr_a->getOffset(); } // return the offset // return offset; } // method: copyAnnotation // // arguments: // const Annotation* anno: (input) graph anchor // // return: annotation copy // // method that makes a copy of the specified annotation // Annotation* AnnotationGraph::copyAnnotation(const Annotation* anno_a) { // declare local variables // String newid; Annotation* annotation = (Annotation*)NULL; // check for null pointer exceptions // if (anchorids_d == (Identifier*)NULL) { Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } if (annotationids_d == (Identifier*)NULL) { Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } // clone the annotation // newid.assign(annotationids_d->registerId()); annotation = new Annotation(newid, anno_a); // add the cloned annotation to the graph // add(annotation); // return the annotation copy // return annotation; } // method: splitAnnotation // // arguments: // Annotation* anno: (input) annotation to split // // return: split annotation // // method that split an annotation a in two creating a new annotation a' // having the same label data as the original one. the two annotations a, // a' connect head-to-tail at a new anchor. the new annotation and anchor // have identifiers taken from the specified identifier spaces. the new // anchor is unanchored, i.e. has no offset. // Annotation* AnnotationGraph::splitAnnotation(Annotation* anno_a) { // dclare local variables // String newid; String newunit; Anchor* endancr = (Anchor*)NULL; Annotation* newanno = (Annotation*)NULL; Anchor* newancr = (Anchor*)NULL; // check for null pointer exceptions // if (anchorids_d == (Identifier*)NULL) { Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } if (annotationids_d == (Identifier*)NULL) { Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } // get the end anchor of the annotation // endancr = anno_a->getEndAnchor(); // clone the annotation // newanno = copyAnnotation(anno_a); // create a new anchor positioned between the split annotations // newunit.assign(endancr->getUnit()); newid.assign(anchorids_d->registerId()); newancr = new Anchor(newid, newunit); // make anno_a end at this anchor // setEndAnchor(anno_a, newancr); // make newanno start at this anchor // setStartAnchor(newanno, newancr); // return the new annotation // return newanno; } // method: nSplitAnnotation // // arguments: // Annotation* anno: (input) annotation to split // int32 num_split: number of splits // DoubleLinkedList annos: (output) annotation list // // return: split annotations // // method that split an annotation to n annotations. aversion of split // which does the split operation n-1 times, i.e. splits the original // annotation into n annotations. // bool8 AnnotationGraph::nSplitAnnotation(Annotation* anno_a, int32 num_split_a, DoubleLinkedList& annos_a) { // declare local variables // Annotation* anno = anno_a; // clear the list to start with // annos_a.clear(); annos_a.setAllocationMode(DstrBase::USER); // insert the into the list // if (anno != (Annotation*)NULL) { annos_a.insert(anno); } // split the annotation as per the number specified // for (int i=num_split_a; i > 1; i--) { if (anno != (Annotation*)NULL) { anno = splitAnnotation(anno); annos_a.insert(anno); } } // exit gracefully // return true; } // method: deleteAnnotation // // arguments: // Annotation* anno: (input) annotation to delete // // return: logical error status // // method that deletes the annotation from the graph // bool8 AnnotationGraph::deleteAnnotation(Annotation* anno_a) { // check for null pointer exceptions // if (anchorids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } if (annotationids_d == (Identifier*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } // determine if the annotation is present in the graph // if (getById(anno_a->getId()) != (Annotation*)NULL) { // delete the annotation from the indices and identifier issuer // annotationids_d->deleteAnnotationRef(anno_a->getId()); index_d.deleteAnnotation(anno_a); // remove the annotation from the sequence and reclaim the identifier // if (annoseq_d.find(anno_a)) { annoseq_d.remove(); } annotationids_d->reclaimId(anno_a->getId()); // delete the annotation // delete anno_a; // exit gracefully // return true; } // exit gracefully // return false; } // method: setStartAnchor // // arguments: // Annotation* anno: (input) graph annotation // Anchor* ancr: (input) start anchor // // return: logical error status // // method that sets the start anchor of an annotation to the input anchor // bool8 AnnotationGraph::setStartAnchor(Annotation* anno_a, Anchor* ancr_a) { // delete the annotation from the indices // index_d.deleteAnnotation(anno_a); // set the start anchor of the annotation // anno_a->setStartAnchor(ancr_a); // add the annotation to the indices // index_d.add(anno_a); // exit gracefully // return true; } // method: setEndAnchor // // arguments: // Annotation* anno: (input) graph annotation // Anchor* ancr: (input) end anchor // // return: logical error status // // method that sets the end anchor of an annotation to the specified anchor // bool8 AnnotationGraph::setEndAnchor(Annotation* anno_a, Anchor* ancr_a) { // delete the annotation from the indices // index_d.deleteAnnotation(anno_a); // set the end anchor of the annotation // anno_a->setEndAnchor(ancr_a); // add the annotation to the indices // index_d.add(anno_a); // exit gracefully // return true; } // method: unsetAnchorOffset // // arguments: // Anchor* ancr: (input) graph anchor // // return: logical error status // // method that unsets the offset of the specified anchor // bool8 AnnotationGraph::unsetAnchorOffset(Anchor* ancr_a) { // delete anchor from indices // index_d.deleteAnchor(ancr_a); // update the anchor offset // ancr_a->unsetOffset(); // add new anchor to indices // index_d.addAnchor(ancr_a); // exit gracefully // return true; } // method: getAnchorSet // // arguments: // DoubleLinkedList& ancrs: (output) anchors list // // return: graph anchor set // // metod that gets the set of anchors, sorted by offsets // bool8 AnnotationGraph::getAnchorSet(DoubleLinkedList& ancrs_a) { // clear the list to start with // ancrs_a.clear(); ancrs_a.setAllocationMode(DstrBase::USER); // assign the anchor set to the input list // ancrs_a.assign(index_d.ancrset_d); // exit gracefully // return true; } // method: getById // // arguments: // const String& id: (input) annotation id // // return: annotation // // method that gets the annotation reference by its id // Annotation* AnnotationGraph::getById(const String& id_a) { // declare local variables // Annotation* annotation = (Annotation*)NULL; // check if the annotation exists // if(index_d.existsAnnotation(id_a)) { annotation = index_d.anno_by_id_d.get(id_a); } // return the annotation // return annotation; } // method: // // arguments: // const String& id: (input) anchor id // // return: anchor // // method that gets the anchor reference by its id // Anchor* AnnotationGraph::getAnchorById(const String& id_a) { // declare local variables // Anchor* anchor = (Anchor*)NULL; // check if the anchor exists // if(index_d.existsAnchor(id_a)) { anchor = index_d.ancr_by_id_d.get(id_a); } // return the annotation // return anchor; } // method: getAnchorSetByOffset // // arguments: // float32 offset: (input) anchor offset // DoubleLinkedList ancrs: (output) anchors list // float64 esp: (input) epsilon value // // return: anchor set // // method that gets anchors with the specified offset // bool8 AnnotationGraph::getAnchorSetByOffset(float32 offset_a, DoubleLinkedList& ancrs_a, float64 eps_a) { // d eclare local variables // float64 delta; Float offset; DoubleLinkedList ancrset(DstrBase::USER); // clear the list to start with // ancrs_a.clear(); ancrs_a.setAllocationMode(DstrBase::USER); // epsilon should not be a negative number // eps_a = eps_a > 0.0 ? eps_a : -eps_a; // when the specified epsilon is zero // if (eps_a == 0.0) { offset.assign(offset_a); if (index_d.ancrset_by_offset_d.get(offset) != (DoubleLinkedList*)NULL) { ancrs_a.assign(*(index_d.ancrset_by_offset_d.get(offset))); } } // when the specified epsilon is greater than zero // else { // get the list of anchors // getAnchorSet(ancrset); // loop over all anchors in the set // for(bool8 more = ancrset.gotoFirst(); more; more = ancrset.gotoNext()) { // determine the variance between the current and input offsets // delta = ancrset.getCurr()->getOffset() - offset_a; delta = delta > 0.0 ? delta : -delta; // insert the anchor into the list if the variance is within epsilon // if (delta <= eps_a) { ancrs_a.insert(ancrset.getCurr()); } } } // exit gracefully // return true; } // method: getAnnotationSetByType // // arguments: // const String& type: (input) annotation type // DoubleLinkedList& annos: (output) annotation list // // return: annotation set // // method that gets the annotations using the type // bool8 AnnotationGraph::getAnnotationSetByType(const String& type_a, DoubleLinkedList& annos_a) { // clear the list to start with // annos_a.clear(); annos_a.setAllocationMode(DstrBase::USER); DoubleLinkedList* list; // assign the annotation set // if (index_d.anno_by_type_d.get(type_a) != (DoubleLinkedList*)NULL) { list = index_d.anno_by_type_d.get(type_a); annos_a.assign(*(index_d.anno_by_type_d.get(type_a))); } // exit gracefully // return true; } // method: getAnnotationSetByOffset // // arguments: // float32 offset: (input) annotation offset // DoubleLinkedList& annos: (input) annotation list // // return: annotation set // // method that gets the annotations that overlap a particular time offset. // gets all annotations whose start anchor offset is smaller than or // equal to the given offset AND end anchor offset is greater than // or equal to the given offet // bool8 AnnotationGraph::getAnnotationSetByOffset(float32 offset_a, DoubleLinkedList& annos_a) { // clear the list to start with // annos_a.clear(); annos_a.setAllocationMode(DstrBase::USER); // get the annotation set by offset // index_d.getByOffset(offset_a, annos_a); // exit gracefully // return true; } // method: getIncomingAnnotationSet // // arguments: // Anchor* ancr: (input) graph anchor // DoubleLinkedList& annos: (input) annotation list // // return: annotation set // // method that gets the incoming annotations to the specified node // bool8 AnnotationGraph::getIncomingAnnotationSet(Anchor* ancr_a, DoubleLinkedList& annos_a) { // define local variables // HashKey hashkey; // clear the list to start with // annos_a.clear(); annos_a.setAllocationMode(DstrBase::USER); // get the incoming annotation set // hashkey.assign(ancr_a); if (index_d.incoming_d.get(hashkey) != (DoubleLinkedList*)NULL) { annos_a.assign(*(index_d.incoming_d.get(hashkey))); } // exit gracefully // return true; } // method: getOutgoingAnnotationSet // // arguments: // Anchor* ancr: (input) graph anchor // DoubleLinkedList& annos: (input) annotation list // // return: annotation set // // method that gets the outgoing annotations from the specified node // bool8 AnnotationGraph::getOutgoingAnnotationSet(Anchor* ancr_a, DoubleLinkedList& annos_a) { // define local variables // HashKey hashkey; // clear the list to start with // annos_a.clear(); annos_a.setAllocationMode(DstrBase::USER); // get the outgoing annotation set // hashkey.assign(ancr_a); if (index_d.outgoing_d.get(hashkey) != (DoubleLinkedList*)NULL) { annos_a.assign(*(index_d.outgoing_d.get(hashkey))); } // exit gracefully // return true; } // method: getNearestOffset // // arguments: // float32 offset: (input) offset target // // return: nearest offset // // method that gets the nearest used offset to the specified offset // float32 AnnotationGraph::getNearestOffset(float32 offset_a) { // get the nearest offset // return index_d.getNearestOffset(offset_a); } // method: getAnnotationSeqByOffset // // arguments: // DoubleLinkedList& annos: (output) annotation list // float32 begin: (input) start offset // float32 end: (input) end offset // // return: annotation set // // method that get all annotations with its start anchor offset in between // the specified values. gets all annotations with its start anchor offset // in between the specified values. if both values are 0, return all // annotations in the graph // bool8 AnnotationGraph::getAnnotationSeqByOffset(DoubleLinkedList& annos_a, float32 begin_a, float32 end_a) { // declate local variables // Annotation* anno; // clear the list to start with // annos_a.clear(); annos_a.setAllocationMode(DstrBase::USER); // determine if the annotation sequence is not empty // if (!annoseq_d.isEmpty()) { // when the begin and end times are zero return the annotation sequence // if ((begin_a == 0.0) && (end_a == 0.0)) { annos_a.assign(annoseq_d); } // determine which annotations in the sequence lie in the specified range // else { // loop over all annotations in the sequence // for (bool8 more = annoseq_d.gotoFirst(); more; more = annoseq_d.gotoNext()) { // get the current annotation // anno = annoseq_d.getCurr(); // check if the annotation start anchor is within bounds // if (anno->getStartAnchor()->getOffset() >= begin_a) { // check if the annotation start anchor is within bounds // if (anno->getStartAnchor()->getOffset() <= end_a) { // insert the annotation into the list // annos_a.insert(anno); } } } } } // exit gracefully // return true; } // method: getAnnotationByOffset // // arguments: // float32 offset: (input) annotation offset // // return: annotation // // method that gets one of the annotations which overlap a particular time // offset. same as getByOffset except that getAnnotationByOffset returns only // one qualified annotation while getByOffset returns all of them // Annotation* AnnotationGraph::getAnnotationByOffset(float32 offset_a) { // get the annotation by offset // return index_d.getAnnotationByOffset(offset_a); } // method: getAnchorSetNearestOffset // // arguments: // float32 offset: (input) anchor offset // DoubleLinkedList& ancrs: (output) anchots list // // return: anchor set // // method that gets all anchors whose offset is the nearest to the // specified offset // bool8 AnnotationGraph::getAnchorSetNearestOffset(float32 offset_a, DoubleLinkedList& ancrs_a) { // determine the nearest offset // float32 offset = getNearestOffset(offset_a); // get the anchor set corresponding to the nearest offset // getAnchorSetByOffset(offset, ancrs_a); // exit gracefully // return true; } // method: getAnnotationSet // // arguments: // DoubleLinkedList& annos_a: (output) annotation list // // return: logical error status // // method to get all the annotations in the graph // bool8 AnnotationGraph::getAnnotationSet(DoubleLinkedList& annos_a) { // declare local variables // String index; // clear the list to start with // annos_a.clear(); annos_a.setAllocationMode(DstrBase::USER); // get the list of annotations // annos_a.assign(annoseq_d); // exit gracefully // return true; } // method: deleteAnnotationSetByFeature // // arguments: // const String& fname_a: (input) feature name // const String& fvalue_a: (input) feature value // // return: logical error status // // method to delete the annotations and the corresponding redundant // anchors with the feature-value pair // bool8 AnnotationGraph::deleteAnnotationSetByFeature(const String& fname_a, const String& fvalue_a) { // declare local variables // DoubleLinkedList annos(DstrBase::USER); Annotation* anno = (Annotation*)NULL; // get the list of annotations corresponding to the feature-value pair // if (!getAnnotationSetByFeature(fname_a, fvalue_a, annos)) { return Error::handle(name(), L"no annotation for this feature and the value", Error::ARG, __FILE__, __LINE__); } // loop over the list of annotations and delete them // for (bool8 more = annos.gotoFirst(); more; more = annos.gotoNext()) { // get the annotation // anno = annos.getCurr(); // check for null annotation // if (anno == (Annotation*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } // delete the annotation // if (!deleteAnnotation(anno)) { return Error::handle(name(), L"can't delete this Annotation", Error::ARG, __FILE__, __LINE__); } } // get all the anchors and purge the redundant anchors // if (!purgeAnchors()) { return Error::handle(name(), L"can't purge the Anchors", Error::ARG, __FILE__, __LINE__); } // exit gracefully // return true; } // method: purgeAnchors // // arguments: // none // // return: logical error status // // method to purge all the redundant anchors in the graph // bool8 AnnotationGraph::purgeAnchors() { // local variables // DoubleLinkedList ancrs(DstrBase::USER); Anchor* ancr = (Anchor*)NULL; DoubleLinkedList in_annos(DstrBase::USER); DoubleLinkedList out_annos(DstrBase::USER); // get all the anchors // if (!getAnchorSet(ancrs)) { return Error::handle(name(), L"no Anchors in this AnnotationGraph", Error::ARG, __FILE__, __LINE__); } // delete the redundant anchors // for (bool8 morea = ancrs.gotoFirst(); morea; morea = ancrs.gotoNext()) { // get the anchor // ancr = ancrs.getCurr(); // check for null anchor // if (ancr == (Anchor*)NULL) { return Error::handle(name(), L"null pointer", Error::ARG, __FILE__, __LINE__); } // clear the memory // in_annos.clear(); out_annos.clear(); // get the incoming and the outgoing annotations at this anchor // if (!getIncomingAnnotationSet(ancr, in_annos)) { return Error::handle(name(), L"no annotation in this AnnotationGraph", Error::ARG, __FILE__, __LINE__); } if (!getOutgoingAnnotationSet(ancr, out_annos)) { return Error::handle(name(), L"no annotation in this AnnotationGraph", Error::ARG, __FILE__, __LINE__); } // delete this anchor if both the incoming and the outgoig // annotations are zero // if ((in_annos.length() == (int32)0) && (out_annos.length() == (int32)0)) { // delete the annotation // if (!deleteAnchor(ancr)) { return Error::handle(name(), L"can't delete this Anchor", Error::ARG, __FILE__, __LINE__); } } } // exit gracefully // return true; }