1 /****************************************************************************
2 ** libebml : parse EBML files, see http://embl.sourceforge.net/
3 **
4 ** <file/class description>
5 **
6 ** Copyright (C) 2002-2010 Steve Lhomme. All rights reserved.
7 **
8 ** This file is part of libebml.
9 **
10 ** This library is free software; you can redistribute it and/or
11 ** modify it under the terms of the GNU Lesser General Public
12 ** License as published by the Free Software Foundation; either
13 ** version 2.1 of the License, or (at your option) any later version.
14 **
15 ** This library is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ** Lesser General Public License for more details.
19 **
20 ** You should have received a copy of the GNU Lesser General Public
21 ** License along with this library; if not, write to the Free Software
22 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 **
24 ** See http://www.gnu.org/licenses/lgpl-2.1.html for LGPL licensing information.
25 **
26 ** Contact license@matroska.org if any conditions of this licensing are
27 ** not clear to you.
28 **
29 **********************************************************************/
30
31 /*!
32 \file
33 \version \$Id$
34 \author Steve Lhomme <robux4 @ users.sf.net>
35 */
36
37 #include <cassert>
38
39 #include "ebml/EbmlFloat.h"
40
41 START_LIBEBML_NAMESPACE
42
EbmlFloat(const EbmlFloat::Precision prec)43 EbmlFloat::EbmlFloat(const EbmlFloat::Precision prec)
44 :EbmlElement(0, false)
45 {
46 SetPrecision(prec);
47 }
48
EbmlFloat(const double aDefaultValue,const EbmlFloat::Precision prec)49 EbmlFloat::EbmlFloat(const double aDefaultValue, const EbmlFloat::Precision prec)
50 :EbmlElement(0, true), Value(aDefaultValue), DefaultValue(aDefaultValue)
51 {
52 SetDefaultIsSet();
53 SetPrecision(prec);
54 }
55
SetDefaultValue(double aValue)56 void EbmlFloat::SetDefaultValue(double aValue)
57 {
58 assert(!DefaultISset());
59 DefaultValue = aValue;
60 SetDefaultIsSet();
61 }
62
DefaultVal() const63 double EbmlFloat::DefaultVal() const
64 {
65 assert(DefaultISset());
66 return DefaultValue;
67 }
68
operator float() const69 EbmlFloat::operator float() const {return float(Value);}
operator double() const70 EbmlFloat::operator double() const {return double(Value);}
71
GetValue() const72 double EbmlFloat::GetValue() const {return Value;}
73
SetValue(double NewValue)74 EbmlFloat & EbmlFloat::SetValue(double NewValue) {
75 return *this = NewValue;
76 }
77
78 /*!
79 \todo handle exception on errors
80 \todo handle 10 bits precision
81 */
RenderData(IOCallback & output,bool,bool)82 filepos_t EbmlFloat::RenderData(IOCallback & output, bool /* bForceRender */, bool /* bWithDefault */)
83 {
84 assert(GetSize() == 4 || GetSize() == 8);
85
86 if (GetSize() == 4) {
87 float val = Value;
88 int Tmp;
89 memcpy(&Tmp, &val, 4);
90 big_int32 TmpToWrite(Tmp);
91 output.writeFully(&TmpToWrite.endian(), GetSize());
92 } else if (GetSize() == 8) {
93 double val = Value;
94 int64 Tmp;
95 memcpy(&Tmp, &val, 8);
96 big_int64 TmpToWrite(Tmp);
97 output.writeFully(&TmpToWrite.endian(), GetSize());
98 }
99
100 return GetSize();
101 }
102
UpdateSize(bool bWithDefault,bool)103 uint64 EbmlFloat::UpdateSize(bool bWithDefault, bool /* bForceRender */)
104 {
105 if (!bWithDefault && IsDefaultValue())
106 return 0;
107 return GetSize();
108 }
109
110 /*!
111 \todo remove the hack for possible endianess pb (test on little & big endian)
112 */
ReadData(IOCallback & input,ScopeMode ReadFully)113 filepos_t EbmlFloat::ReadData(IOCallback & input, ScopeMode ReadFully)
114 {
115 if (ReadFully == SCOPE_NO_DATA)
116 return GetSize();
117
118 assert(GetSize() == 4 || GetSize() == 8);
119 if (GetSize() != 4 && GetSize() != 8) {
120 // impossible to read, skip it
121 input.setFilePointer(GetSize(), seek_current);
122 return GetSize();
123 }
124
125 binary Buffer[8];
126 input.readFully(Buffer, GetSize());
127
128 if (GetSize() == 4) {
129 big_int32 TmpRead;
130 TmpRead.Eval(Buffer);
131 auto tmpp = int32(TmpRead);
132 float val;
133 memcpy(&val, &tmpp, 4);
134 Value = static_cast<double>(val);
135 SetValueIsSet();
136 } else {
137 big_int64 TmpRead;
138 TmpRead.Eval(Buffer);
139 auto tmpp = int64(TmpRead);
140 double val;
141 memcpy(&val, &tmpp, 8);
142 Value = val;
143 SetValueIsSet();
144 }
145
146 return GetSize();
147 }
148
IsSmallerThan(const EbmlElement * Cmp) const149 bool EbmlFloat::IsSmallerThan(const EbmlElement *Cmp) const
150 {
151 if (EbmlId(*this) == EbmlId(*Cmp))
152 return this->Value < static_cast<const EbmlFloat *>(Cmp)->Value;
153
154 return false;
155 }
156
157 END_LIBEBML_NAMESPACE
158