?? writer.cpp
字號:
/* This file is part of the iom project. * For more information, please see <http://www.interlis.ch>. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//** @file * adapter to xml writer * @defgroup writer xml writer functions * @{ */#include <string.h>//#include <xercesc/util/TransService.hpp>#include <xercesc/framework/XMLFormatter.hpp>#include <xercesc/framework/LocalFileFormatTarget.hpp>#include <iom/iom_p.h>#include <algorithm>#include <string>/** gets the xml representaion of a consistency value. */static const XMLCh *encodeConsistency(int consistency){ const XMLCh *ret; switch(consistency){ case IOM_INCOMPLETE: ret=ustrings::get_INCOMPLETE(); break; case IOM_INCONSISTENT: ret=ustrings::get_INCONSISTENT(); break; case IOM_ADAPTED: ret=ustrings::get_ADAPTED(); break; case IOM_COMPLETE: default: ret=0; break; } return ret;}/** gets the xml representaion of a basket-kind value. */static const XMLCh *encodeBasketKind(int kind){ const XMLCh *ret; switch(kind){ case IOM_UPDATE: ret=ustrings::get_UPDATE(); break; case IOM_INITIAL: ret=ustrings::get_INITIAL(); break; case IOM_FULL: default: ret=0; break; } return ret;}/** gets the xml representaion of a operation value. */static const XMLCh *encodeOperation(int ops){ const XMLCh *ret; switch(ops){ case IOM_OP_UPDATE: ret=ustrings::get_UPDATE(); break; case IOM_OP_DELETE: ret=ustrings::get_DELETE(); break; case IOM_OP_INSERT: default: ret=0; break; } return ret;}/** writes a coord value or a coord segment. */static void writeCoord(XmlWriter &out, IomObject &obj){/* object: COORD C1 102.0 C2 402.0 <COORD><C1>102.0</C1><C2>402.0</C2></COORD>*/ out.startElement(tags::get_COORD(),0,0); out.startElement(tags::get_C1(),0,0); const XMLCh *c1=obj->getAttrPrim(tags::get_C1(),0); out.characters(c1); out.endElement(/*C1*/); const XMLCh *c2=obj->getAttrPrim(tags::get_C2(),0); if(c2){ out.startElement(tags::get_C2(),0,0); out.characters(c2); out.endElement(/*C2*/); const XMLCh *c3=obj->getAttrPrim(tags::get_C3(),0); if(c3){ out.startElement(tags::get_C3(),0,0); out.characters(c3); out.endElement(/*C3*/); } } out.endElement(/*COORD*/);}/** writes a arc segment value. */static void writeArc(XmlWriter &out, IomObject &obj){/* object: ARC C1 103.0 C2 403.0 A1 104.0 A2 404.0 <COORD><C1>103.0</C1><C2>403.0</C2><A1>104.0</A1><A2>404.0</A2></COORD>*/ out.startElement(tags::get_ARC(),0,0); out.startElement(tags::get_C1(),0,0); const XMLCh *c1=obj->getAttrPrim(tags::get_C1(),0); out.characters(c1); out.endElement(/*C1*/); const XMLCh *c2=obj->getAttrPrim(tags::get_C2(),0); out.startElement(tags::get_C2(),0,0); out.characters(c2); out.endElement(/*C2*/); const XMLCh *c3=obj->getAttrPrim(tags::get_C3(),0); if(c3){ out.startElement(tags::get_C3(),0,0); out.characters(c3); out.endElement(/*C3*/); } const XMLCh *a1=obj->getAttrPrim(tags::get_A1(),0); out.characters(a1); out.endElement(/*A1*/); const XMLCh *a2=obj->getAttrPrim(tags::get_A2(),0); out.startElement(tags::get_A2(),0,0); out.characters(a2); out.endElement(/*A2*/); const XMLCh *r=obj->getAttrPrim(tags::get_R(),0); if(r){ out.startElement(tags::get_R(),0,0); out.characters(r); out.endElement(/*R*/); } out.endElement(/*ARC*/);}/** writes a polyline value. */void iom_file::writePolyline(XmlWriter &out, IomObject &obj,bool hasLineAttr){/* object: POLYLINE [INCOMPLETE] lineattr object: Model.Topic.LineAttr attr00 11 sequence // if incomplete; multi sequence values object: SEGMENTS segment object: COORD C1 102.0 C2 402.0 segment object: ARC C1 103.0 C2 403.0 A1 104.0 A2 404.0 segment object: Model.SplineParam SegmentEndPoint object: COORD C1 103.0 C2 403.0 p0 1.0 p1 2.0 <POLYLINE> <LINEATTR> <Model.Topic.LineAttr> <attr00>11</attr00> </Model.Topic.LineAttr> </LINEATTR> <COORD> <C1>101.0</C1> <C2>401.0</C2> </COORD> <COORD> <C1>102.0</C1> <C2>402.0</C2> </COORD> <Model.SplineParam> <SegmentEndPoint> <COORD> <C1>103.0</C1> <C2>403.0</C2> </COORD> </SegmentEndPoint> <p0>1.0</p0> <p1>2.0</p1> </Model.SplineParam> </POLYLINE>*/ out.startElement(tags::get_POLYLINE(),0,0); if(hasLineAttr){ IomObject lineattr=obj->getAttrObj(tags::get_lineattr(),0); if(!lineattr.isNull()){ out.startElement(tags::get_LINEATTR(),0,0); out.startElement(lineattr->getTag(),0,0); writeAttrs(out,lineattr); out.endElement(/*lineattr*/); out.endElement(/*LINEATTR*/); } } bool clipped=obj->getConsistency()==IOM_INCOMPLETE; for(int sequencei=0;sequencei<obj->getAttrValueCount(tags::get_sequence());sequencei++){ if(clipped){ out.startElement(tags::get_CLIPPED(),0,0); }else{ // an unclipped polyline should have only one sequence element if(sequencei>0){ iom_issueerr("unclipped polyline with multi 'sequence' elements"); break; } } IomObject sequence=obj->getAttrObj(tags::get_sequence(),sequencei); for(int segmenti=0;segmenti<sequence->getAttrValueCount(tags::get_segment());segmenti++){ IomObject segment=sequence->getAttrObj(tags::get_segment(),segmenti); if(segment->getTag()==tags::get_COORD()){ // COORD writeCoord(out,segment); }else if(segment->getTag()==tags::get_ARC()){ // ARC writeArc(out,segment); }else{ // custum line form out.startElement(segment->getTag(),0,0); writeAttrs(out,segment); out.endElement(/*segment*/); } } if(clipped){ out.endElement(/*CLIPPED*/); } } out.endElement(/*POLYLINE*/);}/** writes a surface value. */void iom_file::writeSurface(XmlWriter &out, IomObject &obj){/* object: MULTISURFACE [INCOMPLETE] surface // if incomplete; multi surface values object: SURFACE boundary object: BOUNDARY polyline object: POLYLINE <SURFACE> <BOUNDARY> <POLYLINE .../> <POLYLINE .../> </BOUNDARY> <BOUNDARY> <POLYLINE .../> <POLYLINE .../> </BOUNDARY> </SURFACE>*/ out.startElement(tags::get_SURFACE(),0,0); bool clipped=obj->getConsistency()==IOM_INCOMPLETE; for(int surfacei=0;surfacei<obj->getAttrValueCount(tags::get_surface());surfacei++){ if(clipped){ out.startElement(tags::get_CLIPPED(),0,0); }else{ // an unclipped surface should have only one surface element if(surfacei>0){ iom_issueerr("unclipped surface with multi 'surface' elements"); break; } } IomObject surface=obj->getAttrObj(tags::get_surface(),surfacei); for(int boundaryi=0;boundaryi<surface->getAttrValueCount(tags::get_boundary());boundaryi++){ IomObject boundary=surface->getAttrObj(tags::get_boundary(),boundaryi); out.startElement(tags::get_BOUNDARY(),0,0); for(int polylinei=0;polylinei<boundary->getAttrValueCount(tags::get_polyline());polylinei++){ IomObject polyline=boundary->getAttrObj(tags::get_polyline(),polylinei); writePolyline(out,polyline,true); } out.endElement(/*BOUNDARY*/); } if(clipped){ out.endElement(/*CLIPPED*/); } } out.endElement(/*SURFACE*/);}void iom_file::writeAttr(XmlWriter &out, IomObject &obj,int attr){ int valueCount=obj->getAttrValueCount(attr); if(valueCount>0){ const XMLCh *val=obj->getAttrPrim(attr,0); // not a primitive? if(!val){ IomObject child=obj->getAttrObj(attr,0); // some special cases if(child->getTag()==tags::get_COORD()){ // COORD out.startElement(attr,0,0); writeCoord(out,child); out.endElement(/*attr*/); if(valueCount>1){ iom_issueerr("max one COORD value allowed"); } }else if(child->getTag()==tags::get_POLYLINE()){ // POLYLINE out.startElement(attr,0,0); writePolyline(out,child,false); out.endElement(/*attr*/); if(valueCount>1){ iom_issueerr("max one POLYLINE value allowed"); } }else if(child->getTag()==tags::get_MULTISURFACE()){ // MULTISURFACE out.startElement(attr,0,0); writeSurface(out,child); out.endElement(/*attr*/); if(valueCount>1){ iom_issueerr("max one MULTISURFACE value allowed"); } }else{ // normal case const XMLCh *ref=child->getRefOid(); bool isRef= ref ? true : false; // Reference-attribute or Role or EmbeddedLink? if(isRef){ const XMLCh *extref=0; const XMLCh *bid=0; XMLCh itoabuf[40]; const XMLCh *orderpos=0; if(ref){ if(child->getRefOrderPos()>0){ XMLString::binToText( child->getRefOrderPos(),itoabuf,sizeof(itoabuf)-1,10); orderpos=itoabuf; } } bid=child->getRefBid(); if(bid){ extref=ref; ref=0; } XmlWrtAttr refAttr[]={ XmlWrtAttr(ref ? ustrings::get_REF() :0, ref,true) ,XmlWrtAttr(extref ? ustrings::get_EXTREF() :0, extref,true) ,XmlWrtAttr(bid ? ustrings::get_BID() :0, bid,true) ,XmlWrtAttr(orderpos ? ustrings::get_ORDER_POS():0, orderpos) }; out.startElement(attr,refAttr,sizeof(refAttr)/sizeof(refAttr[0])); if(child->getAttrCount()>0){ out.startElement(child->getTag(),0,0); writeAttrs(out,child); out.endElement(/*child*/); } out.endElement(/*attr*/); if(valueCount>1){ iom_issueerr("max one reference value allowed"); } }else{ // struct out.startElement(attr,0,0); int valuei=0; while(1){ out.startElement(child->getTag(),0,0); writeAttrs(out,child); out.endElement(/*child*/); valuei++; if(valuei>=valueCount){ break; } child=obj->getAttrObj(attr,valuei); } out.endElement(/*attr*/); } } }else{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -