diff --git a/src/lib3270++/private.h b/src/lib3270++/private.h index 955a086..9d4c07d 100644 --- a/src/lib3270++/private.h +++ b/src/lib3270++/private.h @@ -241,8 +241,9 @@ }; struct { - DWORD length; - DWORD used; + DWORD length; ///< @brief Length of input buffer. + DWORD used; ///< @brief Length of used block. + DWORD current; ///< @brief Offset of the current argument. uint8_t * block; } in; @@ -256,9 +257,12 @@ Type type; }; - /// @brief Create DataBlock + /// @brief Store value on data block. DataBlock * pushBlock(const void *ptr, size_t len); + /// @brief Get next argument. + DataBlock * getNextBlock() const; + #else struct { DBusMessage * in; @@ -290,7 +294,6 @@ Request & call(); // Push values - Request & push(const char *arg); // Pop values diff --git a/src/lib3270++/windows/request.cc b/src/lib3270++/windows/request.cc index 0721429..54bb244 100644 --- a/src/lib3270++/windows/request.cc +++ b/src/lib3270++/windows/request.cc @@ -91,7 +91,7 @@ } - /// @brief Create DataBlock + /// @brief Store value on data block. IPC::Request::DataBlock * IPC::Request::pushBlock(const void *ptr, size_t length) { if((out.used + length + sizeof(IPC::Request::DataBlock)) >= out.length) { @@ -107,17 +107,61 @@ } + /// @brief Get next argument. + IPC::Request::DataBlock * IPC::Request::getNextBlock() const { + + if((in.current + sizeof(IPC::Request::DataBlock)) >= in.used) { + throw std::runtime_error("Out of range"); + } + + return (IPC::Request::DataBlock *) (in.block + in.current); + + } + IPC::Request & IPC::Request::push(const char *arg) { pushBlock(arg, strlen(arg)+1)->type = IPC::Request::String; return *this; } IPC::Request & IPC::Request::pop(std::string &value) { + DataBlock * block = getNextBlock(); + + if(block->type != IPC::Request::String) + throw std::runtime_error("Invalid format"); + + const char *ptr = (const char *) (block+1); + + in.current += (strlen(ptr)+1+sizeof(DataBlock)); + + value.assign(ptr); return *this; } IPC::Request & IPC::Request::Request::pop(int &value) { + + DataBlock * block = getNextBlock(); + + switch(block->type) { + case IPC::Request::Int16: + value = * ((int16_t *) (block+1)); + in.current += sizeof(int16_t) + sizeof(DataBlock); + break; + + case IPC::Request::Int32: + value = * ((int32_t *) (block+1)); + in.current += sizeof(int32_t) + sizeof(DataBlock); + break; + + case IPC::Request::Int64: + value = * ((int64_t *) (block+1)); + in.current += sizeof(int64_t) + sizeof(DataBlock); + break; + + default: + throw std::runtime_error("Invalid format"); + } + return *this; } diff --git a/src/lib3270++/windows/session.cc b/src/lib3270++/windows/session.cc index f2986a2..58470d2 100644 --- a/src/lib3270++/windows/session.cc +++ b/src/lib3270++/windows/session.cc @@ -95,6 +95,8 @@ lib3270_trace_data(NULL,"Request block",(const char *) this->out.block, this->out.used); #endif // DEBUG + in.current = 0; + if(!TransactNamedPipe( this->hPipe, this->out.block, -- libgit2 0.21.2