diff options
| author | manuel <manuel@nc8430.lan> | 2009-10-31 16:11:26 +0100 |
|---|---|---|
| committer | manuel <manuel@nc8430.lan> | 2009-10-31 16:11:26 +0100 |
| commit | 1d8445b8461f558987067d870f0f11cdc84b4f35 (patch) | |
| tree | 146d7d02dddf1a403392ac4b86c19bca4a3c6f75 /task1/ehrclient.cpp | |
| download | selinux-1d8445b8461f558987067d870f0f11cdc84b4f35.tar.gz selinux-1d8445b8461f558987067d870f0f11cdc84b4f35.tar.bz2 selinux-1d8445b8461f558987067d870f0f11cdc84b4f35.zip | |
pushing task1 to repo
Diffstat (limited to 'task1/ehrclient.cpp')
| -rw-r--r-- | task1/ehrclient.cpp | 496 |
1 files changed, 496 insertions, 0 deletions
diff --git a/task1/ehrclient.cpp b/task1/ehrclient.cpp new file mode 100644 index 0000000..ec3c2c1 --- /dev/null +++ b/task1/ehrclient.cpp | |||
| @@ -0,0 +1,496 @@ | |||
| 1 | /** | ||
| 2 | * $Id: ehrclient.cpp 2 2009-10-31 02:48:23Z l0728348 $ | ||
| 3 | * | ||
| 4 | * Copyright 2009 | ||
| 5 | * | ||
| 6 | * @author Manuel Mausz (0728348) | ||
| 7 | * @brief implements the main routines of the console application | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <iostream> | ||
| 11 | #include <iomanip> | ||
| 12 | #include <fstream> | ||
| 13 | #include <Ice/Plugin.h> | ||
| 14 | #include <time.h> | ||
| 15 | #include <sys/time.h> | ||
| 16 | #include "ehrclient.h" | ||
| 17 | #include "getoptwrapper.h" | ||
| 18 | #include "cairodocument.h" | ||
| 19 | #include "utils.h" | ||
| 20 | |||
| 21 | using namespace std; | ||
| 22 | using namespace Ehr; | ||
| 23 | |||
| 24 | int EhrClient::run(int argc, char *argv[]) | ||
| 25 | { | ||
| 26 | /* setup commandline option */ | ||
| 27 | CommandOption optnode("node", 0, "The object identifier string used to connect to the EHR provider node", CommandOption::needArg); | ||
| 28 | CommandOption optreq("requestor", 0, "The PEM file containing the requestors certifcate and private key for signing", CommandOption::needArg); | ||
| 29 | CommandOption optowner("owner", 0, "The PEM file containing the patients certifcate and private key for signing", CommandOption::needArg); | ||
| 30 | CommandOption optlist("list", 0, "Display a list of all documents available in the patient's EHR", CommandOption::noArg); | ||
| 31 | CommandOption optdoc("document", 0, "The ID of the document selected for exporting to PDF", CommandOption::needArg); | ||
| 32 | CommandOption optout("output", 0, "The output file", CommandOption::needArg); | ||
| 33 | CommandOption opthelp("help", 0, "Display this help and exit", CommandOption::noArg); | ||
| 34 | CommandOptionParse opts(argc, argv, "Allowed options"); | ||
| 35 | opts.addSynopsis("--node <providernode> --requestor <infile> --owner <infile> --list"); | ||
| 36 | opts.addSynopsis("--node <providernode> --requestor <infile> --owner <infile> --document <id> --output <outfile>"); | ||
| 37 | |||
| 38 | /* error during parsing or help-option set */ | ||
| 39 | if (!opts.parse() || opts["help"]) | ||
| 40 | { | ||
| 41 | cerr << opts; | ||
| 42 | return EXIT_FAILURE; | ||
| 43 | } | ||
| 44 | |||
| 45 | /* check commandline option combinations */ | ||
| 46 | try | ||
| 47 | { | ||
| 48 | /* missing mandatory options */ | ||
| 49 | if (!opts["node"] || !opts["requestor"] || !opts["owner"] | ||
| 50 | || (!opts["list"] && !opts["document"])) | ||
| 51 | throw runtime_error("missing mandatory commandline options"); | ||
| 52 | |||
| 53 | /* list-option needs to be alone (and vica-versa) */ | ||
| 54 | if (opts["list"] && (opts["document"] || opts["output"])) | ||
| 55 | throw runtime_error("unable to combine these commandline options"); | ||
| 56 | |||
| 57 | /* document-option needs output-option */ | ||
| 58 | if (opts["document"] && !opts["output"]) | ||
| 59 | throw runtime_error("--document needs --output"); | ||
| 60 | |||
| 61 | /* don't allow options to occur multiple times */ | ||
| 62 | if (opts["node"] > 1 || opts["requestor"] > 1 || opts["owner"] > 1 | ||
| 63 | || opts["list"] > 1 || opts["document"] > 1 || opts["output"] > 1) | ||
| 64 | throw runtime_error("commandline options may occur only once"); | ||
| 65 | } | ||
| 66 | catch(runtime_error& ex) | ||
| 67 | { | ||
| 68 | cerr << appName() << ": " << ex.what() << endl | ||
| 69 | << opts; | ||
| 70 | return EXIT_FAILURE; | ||
| 71 | } | ||
| 72 | |||
| 73 | /* save for later */ | ||
| 74 | m_ownercert = opts["owner"].value(); | ||
| 75 | m_requestorcert = opts["requestor"].value(); | ||
| 76 | |||
| 77 | /* set some properties */ | ||
| 78 | Ice::PropertiesPtr props = communicator()->getProperties(); | ||
| 79 | if (props->getProperty("IceSSL.CertAuthFile").empty()) | ||
| 80 | props->setProperty("IceSSL.CertAuthFile", "./certs/rootca.pem"); | ||
| 81 | props->setProperty("IceSSL.CertFile", m_requestorcert); | ||
| 82 | |||
| 83 | /* load plugins */ | ||
| 84 | Ice::PluginManagerPtr pluginmgr = communicator()->getPluginManager(); | ||
| 85 | pluginmgr->initializePlugins(); | ||
| 86 | |||
| 87 | /* get security instance */ | ||
| 88 | m_security = &Security::instance(); | ||
| 89 | |||
| 90 | /* get provider proxy */ | ||
| 91 | Ice::ObjectPrx base = communicator()->stringToProxy(opts["node"]); | ||
| 92 | if (!(m_provider = ProviderPrx::checkedCast(base))) | ||
| 93 | throw runtime_error("error - invalid node or doesn't exist"); | ||
| 94 | |||
| 95 | try | ||
| 96 | { | ||
| 97 | if (opts["list"]) | ||
| 98 | listDocuments(); | ||
| 99 | else if (opts["document"] && opts["output"]) | ||
| 100 | { | ||
| 101 | long docid; | ||
| 102 | try | ||
| 103 | { | ||
| 104 | docid = Utils::lexical_cast<long, string>(opts["document"].value()); | ||
| 105 | } | ||
| 106 | catch(Utils::bad_lexical_cast& ex) | ||
| 107 | { | ||
| 108 | throw runtime_error("error - invalid document-parameter - not a number"); | ||
| 109 | } | ||
| 110 | if (docid <= 0) | ||
| 111 | throw runtime_error("error - invalid document-parameter - only positive numbers"); | ||
| 112 | saveDocument(docid, opts["output"]); | ||
| 113 | } | ||
| 114 | } | ||
| 115 | catch(EhrException& e) | ||
| 116 | { | ||
| 117 | throw runtime_error("error - " + e.what); | ||
| 118 | } | ||
| 119 | |||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 123 | /*----------------------------------------------------------------------------*/ | ||
| 124 | |||
| 125 | #include <memory> | ||
| 126 | Ehr::DocumentList EhrClient::getDocumentList() | ||
| 127 | { | ||
| 128 | /* fill in request */ | ||
| 129 | ListDocumentsRequestPtr request = new ListDocumentsRequest(); | ||
| 130 | pair<string, string> cnowner = splitCN(m_ownercert); | ||
| 131 | pair<string, string> cnrequestor = splitCN(m_requestorcert); | ||
| 132 | request->owner.user = cnowner.first; | ||
| 133 | request->owner.provider = cnowner.second; | ||
| 134 | request->requestor.user = cnrequestor.first; | ||
| 135 | request->requestor.provider = cnrequestor.second; | ||
| 136 | request->when.msecs = getTime(); | ||
| 137 | |||
| 138 | /* objects containing the signature */ | ||
| 139 | Signature requestor; | ||
| 140 | Signature owner; | ||
| 141 | |||
| 142 | /* sign the request */ | ||
| 143 | vector<Ice::Byte> data = convertToByteStream(request); | ||
| 144 | m_security->sign(m_requestorcert, data, requestor.data); | ||
| 145 | m_security->sign(m_ownercert, data, owner.data); | ||
| 146 | |||
| 147 | /* execute */ | ||
| 148 | return m_provider->listDocuments(request, requestor, owner); | ||
| 149 | } | ||
| 150 | |||
| 151 | /*----------------------------------------------------------------------------*/ | ||
| 152 | |||
| 153 | Ehr::DocumentList EhrClient::searchDocument(const bool hasFrom, const long from, | ||
| 154 | const bool hasTill, const long till, | ||
| 155 | const Ehr::DocumentType doctype, const long docid) | ||
| 156 | { | ||
| 157 | /* fill in request */ | ||
| 158 | FindDocumentsRequestPtr request = new FindDocumentsRequest(); | ||
| 159 | pair<string, string> cnowner = splitCN(m_ownercert); | ||
| 160 | pair<string, string> cnrequestor = splitCN(m_requestorcert); | ||
| 161 | request->owner.user = cnowner.first; | ||
| 162 | request->owner.provider = cnowner.second; | ||
| 163 | request->requestor.user = cnrequestor.first; | ||
| 164 | request->requestor.provider = cnrequestor.second; | ||
| 165 | request->when.msecs = getTime(); | ||
| 166 | request->hasFrom = hasFrom; | ||
| 167 | request->from.msecs = from; | ||
| 168 | request->hasTill = hasTill; | ||
| 169 | request->from.msecs = till; | ||
| 170 | request->type = doctype; | ||
| 171 | request->documentId = docid; | ||
| 172 | |||
| 173 | /* objects containing the signature */ | ||
| 174 | Signature requestor; | ||
| 175 | Signature owner; | ||
| 176 | |||
| 177 | /* sign the request */ | ||
| 178 | vector<Ice::Byte> data = convertToByteStream(request); | ||
| 179 | m_security->sign(m_requestorcert, data, requestor.data); | ||
| 180 | m_security->sign(m_ownercert, data, owner.data); | ||
| 181 | |||
| 182 | /* execute */ | ||
| 183 | return m_provider->findDocuments(request, requestor, owner); | ||
| 184 | } | ||
| 185 | |||
| 186 | /*----------------------------------------------------------------------------*/ | ||
| 187 | |||
| 188 | void EhrClient::listDocuments() | ||
| 189 | { | ||
| 190 | /* get document list */ | ||
| 191 | DocumentList doclist = getDocumentList(); | ||
| 192 | DocumentPtr doc = new Document(); | ||
| 193 | |||
| 194 | /* print the list */ | ||
| 195 | cout << "Documentlist for " << m_security->getCommonName(m_ownercert) << ":" << endl; | ||
| 196 | if (doclist.size() != 0) | ||
| 197 | { | ||
| 198 | for(unsigned i = 0; i < doclist.size(); ++i) | ||
| 199 | { | ||
| 200 | /* decrypt our document */ | ||
| 201 | vector<Ice::Byte> data; | ||
| 202 | m_security->decryptPrivate(m_ownercert, doclist[i].document.encryptedData, | ||
| 203 | doclist[i].document.initialVector, doclist[i].document.encryptedKey, data); | ||
| 204 | Ice::InputStreamPtr in = Ice::createInputStream(communicator(), data); | ||
| 205 | ice_readDocument(in, doc); | ||
| 206 | in->readPendingObjects(); | ||
| 207 | |||
| 208 | cout << " ID#" << doclist[i].id | ||
| 209 | << " " << getDate(doclist[i].created.msecs) | ||
| 210 | << endl; | ||
| 211 | if (doc->type == DOCPRESCRIPTION || doc->type == DOCCONSUMEDPRESCRIPTION) | ||
| 212 | { | ||
| 213 | PrescriptionPtr presc = PrescriptionPtr::dynamicCast(doc); | ||
| 214 | cout << " Orginator: " << presc->originatorName << ", " << presc->originatorProfession << endl | ||
| 215 | << " Parmaceutical: " << presc->drugDescription << endl | ||
| 216 | << " Valid: " << getDate(presc->validFrom) << " - " << getDate(presc->expires) << endl; | ||
| 217 | } | ||
| 218 | |||
| 219 | cout << endl; | ||
| 220 | } | ||
| 221 | } | ||
| 222 | else | ||
| 223 | cout << "There are no documents available" << endl; | ||
| 224 | } | ||
| 225 | |||
| 226 | /*----------------------------------------------------------------------------*/ | ||
| 227 | |||
| 228 | void EhrClient::saveDocument(const long docid, const std::string& output) | ||
| 229 | { | ||
| 230 | /* first check if file already exist */ | ||
| 231 | ifstream ifile(output.c_str()); | ||
| 232 | if (ifile) | ||
| 233 | throw runtime_error("error - output file already exist"); | ||
| 234 | ifile.close(); | ||
| 235 | |||
| 236 | /* search for document */ | ||
| 237 | DocumentList doclist = searchDocument(docid); | ||
| 238 | if (doclist.size() == 0) | ||
| 239 | throw runtime_error("error - document not found"); | ||
| 240 | else if (doclist.size() > 1) | ||
| 241 | throw runtime_error("error - document exists multiple times"); | ||
| 242 | |||
| 243 | /* decrypt our document */ | ||
| 244 | DocumentPtr doc = new Document(); | ||
| 245 | vector<Ice::Byte> data; | ||
| 246 | m_security->decryptPrivate(m_ownercert, doclist[0].document.encryptedData, | ||
| 247 | doclist[0].document.initialVector, doclist[0].document.encryptedKey, data); | ||
| 248 | Ice::InputStreamPtr in = Ice::createInputStream(communicator(), data); | ||
| 249 | ice_readDocument(in, doc); | ||
| 250 | in->readPendingObjects(); | ||
| 251 | |||
| 252 | if (doc->type == DOCPRESCRIPTION || doc->type == DOCCONSUMEDPRESCRIPTION) | ||
| 253 | { | ||
| 254 | PrescriptionPtr presc = PrescriptionPtr::dynamicCast(doc); | ||
| 255 | |||
| 256 | /* create our pdf document */ | ||
| 257 | //CairoDocument cairodoc(210, 148); // A6 lanscape | ||
| 258 | CairoDocument cairodoc(148, 105); // A5 landscape | ||
| 259 | CairoColor colblack(0, 0, 0); | ||
| 260 | CairoColor colgrey(0.5, 0.5, 0.5); | ||
| 261 | CairoFont fontsmall(7, "sans-serif"); | ||
| 262 | CairoFont fontbig(10, "sans-serif"); | ||
| 263 | |||
| 264 | /* set default */ | ||
| 265 | cairodoc.add(fontbig).add(colblack); | ||
| 266 | |||
| 267 | /* our current position */ | ||
| 268 | double docleft = 0; | ||
| 269 | double doctop = 0; | ||
| 270 | double docwidth = cairodoc.width(); | ||
| 271 | double docheight = cairodoc.height(); | ||
| 272 | double padding = 3; | ||
| 273 | |||
| 274 | /* add document border */ | ||
| 275 | CairoRectangle docborder(docleft += padding, doctop += padding, | ||
| 276 | docwidth -= 2 * padding, docheight -= 2 * padding, 0.2); | ||
| 277 | cairodoc.add(docborder); | ||
| 278 | |||
| 279 | /* add inner padding */ | ||
| 280 | docleft += padding; | ||
| 281 | doctop += padding; | ||
| 282 | docwidth -= 2 * padding; | ||
| 283 | docheight -= 2 * padding; | ||
| 284 | |||
| 285 | /* add consumer name + label */ | ||
| 286 | double boxleftwith = (docwidth - docleft) * 3 / 4; | ||
| 287 | double boxleftwithin = boxleftwith - padding; | ||
| 288 | CairoTextBox consumerlabel(docleft, doctop, boxleftwithin, fontsmall.height()); | ||
| 289 | consumerlabel << "Consumer name:"; | ||
| 290 | cairodoc.add(consumerlabel.add(colgrey).add(fontsmall)); | ||
| 291 | doctop += consumerlabel.height(); | ||
| 292 | |||
| 293 | CairoTextBox consumername(docleft, doctop, boxleftwithin, fontbig.height()); | ||
| 294 | consumername << presc->consumerName; | ||
| 295 | cairodoc.add(consumername); | ||
| 296 | doctop += consumername.height(); | ||
| 297 | |||
| 298 | /* add consumer birth + label */ | ||
| 299 | doctop += 1; | ||
| 300 | CairoTextBox consumerdatelabel(docleft, doctop, boxleftwithin, fontsmall.height(), 0); | ||
| 301 | consumerdatelabel << "Date of birth:"; | ||
| 302 | cairodoc.add(consumerdatelabel.add(colgrey).add(fontsmall)); | ||
| 303 | doctop += consumerdatelabel.height(); | ||
| 304 | |||
| 305 | CairoTextBox consumerdate(docleft, doctop, boxleftwithin, fontbig.height()); | ||
| 306 | consumerdate << getDate(presc->consumerDateOfBirth); | ||
| 307 | cairodoc.add(consumerdate); | ||
| 308 | doctop += consumerdate.height(); | ||
| 309 | |||
| 310 | /* put that in a box */ | ||
| 311 | CairoRectangle consumerborder(docborder.x(), docborder.y(), | ||
| 312 | docleft - docborder.x() + boxleftwith, doctop - docborder.y() + padding); | ||
| 313 | cairodoc.add(consumerborder); | ||
| 314 | doctop += 2 * padding; | ||
| 315 | |||
| 316 | /* add originator */ | ||
| 317 | CairoTextBox originatorlabel(docleft, doctop, boxleftwithin, fontsmall.height()); | ||
| 318 | originatorlabel << "Originator:"; | ||
| 319 | cairodoc.add(originatorlabel.add(colgrey).add(fontsmall)); | ||
| 320 | doctop += originatorlabel.height(); | ||
| 321 | |||
| 322 | CairoTextBox originator(docleft, doctop, boxleftwithin, fontbig.height() * 2); | ||
| 323 | originator << presc->originatorName << ", " << presc->originatorProfession | ||
| 324 | << "\n" << presc->originatorAddress; | ||
| 325 | cairodoc.add(originator); | ||
| 326 | doctop += originator.height(); | ||
| 327 | |||
| 328 | /* put that in a box */ | ||
| 329 | CairoRectangle originatorborder(docborder.x(), docborder.y(), | ||
| 330 | docleft - docborder.x() + boxleftwith, originator.y() + originator.height()); | ||
| 331 | cairodoc.add(originatorborder); | ||
| 332 | doctop += 2 * padding; | ||
| 333 | |||
| 334 | /* add left box */ | ||
| 335 | double boxrightx = consumerlabel.x() + boxleftwith; | ||
| 336 | double boxrighty = docborder.y(); | ||
| 337 | double boxrightwidth = docborder.x() + docborder.width() - boxrightx; | ||
| 338 | CairoRectangle datesborder(boxrightx, boxrighty, boxrightwidth, originator.y() + originator.height()); | ||
| 339 | cairodoc.add(datesborder); | ||
| 340 | |||
| 341 | /* add inner padding */ | ||
| 342 | double boxrightxin = boxrightx + padding; | ||
| 343 | boxrighty += padding; | ||
| 344 | double boxrightwidthin = boxrightwidth - 2 * padding; | ||
| 345 | |||
| 346 | /* add creation date */ | ||
| 347 | CairoTextBox createdlabel(boxrightxin, boxrighty, boxrightwidthin, fontsmall.height()); | ||
| 348 | createdlabel << "Created on:"; | ||
| 349 | cairodoc.add(createdlabel.add(colgrey).add(fontsmall)); | ||
| 350 | boxrighty += consumerlabel.height(); | ||
| 351 | |||
| 352 | CairoTextBox created(boxrightxin, boxrighty, boxrightwidthin, fontbig.height()); | ||
| 353 | created << getDate(presc->creationDate); | ||
| 354 | cairodoc.add(created); | ||
| 355 | boxrighty += created.height(); | ||
| 356 | boxrighty += 1; | ||
| 357 | |||
| 358 | /* add valid from date */ | ||
| 359 | CairoTextBox validfromlabel(boxrightxin, boxrighty, boxrightwidthin, fontsmall.height()); | ||
| 360 | validfromlabel << "Valid from:"; | ||
| 361 | cairodoc.add(validfromlabel.add(colgrey).add(fontsmall)); | ||
| 362 | boxrighty += validfromlabel.height(); | ||
| 363 | |||
| 364 | CairoTextBox valid(boxrightxin, boxrighty, boxrightwidthin, fontbig.height()); | ||
| 365 | valid << getDate(presc->validFrom); | ||
| 366 | cairodoc.add(valid); | ||
| 367 | boxrighty += valid.height(); | ||
| 368 | boxrighty += 1; | ||
| 369 | |||
| 370 | /* add expire date */ | ||
| 371 | CairoTextBox expirelabel(boxrightxin, boxrighty, boxrightwidthin, fontsmall.height()); | ||
| 372 | expirelabel << "Expire on:"; | ||
| 373 | cairodoc.add(expirelabel.add(colgrey).add(fontsmall)); | ||
| 374 | boxrighty += expirelabel.height(); | ||
| 375 | |||
| 376 | CairoTextBox expire(boxrightxin, boxrighty, boxrightwidthin, fontbig.height()); | ||
| 377 | expire << getDate(presc->expires); | ||
| 378 | cairodoc.add(expire); | ||
| 379 | |||
| 380 | /* add drug */ | ||
| 381 | CairoTextBox druglabel(docleft, doctop, docwidth, fontsmall.height()); | ||
| 382 | druglabel << "Pharmaceutical:"; | ||
| 383 | cairodoc.add(druglabel.add(colgrey).add(fontsmall)); | ||
| 384 | doctop += druglabel.height(); | ||
| 385 | |||
| 386 | CairoTextBox drug(docleft, doctop, docwidth, fontbig.height()); | ||
| 387 | drug << presc->drugDescription | ||
| 388 | << "\n" << presc->dosage << " " << presc->measuringUnit | ||
| 389 | << ", " << presc->form; | ||
| 390 | cairodoc.add(drug); | ||
| 391 | |||
| 392 | if (doc->type == DOCCONSUMEDPRESCRIPTION) | ||
| 393 | { | ||
| 394 | ConsumedPrescriptionPtr presc2 = ConsumedPrescriptionPtr::dynamicCast(doc); | ||
| 395 | |||
| 396 | /* add consumed prescreption */ | ||
| 397 | double boxbottomy = docborder.y() + docborder.height() - | ||
| 398 | (2 * padding + 2 * fontbig.height() + fontsmall.height()); | ||
| 399 | CairoRectangle consumedborder(docborder.x(), boxbottomy, docleft - docborder.x() + boxleftwith, | ||
| 400 | docborder.height() - boxbottomy + docborder.x()); | ||
| 401 | cairodoc.add(consumedborder); | ||
| 402 | |||
| 403 | double boxbottomyin = boxbottomy + padding; | ||
| 404 | CairoTextBox consumedlabel(docleft, boxbottomyin, boxleftwithin, fontsmall.height()); | ||
| 405 | consumedlabel << "Consumed by:"; | ||
| 406 | cairodoc.add(consumedlabel.add(colgrey).add(fontsmall)); | ||
| 407 | |||
| 408 | CairoTextBox consumeddatelabel(boxrightxin, boxbottomyin, boxrightwidth, fontsmall.height()); | ||
| 409 | consumeddatelabel << "Consumed on:"; | ||
| 410 | cairodoc.add(consumeddatelabel.add(colgrey).add(fontsmall)); | ||
| 411 | boxbottomyin += consumedlabel.height(); | ||
| 412 | |||
| 413 | CairoTextBox consumed(docleft, boxbottomyin, boxleftwithin, fontbig.height() * 2); | ||
| 414 | consumed << presc2->dispenserName << ", " << presc2->dispenserProfession | ||
| 415 | << "\n" << presc2->dispenserAddress; | ||
| 416 | cairodoc.add(consumed); | ||
| 417 | |||
| 418 | CairoTextBox consumedon(boxrightxin, boxbottomyin, boxrightwidth, fontbig.height()); | ||
| 419 | consumedon << getDate(presc2->dispensingDate); | ||
| 420 | cairodoc.add(consumedon); | ||
| 421 | |||
| 422 | /* add consumed date border */ | ||
| 423 | CairoRectangle consumedborder2(boxrightx, boxbottomy, boxrightwidth, | ||
| 424 | docborder.height() - boxbottomy + docborder.x()); | ||
| 425 | cairodoc.add(consumedborder2); | ||
| 426 | } | ||
| 427 | |||
| 428 | cairodoc.save(output, CairoDocument::PDF); | ||
| 429 | } | ||
| 430 | else | ||
| 431 | throw runtime_error("error - unsupported document type"); | ||
| 432 | |||
| 433 | return; | ||
| 434 | } | ||
| 435 | |||
| 436 | /*----------------------------------------------------------------------------*/ | ||
| 437 | |||
| 438 | long EhrClient::getTime() | ||
| 439 | { | ||
| 440 | /* get time in milliseconds */ | ||
| 441 | struct timeval tv; | ||
| 442 | gettimeofday(&tv, NULL); | ||
| 443 | return tv.tv_sec * 1000 + tv.tv_usec / 1000; | ||
| 444 | } | ||
| 445 | |||
| 446 | /*----------------------------------------------------------------------------*/ | ||
| 447 | |||
| 448 | std::string EhrClient::getDate(long msecs) | ||
| 449 | { | ||
| 450 | struct tm doctime; | ||
| 451 | const time_t timep = msecs / 1000; | ||
| 452 | localtime_r(&timep, &doctime); | ||
| 453 | stringstream out(""); | ||
| 454 | out << doctime.tm_mday << "." << doctime.tm_mon << "." << doctime.tm_year + 1900 | ||
| 455 | << " " << doctime.tm_hour << ':' << doctime.tm_min << ':' << doctime.tm_sec; | ||
| 456 | return out.str(); | ||
| 457 | } | ||
| 458 | |||
| 459 | /*----------------------------------------------------------------------------*/ | ||
| 460 | |||
| 461 | std::string EhrClient::getDate(const Ehr::Date& date) | ||
| 462 | { | ||
| 463 | stringstream out(""); | ||
| 464 | out << static_cast<unsigned>(date.day) << "." << static_cast<unsigned>(date.month) | ||
| 465 | << "." << date.year; | ||
| 466 | return out.str(); | ||
| 467 | } | ||
| 468 | |||
| 469 | /*----------------------------------------------------------------------------*/ | ||
| 470 | |||
| 471 | vector<Ice::Byte> EhrClient::convertToByteStream(const Ice::ObjectPtr& request) | ||
| 472 | { | ||
| 473 | /* in order to sign our request, we need to convert | ||
| 474 | * the request to a bytestream first | ||
| 475 | */ | ||
| 476 | Ice::OutputStreamPtr out = Ice::createOutputStream(communicator()); | ||
| 477 | vector<Ice::Byte> data; | ||
| 478 | out->writeObject(request); | ||
| 479 | out->writePendingObjects(); | ||
| 480 | out->finished(data); | ||
| 481 | return data; | ||
| 482 | } | ||
| 483 | |||
| 484 | /*----------------------------------------------------------------------------*/ | ||
| 485 | |||
| 486 | std::pair<std::string, std::string> EhrClient::splitCN(const std::string& cert) | ||
| 487 | { | ||
| 488 | /* parse requestor details from cert */ | ||
| 489 | string commonname = m_security->getCommonName(cert); | ||
| 490 | size_t pos = commonname.find_first_of('@'); | ||
| 491 | if (pos == string::npos) | ||
| 492 | throw runtime_error("error - commonname of cert \"" + cert + "\" doesn't have user@provider syntax"); | ||
| 493 | return pair<string, string>(commonname.substr(0, pos), commonname.substr(pos + 1)); | ||
| 494 | } | ||
| 495 | |||
| 496 | /* vim: set et sw=2 ts=2: */ | ||
