1 /* Webcamoid, webcam capture application.
2  * Copyright (C) 2018  Gonzalo Exequiel Pedone
3  *
4  * Webcamoid is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * Webcamoid is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Webcamoid. If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Web-Site: http://webcamoid.github.io/
18  */
19 
20 #include <cstdlib>
21 #include <cwchar>
22 #include <sstream>
23 #include <string>
24 
25 #include "fraction.h"
26 #include "utils.h"
27 
28 namespace AkVCam
29 {
30     class FractionPrivate
31     {
32         public:
33             int64_t m_num;
34             int64_t m_den;
35     };
36 }
37 
Fraction()38 AkVCam::Fraction::Fraction()
39 {
40     this->d = new FractionPrivate;
41     this->d->m_num = 0;
42     this->d->m_den = 0;
43 }
44 
Fraction(int64_t num,int64_t den)45 AkVCam::Fraction::Fraction(int64_t num, int64_t den)
46 {
47     this->d = new FractionPrivate;
48     this->d->m_num = num;
49     this->d->m_den = den;
50 }
51 
Fraction(const std::string & str)52 AkVCam::Fraction::Fraction(const std::string &str)
53 {
54     this->d = new FractionPrivate;
55     this->d->m_num = 0;
56     this->d->m_den = 1;
57     auto pos = str.find('/');
58 
59     if (pos == std::string::npos) {
60         auto strCpy = trimmed(str);
61         this->d->m_num = uint32_t(strtol(strCpy.c_str(), nullptr, 10));
62     } else {
63         auto numStr = trimmed(str.substr(0, pos));
64         auto denStr = trimmed(str.substr(pos + 1));
65 
66         this->d->m_num = uint32_t(strtol(numStr.c_str(), nullptr, 10));
67         this->d->m_den = uint32_t(strtol(denStr.c_str(), nullptr, 10));
68 
69         if (this->d->m_den < 1) {
70             this->d->m_num = 0;
71             this->d->m_den = 1;
72         }
73     }
74 }
75 
Fraction(const std::wstring & str)76 AkVCam::Fraction::Fraction(const std::wstring &str)
77 {
78     this->d = new FractionPrivate;
79     this->d->m_num = 0;
80     this->d->m_den = 1;
81     auto pos = str.find(L'/');
82 
83     if (pos == std::wstring::npos) {
84         auto strCpy = trimmed(str);
85 
86         this->d->m_num = uint32_t(wcstol(strCpy.c_str(), nullptr, 10));
87     } else {
88         auto numStr = trimmed(str.substr(0, pos));
89         auto denStr = trimmed(str.substr(pos + 1));
90 
91         this->d->m_num = uint32_t(wcstol(numStr.c_str(), nullptr, 10));
92         this->d->m_den = uint32_t(wcstol(denStr.c_str(), nullptr, 10));
93 
94         if (this->d->m_den < 1) {
95             this->d->m_num = 0;
96             this->d->m_den = 1;
97         }
98     }
99 }
100 
Fraction(const Fraction & other)101 AkVCam::Fraction::Fraction(const Fraction &other)
102 {
103     this->d = new FractionPrivate;
104     this->d->m_num = other.d->m_num;
105     this->d->m_den = other.d->m_den;
106 }
107 
~Fraction()108 AkVCam::Fraction::~Fraction()
109 {
110     delete this->d;
111 }
112 
operator =(const Fraction & other)113 AkVCam::Fraction &AkVCam::Fraction::operator =(const Fraction &other)
114 {
115     if (this != &other) {
116         this->d->m_num = other.d->m_num;
117         this->d->m_den = other.d->m_den;
118     }
119 
120     return *this;
121 }
122 
operator ==(const Fraction & other) const123 bool AkVCam::Fraction::operator ==(const Fraction &other) const
124 {
125     if (this->d->m_den == 0 && other.d->m_den != 0)
126         return false;
127 
128     if (this->d->m_den != 0 && other.d->m_den == 0)
129         return false;
130 
131     return this->d->m_num * other.d->m_den == this->d->m_den * other.d->m_num;
132 }
133 
operator <(const Fraction & other) const134 bool AkVCam::Fraction::operator <(const Fraction &other) const
135 {
136     return this->d->m_num * other.d->m_den < this->d->m_den * other.d->m_num;
137 }
138 
num() const139 int64_t AkVCam::Fraction::num() const
140 {
141     return this->d->m_num;
142 }
143 
num()144 int64_t &AkVCam::Fraction::num()
145 {
146     return this->d->m_num;
147 }
148 
den() const149 int64_t AkVCam::Fraction::den() const
150 {
151     return this->d->m_den;
152 }
153 
den()154 int64_t &AkVCam::Fraction::den()
155 {
156     return this->d->m_den;
157 }
158 
value() const159 double AkVCam::Fraction::value() const
160 {
161     return double(this->d->m_num) / this->d->m_den;
162 }
163 
toString() const164 std::string AkVCam::Fraction::toString() const
165 {
166     std::stringstream ss;
167     ss << this->d->m_num << '/' << this->d->m_den;
168 
169     return ss.str();
170 }
171 
toWString() const172 std::wstring AkVCam::Fraction::toWString() const
173 {
174     std::wstringstream ss;
175     ss << this->d->m_num << L'/' << this->d->m_den;
176 
177     return ss.str();
178 }
179