######################################## # # The Implement of XmlHandle. # # @author Kai Yao(yaokai) # ######################################## implement XmlHandle; include "sys.m"; include "../dfs/dfsutil.m"; include "xml.m"; include "bufio.m"; include "xmlhandle.m"; sys : Sys; xml : Xml; dfsutil : DFSUtil; DFSFile : import dfsutil; DFSNode : import dfsutil; DFSChunk : import dfsutil; Parser : import xml; Item : import xml; file2xml(xmlf : ref Sys->FD, file : ref DFSUtil->DFSFile) { if (sys == nil) sys = load Sys Sys->PATH; sys->fprint(xmlf, ""); sys->fprint(xmlf, "%s", file.name); sys->fprint(xmlf, "%d", file.id); sys->fprint(xmlf, "%d", file.replicas); for (p := file.chunks; p != nil; p = tl p) chunk2xml(xmlf, hd p); sys->fprint(xmlf, ""); } chunk2xml(xmlf : ref Sys->FD, chunk : ref DFSUtil->DFSChunk) { if (sys == nil) sys = load Sys Sys->PATH; sys->fprint(xmlf, ""); sys->fprint(xmlf, "%d", chunk.id); sys->fprint(xmlf, "%bd", chunk.offset); sys->fprint(xmlf, "%d", chunk.size); for (p := chunk.nodes; p != nil; p = tl p) node2xml(xmlf, hd p); sys->fprint(xmlf, ""); } node2xml(xmlf : ref Sys->FD, node : ref DFSUtil->DFSNode) { if (sys == nil) sys = load Sys Sys->PATH; sys->fprint(xmlf, ""); sys->fprint(xmlf, "%s", node.addr); sys->fprint(xmlf, "

%d

", node.port); sys->fprint(xmlf, "%d", node.chunkNumber); sys->fprint(xmlf, "
"); } init(fileName : string) : ref Parser { if (sys == nil) sys = load Sys Sys->PATH; xml = load Xml Xml->PATH; dfsutil = load DFSUtil DFSUtil->PATH; xml->init(); dfsutil->init(); warning := chan of (Xml->Locator, string); preelem : string; (parser, err) := xml->open(fileName, warning, preelem); if (parser == nil) sys->print("Error: %s", err); parser.next(); parser.down(); return parser; } xml2file(parser : ref Parser) : ref DFSFile { (nil, name) := read(parser); (nil, id) := read(parser); (nil, rep) := read(parser); file := ref DFSFile(int id, name, nil, int rep); item := parser.next(); while(item != nil) { parser.down(); chunk := xml2chunk(parser, int id); file.addChunk(chunk); item = parser.next(); } parser.up(); return file; } xml2chunk(parser : ref Parser, fileId : int) : ref DFSChunk { (nil, id) := read(parser); (nil, offset) := read(parser); (nil, size) := read(parser); chunk := ref DFSChunk(int id, fileId, big offset, int size, nil); item := parser.next(); while (item != nil) { parser.down(); node := xml2node(parser); chunk.addNode(node); item = parser.next(); } parser.up(); return chunk; } xml2node(parser : ref Parser) : ref DFSNode { (nil, addr) := read(parser); (nil, port) := read(parser); (nil, chunkNumber) := read(parser); node := ref DFSNode(addr, int port, int chunkNumber); parser.up(); return node; } read(parser : ref Parser) : (string, string) { name, text : string; item := parser.next(); if (item == nil) return (nil, nil); pick it := item { Tag => name = it.name; * => { sys->print("Parsing error, wrong depth!\n"); return (nil, nil); } } parser.down(); mark := parser.mark(); item = parser.next(); if (item == nil) { return (name, nil); } pick it2 := item { Tag => { text = it2.name; parser.goto(mark); } Text => { text = it2.ch; parser.up(); } * => { sys->print("Parsing error, wrong item!\n"); return (nil, nil); } } return (name, text); }