Commit c1fd4deeac0abfa03a8dd909584213634cce7016

Authored by Perry Werneck
1 parent d9da6680

Working on the new API.

src/include/lib3270++.h
@@ -67,6 +67,8 @@ @@ -67,6 +67,8 @@
67 class Host; 67 class Host;
68 class Controller; 68 class Controller;
69 69
  70 + #define DEFAULT_TIMEOUT 5
  71 +
70 class TN3270_PUBLIC Event { 72 class TN3270_PUBLIC Event {
71 public: 73 public:
72 enum Type : uint8_t { 74 enum Type : uint8_t {
@@ -200,7 +202,7 @@ @@ -200,7 +202,7 @@
200 virtual void disconnect() = 0; 202 virtual void disconnect() = 0;
201 203
202 // Wait for session state. 204 // Wait for session state.
203 - virtual void waitForReady(time_t timeout = 5) throw() = 0; 205 + virtual void waitForReady(time_t timeout = DEFAULT_TIMEOUT) throw() = 0;
204 206
205 // Gets 207 // Gets
206 virtual std::string toString(int baddr = 0, size_t len = -1, char lf = '\n') const = 0; 208 virtual std::string toString(int baddr = 0, size_t len = -1, char lf = '\n') const = 0;
@@ -255,6 +257,9 @@ @@ -255,6 +257,9 @@
255 /// @brief Connection with the host 257 /// @brief Connection with the host
256 Session *session; 258 Session *session;
257 259
  260 + /// @brief How much seconds we wait for the terminal to be ready?
  261 + time_t timeout;
  262 +
258 protected: 263 protected:
259 264
260 /// @brief Writes characters to the associated file from the put area 265 /// @brief Writes characters to the associated file from the put area
@@ -273,19 +278,23 @@ @@ -273,19 +278,23 @@
273 void error(const char *fmt, ...) const; 278 void error(const char *fmt, ...) const;
274 279
275 public: 280 public:
276 - Host(const char *id = nullptr, const char *url = nullptr); 281 + Host(const char *id = nullptr, const char *url = nullptr, time_t timeout = DEFAULT_TIMEOUT);
277 ~Host(); 282 ~Host();
278 283
279 inline bool operator==(ConnectionState state) const noexcept { 284 inline bool operator==(ConnectionState state) const noexcept {
280 return session->getConnectionState() == state; 285 return session->getConnectionState() == state;
281 } 286 }
282 287
283 - void connect(const char *url); 288 + void connect(const char *url, bool sync = true);
284 289
285 inline ProgramMessage getProgramMessage() const { 290 inline ProgramMessage getProgramMessage() const {
286 return session->getProgramMessage(); 291 return session->getProgramMessage();
287 } 292 }
288 293
  294 + inline bool isReady() const {
  295 + return getProgramMessage() == MESSAGE_NONE;
  296 + }
  297 +
289 inline operator ProgramMessage() const { 298 inline operator ProgramMessage() const {
290 return getProgramMessage(); 299 return getProgramMessage();
291 } 300 }
@@ -294,6 +303,10 @@ @@ -294,6 +303,10 @@
294 return session->getConnectionState(); 303 return session->getConnectionState();
295 } 304 }
296 305
  306 + inline bool isConnected() const {
  307 + return getConnectionState() == CONNECTED_TN3270E;
  308 + }
  309 +
297 inline operator ConnectionState() const { 310 inline operator ConnectionState() const {
298 return getConnectionState(); 311 return getConnectionState();
299 } 312 }
@@ -336,22 +349,13 @@ @@ -336,22 +349,13 @@
336 349
337 // Get contents. 350 // Get contents.
338 351
339 - inline Host & pop(int baddr, std::string &text) {  
340 - session->pop(baddr, text);  
341 - return *this;  
342 - }  
343 -  
344 - inline Host & pop(int row, int col, std::string &text) {  
345 - session->pop(row,col,text);  
346 - return *this;  
347 - }  
348 -  
349 - inline Host & pop(std::string &text) {  
350 - session->pop(text);  
351 - return *this;  
352 - } 352 + Host & pop(int baddr, std::string &text);
  353 + Host & pop(int row, int col, std::string &text);
  354 + Host & pop(std::string &text);
353 355
354 std::string toString() const; 356 std::string toString() const;
  357 + std::string toString(int baddr, size_t len = -1, char lf = '\n') const;
  358 + std::string toString(int row, int col, size_t sz, char lf = '\n') const;
355 359
356 // Event listeners 360 // Event listeners
357 inline Host & insert(Event::Type type, std::function <void(const Event &event)> listener) noexcept { 361 inline Host & insert(Event::Type type, std::function <void(const Event &event)> listener) noexcept {
src/include/lib3270.h
@@ -555,6 +555,18 @@ @@ -555,6 +555,18 @@
555 LIB3270_EXPORT int lib3270_emulate_input(H3270 *session, const char *s, int len, int pasting); 555 LIB3270_EXPORT int lib3270_emulate_input(H3270 *session, const char *s, int len, int pasting);
556 556
557 /** 557 /**
  558 + * @brief Converts row/col in a buffer address.
  559 + *
  560 + * @param hSession TN3270 Session.
  561 + * @param row Row inside the screen.
  562 + * @param col Col inside the screen.
  563 + *
  564 + * @return Current address or -1 if invalid (sets errno).
  565 + *
  566 + */
  567 + LIB3270_EXPORT int lib3270_translate_to_address(H3270 *hSession, int row, int col);
  568 +
  569 + /**
558 * Set string at current cursor position. 570 * Set string at current cursor position.
559 * 571 *
560 * Returns are ignored; newlines mean "move to beginning of next line"; 572 * Returns are ignored; newlines mean "move to beginning of next line";
@@ -578,7 +590,7 @@ @@ -578,7 +590,7 @@
578 * @param h Session handle. 590 * @param h Session handle.
579 * @param baddr New cursor address. 591 * @param baddr New cursor address.
580 * 592 *
581 - * @return last cursor address. 593 + * @return or -1 if invalid (sets errno).
582 * 594 *
583 */ 595 */
584 LIB3270_EXPORT int lib3270_set_cursor_address(H3270 *h, int baddr); 596 LIB3270_EXPORT int lib3270_set_cursor_address(H3270 *h, int baddr);
@@ -590,7 +602,7 @@ @@ -590,7 +602,7 @@
590 * @param row New cursor row. 602 * @param row New cursor row.
591 * @param col New cursor col. 603 * @param col New cursor col.
592 * 604 *
593 - * @return last cursor address. 605 + * @return last cursor address or -1 if invalid (sets errno)..
594 * 606 *
595 */ 607 */
596 LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *h, int row, int col); 608 LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *h, int row, int col);
src/lib3270++/host.cc
@@ -43,7 +43,8 @@ @@ -43,7 +43,8 @@
43 43
44 namespace TN3270 { 44 namespace TN3270 {
45 45
46 - Host::Host(const char *id, const char *url) { 46 + Host::Host(const char *id, const char *url, time_t timeout) {
  47 + this->timeout = timeout;
47 this->session = Session::create(id); 48 this->session = Session::create(id);
48 if(url) { 49 if(url) {
49 this->connect(url); 50 this->connect(url);
@@ -55,15 +56,17 @@ @@ -55,15 +56,17 @@
55 this->session = nullptr; 56 this->session = nullptr;
56 } 57 }
57 58
58 - void Host::connect(const char *url) { 59 + void Host::connect(const char *url, bool sync) {
59 this->session->connect(url); 60 this->session->connect(url);
60 - sync(); 61 + if(sync) {
  62 + this->sync();
  63 + }
61 } 64 }
62 65
63 66
64 /// @brief Writes characters to the associated file from the put area 67 /// @brief Writes characters to the associated file from the put area
65 int Host::sync() { 68 int Host::sync() {
66 - this->session->waitForReady(); 69 + this->session->waitForReady(this->timeout);
67 return 0; 70 return 0;
68 } 71 }
69 72
@@ -89,6 +92,8 @@ @@ -89,6 +92,8 @@
89 92
90 std::string Host::toString() const { 93 std::string Host::toString() const {
91 94
  95 + this->session->waitForReady(this->timeout);
  96 +
92 if(this->session->getConnectionState() == TN3270::DISCONNECTED) { 97 if(this->session->getConnectionState() == TN3270::DISCONNECTED) {
93 throw std::system_error(ENOTCONN, std::system_category()); 98 throw std::system_error(ENOTCONN, std::system_category());
94 } 99 }
@@ -96,5 +101,70 @@ @@ -96,5 +101,70 @@
96 return this->session->toString(); 101 return this->session->toString();
97 } 102 }
98 103
  104 + std::string Host::toString(int baddr, size_t len, char lf) const {
  105 +
  106 + this->session->waitForReady(this->timeout);
  107 +
  108 + if(this->session->getConnectionState() == TN3270::DISCONNECTED) {
  109 + throw std::system_error(ENOTCONN, std::system_category());
  110 + }
  111 +
  112 + return this->session->toString(baddr,len,lf);
  113 +
  114 + }
  115 +
  116 + std::string Host::toString(int row, int col, size_t sz, char lf) const {
  117 +
  118 + this->session->waitForReady(this->timeout);
  119 +
  120 + if(this->session->getConnectionState() == TN3270::DISCONNECTED) {
  121 + throw std::system_error(ENOTCONN, std::system_category());
  122 + }
  123 +
  124 + return this->session->toString(row,col,sz,lf);
  125 +
  126 +
  127 + }
  128 +
  129 + Host & Host::pop(int baddr, std::string &text) {
  130 +
  131 + this->session->waitForReady(this->timeout);
  132 +
  133 + if(this->session->getConnectionState() == TN3270::DISCONNECTED) {
  134 + throw std::system_error(ENOTCONN, std::system_category());
  135 + }
  136 +
  137 + session->pop(baddr, text);
  138 +
  139 + return *this;
  140 + }
  141 +
  142 + Host & Host::pop(int row, int col, std::string &text) {
  143 +
  144 + this->session->waitForReady(this->timeout);
  145 +
  146 + if(this->session->getConnectionState() == TN3270::DISCONNECTED) {
  147 + throw std::system_error(ENOTCONN, std::system_category());
  148 + }
  149 +
  150 + session->pop(row,col,text);
  151 +
  152 + return *this;
  153 + }
  154 +
  155 + Host & Host::pop(std::string &text) {
  156 +
  157 + this->session->waitForReady(this->timeout);
  158 +
  159 + if(this->session->getConnectionState() == TN3270::DISCONNECTED) {
  160 + throw std::system_error(ENOTCONN, std::system_category());
  161 + }
  162 +
  163 + session->pop(text);
  164 +
  165 + return *this;
  166 + }
  167 +
  168 +
99 } 169 }
100 170
src/lib3270++/local/session.cc
@@ -216,7 +216,19 @@ @@ -216,7 +216,19 @@
216 } 216 }
217 217
218 TN3270::Session & Local::Session::pop(int baddr, std::string &text) { 218 TN3270::Session & Local::Session::pop(int baddr, std::string &text) {
  219 +
219 std::lock_guard<std::mutex> lock(sync); 220 std::lock_guard<std::mutex> lock(sync);
  221 +
  222 + char *contents = lib3270_get_field_at(hSession, baddr);
  223 +
  224 + if(!contents) {
  225 + throw std::runtime_error("Can't get field contents");
  226 + }
  227 +
  228 + text.assign(convertFromHost(contents).c_str());
  229 +
  230 + lib3270_free(contents);
  231 +
220 return *this; 232 return *this;
221 } 233 }
222 234
src/lib3270++/testprogram/testprogram.cc
@@ -47,7 +47,7 @@ @@ -47,7 +47,7 @@
47 47
48 TN3270::Host host; 48 TN3270::Host host;
49 49
50 - host.connect(getenv("TN3270URL")); 50 + host.connect(getenv("LIB3270_DEFAULT_HOST"));
51 cout << host << endl; 51 cout << host << endl;
52 52
53 host << TN3270::ENTER; 53 host << TN3270::ENTER;
src/lib3270/screen.c
@@ -382,20 +382,80 @@ LIB3270_EXPORT int lib3270_get_cursor_address(H3270 *h) @@ -382,20 +382,80 @@ LIB3270_EXPORT int lib3270_get_cursor_address(H3270 *h)
382 return h->cursor_addr; 382 return h->cursor_addr;
383 } 383 }
384 384
385 -LIB3270_EXPORT int lib3270_set_cursor_address(H3270 *h, int baddr) 385 +/**
  386 + * @brief Converts row/col in a buffer address.
  387 + *
  388 + * @param hSession TN3270 Session.
  389 + * @param row Row inside the screen.
  390 + * @param col Col inside the screen.
  391 + *
  392 + * @return Current address or -1 if invalid (sets errno).
  393 + *
  394 + */
  395 +LIB3270_EXPORT int lib3270_translate_to_address(H3270 *hSession, int row, int col)
