NCBI C++ ToolKit
http_session_sample.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: http_session_sample.cpp 96053 2022-02-01 19:29:14Z vakatov $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Aleksey Grichenko
27  *
28  * File Description:
29  * Plain example of CHTTPSession.
30  *
31  * USAGE: http_session_sample
32  *
33  */
34 
35 #include <ncbi_pch.hpp>
36 #include <corelib/ncbiapp.hpp>
37 #include <corelib/ncbistr.hpp>
39 
40 // This header is not necessary for real application,
41 // but required for automatic testsuite.
42 #include <common/test_assert.h> /* This header must go last */
43 
44 
46 
47 
48 /////////////////////////////////////////////////////////////////////////////
49 // CHttpSessionApplication::
50 //
51 
53 {
54 public:
55  CHttpSessionApp(void);
56  virtual void Init(void);
57  virtual int Run(void);
58 
59  bool PrintResponse(const CHttp2Session* session, const CHttpResponse& response);
60 
61 private:
62  CHttpParam SetupParam(void);
63  void LoadCredentials(CNcbiIstream& cert_str, CNcbiIstream& pkey_str);
64 
68  int m_Errors;
69  shared_ptr<CTlsCertCredentials> m_Credentials;
70 };
71 
72 
74  : m_PrintHeaders(true),
75  m_PrintCookies(true),
76  m_PrintBody(true),
77  m_Errors(0)
78 {
79 }
80 
81 
83 {
84  const CArgs& args = GetArgs();
85  CHttpParam ret;
86  if (args["timeout"]) {
87  ret.SetTimeout(CTimeout(args["timeout"].AsDouble()));
88  }
89  if (args["retries"]) {
90  ret.SetRetries((unsigned short)args["retries"].AsInteger());
91  }
92  if (m_Credentials) {
94  }
95  if (args["proxy-host"]) {
96  string phost = args["proxy-host"].AsString();
97  _ASSERT(args["proxy-port"]);
98  unsigned short pport = (unsigned short)args["proxy-port"].AsInteger();
99  if (args["proxy-user"]) {
100  string puser = args["proxy-user"].AsString();
101  string ppass;
102  if (args["proxy-password"]) {
103  ppass = args["proxy-password"].AsString();
104  }
105  ret.SetProxy(CHttpProxy(phost, pport, puser, ppass));
106  }
107  else {
108  ret.SetProxy(CHttpProxy(phost, pport));
109  }
110  }
111  if ( args["deadline"] ) {
112  ret.SetDeadline(CTimeout(args["deadline"].AsDouble()));
113  }
114  if ( args["retry-processing"] ) {
115  ret.SetRetryProcessing(args["retry-processing"].AsBoolean() ? eOn : eOff);
116  }
117  return ret;
118 }
119 
120 
121 static string LoadFile(CNcbiIstream& str)
122 {
123  string content;
124  size_t size = NcbiStreamToString(&content, str);
125  return size ? content : kEmptyStr;
126 }
127 
128 
130 {
131  string cert = LoadFile(cert_str);
132  string pkey = LoadFile(pkey_str);
133  if (!cert.empty() && !pkey.empty()) {
134  m_Credentials = make_shared<CTlsCertCredentials>(cert, pkey);
135  }
136 }
137 
138 
140 {
142 
143  unique_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
144 
145  arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
146  "HTTP session sample application");
147 
148  arg_desc->AddFlag("http-11", "Use HTTP/1.1 protocol", true);
149  arg_desc->AddFlag("http-2", "Use HTTP/2 protocol", true);
150  arg_desc->AddFlag("print-headers", "Print HTTP response headers", true);
151  arg_desc->AddFlag("print-cookies", "Print HTTP cookies", true);
152  arg_desc->AddFlag("print-body", "Print HTTP response body", true);
153 
154  // Simple requests
155  arg_desc->AddOptionalKey("head", "url", "URL to load using HEAD request",
158  arg_desc->AddOptionalKey("get", "url", "URL to load using GET request",
161  arg_desc->AddOptionalKey("post", "url", "URL to POST data to (the data is read from STDIN)",
163 
164  // Requests to specific url/service
165  arg_desc->AddOptionalKey("method", "method", "HTTP request method: HEAD/GET/POST",
167  CArgAllow_Strings allow_methods;
168  allow_methods.Allow("HEAD");
169  allow_methods.Allow("GET");
170  allow_methods.Allow("POST");
171  arg_desc->SetConstraint("method", allow_methods);
172  arg_desc->SetDependency("method", CArgDescriptions::eExcludes, "head");
173  arg_desc->SetDependency("method", CArgDescriptions::eExcludes, "get");
174  arg_desc->SetDependency("method", CArgDescriptions::eExcludes, "post");
175 
176  arg_desc->AddOptionalKey("url", "url", "URL to access using the specified method.",
178  arg_desc->SetDependency("url", CArgDescriptions::eRequires, "method");
179 
180  arg_desc->AddOptionalKey("service-name", "name", "Named service to access using the specified method.",
182  arg_desc->SetDependency("service-name", CArgDescriptions::eRequires, "method");
183  arg_desc->SetDependency("service-name", CArgDescriptions::eExcludes, "url");
184 
185  arg_desc->AddOptionalKey("service-path", "path", "Path to be appended to the service name.",
187  arg_desc->SetDependency("service-path", CArgDescriptions::eRequires, "service-name");
188 
189  arg_desc->AddOptionalKey("service-args", "name", "Named service arguments.",
191  arg_desc->SetDependency("service-args", CArgDescriptions::eRequires, "service-name");
192 
193  // Connection parameters
194  arg_desc->AddOptionalKey("timeout", "double", "Timeout in seconds",
196  arg_desc->AddOptionalKey("retries", "int", "Number of retries",
198  arg_desc->AddOptionalKey("deadline", "double", "Deadline for request total processing, in seconds",
200  arg_desc->AddOptionalKey("retry-processing", "bool", "Whether to wait for actual response",
202 
203  // Proxy parameters
204  arg_desc->AddOptionalKey("proxy-host", "phost", "Proxy host", CArgDescriptions::eString);
205  arg_desc->AddOptionalKey("proxy-port", "pport", "Proxy port", CArgDescriptions::eInteger);
206  arg_desc->AddOptionalKey("proxy-user", "puser", "Proxy user", CArgDescriptions::eString);
207  arg_desc->AddOptionalKey("proxy-password", "ppass", "Proxy password", CArgDescriptions::eString);
208  arg_desc->SetDependency("proxy-host", CArgDescriptions::eRequires, "proxy-port");
209  arg_desc->SetDependency("proxy-port", CArgDescriptions::eRequires, "proxy-host");
210  arg_desc->SetDependency("proxy-user", CArgDescriptions::eRequires, "proxy-host");
211  arg_desc->SetDependency("proxy-password", CArgDescriptions::eRequires, "proxy-host");
212  arg_desc->SetDependency("proxy-password", CArgDescriptions::eRequires, "proxy-user");
213 
214  arg_desc->AddOptionalKey("cert-file", "file", "Certificate file", CArgDescriptions::eInputFile, CArgDescriptions::fBinary);
215  arg_desc->AddOptionalKey("pkey-file", "file", "Private key file", CArgDescriptions::eInputFile, CArgDescriptions::fBinary);
216  arg_desc->SetDependency("cert-file", CArgDescriptions::eRequires, "pkey-file");
217  arg_desc->SetDependency("pkey-file", CArgDescriptions::eRequires, "cert-file");
218 
219  // Setup arg.descriptions for this application
220  SetupArgDescriptions(arg_desc.release());
221 }
222 
223 
225 {
226 public:
228  virtual string GetContentType(void) const { return "text/plain"; }
229  virtual string GetFileName(void) const { return "test.txt"; }
230  virtual void WriteData(CNcbiOstream& out) const { out << "Provider test"; }
231 };
232 
233 
235 {
236  const CArgs& args = GetArgs();
237  m_PrintHeaders = args["print-headers"];
238  m_PrintCookies = args["print-cookies"];
239  m_PrintBody = args["print-body"];
240 
241  CHttpParam param = SetupParam();
242 
243  CHttp2Session session;
244 
245  if ( args["http-11"] ) {
247 
248  } else if (!args["http-2"]) {
250  }
251 
252  if (args["cert-file"]) {
253  LoadCredentials(args["cert-file"].AsInputFile(), args["pkey-file"].AsInputFile());
254  session.SetCredentials(m_Credentials);
255  }
256 
257  bool skip_defaults = false;
258  if (args["method"]) {
260  if (args["method"].AsString() == "GET")
261  method = CHttpSession::eGet;
262  else if (args["method"].AsString() == "POST")
263  method = CHttpSession::ePost;
264  CUrl url;
265  if (args["url"]) {
266  url.SetUrl(args["url"].AsString());
267  }
268  else if (args["service-name"]) {
269  url.SetService(args["service-name"].AsString());
270  if (args["service-path"]) {
271  url.SetPath(args["service-path"].AsString());
272  }
273  if (args["service-args"]) {
274  url.GetArgs().SetQueryString(args["service-args"].AsString());
275  }
276  }
277  else {
278  cout << "Missing 'url' or 'service-name' argument for " << args["method"] << " request." << endl;
279  return 1;
280  }
281  cout << args["method"].AsString() << " " << url.ComposeUrl(CUrlArgs::eAmp_Char) << endl;
282  CHttpRequest req = session.NewRequest(url, method, param);
283  if (method == CHttpSession::ePost) {
284  NcbiStreamCopy(req.ContentStream(), cin);
285  }
286  PrintResponse(&session, req.Execute());
287  return 0;
288  }
289  if ( args["head"] ) {
290  skip_defaults = true;
291  const auto& urls = args["head"].GetStringList();
292  for (const auto& url : urls) {
293  cout << "HEAD " << url << endl;
294  CHttpRequest req = session.NewRequest(url, CHttpSession::eHead, param);
295  if (!PrintResponse(&session, req.Execute())) m_Errors++;
296  cout << "-------------------------------------" << endl << endl;
297  }
298  }
299  if ( args["get"] ) {
300  skip_defaults = true;
301  const auto& urls = args["get"].GetStringList();
302  for (const auto& url : urls) {
303  cout << "GET " << url << endl;
304  CHttpRequest req = session.NewRequest(url, CHttpSession::eGet, param);
305  cout << "-------------------------------------" << endl;
306  if (!PrintResponse(&session, req.Execute())) m_Errors++;
307  cout << "-------------------------------------" << endl << endl;
308  }
309  }
310  if ( args["post"] ) {
311  skip_defaults = true;
312  string url = args["post"].AsString();
313  cout << "POST " << url << endl;
314  CHttpRequest req = session.NewRequest(url, CHttpSession::ePost, param);
315  NcbiStreamCopy(req.ContentStream(), cin);
316  if (!PrintResponse(&session, req.Execute())) m_Errors++;
317  cout << "-------------------------------------" << endl << endl;
318  }
319 
320  if ( skip_defaults ) {
321  return 0;
322  }
323 
324  const string sample_url = "https://dev.ncbi.nlm.nih.gov/Service/sample/cgi_sample.cgi";
325  const string bad_url = "https://dev.ncbi.nlm.nih.gov/Service/sample/404";
326  CUrl url(sample_url);
327 
328  {{
329  // HEAD request
330  cout << "HEAD " << sample_url << endl;
331  // Requests can be initialized with either a string or a CUrl
332  CHttpRequest req = session.NewRequest(url, CHttpSession::eHead, param);
333  CHttpResponse resp = req.Execute();
334  if (!PrintResponse(&session, resp)) m_Errors++;
335  cout << "-------------------------------------" << endl << endl;
336  }}
337 
338  {{
339  // Simple GET request
340  cout << "GET (no args) " << sample_url << endl;
341  CHttpRequest req = session.NewRequest(url, CHttpSession::eGet, param);
342  if (!PrintResponse(&session, req.Execute())) m_Errors++;
343  cout << "-------------------------------------" << endl << endl;
344  }}
345 
346  {{
347  // GET using shortcut
348  cout << "GET (shortcut) " << sample_url << endl;
349  CHttpResponse response = g_HttpGet(url, param);
350  if (!PrintResponse(0, response)) m_Errors++;
351  cout << "-------------------------------------" << endl << endl;
352  }}
353 
354  {{
355  CUrl url_with_args(sample_url);
356  // GET request with arguments
357  cout << "GET (with args) " << sample_url << endl;
358  url_with_args.GetArgs().SetValue("message", "GET data");
359  CHttpRequest req = session.NewRequest(url_with_args, CHttpSession::eGet, param);
360  if (!PrintResponse(&session, req.Execute())) m_Errors++;
361  cout << "-------------------------------------" << endl << endl;
362  }}
363 
364  {{
365  // POST request with form data
366  cout << "POST (form data) " << sample_url << endl;
367  CHttpRequest req = session.NewRequest(url, CHttpSession::ePost, param);
368  CHttpFormData& data = req.FormData();
369  data.AddEntry("message", "POST data");
370  if (!PrintResponse(&session, req.Execute())) m_Errors++;
371  cout << "-------------------------------------" << endl << endl;
372  }}
373 
374  {{
375  // POST using a provider
376  cout << "POST (provider) " << sample_url << endl;
377  CHttpRequest req = session.NewRequest(url, CHttpSession::ePost, param);
378  CHttpFormData& data = req.FormData();
379  data.AddProvider("message", new CTestDataProvider);
380  if (!PrintResponse(&session, req.Execute())) m_Errors++;
381  cout << "-------------------------------------" << endl << endl;
382  }}
383 
384  {{
385  // POST some data manually
386  cout << "POST (manual) " << sample_url << endl;
387  CHttpRequest req = session.NewRequest(url, CHttpSession::ePost, param);
388  req.Headers().SetValue(CHttpHeaders::eContentType, "application/x-www-form-urlencoded");
389  CNcbiOstream& out = req.ContentStream();
390  out << "message=POST manual data";
391  if (!PrintResponse(&session, req.Execute())) m_Errors++;
392  cout << "-------------------------------------" << endl << endl;
393  }}
394 
395  {{
396  // POST using shortcut
397  cout << "POST (shortcut) " << sample_url << endl;
398  CHttpResponse response = g_HttpPost(url, "message=POST%20shortcut%20data", param);
399  if (!PrintResponse(0, response)) m_Errors++;
400  cout << "-------------------------------------" << endl << endl;
401  }}
402 
403  {{
404  // PUT using a provider
405  cout << "PUT (provider) " << sample_url << endl;
406  CHttpRequest req = session.NewRequest(url, CHttpSession::ePut, param);
407  CHttpFormData& data = req.FormData();
408  data.AddProvider("message", new CTestDataProvider);
409  if (!PrintResponse(&session, req.Execute())) m_Errors++;
410  cout << "-------------------------------------" << endl << endl;
411  }}
412 
413  {{
414  // Bad GET request
415  cout << "GET (404) " << bad_url << endl;
416  CHttpRequest req = session.NewRequest(bad_url, CHttpSession::eGet, param);
417  PrintResponse(&session, req.Execute());
418  cout << "-------------------------------------" << endl << endl;
419  }}
420 
421  {{
422  // Service request
423  cout << "GET service: test" << endl;
424  CHttpRequest req = session.NewRequest(CUrl("test"), CHttpSession::eGet, param);
425  if (!PrintResponse(&session, req.Execute())) m_Errors++;
426  cout << "-------------------------------------" << endl << endl;
427  }}
428 
429  {{
430  // Service request
431  cout << "GET service (shortcut): test" << endl;
432  CHttpResponse response = g_HttpGet(CUrl("test"), param);
433  if (!PrintResponse(0, response)) m_Errors++;
434  cout << "-------------------------------------" << endl << endl;
435  }}
436 
437  if (m_Errors > 0) {
438  cout << m_Errors << " requests failed." << endl;
439  return 1;
440  }
441  return 0;
442 }
443 
444 
445 
447  const CHttpResponse& response)
448 {
449  cout << "Status: " << response.GetStatusCode() << " "
450  << response.GetStatusText() << endl;
451  if ( m_PrintHeaders ) {
452  cout << "--- Headers ---" << endl;
453  for (const auto& header : response.Headers().Get()) {
454  for (const auto& value : header.second) {
455  cout << header.first << ": " << value << endl;
456  }
457  }
458  }
459 
460  if (m_PrintCookies && session) {
461  cout << "--- Cookies ---" << endl;
462  for (const auto& cookie : session->Cookies()) {
463  cout << cookie.AsString(CHttpCookie::eHTTPResponse) << endl;
464  }
465  }
466 
467  if ( m_PrintBody ) {
468  cout << "--- Body ---" << endl;
469  if ( response.CanGetContentStream() ) {
470  CNcbiIstream& in = response.ContentStream();
471  if ( in.good() ) {
472  NcbiStreamCopy(cout, in);
473  }
474  }
475  else {
476  CNcbiIstream& in = response.ErrorStream();
477  if ( in.good() ) {
478  NcbiStreamCopy(cout, in);
479  }
480  }
481  }
482  return response.GetStatusCode() == 200;
483 }
484 
485 
486 /////////////////////////////////////////////////////////////////////////////
487 // MAIN
488 //
489 
490 int NcbiSys_main(int argc, ncbi::TXChar* argv[])
491 {
492  return CHttpSessionApp().AppMain(argc, argv);
493 }
CArgAllow_Strings –.
Definition: ncbiargs.hpp:1641
CArgDescriptions –.
Definition: ncbiargs.hpp:541
CArgs –.
Definition: ncbiargs.hpp:379
Interface for custom form data providers.
POST request data.
CHttpSession and CHttpRequest parameters.
Per-request proxy settings.
HTTP request.
HTTP response.
virtual int Run(void)
Run the application.
shared_ptr< CTlsCertCredentials > m_Credentials
bool PrintResponse(const CHttp2Session *session, const CHttpResponse &response)
void LoadCredentials(CNcbiIstream &cert_str, CNcbiIstream &pkey_str)
CHttpParam SetupParam(void)
virtual void Init(void)
Initialize the application.
virtual string GetContentType(void) const
Get content type.
virtual void WriteData(CNcbiOstream &out) const
Write user data to the stream.
virtual string GetFileName(void) const
Get optional filename to be shown in Content-Disposition header.
CTimeout – Timeout interval.
Definition: ncbitime.hpp:1693
CUrl –.
Definition: ncbi_url.hpp:353
The NCBI C++ standard methods for dealing with std::string.
std::ofstream out("events_result.xml")
main entry point for tests
#define true
Definition: bool.h:35
static const char * str(char *buf, int n)
Definition: stats.c:84
char data[12]
Definition: iconv.c:80
virtual void Init(void)
Initialize the application.
Definition: ncbiapp.cpp:286
virtual const CArgs & GetArgs(void) const
Get parsed command line arguments.
Definition: ncbiapp.cpp:305
int AppMain(int argc, const char *const *argv, const char *const *envp=0, EAppDiagStream diag=eDS_Default, const char *conf=NcbiEmptyCStr, const string &name=NcbiEmptyString)
Main function (entry point) for the NCBI application.
Definition: ncbiapp.cpp:832
virtual void SetupArgDescriptions(CArgDescriptions *arg_desc)
Setup the command line argument descriptions.
Definition: ncbiapp.cpp:1208
const CNcbiArguments & GetArguments(void) const
Get the application's cached unprocessed command-line arguments.
@ eOn
Definition: ncbi_types.h:111
CArgAllow_Strings * Allow(const string &value)
Add allowed string values.
Definition: ncbiargs.cpp:4598
@ fAllowMultiple
Repeated key arguments are legal (use with AddKey)
Definition: ncbiargs.hpp:635
@ fBinary
Open as binary file; for eInputFile, eOutputFile, eIOFile.
Definition: ncbiargs.hpp:620
@ eRequires
One argument requires another.
Definition: ncbiargs.hpp:956
@ eExcludes
One argument excludes another.
Definition: ncbiargs.hpp:957
@ eInputFile
Name of file (must exist and be readable)
Definition: ncbiargs.hpp:595
@ eBoolean
{'true', 't', 'false', 'f'}, case-insensitive
Definition: ncbiargs.hpp:590
@ eDouble
Convertible into a floating point number (double)
Definition: ncbiargs.hpp:594
@ eString
An arbitrary string.
Definition: ncbiargs.hpp:589
@ eInteger
Convertible into an integer number (int or Int8)
Definition: ncbiargs.hpp:592
const THeaders & Get() const
CHttpParam & SetRetries(THttpRetries retries)
CNcbiIstream & ContentStream(void) const
Get input stream.
int GetStatusCode(void) const
Get response status code.
void SetValue(CHeaderNameConverter name, CTempString value)
Remove all existing values with the name, set the new value.
const CHttpHeaders & Headers(void) const
Get incoming HTTP headers.
CNcbiIstream & ErrorStream(void) const
Get input stream containing error message (e.g.
CHttpParam & SetCredentials(shared_ptr< CTlsCertCredentials > credentials)
CNcbiOstream & ContentStream(void)
Get output stream to write user data.
CHttpParam & SetRetryProcessing(ESwitch on_off)
bool CanGetContentStream(void) const
Check if the requested content can be read from the content stream.
CHttpHeaders & Headers(void)
Get HTTP headers to be sent.
const string & GetStatusText(void) const
Get response status text.
CHttpResponse g_HttpPost(const CUrl &url, CTempString data, const CHttpParam &param=CHttpParam())
Shortcut for POST request.
const CHttpCookies & Cookies(void) const
Get all stored cookies.
CHttpParam & SetTimeout(const CTimeout &timeout)
void SetProtocol(EProtocol protocol)
CHttpRequest NewRequest(const CUrl &url, ERequestMethod method=eGet, const CHttpParam &param={})
Initialize request.
CHttpResponse Execute(void)
Send the request, initialize and return the response.
ERequestMethod
Supported request methods, proxy for EReqMethod.
void SetCredentials(shared_ptr< CTlsCertCredentials > cred)
Set TLS credentials.
CHttpResponse g_HttpGet(const CUrl &url, const CHttpParam &param)
Shortcut for GET request.
CHttpParam & SetDeadline(const CTimeout &deadline)
CHttpParam & SetProxy(const CHttpProxy &proxy)
CHttpFormData & FormData(void)
Get form data to be sent with POST request.
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
Definition: ncbistre.hpp:146
bool NcbiStreamCopy(CNcbiOstream &os, CNcbiIstream &is)
Copy the entire contents of stream "is" to stream "os".
Definition: ncbistre.cpp:211
size_t NcbiStreamToString(string *s, CNcbiIstream &is, size_t pos=0)
Input the entire contents of an istream into a string (NULL causes drain).
Definition: ncbistre.cpp:296
#define kEmptyStr
Definition: ncbistr.hpp:123
char TXChar
Definition: ncbistr.hpp:172
const CUrlArgs & GetArgs(void) const
Get const list of arguments.
Definition: ncbi_url.cpp:674
void SetPath(const string &value)
Definition: ncbi_url.hpp:422
void SetService(const string &value)
Definition: ncbi_url.hpp:576
void SetQueryString(const string &query, NStr::EUrlEncode encode)
Parse query string, call AddArgument() to store each value.
Definition: ncbi_url.cpp:49
void SetUrl(const string &url, const IUrlEncoder *encoder=0)
Parse the URL.
Definition: ncbi_url.cpp:409
void SetValue(const string &name, const string &value)
Set new value for the first argument with the given name or add a new argument.
Definition: ncbi_url.cpp:270
string ComposeUrl(CUrlArgs::EAmpEncoding amp_enc, const IUrlEncoder *encoder=0) const
Compose the URL.
Definition: ncbi_url.cpp:580
@ eAmp_Char
Use & to separate arguments.
Definition: ncbi_url.hpp:254
int NcbiSys_main(int argc, ncbi::TXChar *argv[])
static string LoadFile(CNcbiIstream &str)
USING_NCBI_SCOPE
const struct ncbi::grid::netcache::search::fields::SIZE size
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
Defines the CNcbiApplication and CAppException classes for creating NCBI applications.
std::istream & in(std::istream &in_, double &x_)
#define _ASSERT
Modified on Fri Sep 20 14:57:45 2024 by modify_doxy.py rev. 669887