[Libreoffice-commits] core.git: Branch 'feature/unitver' - 8 commits - sc/inc sc/qa sc/source
Andrzej Hunt
andrzej at ahunt.org
Fri Feb 6 10:49:21 PST 2015
sc/inc/units.hxx | 12 +++++
sc/qa/unit/units.cxx | 86 ++++++++++++++++++++++++++++++++++---
sc/source/core/units/unitsimpl.cxx | 74 +++++++++++++++++++------------
sc/source/core/units/unitsimpl.hxx | 1
sc/source/core/units/utunit.cxx | 17 +++++++
sc/source/core/units/utunit.hxx | 46 +++++++++++++++----
6 files changed, 193 insertions(+), 43 deletions(-)
New commits:
commit 683eb1b54412c2ceaafd46c607606a5b6b3e27af
Author: Andrzej Hunt <andrzej at ahunt.org>
Date: Fri Feb 6 18:46:30 2015 +0000
Implement splitUnitsFromInputString.
Change-Id: I1f781948e57c37dc3adbfcd14cb3d6ba488c10a0
diff --git a/sc/inc/units.hxx b/sc/inc/units.hxx
index cfeae9e..9561b40 100644
--- a/sc/inc/units.hxx
+++ b/sc/inc/units.hxx
@@ -10,6 +10,8 @@
#ifndef INCLUDED_SC_INC_UNITS_HXX
#define INCLUDED_SC_INC_UNITS_HXX
+#include <rtl/ustring.hxx>
+
#include <boost/shared_ptr.hpp>
class ScAddress;
@@ -27,6 +29,16 @@ public:
virtual bool verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAddress, ScDocument* pDoc) = 0;
+ /*
+ * Split the input into value and unit, where rInput == rValue + rUnit.
+ * (We assume that the unit is always the last part of the input string.)
+ *
+ * Returns whether or not the string has been split.
+ * rValue and rUnit are always set to valid values, irrespective of string
+ * splitting having actually taken place.
+ */
+ virtual bool splitUnitsFromInputString(const OUString& rInput, OUString& rValue, OUString& rUnit) = 0;
+
virtual ~Units() {}
};
diff --git a/sc/qa/unit/units.cxx b/sc/qa/unit/units.cxx
index 3515254..f6a0aa0 100644
--- a/sc/qa/unit/units.cxx
+++ b/sc/qa/unit/units.cxx
@@ -38,15 +38,22 @@ public:
::boost::shared_ptr< UnitsImpl > mpUnitsImpl;
+
void testUTUnit();
void testUnitVerification();
void testUnitFromFormatStringExtraction();
+ void testUnitValueStringSplitting();
+
CPPUNIT_TEST_SUITE(UnitsTest);
+
CPPUNIT_TEST(testUTUnit);
CPPUNIT_TEST(testUnitVerification);
+
CPPUNIT_TEST(testUnitFromFormatStringExtraction);
+ CPPUNIT_TEST(testUnitValueStringSplitting);
+
CPPUNIT_TEST_SUITE_END();
private:
@@ -209,6 +216,45 @@ void UnitsTest::testUnitFromFormatStringExtraction() {
CPPUNIT_ASSERT(mpUnitsImpl->extractUnitStringFromFormat("#\"cm\"") == "cm");
}
+void UnitsTest::testUnitValueStringSplitting() {
+ OUString sValue, sUnit;
+
+ OUString sEmptyString = "";
+ CPPUNIT_ASSERT(!mpUnitsImpl->splitUnitsFromInputString(sEmptyString, sValue, sUnit));
+ CPPUNIT_ASSERT(sValue.isEmpty());
+ CPPUNIT_ASSERT(sUnit.isEmpty());
+
+ OUString sNumberOnlyString = "10";
+ CPPUNIT_ASSERT(!mpUnitsImpl->splitUnitsFromInputString(sNumberOnlyString, sValue, sUnit));
+ CPPUNIT_ASSERT(sValue == "10");
+ CPPUNIT_ASSERT(sUnit.isEmpty());
+
+ OUString sTextOnlyString = "hello world";
+ CPPUNIT_ASSERT(!mpUnitsImpl->splitUnitsFromInputString(sTextOnlyString, sValue, sUnit));
+ CPPUNIT_ASSERT(sValue == "hello world");
+ CPPUNIT_ASSERT(sUnit.isEmpty());
+
+ OUString sDeceptiveInput = "30garbage";
+ CPPUNIT_ASSERT(!mpUnitsImpl->splitUnitsFromInputString(sDeceptiveInput, sValue, sUnit));
+ CPPUNIT_ASSERT(sValue == "30garbage");
+ CPPUNIT_ASSERT(sUnit.isEmpty());
+
+ OUString sUnitOnly = "cm";
+ CPPUNIT_ASSERT(!mpUnitsImpl->splitUnitsFromInputString(sUnitOnly, sValue, sUnit));
+ CPPUNIT_ASSERT(sValue == "cm");
+ CPPUNIT_ASSERT(sUnit.isEmpty());
+
+ OUString sSimpleUnitedValue = "20m/s";
+ CPPUNIT_ASSERT(mpUnitsImpl->splitUnitsFromInputString(sSimpleUnitedValue, sValue, sUnit));
+ CPPUNIT_ASSERT(sValue == "20");
+ CPPUNIT_ASSERT(sUnit == "m/s");
+
+ OUString sMultipleTokens = "40E-4kg";
+ CPPUNIT_ASSERT(mpUnitsImpl->splitUnitsFromInputString(sMultipleTokens, sValue, sUnit));
+ CPPUNIT_ASSERT(sValue == "40E-4");
+ CPPUNIT_ASSERT(sUnit == "kg");
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(UnitsTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/core/units/unitsimpl.cxx b/sc/source/core/units/unitsimpl.cxx
index 2ca85e1..34eccde 100644
--- a/sc/source/core/units/unitsimpl.cxx
+++ b/sc/source/core/units/unitsimpl.cxx
@@ -285,5 +285,40 @@ bool UnitsImpl::verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAdd
return true;
}
+bool IsDigit(sal_Unicode c) {
+ return (c>= '0' && c <= '9');
+}
+
+bool UnitsImpl::splitUnitsFromInputString(const OUString& rInput, OUString& rValueOut, OUString& rUnitOut) {
+ int nPos = rInput.getLength();
+
+ while (nPos) {
+ if (IsDigit(rInput[nPos-1])) {
+ break;
+ }
+ nPos--;
+ }
+
+ rUnitOut = rInput.copy(nPos);
+
+ UtUnit aUnit;
+ // If the entire input is a string (nPos == 0) then treating it as a unit
+ // makes little sense as there is no numerical value associated with it.
+ // Hence it makes sense to skip testing in this case.
+ // We also need to specifically ignore the no unit case (nPos == rInput.getLength())
+ // as otherwise we are obtaining the unit for "" which is a valid unit
+ // (the dimensionless) unit, even though in reality we should obtain no unit
+ // and return false.
+ if ((nPos < rInput.getLength())
+ && (nPos > 0)
+ && UtUnit::createUnit(rUnitOut, aUnit, mpUnitSystem)) {
+ rValueOut = rInput.copy(0, nPos);
+ return true;
+ } else {
+ rValueOut = rInput;
+ rUnitOut.clear();
+ return false;
+ }
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/units/unitsimpl.hxx b/sc/source/core/units/unitsimpl.hxx
index 2561e1e..1009a95 100644
--- a/sc/source/core/units/unitsimpl.hxx
+++ b/sc/source/core/units/unitsimpl.hxx
@@ -61,6 +61,7 @@ public:
virtual ~UnitsImpl();
virtual bool verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAddress, ScDocument* pDoc) SAL_OVERRIDE;
+ virtual bool splitUnitsFromInputString(const OUString& rInput, OUString& rValue, OUString& rUnit) SAL_OVERRIDE;
private:
UtUnit getOutputUnitsForOpCode(std::stack< UtUnit >& rUnitStack, const OpCode& rOpCode);
commit e68cf2b5b1dbde20b8ae89de8d19e1c0dd752a83
Author: Andrzej Hunt <andrzej at ahunt.org>
Date: Thu Feb 5 20:21:37 2015 +0000
Move and rename string extraction test.
Change-Id: I39574e227b4d2f3ff0df8c36b1c96337d5fcbfb7
diff --git a/sc/qa/unit/units.cxx b/sc/qa/unit/units.cxx
index 062262e..3515254 100644
--- a/sc/qa/unit/units.cxx
+++ b/sc/qa/unit/units.cxx
@@ -39,13 +39,14 @@ public:
::boost::shared_ptr< UnitsImpl > mpUnitsImpl;
void testUTUnit();
- void testStringExtraction();
void testUnitVerification();
+ void testUnitFromFormatStringExtraction();
+
CPPUNIT_TEST_SUITE(UnitsTest);
CPPUNIT_TEST(testUTUnit);
- CPPUNIT_TEST(testStringExtraction);
CPPUNIT_TEST(testUnitVerification);
+ CPPUNIT_TEST(testUnitFromFormatStringExtraction);
CPPUNIT_TEST_SUITE_END();
private:
@@ -98,11 +99,6 @@ void UnitsTest::testUTUnit() {
CPPUNIT_ASSERT(aM/aS == aM_S);
}
-void UnitsTest::testStringExtraction() {
- CPPUNIT_ASSERT(mpUnitsImpl->extractUnitStringFromFormat("\"weight: \"0.0\"kg\"") == "kg");
- CPPUNIT_ASSERT(mpUnitsImpl->extractUnitStringFromFormat("#\"cm\"") == "cm");
-}
-
void UnitsTest::testUnitVerification() {
// Make sure we have at least one tab to work with
mpDoc->EnsureTable(0);
@@ -208,6 +204,11 @@ void UnitsTest::testUnitVerification() {
CPPUNIT_ASSERT(!mpUnitsImpl->verifyFormula(pTokens, address, mpDoc));
}
+void UnitsTest::testUnitFromFormatStringExtraction() {
+ CPPUNIT_ASSERT(mpUnitsImpl->extractUnitStringFromFormat("\"weight: \"0.0\"kg\"") == "kg");
+ CPPUNIT_ASSERT(mpUnitsImpl->extractUnitStringFromFormat("#\"cm\"") == "cm");
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(UnitsTest);
CPPUNIT_PLUGIN_IMPLEMENT();
commit ea4fc7a418039abc73831cb7fa7f83da4d62c79f
Author: Andrzej Hunt <andrzej at ahunt.org>
Date: Thu Feb 5 18:17:09 2015 +0000
Add stream-printing operator<< for UtUnit.
Change-Id: I1c36415d673841683fe9007f17bee110a494baa7
diff --git a/sc/source/core/units/unitsimpl.cxx b/sc/source/core/units/unitsimpl.cxx
index 0adbd28..2ca85e1 100644
--- a/sc/source/core/units/unitsimpl.cxx
+++ b/sc/source/core/units/unitsimpl.cxx
@@ -139,7 +139,7 @@ UtUnit UnitsImpl::getOutputUnitsForOpCode(stack< UtUnit >& rUnitStack, const OpC
if (pFirstUnit == pSecondUnit) {
// The two units are identical, hence we can return either.
pOut = pFirstUnit;
- SAL_INFO("sc.units", "verified equality for unit " << pFirstUnit.getString());
+ SAL_INFO("sc.units", "verified equality for unit " << pFirstUnit);
} else {
// TODO: notify/link UI.
}
diff --git a/sc/source/core/units/utunit.hxx b/sc/source/core/units/utunit.hxx
index b79c057..97b6305 100644
--- a/sc/source/core/units/utunit.hxx
+++ b/sc/source/core/units/utunit.hxx
@@ -93,6 +93,13 @@ public:
}
};
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, const UtUnit& rUnit )
+{
+ return stream << "[" << rUnit.getString() << "]";
+}
+
}} // namespace sc::units
#endif // INCLUDED_SC_SOURCE_CORE_UNITS_UTUNIT_HXX
commit c47230f8927ecd4c431dad3909a86cfebff88ea2
Author: Andrzej Hunt <andrzej at ahunt.org>
Date: Thu Feb 5 17:56:13 2015 +0000
Add some tests for our UtUnit arithmetic operators.
Change-Id: I5a29bdf306ec1980b44f54b161d0ba7df0f1a83e
diff --git a/sc/qa/unit/units.cxx b/sc/qa/unit/units.cxx
index c5013c1..062262e 100644
--- a/sc/qa/unit/units.cxx
+++ b/sc/qa/unit/units.cxx
@@ -85,6 +85,17 @@ void UnitsTest::testUTUnit() {
// Test that we can't create garbage units
UtUnit aGarbage;
CPPUNIT_ASSERT(!UtUnit::createUnit("garbage", aGarbage, mpUnitsImpl->mpUnitSystem));
+
+ // Do some addition, subtraction, comparison tests.
+ UtUnit aM;
+ UtUnit::createUnit("m", aM, mpUnitsImpl->mpUnitSystem);
+ UtUnit aS;
+ UtUnit::createUnit("s", aS, mpUnitsImpl->mpUnitSystem);
+ UtUnit aM_S;
+ UtUnit::createUnit("m/s", aM_S, mpUnitsImpl->mpUnitSystem);
+
+ CPPUNIT_ASSERT(aM_S*aS == aM);
+ CPPUNIT_ASSERT(aM/aS == aM_S);
}
void UnitsTest::testStringExtraction() {
commit 3931221f867ef781fc162a2ad9130fee5c66b44f
Author: Andrzej Hunt <andrzej at ahunt.org>
Date: Thu Feb 5 17:51:07 2015 +0000
Hide raw ut_unit access in UTUnit.
UtUnit exists to hide all raw fiddling with ut_unit pointers
and the various ut_* methods.
We also get rid of the implicit bool conversion and instead have
and explicit method to check whether or not we hold a valid unit
to make things more obvious.
Change-Id: I654c47ba6daf8dfc4c2cc648150b6a86b90195bc
diff --git a/sc/source/core/units/unitsimpl.cxx b/sc/source/core/units/unitsimpl.cxx
index c2d4721..0adbd28 100644
--- a/sc/source/core/units/unitsimpl.cxx
+++ b/sc/source/core/units/unitsimpl.cxx
@@ -89,7 +89,7 @@ UtUnit UnitsImpl::getOutputUnitsForOpCode(stack< UtUnit >& rUnitStack, const OpC
if (!(rUnitStack.size() >= 1)) {
SAL_WARN("sc.units", "no units on stack for unary operation");
- return 0;
+ return UtUnit();
}
UtUnit pUnit = rUnitStack.top();
@@ -97,8 +97,8 @@ UtUnit UnitsImpl::getOutputUnitsForOpCode(stack< UtUnit >& rUnitStack, const OpC
switch (rOpCode) {
case ocNot:
- if (!ut_is_dimensionless(pUnit.get())) {
- return 0;
+ if (!pUnit.isDimensionless()) {
+ return UtUnit();
}
// We just keep the same unit (in this case no unit) so can
// fall through.
@@ -123,7 +123,7 @@ UtUnit UnitsImpl::getOutputUnitsForOpCode(stack< UtUnit >& rUnitStack, const OpC
SAL_WARN("sc.units", "less than two units on stack when attempting binary operation");
// TODO: what should we be telling the user in this case? Can this even happen (i.e.
// should we just be asserting here?)
- return 0;
+ return UtUnit();
}
UtUnit pSecondUnit = rUnitStack.top();
@@ -215,31 +215,14 @@ UtUnit UnitsImpl::getUnitForRef(FormulaToken* pToken, const ScAddress& rFormulaA
// by adding the current address to the relative formula address).
ScAddress aInputAddress = pRef->toAbs( rFormulaAddress );
- // udunits requires strings to be trimmed before parsing -- it's easiest to do this
- // using the OUString utils (as opposed to using ut_trim once we have a c string.
- OUString sUnitString = extractUnitStringForCell(aInputAddress, pDoc).trim();
+ OUString sUnitString = extractUnitStringForCell(aInputAddress, pDoc);
- // empty string == dimensionless unit. ut_parse returns an error for an empty string
- // hence we need to manually detect that case and return the dimensionless unit.
- if (sUnitString.getLength() == 0) {
- SAL_INFO("sc.units", "empty unit string: returning dimensionless unit");
- return UtUnit(ut_get_dimensionless_unit_one(mpUnitSystem.get()));
- }
-
- SAL_INFO("sc.units", "got unit string [" << sUnitString << "]");
- OString sUnitStringUTF8 = OUStringToOString(sUnitString, RTL_TEXTENCODING_UTF8);
-
- // TODO: we should probably have a cache of unit strings here to save reparsing
- // on every run?
-
- UtUnit pUnit(ut_parse(mpUnitSystem.get(), sUnitStringUTF8.getStr(), UT_UTF8));
-
- if (!pUnit) {
+ UtUnit aUnit;
+ if (!UtUnit::createUnit(sUnitString, aUnit, mpUnitSystem)) {
SAL_INFO("sc.units", "no unit obtained for token at cell " << aInputAddress.GetColRowString());
- SAL_INFO("sc.units", "error encountered: " << getUTStatus());
}
- return pUnit;
+ return aUnit;
}
// getUnitForRef: check format -> if not in format, use more complicated method? (Format overrides header definition)
@@ -258,7 +241,7 @@ bool UnitsImpl::verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAdd
{
UtUnit pUnit(getUnitForRef(pToken, rFormulaAddress, pDoc));
- if (!pUnit) {
+ if (!pUnit.isValid()) {
SAL_INFO("sc.units", "no unit returned for scSingleRef, ut_status: " << getUTStatus());
// This only happens in case of parsing (or system) errors.
@@ -278,7 +261,7 @@ bool UnitsImpl::verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAdd
// A null unit indicates either invalid units and/or other erronous input
// i.e. is an indication that getOutputUnitsForOpCode failed.
- if (pOut) {
+ if (pOut.isValid()) {
aUnitStack.push(pOut);
} else {
return false;
diff --git a/sc/source/core/units/utunit.cxx b/sc/source/core/units/utunit.cxx
index 1cd64b7..f539502 100644
--- a/sc/source/core/units/utunit.cxx
+++ b/sc/source/core/units/utunit.cxx
@@ -20,7 +20,7 @@ bool UtUnit::createUnit(const OUString& rUnitString, UtUnit& rUnitOut, const boo
UtUnit pParsedUnit(ut_parse(pUTSystem.get(), sUnitStringUTF8.getStr(), UT_UTF8));
- if (pParsedUnit) {
+ if (pParsedUnit.isValid()) {
rUnitOut = pParsedUnit;
return true;
} else {
diff --git a/sc/source/core/units/utunit.hxx b/sc/source/core/units/utunit.hxx
index c1df459..b79c057 100644
--- a/sc/source/core/units/utunit.hxx
+++ b/sc/source/core/units/utunit.hxx
@@ -42,29 +42,40 @@ private:
ut_free(pUnit);
}
+ UtUnit(ut_unit* pUnit):
+ mpUnit(pUnit, &freeUt)
+ {}
+
+ void reset(ut_unit* pUnit) {
+ mpUnit.reset(pUnit, &freeUt);
+ }
+
+ ut_unit* get() const {
+ return mpUnit.get();
+ }
+
public:
static bool createUnit(const OUString& rUnitString, UtUnit& rUnitOut, const boost::shared_ptr< ut_system >& pUTSystem);
- UtUnit(ut_unit* pUnit = 0):
- mpUnit(pUnit, &freeUt)
- {}
+ /*
+ * Default constructor returns an empty/invalid unit.
+ * (Note: this is different from the dimensionless unit which is valid.)
+ */
+ UtUnit() {};
UtUnit(const UtUnit& rUnit):
mpUnit(rUnit.mpUnit)
{}
- void reset(ut_unit* pUnit) {
- mpUnit.reset(pUnit, &freeUt);
- }
-
OUString getString() const;
- ut_unit* get() const {
- return mpUnit.get();
+ bool isValid() {
+ // We use a null pointer/empty unit to indicate an invalid unit.
+ return mpUnit.get() != 0;
}
- explicit operator bool() const {
- return mpUnit.operator bool();
+ bool isDimensionless() const {
+ return ut_is_dimensionless(this->get());
}
bool operator==(const UtUnit& rUnit) {
commit 70917fb99fdcf5bf9d7f93dd74443b5e151beecf
Author: Andrzej Hunt <andrzej at ahunt.org>
Date: Thu Feb 5 17:45:01 2015 +0000
Trim unit string for ut_parse.
Change-Id: I83c32e5336b589174db92123c4959db4ac8624c8
diff --git a/sc/source/core/units/utunit.cxx b/sc/source/core/units/utunit.cxx
index 7061658..1cd64b7 100644
--- a/sc/source/core/units/utunit.cxx
+++ b/sc/source/core/units/utunit.cxx
@@ -14,7 +14,9 @@
using namespace sc::units;
bool UtUnit::createUnit(const OUString& rUnitString, UtUnit& rUnitOut, const boost::shared_ptr< ut_system >& pUTSystem) {
- OString sUnitStringUTF8 = OUStringToOString(rUnitString, RTL_TEXTENCODING_UTF8);
+ // ut_parse requires the string to be trimmed of whitespace, it's
+ // simplest just to do this during conversion:
+ OString sUnitStringUTF8 = OUStringToOString(rUnitString.trim(), RTL_TEXTENCODING_UTF8);
UtUnit pParsedUnit(ut_parse(pUTSystem.get(), sUnitStringUTF8.getStr(), UT_UTF8));
commit fb77de002cc5e52b9d38eca031cef0f3657f26a6
Author: Andrzej Hunt <andrzej at ahunt.org>
Date: Thu Feb 5 17:24:27 2015 +0000
Add some basic tests for UtUnit creation.
Change-Id: Ic4d2e26b383fa07b53757dd755508d42dcf88593
diff --git a/sc/qa/unit/units.cxx b/sc/qa/unit/units.cxx
index e8ec0ab..c5013c1 100644
--- a/sc/qa/unit/units.cxx
+++ b/sc/qa/unit/units.cxx
@@ -8,6 +8,7 @@
*/
#include "unitsimpl.hxx"
+#include "utunit.hxx"
#include "formulacell.hxx"
@@ -37,10 +38,12 @@ public:
::boost::shared_ptr< UnitsImpl > mpUnitsImpl;
+ void testUTUnit();
void testStringExtraction();
void testUnitVerification();
CPPUNIT_TEST_SUITE(UnitsTest);
+ CPPUNIT_TEST(testUTUnit);
CPPUNIT_TEST(testStringExtraction);
CPPUNIT_TEST(testUnitVerification);
CPPUNIT_TEST_SUITE_END();
@@ -69,6 +72,21 @@ void UnitsTest::tearDown() {
BootstrapFixture::tearDown();
}
+void UnitsTest::testUTUnit() {
+ // Test that we can create units.
+ UtUnit aDimensionless;
+ CPPUNIT_ASSERT(UtUnit::createUnit("", aDimensionless, mpUnitsImpl->mpUnitSystem));
+ // And test that an empty string does in fact map to the dimensionless unit one.
+ // The documentation states that ut_is_dimensionless returns zero for dimensionless
+ // units, however the sources (and udunits2's unit tests) suggest that zero is returned
+ // for a unit WITH dimensions (as the method name would suggest).
+ CPPUNIT_ASSERT(ut_is_dimensionless(aDimensionless.mpUnit.get()) != 0);
+
+ // Test that we can't create garbage units
+ UtUnit aGarbage;
+ CPPUNIT_ASSERT(!UtUnit::createUnit("garbage", aGarbage, mpUnitsImpl->mpUnitSystem));
+}
+
void UnitsTest::testStringExtraction() {
CPPUNIT_ASSERT(mpUnitsImpl->extractUnitStringFromFormat("\"weight: \"0.0\"kg\"") == "kg");
CPPUNIT_ASSERT(mpUnitsImpl->extractUnitStringFromFormat("#\"cm\"") == "cm");
diff --git a/sc/source/core/units/utunit.hxx b/sc/source/core/units/utunit.hxx
index c075d00..c1df459 100644
--- a/sc/source/core/units/utunit.hxx
+++ b/sc/source/core/units/utunit.hxx
@@ -19,6 +19,10 @@
namespace sc {
namespace units {
+namespace test {
+ class UnitsTest;
+}
+
/*
* Convenience shared_ptr wrapper for ut_unit, which takes
* care of dealing with the necessary custom deleter.
@@ -29,6 +33,8 @@ namespace units {
* wrapper.
*/
class UtUnit {
+ friend class test::UnitsTest;
+
private:
::boost::shared_ptr< ut_unit > mpUnit;
commit db2c8607dd8111e81f0d673a66dcd07b41e0b467
Author: Andrzej Hunt <andrzej at ahunt.org>
Date: Thu Feb 5 17:23:50 2015 +0000
Add factory method for UtUnit creation when parsing.
Change-Id: I1e812fc9f2dfaeccb7a6c65f3739f3be6e206760
diff --git a/sc/source/core/units/utunit.cxx b/sc/source/core/units/utunit.cxx
index 74e28b6..7061658 100644
--- a/sc/source/core/units/utunit.cxx
+++ b/sc/source/core/units/utunit.cxx
@@ -13,6 +13,21 @@
using namespace sc::units;
+bool UtUnit::createUnit(const OUString& rUnitString, UtUnit& rUnitOut, const boost::shared_ptr< ut_system >& pUTSystem) {
+ OString sUnitStringUTF8 = OUStringToOString(rUnitString, RTL_TEXTENCODING_UTF8);
+
+ UtUnit pParsedUnit(ut_parse(pUTSystem.get(), sUnitStringUTF8.getStr(), UT_UTF8));
+
+ if (pParsedUnit) {
+ rUnitOut = pParsedUnit;
+ return true;
+ } else {
+ SAL_INFO("sc.units", "error encountered parsing unit \"" << rUnitString << "\": " << getUTStatus());
+ return false;
+ }
+}
+
+
OUString UtUnit::getString() const {
char aBuf[200];
int nChars = ut_format(mpUnit.get(), aBuf, 200, UT_UTF8);
diff --git a/sc/source/core/units/utunit.hxx b/sc/source/core/units/utunit.hxx
index a209cf9..c075d00 100644
--- a/sc/source/core/units/utunit.hxx
+++ b/sc/source/core/units/utunit.hxx
@@ -37,6 +37,8 @@ private:
}
public:
+ static bool createUnit(const OUString& rUnitString, UtUnit& rUnitOut, const boost::shared_ptr< ut_system >& pUTSystem);
+
UtUnit(ut_unit* pUnit = 0):
mpUnit(pUnit, &freeUt)
{}
More information about the Libreoffice-commits
mailing list