386 { 396 {
387 - CHECK_SESSION_HANDLE(h); 397 + CHECK_SESSION_HANDLE(hSession);
  398 +
  399 + row--;
  400 + col--;
  401 +
  402 + if(row < 0 || col < 0 || row > hSession->rows || col > hSession->cols)
  403 + {
  404 + // Invalid coordinates
  405 + errno = EINVAL;
  406 + return -1;
  407 + }
  408 +
  409 + return (row * hSession->cols) + col;
  410 +}
  411 +
  412 +
  413 +/**
  414 + * @brief Move cursor to a new position.
  415 + *
  416 + * @see lib3270_set_cursor_position
  417 + *
  418 + * @param hSession TN3270 session.
  419 + * @param baddr New cursor position.
  420 + *
  421 + * @return Old cursor address or -1 in case of error (sets errno).
  422 + *
  423 + */
  424 +LIB3270_EXPORT int lib3270_set_cursor_address(H3270 *hSession, int baddr)
  425 +{
  426 + CHECK_SESSION_HANDLE(hSession);
388 427
389 trace("%s(%d)",__FUNCTION__,baddr); 428 trace("%s(%d)",__FUNCTION__,baddr);
390 429
391 - if(h->selected && !lib3270_get_toggle(h,LIB3270_TOGGLE_KEEP_SELECTED))  
392 - lib3270_unselect(h); 430 + if(baddr < 0 || baddr > (hSession->rows * hSession->cols))
  431 + {
  432 + errno = EINVAL;
  433 + return -1;
  434 + }
  435 +
  436 + if(hSession->selected && !lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_SELECTED))
  437 + lib3270_unselect(hSession);
393 438
394 - return cursor_move(h,baddr); 439 + return cursor_move(hSession,baddr);
395 } 440 }
396 441
397 -LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *h, int row, int col) 442 +/**
  443 + * @brief Move cursor to a new position.
  444 + *
  445 + * @see lib3270_set_cursor_position
  446 + *
  447 + * @param hSession TN3270 session.
  448 + * @param row New cursor row.
  449 + * @parma col New cursor column.
  450 + *
  451 + * @return Old cursor address or -1 in case of error (sets errno).
  452 + *
  453 + */
  454 +LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *hSession, int row, int col)
