Change copyrights from Nokia to Digia
[profile/ivi/qtxmlpatterns.git] / src / xmlpatterns / data / qhexbinary.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtGlobal>
43
44 #include "qbase64binary_p.h"
45 #include "qbuiltintypes_p.h"
46 #include "qpatternistlocale_p.h"
47 #include "qvalidationerror_p.h"
48
49 #include "qhexbinary_p.h"
50
51 QT_BEGIN_NAMESPACE
52
53 using namespace QPatternist;
54
55 HexBinary::HexBinary(const QByteArray &val) : Base64Binary(val)
56 {
57 }
58
59 qint8 HexBinary::fromHex(const QChar &c)
60 {
61     if(c.unicode() > 'f')
62         return -1;
63
64     const char *const range = "0123456789ABCDEFabcdef";
65
66     const char *const in = strchr(range, c.unicode());
67
68     if(!in)
69         return -1;
70
71     /* Pointer arithmetic. */
72     int digit = in - range;
73
74     if(digit > 15)
75         digit -= 6;
76
77     return digit;
78 }
79
80 AtomicValue::Ptr HexBinary::fromLexical(const NamePool::Ptr &np, const QString &str)
81 {
82     const QString lexical(str.trimmed());
83     const int len = lexical.length();
84
85     if(len == 0)
86         return AtomicValue::Ptr(new HexBinary(QByteArray()));
87
88     if((len & 1) != 0)
89     {
90         /* Catch a common case. */
91         return ValidationError::createError(QtXmlPatterns::tr(
92                   "A value of type %1 must contain an even number of "
93                   "digits. The value %2 does not.")
94                   .arg(formatType(np, BuiltinTypes::xsHexBinary),
95                        formatData(QString::number(len))));
96     }
97
98     QByteArray val;
99     val.resize(len / 2);
100
101     for(int i = 0; i < len / 2; ++i)
102     {
103         qint8 p1 = fromHex(lexical[i * 2]);
104         qint8 p2 = fromHex(lexical[i * 2 + 1]);
105
106         if(p1 == -1 || p2 == -1)
107         {
108             const QString hex(QString::fromLatin1("%1%2").arg(lexical[i * 2], lexical[i * 2 + 1]));
109
110             return ValidationError::createError(QtXmlPatterns::tr(
111                              "%1 is not valid as a value of type %2.")
112                              .arg(formatData(hex),
113                                   formatType(np, BuiltinTypes::xsHexBinary)));
114         }
115
116         val[i] = static_cast<char>(p1 * 16 + p2);
117     }
118     Q_ASSERT(!val.isEmpty());
119
120     return AtomicValue::Ptr(new HexBinary(val));
121 }
122
123 HexBinary::Ptr HexBinary::fromValue(const QByteArray &data)
124 {
125     return HexBinary::Ptr(new HexBinary(data));
126 }
127
128 QString HexBinary::stringValue() const
129 {
130     static const char s_toHex[] = "0123456789ABCDEF";
131     const int len = m_value.count();
132     QString result;
133     result.reserve(len * 2);
134
135     for(int i = 0; i < len; ++i)
136     {
137         // This cast is significant.
138         const unsigned char val = static_cast<unsigned char>(m_value.at(i));
139         result += QLatin1Char(s_toHex[val >> 4]);
140         result += QLatin1Char(s_toHex[val & 0x0F]);
141     }
142
143     return result;
144 }
145
146 ItemType::Ptr HexBinary::type() const
147 {
148     return BuiltinTypes::xsHexBinary;
149 }
150
151 QT_END_NAMESPACE