LibreOffice Module sc (master)  1
csvdataprovider.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #include <dataprovider.hxx>
11 #include <datatransformation.hxx>
12 #include <datamapper.hxx>
13 #include <stringutil.hxx>
14 
15 #include <tools/stream.hxx>
16 #include <vcl/svapp.hxx>
17 #include <docsh.hxx>
18 #include <orcus/csv_parser.hpp>
19 #include <utility>
20 
21 namespace {
22 
23 class CSVHandler
24 {
25  ScDocument* mpDoc;
26  SCCOL mnCol;
27  SCROW mnRow;
28 
29 public:
30  CSVHandler(ScDocument* pDoc) :
31  mpDoc(pDoc), mnCol(0), mnRow(0)
32  {
33  }
34 
35  static void begin_parse() {}
36  static void end_parse() {}
37  static void begin_row() {}
38  void end_row()
39  {
40  ++mnRow;
41  mnCol = 0;
42  }
43 
44  void cell(const char* p, size_t n, bool /*transient*/)
45  {
46  if (mnCol > mpDoc->MaxCol())
47  return;
48 
49  double mfValue = 0.0;
50  if (ScStringUtil::parseSimpleNumber(p, n, '.', ',', mfValue))
51  {
52  mpDoc->SetValue(mnCol, mnRow, 0, mfValue);
53  }
54  else
55  {
56  OString aStr(p, n);
57  mpDoc->SetString(mnCol, mnRow, 0, OStringToOUString(aStr, RTL_TEXTENCODING_UTF8));
58  }
59 
60  ++mnCol;
61  }
62 };
63 
64 }
65 
66 namespace sc {
68  ScDocument& rDoc, const OUString& mrURL, std::function<void()> aImportFinishedHdl,
69  const std::vector<std::shared_ptr<sc::DataTransformation>>& rDataTransformations)
70  : Thread("CSV Fetch Thread")
71  , mrDocument(rDoc)
72  , maURL(mrURL)
73  , mbTerminate(false)
74  , maDataTransformations(rDataTransformations)
75  , maImportFinishedHdl(std::move(aImportFinishedHdl))
76 {
77  maConfig.delimiters.push_back(',');
78  maConfig.text_qualifier = '"';
79 }
80 
82 {
83 }
84 
86 {
87  osl::MutexGuard aGuard(maMtxTerminate);
88  return mbTerminate;
89 }
90 
92 {
93  osl::MutexGuard aGuard(maMtxTerminate);
94  mbTerminate = true;
95 }
96 
98 {
100 }
101 
103 {
104  OStringBuffer aBuffer(64000);
106  if (mbTerminate)
107  return;
108 
109  CSVHandler aHdl(&mrDocument);
110  orcus::csv_parser<CSVHandler> parser(aBuffer.getStr(), aBuffer.getLength(), aHdl, maConfig);
111  parser.parse();
112 
113  for (const auto& itr : maDataTransformations)
114  {
115  itr->Transform(mrDocument);
116  }
117 
118  SolarMutexGuard aGuard;
120 }
121 
123  DataProvider(rDataSource),
124  mpDocument(pDoc)
125 {
126 }
127 
129 {
130  if (mxCSVFetchThread.is())
131  {
132  SolarMutexReleaser aReleaser;
133  mxCSVFetchThread->join();
134  }
135 }
136 
138 {
139  // already importing data
140  if (mpDoc)
141  return;
142 
143  mpDoc.reset(new ScDocument(SCDOCMODE_CLIP));
144  mpDoc->ResetClip(mpDocument, SCTAB(0));
146  mxCSVFetchThread->launch();
147 
148  if (mbDeterministic)
149  {
150  SolarMutexReleaser aReleaser;
151  mxCSVFetchThread->join();
152  }
153 }
154 
156 {
158  mpDoc.reset();
159  Refresh();
160 }
161 
163 {
164  ScDocShell* pDocShell = static_cast<ScDocShell*>(mpDocument->GetDocumentShell());
165  if (pDocShell)
166  pDocShell->SetDocumentModified();
167 }
168 
169 const OUString& CSVDataProvider::GetURL() const
170 {
171  return mrDataSource.getURL();
172 }
173 
174 }
175 
176 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScDocument & mrDocument
static bool parseSimpleNumber(const OUString &rStr, sal_Unicode dsep, sal_Unicode gsep, sal_Unicode dsepa, double &rVal)
Check if a given string is a simple decimal number (e.g.
Definition: stringutil.cxx:52
tuple parser
sc::ExternalDataSource & mrDataSource
std::function< void()> maImportFinishedHdl
CSVFetchThread(ScDocument &rDoc, const OUString &, std::function< void()> aImportFinishedHdl, const std::vector< std::shared_ptr< sc::DataTransformation >> &mrDataTransformations)
Abstract class for all data provider.
sal_Int32 mnCol
void SetDocumentModified()
Definition: docsh.cxx:2819
orcus::csv::parser_config maConfig
SC_DLLPUBLIC void SetValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rVal)
Definition: document.cxx:3461
const OUString & GetURL() const override
bool mbDeterministic
If true make the threaded import deterministic for the tests.
virtual void execute() override
virtual ~CSVDataProvider() override
SC_DLLPUBLIC void ResetClip(ScDocument *pSourceDoc, const ScMarkData *pMarks)
Definition: documen2.cxx:485
static std::unique_ptr< SvStream > FetchStreamFromURL(const OUString &, OStringBuffer &rBuffer)
void WriteToDoc(ScDocument &rDoc)
SC_DLLPUBLIC bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
Definition: document.cxx:3366
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:872
std::vector< std::shared_ptr< sc::DataTransformation > > maDataTransformations
sal_Int16 SCCOL
Definition: types.hxx:22
const OUString & getURL() const
CSVDataProvider(ScDocument *pDoc, sc::ExternalDataSource &rDataSource)
rtl::Reference< CSVFetchThread > mxCSVFetchThread
ScDBDataManager * getDBManager()
sal_Int32 SCROW
Definition: types.hxx:18
std::unique_ptr< char[]> aBuffer
osl::Mutex maMtxTerminate
ScDocument * mpDocument
virtual void Import() override
virtual ~CSVFetchThread() override
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1058
sal_Int32 mnRow
const std::vector< std::shared_ptr< sc::DataTransformation > > & getDataTransformation() const
aStr
sal_Int16 SCTAB
Definition: types.hxx:23