IODA Bundle
DataHandleFactory.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 1996-2016 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 #include <sstream>
12 #include <memory>
13 
14 #include "eckit/io/MultiHandle.h"
15 #include "eckit/utils/StringTools.h"
16 #include "eckit/exception/Exceptions.h"
17 
22 
23 using namespace eckit;
24 
25 namespace odc {
26 
27 DataHandleFactory::DataHandleFactory(const std::string& prefix)
28 : prefix_(prefix)
29 {
30  factories()[prefix] = this;
31 }
32 
34 {
35  factories().erase(prefix_);
36 }
37 
38 std::string DataHandleFactory::prefix() const { return prefix_; }
39 
41 {
42  static Storage factories;
43  return factories;
44 }
45 
46 DataHandle* DataHandleFactory::makeHandle(const std::string& prefix, const std::string& descriptor)
47 {
48  if (factories().find(prefix) == factories().end())
49  throw UserError(std::string("No factory for '") + prefix + "://' data descriptors");
50 
51  return factories()[prefix]->makeHandle(descriptor);
52 }
53 
54 std::pair<std::string, std::string> DataHandleFactory::splitPrefix(const std::string& handleDescriptor)
55 {
56  const std::string delimiter("://");
57  size_t pos (handleDescriptor.find(delimiter));
58  if (pos != std::string::npos)
59  return make_pair(handleDescriptor.substr(0, pos), handleDescriptor.substr(pos + delimiter.size()));
60 
61  // Sugar.
62  if (StringTools::startsWith(StringTools::lower(StringTools::trim(handleDescriptor)), "retrieve,")
63  || StringTools::startsWith(StringTools::lower(StringTools::trim(handleDescriptor)), "stage,")
64  || StringTools::startsWith(StringTools::lower(StringTools::trim(handleDescriptor)), "list,")
65  || StringTools::startsWith(StringTools::lower(StringTools::trim(handleDescriptor)), "archive,"))
66  return std::make_pair(std::string("mars"), handleDescriptor);
67 
68  return std::make_pair(std::string("file"), handleDescriptor);
69 }
70 
71 void DataHandleFactory::buildMultiHandle(eckit::MultiHandle& mh, const std::string& dataDescriptor)
72 {
74  std::vector<std::string> ds;
75  ds.push_back(dataDescriptor);
76  buildMultiHandle(mh, ds);
77 }
78 
79 void DataHandleFactory::buildMultiHandle(eckit::MultiHandle& mh, const std::vector<std::string>& dataDescriptors)
80 {
82  std::vector<DataHandle*> handles;
83  for (size_t i(0); i < dataDescriptors.size(); ++i)
84  {
85  std::pair<std::string,std::string> p (splitPrefix(dataDescriptors[i]));
86  mh += makeHandle(p.first, p.second);
87  }
88 }
89 
90 DataHandle* DataHandleFactory::openForRead(const std::string& s)
91 {
93  std::pair<std::string,std::string> p (splitPrefix(s));
94  std::unique_ptr<DataHandle> d (makeHandle(p.first, p.second));
95  d->openForRead();
96  return d.release();
97 }
98 
99 DataHandle* DataHandleFactory::openForWrite(const std::string& s, const eckit::Length& length)
100 {
102  std::pair<std::string,std::string> p (splitPrefix(s));
103  std::unique_ptr<DataHandle> d (makeHandle(p.first, p.second));
104  d->openForWrite(length);
105  return d.release();
106 }
107 
109 {
110  static PartFileHandleFactory partFileHandleFactory;
111  static FileHandleFactory fileHandleFactory;
112  static HttpHandleFactory httpHandleFactory;
113 }
114 
115 } //namespace odc
std::string prefix() const
static eckit::DataHandle * makeHandle(const std::string &, const std::string &)
static eckit::DataHandle * openForRead(const std::string &)
static void buildMultiHandle(eckit::MultiHandle &, const std::vector< std::string > &)
std::map< std::string, DataHandleFactory * > Storage
static std::pair< std::string, std::string > splitPrefix(const std::string &)
static Storage & factories()
static eckit::DataHandle * openForWrite(const std::string &, const eckit::Length &=eckit::Length(0))
std::string trim(const std::string &str)
Definition: ColumnInfo.h:23