virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* opt) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (osgDB::equalCaseInsensitive(ext,"terrain")) { std::istringstream fin(osgDB::getNameLessExtension(file)); if (fin) return readNode(fin,opt); return 0; } if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, opt ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; // code for setting up the database path so that internally referenced file are searched for on relative paths. osg::ref_ptr<Options> local_opt = opt ? static_cast<Options*>(opt->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; local_opt->setDatabasePath(osgDB::getFilePath(fileName)); osgDB::ifstream fin(fileName.c_str()); if (fin) { return readNode(fin, local_opt.get()); } return 0L; }
TNode *TOutline::readNode(ipstream &ip) { int nChildren; uchar more; uchar expand; TNode *node = new TNode((char *)0); ip >> more; ip >> expand; ip >> nChildren; node->text = ip.readString(); node->expanded = Boolean(expand); if (nChildren) node->childList = readNode(ip); else node->childList = 0; if (more) node->next = readNode(ip); else node->next = 0; return node; }
BSPNode* BSPFile::readNode( ChunkInputStream* in ) { long chunkend = 0; String name; in->beginChunk( &name, &chunkend ); Vector4 plane = Vector4(0,0,0,1); plane.x = in->readFloat(); plane.y = in->readFloat(); plane.z = in->readFloat(); plane.w = in->readFloat(); BSPNode* pos = 0; BSPNode* neg = 0; int childFlags = in->readInt(); if ( childFlags & 1 ) pos = readNode( in ); if ( childFlags & 2 ) neg = readNode( in ); int npolygons = in->readInt(); m_polygonBuffer.setSize( npolygons ); for ( int i = 0; i < npolygons; ++i ) { int ix = in->readInt(); if ( ix < 0 || ix >= m_tree->polygons() ) throw IOException( Format("Invalid polygon index in BSP {0}", in->toString()) ); m_polygonBuffer[i] = m_tree->getPolygon(ix); } in->endChunk( chunkend ); return m_tree->createNode( plane, m_polygonBuffer, pos, neg ); }
void Btree<T>::recDelete(T& x, unsigned ptr, Boolean& found) // // // Purpose: function that performs node deletion. // // Parameters: // // input: x - the data to be removed // ptr - the // // output: // found - flag that indicates whether item x was found // { Bstruct<T> *buf, *buf2; unsigned i; if (ptr == BTREE_NIL) found = FALSE; else { buf = new Bstruct<T>; readNode(buf, ptr); // search for x in the current node found = (searchNode(x, buf, i)) ? TRUE : FALSE; // found an element that matches item x? if (found) { // does ptr point to a leaf node? if (buf->nodeLink[i - 1] == BTREE_NIL) { // remove element at index i trim(buf, i); writeNode(buf, ptr); } else { // replace data[i] with its successor in node ptr successor(buf, i); writeNode(buf, ptr); recDelete(buf->data[i], buf->nodeLink[i], found); } } else recDelete(x, buf->nodeLink[i], found); if (buf->nodeLink[i] != BTREE_NIL) { buf2 = new Bstruct<T>; readNode(buf2, buf->nodeLink[i]); if (buf2->count < BTREE_MIN) { restore(buf, i); writeNode(buf, ptr); } delete buf2; } delete buf; } }
Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readAscii(SMESH_File& theFile) const { Status aResult = DRS_OK; // get the file size long filesize = theFile.size(); theFile.close(); // Open the file FILE* file = fopen( myFile.c_str(),"r"); // count the number of lines Standard_Integer nbLines = 0; for (long ipos = 0; ipos < filesize; ++ipos) { if (getc(file) == '\n') nbLines++; } // go back to the beginning of the file rewind(file); Standard_Integer nbTri = (nbLines / ASCII_LINES_PER_FACET); TDataMapOfPntNodePtr uniqnodes; // skip header while (getc(file) != '\n'); // main reading for (Standard_Integer iTri = 0; iTri < nbTri; ++iTri) { // skipping the facet normal Standard_ShortReal normal[3]; fscanf(file,"%*s %*s %f %f %f\n",&normal[0],&normal[1],&normal[2]); // skip the keywords "outer loop" fscanf(file,"%*s %*s"); // reading nodes SMDS_MeshNode* node1 = readNode( file, uniqnodes, myMesh ); SMDS_MeshNode* node2 = readNode( file, uniqnodes, myMesh ); SMDS_MeshNode* node3 = readNode( file, uniqnodes, myMesh ); if (myIsCreateFaces) myMesh->AddFace(node1,node2,node3); // skip the keywords "endloop" fscanf(file,"%*s"); // skip the keywords "endfacet" fscanf(file,"%*s"); } fclose(file); return aResult; }
void Btree<T>::compact(Bstruct<T> *ptr, unsigned pos) // // Purpose: combines adjacent nodes. // // Parameters: // // input: ptr - the pointer to the manipulated node // pos - the index of the merged right node // { Bstruct<T> *bufP = new Bstruct<T>; Bstruct<T> *bufQ = new Bstruct<T>; unsigned p, q, i; p = ptr->nodeLink[pos - 1]; readNode(bufP, p); // q is the index to the right node that will be made vacant // and then deleted q = ptr->nodeLink[pos]; readNode(bufQ, q); // process the left node and insert data elements from // the parent node bufP->count++; bufP->data[bufP->count] = ptr->data[pos]; bufP->nodeLink[bufP->count] = bufQ->nodeLink[0]; // inserts all data elements from the right node for (i = 1; i <= bufQ->count; i++) { bufP->count++; bufP->data[bufP->count] = bufQ->data[i]; bufP->nodeLink[bufP->count] = bufQ->nodeLink[i]; } // remove data elements from the parent node for (i = pos; i < ptr->count; i++) { ptr->data[i] = ptr->data[i + 1]; ptr->nodeLink[i] = ptr->nodeLink[i + 1]; } ptr->count--; // remove the empty right node numDelNodes++; // increment the counter for the number // of deleted nodes // does the array delNodeArray need to expand? if (numDelNodes == countDelNodeArray) expandDelNodeArray(); // assign index q to an element of array delNodeArray *(delNodeArray + numDelNodes - 1) = q; numNodes--; writeNode(bufP, p); delete bufQ; delete bufP; }
QvBool QvNode::read(QvInput *in, QvNode *&node) { QvBool ret; QvName name; if (! in->read(name, TRUE)) { node = NULL; ret = in->headerOk; } else if (! name || name == NULL_KEYWORD) { node = NULL; ret = TRUE; } else if (name == REFERENCE_KEYWORD) { node = readReference(in); ret = (node != NULL); } else ret = readNode(in, name, node); return ret; }
bool parseSpriteNode(SpriteNode* node, TiXmlElement* elemParent) { //TODO: there is a leak here somewhere. SpriteBlock* oldSibling = NULL; TiXmlElement* elemNode = elemParent->FirstChildElement(); const char* strParent = elemParent->Value(); if (elemNode == NULL) { contentError("Empty SpriteNode Element",elemParent); return false; } if ( strcmp(strParent,"building") != 0 && strcmp(strParent,"custom_workshop") != 0 && strcmp(strParent,"rotate") != 0) { //flag to allow else statements to be empty, rather than needing an "always" tag bool allowBlank = (strcmp(strParent,"else") == 0 || elemParent->Attribute("else")); // cast should be safe, because only spriteblocks // should get here int retvalue =parseConditionNode((SpriteBlock *)node,elemNode,allowBlank); if (retvalue == 0) return false; if (retvalue > 0) elemNode = elemNode->NextSiblingElement(); } while (elemNode) { if (!readNode(node, elemNode, elemParent, oldSibling)) return false; elemNode = elemNode->NextSiblingElement(); } return true; }
void *TOutline::read(ipstream &ip) { TOutlineViewer::read(ip); root = readNode(ip); return this; }
int recDelete(rect *r, node *n, int pos){ int i,j; node *n1, *n2; if(n->leaf){ for(i = 0; i < n->size; ++i) if(n->values[i]->child == pos){ deleteValue(n, i); writeNode(n); return TRUE; } return FALSE; } for(i = 0; i < n->size; ++i) if(intersect(r, n->values[i]->r)){ n1 = readNode(n->values[i]->child); if(recDelete(r, n1, pos)){ n->values[i]->r = dupRect(n1->MBR); if(n1->size < b ) underflow(n, n1, i); else{ refreshMBR(n); writeNode(n); freeNode(n1); } return TRUE; } else freeNode(n1); } return FALSE; }
void NewickTreeReader::read(std::istream &in, Tree &tree) const { peekNextCharacter(in); Node *rootNode = readNode(in); ignoreNextCharacter(in); // semicolon tree.setRoot(rootNode); }
void QgsOSMXmlImport::readRoot( QXmlStreamReader& xml ) { int i = 0; int percent = -1; while ( !xml.atEnd() ) { xml.readNext(); if ( xml.isEndElement() ) // </osm> break; if ( xml.isStartElement() ) { if ( ++i == 500 ) { int new_percent = 100 * mInputFile.pos() / mInputFile.size(); if ( new_percent > percent ) { emit progress( new_percent ); percent = new_percent; } i = 0; } if ( xml.name() == "node" ) readNode( xml ); else if ( xml.name() == "way" ) readWay( xml ); else xml.skipCurrentElement(); } } }
void Btree<T>::restore(Bstruct<T> *ptr, unsigned pos) // // // Purpose: locates an item and inserts into nodeLink[pos] of // node ptr in order to restore the minimum number of items in // the targeted node. // // Parameters: // // input: ptr - the pointer to the manipulated node // pos - the index of the inserted element // { Bstruct<T> *childBuf, *childBuf2; childBuf = new Bstruct<T>; if (pos == 0) { readNode(childBuf, ptr->nodeLink[1]); // restore leftmost element in the current node? if (childBuf->count > BTREE_MIN) shiftLeft(ptr, 1); else compact(ptr, 1); } // restore the rightmost element in the current node? else if (pos == ptr->count) { readNode(childBuf, ptr->nodeLink[pos - 1]); if (childBuf->count > BTREE_MIN) shiftRight(ptr, pos); else compact(ptr, pos); } // restore other internal elements in the current node else { childBuf2 = new Bstruct<T>; readNode(childBuf, ptr->nodeLink[pos - 1]); readNode(childBuf2, ptr->nodeLink[pos + 1]); if (childBuf->count > BTREE_MIN) shiftRight(ptr, pos); else if (childBuf2->count > BTREE_MIN) shiftLeft(ptr, pos + 1); else compact(ptr, pos); delete childBuf2; } delete childBuf; }
int inputTransform(JsonParser *parser, Graph *graph) { JsonNode *root; JsonReader *reader; int num_nodes, num_edges; int i; root = json_parser_get_root(parser); reader = json_reader_new(root); // Is the graph directed ? json_reader_read_member(reader, "oriented") if(json_reader_get_boolean_value(reader)) { graph->directed = DIRECTED; } else { graph->directed = NOT_DIRECTED; } json_reader_end_member(reader); // Get the nodes json_reader_read_member(reader, "nodes"); if(json_reader_is_array(reader)) { // Allocate the memory for the nodes, and for the edges num_nodes = json_reader_count_elements(reader); graph->nodes = malloc(num_nodes * sizeof(Node)); graph->edges = malloc(num_nodes * sizeof(Edge *)); for(i=0; i < num_nodes; i++) { graph->edges[i] = malloc(num_nodes * sizeof(Edge)); } for(i=0; i < num_nodes; i++) { json_reader_read_element(reader, i); readNode(json_reader_get_value(reader), graph); json_reader_end_element(reader); } } json_reader_end_member(reader); // Get the edges json_reader_read_member(reader, "edges"); if(json_reader_is_array(reader)) { for(i=0; i < num_edges; i++) { json_reader_read_element(reader, i); reader(json_reader_get_value(reader), graph); json_reader_end_element(reader); } } json_reader_end_member(reader); return EXIT_SUCCESS; }
void underflow(node *n, node *n1, int i){ int j, sibling; node *n2; if(n->size == i + 1){ n2 = readNode(n->values[i-1]->child); sibling = i-1; } else{ n2 = readNode(n->values[i+1]->child); sibling = i+1; } if(n2->size > b){ n1->values[n1->size++] = n2->values[--(n2->size)]; refreshMBR(n1); refreshMBR(n2); freeRect(n->values[i]->r); n->values[i]->r = dupRect(n1->MBR); freeRect(n->values[sibling]->r); n->values[sibling]->r = dupRect(n2->MBR); refreshMBR(n); writeNode(n); writeNode(n1); freeNode(n1); writeNode(n2); freeNode(n2); } else{ n2 = merge(n1,n2); freeNodeVal(n->values[i]); n->values[i] = new(nodeVal); n->values[i]->child = n2->address; n->values[i]->r=dupRect(n2->MBR); deleteValue(n, sibling); writeNode(n); freeNode(n2); } }
void Btree<T>::cutNode(T& x, unsigned xRST, unsigned ptr, unsigned pos, T& y, unsigned &yRST) // // Purpose: divides the node accessed by index ptr that contains // item x and index xRST at index pos. The new nodes are accessed // by pointers ptr and yRST. The median element is y. // // Parameters: // // input: x - the inserted data // xRST - the inserted index associated with item x // ptr - the index to the manipulated node // pos - the index of the dividing line // // output: // y - the new median // yRST - the index to the other node. // { unsigned median, i; Bstruct<T> *buf1, *buf2; buf1 = new Bstruct<T>; buf2 = new Bstruct<T>; readNode(buf1, ptr); // calculate the median element which also determines if // the new inserted item x is placed in the new left or the // new right nodes median = (pos <= BTREE_MIN) ? BTREE_MIN : BTREE_MIN + 1; // create a new tree node and put it on the right yRST = getNodeIndex(); for (i = 0; i <= BTREE_MAX; i++) buf2->nodeLink[i] = BTREE_NIL; numNodes++; // loop to move half of the keys for (i = median + 1; i <= BTREE_MAX; i++) { buf2->data[i - median] = buf1->data[i]; buf2->nodeLink[i - median] = buf1->nodeLink[i]; } buf2->count = BTREE_MAX - median; buf1->count = median; // push in the new data if (pos <= BTREE_MIN) pushIn(x, xRST, buf1, pos); else pushIn(x, xRST, buf2, pos - median); y = buf1->data[buf1->count]; buf2->nodeLink[0] = buf1->nodeLink[buf1->count--]; writeNode(buf1, ptr); writeNode(buf2, yRST); delete buf1; delete buf2; }
Boolean Btree<T>::pushDown(T& x, unsigned ptr, T& item, unsigned &itemRST) // // Purpose: recursive function that inserts item x in the B-tree. // The function returns TRUE if a the height of the B-tree needs // to be increased. Otherwise, the function yields FALSE. // // Parameters: // // input: x - the inserted data // ptr - the index to the manipulated node // // output: // item - the median element // itemRST - the index to the right subtree of the node // which contains item // { unsigned i; Bstruct<T> *buf; if (ptr == BTREE_NIL) { // cannot insert into an empty tree item = x; itemRST = BTREE_NIL; return TRUE; } else { buf = new Bstruct<T>; readNode(buf, ptr); // attempt to isnert a duplicate key in the current node? if (searchNode(x, buf, i)) { strcpy(errMsg, "Cannot insert duplicates"); return FALSE; } // reinsert the median element if (pushDown(x, buf->nodeLink[i], item, itemRST)) { if (buf->count < BTREE_MAX) { pushIn(item, itemRST, buf, i); writeNode(buf, ptr); delete buf; return FALSE; } else { cutNode(item, itemRST, ptr, i, item, itemRST); delete buf; return TRUE; } } else { delete buf; return FALSE; } } }
Huffman::Node* Huffman::readNode(BitInput*& reader) { int tmp = (*reader).readBit(); if (tmp == 1) { countOfOperations += 3; return new Node((*reader).readChar32(), nullptr, nullptr); } else { Node* left = readNode(reader); Node* right = readNode(reader); root = new Node(0, left, right); countOfOperations += 5; return root; } }
/* Read LLS from each node */ void readNode(typeList *lis) { int temp; if (readDataType(&temp) == EOF) *lis = NULL; else { *lis = (typeList)malloc(sizeof(typeNodeList)); (*lis)->data = temp; readNode(&((*lis)->next)); } }
void Btree<T>::shiftLeft(Bstruct<T> *ptr, unsigned pos) // // // Purpose: moves a data element into the left in a node. // // Parameters: // // input: ptr - the index to the manipulated node // pos - the index of the shifted data element // { Bstruct<T> *bufP = new Bstruct<T>; Bstruct<T> *bufQ = new Bstruct<T>; unsigned p, q; // shift data element from parent node into the left node p = ptr->nodeLink[pos - 1]; readNode(bufP, p); bufP->count++; bufP->data[bufP->count] = ptr->data[pos]; q = ptr->nodeLink[pos]; readNode(bufQ, q); bufP->nodeLink[bufP->count] = bufQ->nodeLink[0]; writeNode(bufP, p); // shift the data element from the right node into // the parent node p = ptr->nodeLink[pos]; readNode(bufP, p); ptr->data[pos] = bufP->data[1]; bufP->nodeLink[0] = bufP->nodeLink[1]; bufP->count--; // loop that shifts all of the data elements in the right node // by one position upward for (unsigned i = 1; i <= bufP->count; i++) { bufP->data[i] = bufP->data[i + 1]; bufP->nodeLink[i] = bufP->nodeLink[i + 1]; } // update nodes p and ptr in the stream writeNode(bufP, p); delete bufP; delete bufQ; }
Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readBinary(SMESH_File& file) const { Status aResult = DRS_OK; // the size of the file (minus the header size) // must be a multiple of SIZEOF_STL_FACET long filesize = file.size(); if ( (filesize - HEADER_SIZE) % SIZEOF_STL_FACET !=0 // Commented to allow reading small files (ex: 1 face) /*|| (filesize < STL_MIN_FILE_SIZE)*/) { Standard_NoMoreObject::Raise("DriverSTL_R_SMDS_MESH::readBinary (wrong file size)"); } // don't trust the number of triangles which is coded in the file // sometimes it is wrong, and with this technique we don't need to swap endians for integer Standard_Integer nbTri = ((filesize - HEADER_SIZE) / SIZEOF_STL_FACET); // skip the header file += HEADER_SIZE; TDataMapOfPntNodePtr uniqnodes; for (Standard_Integer iTri = 0; iTri < nbTri; ++iTri) { // ignore normals file += 3 * SIZE_OF_FLOAT; // read vertices SMDS_MeshNode* node1 = readNode( file, uniqnodes, myMesh ); SMDS_MeshNode* node2 = readNode( file, uniqnodes, myMesh ); SMDS_MeshNode* node3 = readNode( file, uniqnodes, myMesh ); if (myIsCreateFaces) myMesh->AddFace(node1,node2,node3); // skip extra bytes file += 2; } return aResult; }
void Btree<T>::shiftRight(Bstruct<T> *ptr, unsigned pos) // // // Purpose: moves a data element to the right in a node. // // Parameters: // // input: ptr - the pointer to the manipulated node // pos - the index of the shifted data element // { Bstruct<T> *bufP = new Bstruct<T>; Bstruct<T> *bufQ = new Bstruct<T>; unsigned p, q; p = ptr->nodeLink[pos]; readNode(bufP, p); // move all the data elements to the right by one position for (unsigned i = bufP->count; i > 0; i--) { bufP->data[i + 1] = bufP->data[i]; bufP->nodeLink[i + 1] = bufP->nodeLink[i]; } // shift the data element from parent node and into right node bufP->nodeLink[1] = bufP->nodeLink[0]; bufP->count++; bufP->data[1] = ptr->data[pos]; writeNode(bufP, p); // move the last data of the left node into the parent node p = ptr->nodeLink[pos - 1]; readNode(bufP, p); ptr->data[pos] = bufP->data[bufP->count]; q = ptr->nodeLink[pos]; readNode(bufQ, q); bufQ->nodeLink[0] = bufP->nodeLink[bufP->count]; bufP->count--; // update nodes p and ptr in the stream writeNode(bufP, p); writeNode(bufQ, q); delete bufP; delete bufQ; }
virtual ReadResult readObject(const std::string& uri, const Options* options) const { if ( "osgearth_engine_mp" == osgDB::getFileExtension( uri ) ) { if ( "earth" == osgDB::getNameLessExtension( osgDB::getFileExtension( uri ) ) ) { return readNode( uri, options ); } else { MPTerrainEngineOptions terrainOpts; OE_INFO << LC << "Activated!" << std::endl; return ReadResult( new MPTerrainEngineNode() ); } } else { return readNode( uri, options ); } }
virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension( file ); if ( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, options ); if ( fileName.empty() ) return ReadResult::FILE_NOT_FOUND; std::ifstream stream( fileName.c_str(), std::ios::in|std::ios::binary ); if( !stream ) return ReadResult::ERROR_IN_READING_FILE; return readNode( stream, options ); }
FgDgn<T> addInput(const T & defaultVal,const FgString & uid,bool binary=false) { FgDgn<T> node = dg.addNode(defaultVal,uid.as_ascii()); readNode(node,uid,binary); Input inp; inp.nodeIdx = node.idx(); inp.save = boost::bind(&FgGuiGraph::writeNode<T>,this,node,uid,binary); inp.defaultVal = FgVariant(defaultVal); m_inputSaves.push_back(inp); return node; }
Node *NewickTreeReader::readNode(std::istream &in) const { Node *node = new Node(); if(characterStartsBranchNode(peekNextCharacter(in))) { ignoreNextCharacter(in); Node* leftChild = readNode(in); node->setLfDesc(leftChild); leftChild->setAnc(node); if(characterStartsNextChildNode(peekNextCharacter(in))) { ignoreNextCharacter(in); Node* rightChild = readNode(in); node->setRtDesc(rightChild); rightChild->setAnc(node); } else { exitWithError("Tree is not bifurcating."); } ignoreNextCharacter(in); } node->setName(readName(in)); node->setBrlen(readBranchLength(in)); if (node->getLfDesc() == NULL && node->getRtDesc() == NULL) { node->setIsTip(true); } return node; }
void medXMLToLUTReaderPrivate::readTable() { Q_ASSERT(xml.isStartElement() && xml.name() == "table"); medClutEditorTable * table = new medClutEditorTable( xml.attributes().value("title").toString()); while (xml.readNextStartElement()) { if (xml.name() == "node") readNode(*table); else xml.skipCurrentElement(); } tables->append(table); }
treenode* readTree(char*file){ int d; FILE *fp = fopen(file,"r"); if(fp==NULL){ fprintf(stderr,"unable to open input file... exiting \n"); exit(1); } if(fscanf(fp,"%d \n",&d)==EOF){ fprintf(stderr, "error reading tree... exiting \n"); exit(1); } return readNode(d,fp); fclose(fp); }
void SceneFileLoader::readNodes(TiXmlElement* Nodes, vector<NODE>& container ) { TiXmlElement* Node=0; string val; for( Node = Nodes->FirstChildElement(); Node; Node = Node->NextSiblingElement() ) { val = Node->Value(); if (val == "Node") { readNode(Node,container); } } }
treenode* readNode(int d,FILE* fp){ int i, pos_error; float temp; treenode* node = (treenode*)calloc(1,sizeof(treenode)); pos_error = fscanf(fp,"%d %f %d\n",&(node->n),&temp,&(node->isLeaf)); node->R = (double)temp; node->mu = calloc(d,sizeof(double)); node->mup = calloc(d,sizeof(double)); node->inds = calloc(node->n,sizeof(int)); for(i=0;i<d;i++){ pos_error = fscanf(fp,"%f ",&temp); node->mu[i]=(double)temp; } pos_error = fscanf(fp,"\n"); for(i=0;i<d;i++){ pos_error = fscanf(fp,"%f ",&temp); node->mup[i]=(double)temp; } pos_error = fscanf(fp,"\n"); for(i=0;i< node->n;i++){ pos_error = fscanf(fp,"%d ",&(node->inds[i])); } pos_error = fscanf(fp,"\n"); if( pos_error == EOF){ fprintf(stderr, "error reading tree... exiting \n"); exit(1); } if (!(node->isLeaf)){ node->l=readNode(d,fp); node->r=readNode(d,fp); } return node; }