00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "Node.h"
00035
00036 #include "Debug.h"
00037
00038 #include <QDataStream>
00039 #include <QTextStream>
00040 #include <QUrl>
00041 #include <QByteArray>
00042
00043 namespace Dataquay
00044 {
00045
00046 static const QString encodedVariantTypeURI = "http://breakfastquay.com/dataquay/datatype/encodedvariant";
00047
00048 Node
00049 Node::fromVariant(QVariant v)
00050 {
00051 static const QString pfx = "http://www.w3.org/2001/XMLSchema#";
00052 Node n;
00053 n.type = Literal;
00054
00055 DEBUG << "Node::fromVariant: QVariant type is " << v.type() << " (" << int(v.type()) << "), variant is " << v << endl;
00056
00057 switch (v.type()) {
00058
00059 case QVariant::Url:
00060 n.type = URI;
00061 n.value = v.toUrl().toString();
00062 break;
00063
00064 case QVariant::Bool:
00065 n.datatype = pfx + "boolean";
00066 n.value = (v.toBool() ? "true" : "false");
00067 break;
00068
00069 case QVariant::Int:
00070 n.datatype = pfx + "int";
00071 n.value = v.toString();
00072 break;
00073
00074 case QVariant::String:
00075 n.datatype = pfx + "string";
00076 n.value = v.toString();
00077 break;
00078
00079 case QVariant::Double:
00080 n.datatype = pfx + "double";
00081 n.value = v.toString();
00082 break;
00083
00084 default:
00085 {
00086 QByteArray b;
00087 QDataStream ds(&b, QIODevice::WriteOnly);
00088 ds << v;
00089 n.datatype = encodedVariantTypeURI;
00090 n.value = QString::fromAscii(b.toPercentEncoding());
00091 }
00092 }
00093
00094 return n;
00095 }
00096
00097 QVariant
00098 Node::toVariant() const
00099 {
00100 if (type == URI) {
00101 return QVariant::fromValue(QUrl(value));
00102 } else if (type == Nothing || type == Blank) {
00103 return QVariant();
00104 }
00105
00106 static const QString pfx = "http://www.w3.org/2001/XMLSchema#";
00107 DEBUG << "Node::toVariant: datatype = " << datatype << endl;
00108 if (datatype.startsWith(pfx)) {
00109 if (datatype == pfx + "boolean") {
00110 return QVariant::fromValue<bool>((value == "true") ||
00111 (value == "1"));
00112 } else if (datatype == pfx + "int") {
00113 return QVariant::fromValue<int>(value.toInt());
00114 } else if (datatype == pfx + "string") {
00115 return QVariant::fromValue<QString>(value);
00116 } else if (datatype == pfx + "double") {
00117 return QVariant::fromValue<double>(value.toDouble());
00118 }
00119 }
00120 if (datatype == encodedVariantTypeURI) {
00121 QByteArray benc = value.toAscii();
00122 QByteArray b = QByteArray::fromPercentEncoding(benc);
00123 QDataStream ds(&b, QIODevice::ReadOnly);
00124 QVariant v;
00125 ds >> v;
00126 return v;
00127 }
00128 return QVariant::fromValue<QString>(value);
00129 }
00130
00131 bool
00132 operator==(const Node &a, const Node &b)
00133 {
00134 if (a.type == Node::Nothing &&
00135 b.type == Node::Nothing) return true;
00136 if (a.type == b.type &&
00137 a.value == b.value &&
00138 a.datatype == b.datatype) return true;
00139 return false;
00140 }
00141
00142 bool
00143 operator!=(const Node &a, const Node &b)
00144 {
00145 return !operator==(a, b);
00146 }
00147
00148 QDataStream &
00149 operator<<(QDataStream &out, const Node &n)
00150 {
00151 return out << (int)n.type << n.value << n.datatype;
00152 }
00153
00154 QDataStream &
00155 operator>>(QDataStream &in, Node &n)
00156 {
00157 int t;
00158 in >> t >> n.value >> n.datatype;
00159 n.type = (Node::Type)t;
00160 return in;
00161 }
00162
00163 std::ostream &
00164 operator<<(std::ostream &out, const Node &n)
00165 {
00166 switch (n.type) {
00167 case Node::Nothing:
00168 out << "[]";
00169 break;
00170 case Node::URI:
00172
00173 if (n.value.startsWith("http:") || n.value.startsWith("file:")) {
00174 out << "<" << n.value.toStdString() << ">";
00175 } else if (n.value == "") {
00176 out << "[empty-uri]";
00177 } else {
00178 out << n.value.toStdString();
00179 }
00180 break;
00181 case Node::Literal:
00182 out << "\"" << n.value.toStdString() << "\"";
00183 if (n.datatype != "") out << "^^" << n.datatype.toStdString();
00184 break;
00185 case Node::Blank:
00186 out << "[blank]";
00187 break;
00188 }
00189 return out;
00190 }
00191
00192 QTextStream &
00193 operator<<(QTextStream &out, const Node &n)
00194 {
00195 switch (n.type) {
00196 case Node::Nothing:
00197 out << "[]";
00198 break;
00199 case Node::URI:
00201
00202 if (n.value.startsWith("http:") || n.value.startsWith("file:")) {
00203 out << "<" << n.value << ">";
00204 } else if (n.value == "") {
00205 out << "[empty-uri]";
00206 } else {
00207 out << n.value;
00208 }
00209 break;
00210 case Node::Literal:
00211 out << "\"" << n.value << "\"";
00212 if (n.datatype != "") out << "^^" << n.datatype;
00213 break;
00214 case Node::Blank:
00215 out << "[blank]";
00216 break;
00217 }
00218 return out;
00219 }
00220
00221 }
00222
00223
00224