// -*- mode:C++; tab-width:2; c-basic-offset:2; indent-tabs-mode:nil -*-
//
// Copyright (C) 2000-2005 by Roger Rene Kommer / artefaktur, Kassel, Germany.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License (LGPL).
//
//
// 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
// License ACDK-FreeLicense document enclosed in the distribution
// for more for more details.
// This file is part of the Artefaktur Component Development Kit:
// ACDK
//
// Please refer to
// - http://www.acdk.de
// - http://www.artefaktur.com
// - http://acdk.sourceforge.net
// for more information.
//
// $Header: /cvsroot/acdk/acdk/acdk_xml/src/acdk/xml/XMLObjectWriter.cpp,v 1.21 2005/03/08 18:50:42 kommer Exp $
#include <acdk.h>
#include <acdk/lang/Boolean.h>
#include <acdk/lang/Character.h>
#include <acdk/lang/Short.h>
#include <acdk/lang/Integer.h>
#include <acdk/lang/Long.h>
#include <acdk/lang/Float.h>
#include <acdk/lang/Double.h>
#include <acdk/lang/dmi/SysFields.h>
#include <acdk/lang/reflect/Modifier.h>
#include <acdk/text/Base64.h>
#include <acdk/net/URLEncoder.h>
#include <acdk/locale/UTF8Encoding.h>
#include <acdk/util/Date.h>
#include "XMLObjectWriter.h"
namespace acdk {
namespace xml {
USING_CLASS(::acdk::net::, URLEncoder);
USING_CLASS(::acdk::io::, AbstractObjectWriter);
using ::acdk::lang::dmi::SysField;
using ::acdk::lang::reflect::Modifier;
XMLObjectWriter::XMLObjectWriter(IN(RWriter) out, int flags /*=::acdk::io::SerializeDefaultFlags*/)
: AbstractObjectWriter(out, flags),
//_ptr2id(new HashMap()),
//_maxLocalRef(0),
_doIndent(true),
//_withFieldInfo(false),
_indent(0)
{
}
RString getObjectName(IN(acdk::lang::Object) obj)
{
if (obj == Nil)
return "acdk/lang/acdk::lang::Object";
return obj->getClass()->getName();
}
//static
RString
XMLObjectWriter::xmlencode(IN(RString) txt)
{
return
txt->replace(">", ">")
->replace("<", "<")
->replace("&", "&")
->replace("\"", """)
;
}
//static
RString
XMLObjectWriter::xmldecode(IN(RString) txt)
{
return
txt->replace(">", ">")
->replace("<", "<")
->replace("&", "&")
->replace(""", "\"")
;
}
void
XMLObjectWriter::_dumpindend()
{
if (_doIndent == false)
return;
_out->write((const byte*)"\n", 0, 1);
for (int i = _indent; i >= 0; i--)
_out->write((const byte*)" ", 0, 1);
}
/*
void
XMLObjectWriter::writeObject(acdk::lang::Object obj)
{
writeObject2(obj);
}
*/
/*
//virtual
void
XMLObjectWriter::writeObject(RClass cls, acdk::lang::Object obj)
{
Object::_throwNotImplementedYet("XMLObjectWriter::writeObject(RClass cls, acdk::lang::Object obj)"); // ## implement
}
void
XMLObjectWriter::writeObject2(acdk::lang::Object obj, RString label)
{
_dumpindend();
if (obj == Nil) {
_out->write("<Nil/>");
return;
}
RClass theClass = obj->getClass();
acdk::lang::Object lo = _ptr2id->get(obj);
if (lo != Nil) {
RString msg = RString("<object lref=\"") + ((RInteger)lo)->toString() + "\"/>";
_out->write(msg->c_str());
return;
}
++_maxLocalRef;
RString objname = getObjectName(obj);
_ptr2id->put(obj, new Integer(_maxLocalRef));
_out->write("<object name=\"");
_out->write(objname->c_str());
RString msg = RString("\" lref=\"") + _maxLocalRef + "\">";
_out->write(msg->c_str());
if (objname->compareTo("acdk/lang/String") == 0) {
_out->write(xmlencode((RString)obj)->c_str());
_out->write("</object>");
return;
} else {
::acdk::lang::dmi::SysFields members = obj->getInternalFields();
bool hasChild = members.size() > 0;
++_indent;
for (int i = 0; i < members.size(); i++) {
::acdk::lang::dmi::SysField& f = members[i];
if (Modifier::isStatic(f.fieldInfo->flags) == true)
continue;
if (_withFieldInfo == true) {
RString msg = RString("<field name=\"") + f.fieldInfo->label + "\">";
_dumpindend();
_out->write(msg->c_str());
++_indent;
}
//_dumpindend(); _out->print("<")->print(f.fieldInfo->label)->print(">\n");
switch (f.type) {
case SysField::FT_Bool: _dumpindend(); writeBoolean(*f.cont.bval); break;
case SysField::FT_Char : _dumpindend(); writeChar(*f.cont.cval); break;
case SysField::FT_Byte : _dumpindend(); writeChar(*f.cont.cval); break;
case SysField::FT_Short : _dumpindend(); writeShort(*f.cont.sval); break;
case SysField::FT_Int : _dumpindend(); writeInt((int)*f.cont.ival); break;
//not valid any more case SysField::FT_Long : _dumpindend(); _out->print(RString("<long value=\"") + (*f.cont.lval) + "\"/>\n"); break;
case SysField::FT_JLong : _dumpindend(); writeLong(*f.cont.jlval); break;
case SysField::FT_Float : _dumpindend(); writeFloat(*f.cont.fval); break;
case SysField::FT_Double : _dumpindend(); writeDouble(*f.cont.dval); break;
case SysField::FT_Object : {
acdk::lang::Object copj = f.cont.oval->impl();
++_indent;
writeObject(copj);
//dumpAnObject(copj, _indent);
--_indent;
break;
}
//default: _dumpindend(); _out->print(RString("<unknown value=\"") + *f.cont.jlval + "\"/>\n"); break;
}
if (_withFieldInfo == true) {
--_indent;
_dumpindend();
_out->write("</field>");
}
}
}
--_indent;
//_out->write("<acdkobject name=\"" + theClass->getName());
_dumpindend();
_out->write("</object>");
}
*/
inline
void
_writeString(IN(RWriter) out, IN(RString) str)
{
URLEncoder().encode(out, str);
}
inline
void _writeString(IN(RWriter) out, const char* cptr)
{
out->write((const byte*)cptr, 0, strlen(cptr));
//THROW1(Exception, "Not implemented yet");
}
inline
void
_writeString(IN(RWriter) out, const char* cptr, int len)
{
out->write((const byte*)cptr, 0, len);
}
//virtual
void
XMLObjectWriter::writeBoolean(bool b)
{
_writeString(_out, Boolean(b).toString());
}
//virtual
void
XMLObjectWriter::writeChar(char b)
{
_writeString(_out, URLEncoder().encode(Character::toString(b)));
}
//virtual
void
XMLObjectWriter::writeUcChar(uc2char b)
{
_writeString(_out, URLEncoder().encode(Character::toString(b)));
}
//virtual
void
XMLObjectWriter::writeShort(short b)
{
_writeString(_out, Short::toString(b));
}
//virtual
void
XMLObjectWriter::writeInt(int b)
{
_writeString(_out, Integer::toString(b));
}
//virtual
void
XMLObjectWriter::writeLong(jlong b)
{
_writeString(_out, Long::toString(b));
}
//virtual
void
XMLObjectWriter::writeFloat(float b)
{
_writeString(_out, Float::toString(b));
}
//virtual
void
XMLObjectWriter::writeDouble(double b)
{
_writeString(_out, Double::toString(b));
}
//virtual
void
XMLObjectWriter::writeStringImpl(IN(RString) str)
{
_writeString(_out, URLEncoder().encode(str));
}
//virtual
void
XMLObjectWriter::writeOpaque(IN(RbyteArray) array)
{
RbyteArray wr = ::acdk::text::Base64::encode(array);
writeInt(wr->length());
_out->write(wr);
}
//virtual
void
XMLObjectWriter::write(IN(RbyteArray) array, int offset, int len)
{
_out->write(array, offset, len);
}
//virtual
void
XMLObjectWriter::writeTagStart(IN(RString) key, IN(RString) value/* = Nil*/)
{
_writeString(_out, "<", 1);
_writeString(_out, key);
_writeString(_out, ">", 1);
}
//virtual
void
XMLObjectWriter::writeTagEnd(IN(RString) key, IN(RString) value/* = Nil*/)
{
_writeString(_out, "</", 2);
_writeString(_out, key);
_writeString(_out, ">" , 1);
}
//virtual
void
XMLObjectWriter::writeClassId(IN(::acdk::lang::RClass) cls)
{
if (cls == Nil)
{
_writeString(_out, "<class value=\"Nil\"/>");
return;
}
StringBuffer sb;
sb << "<class value=\"" << cls->getName() << "\"";
if (withSerialVersionUID() == true)
sb << " SVUID=\"" << cls->objectClazzInfo()->getSerialVersionUID() << "\"";
sb << "/>";
_out->write((const byte*)sb.toString()->c_str(), 0, sb.toString()->length());
}
/*
using ::acdk::lang::dmi::ScriptVar;
//virtual
void
XMLObjectWriter::write(::acdk::lang::dmi::ScriptVar& arg)
{
switch (arg.type) {
case ScriptVar::BoolType : writeBoolean(arg.getBoolVar()); break;
case ScriptVar::CharType : writeChar(arg.getCharVar()); break;
case ScriptVar::ByteType : writeChar(arg.getByteVar()); break;
case ScriptVar::ShortType : writeShort(arg.getShortVar()); break;
case ScriptVar::IntType : writeInt(arg.getIntVar()); break;
case ScriptVar::LongType : writeLong(arg.getLongVar()); break;
case ScriptVar::FloatType : writeFloat(arg.getFloatVar()); break;
case ScriptVar::DoubleType : writeFloat(arg.getDoubleVar()); break;
case ScriptVar::ObjectType : writeObject(arg.getObjectVar()); break;
case ScriptVar::CharPtr : writeString((RString)arg.getObjectVar()); break;
case ScriptVar::UnknownType:
default :
break;
}
}
*/
} // xml
} // acdk
|