IODA Bundle
ODBAPISettings.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 1996-2012 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 <unistd.h>
12 
13 #include "eckit/config/Resource.h"
14 #ifdef HAVE_AIO_H
15 # include "eckit/io/AIOHandle.h"
16 #endif
17 #include "eckit/io/FileHandle.h"
18 #include "eckit/thread/ThreadSingleton.h"
19 #include "eckit/utils/StringTools.h"
20 
21 #include "odc/ODBAPISettings.h"
22 
23 using namespace eckit;
24 using namespace std;
25 
26 template class eckit::ThreadSingleton<odc::ODBAPISettings>;
27 static ThreadSingleton<odc::ODBAPISettings> instance_;
28 
29 bool odc::ODBAPISettings::debug = false;
30 
31 void odc::ODBAPISettings::setHome(const char *argv0)
32 {
33  const char* env(getenv("odc_HOME"));
34  if (env) {
35  home_ = env;
36  Log::info() << "odc_HOME set to " << home_ << endl;
37  } else {
38  string full;
39  if (argv0[0] == '/') {
40  char *absoluteArgv0;
41  // The resolved_path == NULL feature, not standardized in POSIX.1-2001, but standardized in POSIX.1-2008
42  if(0 == (absoluteArgv0 = ::realpath(argv0, 0)))
43  throw eckit::FailedSystemCall(string("realpath ") + argv0);
44  full = string(absoluteArgv0);
45  ::free(absoluteArgv0);
46  } else if (argv0[0] == '.' && argv0[1] == '/')
47  {
48  size_t bufferLen =1024*8;
49  char buffer[bufferLen];
50  full = string( ::getcwd(buffer, bufferLen) ) + string(argv0 + 1);
51  } else
52  {
53  vector<string> ps(StringTools::split(":", getenv("PATH")));
54  for (size_t i(0); i < ps.size(); ++i)
55  {
56  // TODO: perhaps we should also check if the file is readable, executable, etc...
57  if (PathName(ps[i] + "/" + argv0).exists())
58  {
59  full = ps[i] + "/" + argv0;
60  if (ps[i][0] != '/') {
61  size_t bufferLen =1024*8;
62  char buffer[bufferLen];
63  full = string( ::getcwd(buffer, bufferLen) ) + full;
64  }
65  break;
66  }
67  }
68 
69  }
70  vector<string> ps(StringTools::split("/", full));
71  Log::debug() << "ODBAPISettings::setHome: argv0: " << ps << endl;
72  ASSERT("odb executable should be in a bin directory" && ps.size() >= 2 && ps[ps.size() - 2] == "bin");
73  ps.pop_back(); // odb
74  ps.pop_back(); // bin
75  home_ = "/" + StringTools::join("/", ps);
76  Log::info() << "odc_HOME inferred as " << home_ << endl;
77  }
78 }
79 
80 string odc::ODBAPISettings::fileInHome(const string& fileName)
81 {
82  ASSERT(fileName[0] == '~');
83  ASSERT(fileName[1] == '/');
84  return home_ + fileName.substr(1);
85 }
86 
88  integersAsDoubles_ = flag;
89 }
90 
92  return integersAsDoubles_;
93 }
94 
95 void debugMeNow() {
96  Log::info() << "Debug me now" << endl;
98 }
99 
100 namespace odc {
101 
102 ODBAPISettings& ODBAPISettings::instance()
103 {
104  //ASSERT( &instance_.instance() != 0 );
105  return instance_.instance();
106 }
107 
108 ODBAPISettings::ODBAPISettings()
109 : headerBufferSize_(Resource<long>("$ODC_HEADER_BUFFER_SIZE;-headerBufferSize;headerBufferSize", 4 * 1024 * 1024)),
110  setvbufferSize_(Resource<long>("$ODC_SETVBUFFER_SIZE;-setvbufferSize;setvbufferSize", 8 * 1024 * 1024)),
111  useAIO_(Resource<bool>("$ODC_USE_AIO", false)),
112  integersAsDoubles_(Resource<bool>("$ODC_INTEGERS_AS_DOUBLES", true))
113 {}
114 
117 
120 
121 void ODBAPISettings::createDirectories(const PathName& path)
122 {
123  vector<string> parts (StringTools::split("/", path));
124  if (parts.size() < 2)
125  return;
126 
127  parts.pop_back();
128  PathName directory ((string(path)[0] == '/' ? "/" : "") + StringTools::join("/", parts));
129 
130  Log::debug() << "Making sure diretory " << directory << " exists" << endl;
131 
132  directory.mkdir();
133 }
134 
135 DataHandle* ODBAPISettings::writeToFile(const PathName& fn, const Length& length, bool openDataHandle)
136 {
137  // ODB-122 Create subdirectories before creating a file
138  createDirectories(fn);
139 
140 #ifdef HAVE_AIO_H
141  DataHandle* h (useAIO_
142  ? static_cast<DataHandle*>(new AIOHandle(fn))
143  : static_cast<DataHandle*>(new FileHandle(fn)));
144 #else
145  DataHandle* h (static_cast<DataHandle*>(new FileHandle(fn)));
146 #endif
147  if (openDataHandle) h->openForWrite(length);
148  return h;
149 }
150 
151 DataHandle* ODBAPISettings::appendToFile(const PathName& fn, const Length& length, bool openDataHandle)
152 {
153 #ifdef HAVE_AIO_H
154  DataHandle *h (useAIO_
155  ? static_cast<DataHandle*>(new AIOHandle(fn))
156  : static_cast<DataHandle*>(new FileHandle(fn)));
157 #else
158  DataHandle* h (static_cast<DataHandle*>(new FileHandle(fn)));
159 #endif
160  if (openDataHandle) h->openForAppend(length);
161  return h;
162 }
163 
164 } // namespace odc
static ThreadSingleton< odc::ODBAPISettings > instance_
void debugMeNow()
void setHome(const char *argv0)
static void createDirectories(const eckit::PathName &path)
eckit::DataHandle * writeToFile(const eckit::PathName &, const eckit::Length &=eckit::Length(0), bool openDataHandle=true)
std::string fileInHome(const std::string &)
void treatIntegersAsDoubles(bool flag)
eckit::DataHandle * appendToFile(const eckit::PathName &, const eckit::Length &=eckit::Length(0), bool openDataHandle=true)
bool integersAsDoubles() const
Definition: ColumnInfo.h:23
Definition: encode.cc:30