398 { 455 {
  456 + return lib3270_set_cursor_address(hSession,lib3270_translate_to_address(hSession, row, col));
  457 +
  458 + /*
399 int baddr = -1; 459 int baddr = -1;
400 460
401 CHECK_SESSION_HANDLE(h); 461 CHECK_SESSION_HANDLE(h);
@@ -418,20 +478,37 @@ LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *h, int row, int col) @@ -418,20 +478,37 @@ LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *h, int row, int col)
418 } 478 }
419 479
420 return baddr; 480 return baddr;
  481 + */
421 } 482 }
422 483
423 -  
424 -int cursor_move(H3270 *h, int baddr) 484 +/**
  485 + * @brief Move cursor to a new position.
  486 + *
  487 + * @see lib3270_set_cursor_address
  488 + *
  489 + * @param hSession TN3270 session.
  490 + * @param baddr New cursor position.
  491 + *
  492 + * @return Old cursor position.
  493 + *
  494 + */
  495 +int cursor_move(H3270 *hSession, int baddr)
425 { 496 {
426 - int ret = h->cursor_addr; 497 + int ret = hSession->cursor_addr;
427 498
428 if(ret == baddr) 499 if(ret == baddr)
429 return ret; 500 return ret;
430 501
431 if(baddr >= 0) 502 if(baddr >= 0)
432 { 503 {
433 - h->cursor_addr = baddr;  
434 - h->cbk.update_cursor(h,(unsigned short) (baddr/h->cols),(unsigned short) (baddr%h->cols),h->text[baddr].chr,h->text[baddr].attr); 504 + hSession->cursor_addr = baddr;
  505 + hSession->cbk.update_cursor(
  506 + hSession,
  507 + (unsigned short) (baddr/hSession->cols),
  508 + (unsigned short) (baddr%hSession->cols),
  509 + hSession->text[baddr].chr,
  510 + hSession->text[baddr].attr
  511 + );
435 } 512 }
436 513
437 return ret; 514 return ret;