writer.cpp

来自「支持各种栅格图像和矢量图像读取的库」· C++ 代码 · 共 867 行 · 第 1/2 页

CPP
867
字号
/* 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 + =
减小字号Ctrl + -
显示快捷键?