bool CdTreeStream::read(std::istream& is, SeqTree& seqTree) { if (!is.good()) return false; char ch; is.get(ch); // skip to the first ( while((ch != '(') && (is.good())) { is.get(ch); } if (!is.good()) return false; SeqItem item; SeqTree::iterator top = seqTree.insert(seqTree.begin(),item); SeqTree::iterator cursor = top; std::string nameDist; std::string distance; std::string delimiters = "(),"; while(is.get(ch)) { if (!isspace((unsigned char) ch)) { SeqItem tmp1; switch (ch) { case ';': //end seq tree data return true; //break; case '(': // start a node cursor = seqTree.append_child(cursor, tmp1); break; case ',': // end a sibling, nothing needs done, skip it. break; case ')': //end a node; read and set the distance readToDelimiter(is,distance); if (distance.size() >0) { // allow interior nodes to be named int colon_loc = distance.find_first_of(":"); if (colon_loc > 0) { cursor->name = distance.substr(0, colon_loc); distance = distance.erase(0, colon_loc); } //skip the leading : //if not present, check if dealing w/ a final named internal node if (distance[0] != ':') { int semi_loc = distance.find_first_of(";"); if (semi_loc > 0) { cursor->name = distance.substr(0, semi_loc); is.putback(distance[semi_loc]); // } else { // std::cout<<"length missing; semi_loc = "<<semi_loc<<std::endl; } } else { distance.erase(0,1); double dist = atof(distance.c_str()); if (dist < 0.0) { std::cout << "Warning: negative branch length! " << cursor->name << ", D = " << distance << std::endl; } //set distance cursor->distance = dist; if (cursor == top) { std::cout<<"Warning: already reached top before processing )"; return false; } else cursor = seqTree.parent(cursor); } } distance.erase(); break; default: // non-delimiter starts a new leaf node nameDist += ch; readToDelimiter(is, nameDist); tmp1 = SeqItem(nameDist); seqTree.append_child(cursor,tmp1); //don't move cursor //reset the word nameDist.erase(); } } } return true; }
std::string readline(std::istream& in) { return readToDelimiter(in, in.widen('\n')); }