/* * Copyright (c) 1996 Gunther Schadow. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ // Tiny send and receive program for just a `register patient' (A04) message // sent and received via a file channel. Only some dummy data is handled, in // order to exemplyfy what can be done. // Dedicated to Nancy van Schooenderwoert. #include "hl7/ADT_A04msg.h" // include the A04 message #include "xios.h" // and the iostream extension #include // cannel will be files void send_it(const char *filename) { // first declare a message ADT_A04msg msg; // now we fill some data into it: // 1. MSH: SENDING APPLICATION (ST) msg.MesHea.SenApp = "MY-APP-ID"; // 2. MSH: DATE/TIME OF MESSAGE (TS) // as a timestamp of the current system time // the stamp(TStyp&) function is declared in TStyp.h stamp(msg.MesHea.DateTimeOfMes); // 3. The MESSAGE TYPE field is filled automatically // 4. MSH: MESSAGE CONTROL ID (ST) // 5. MSH: PROCESSING ID (ID: 103) // 6. MSH: VERSION ID (ID: 104) msg.MesHea.MesConTrolId = "REQ12345"; msg.MesHea.ProId = ProIdCode::Pro; msg.MesHea.VerId = VerIdCode::_2_2val; // 7. PID: PATIENT ID (EXTERNAL ID) (CK) char *eidnum = "EID08157411"; msg.PatIde.PatIdExtId.IdNum = eidnum; msg.PatIde.PatIdExtId.CheckDigit = cdmod(eidnum, 10); msg.PatIde.PatIdExtId.CheckDigitSch = CheckDigitSchCode::M10val; // 8. PID: PATIENT ID (EXTERNAL ID) (repeated CK) char *iidnum0 = "IID0815741100"; char *iidnum1 = "IID0815741101"; msg.PatIde.PatIdIntId[0].IdNum = iidnum0; msg.PatIde.PatIdIntId[0].CheckDigit = cdmod(iidnum0, 10); msg.PatIde.PatIdIntId[0].CheckDigitSch = CheckDigitSchCode::M10val; msg.PatIde.PatIdIntId[1].IdNum = iidnum1; msg.PatIde.PatIdIntId[1].CheckDigit = cdmod(iidnum1, 10); msg.PatIde.PatIdIntId[1].CheckDigitSch = CheckDigitSchCode::M10val; // 9. PID: PATIENT NAME (PN) msg.PatIde.PatName.GivenName = "Nancy"; msg.PatIde.PatName.FamName = "Schooenderwoert"; msg.PatIde.PatName.Pre = "van"; // 10. PID: SEX (ID: 1) msg.PatIde.Sex = SexCode::Fem; // 11. An NK1 msg.NextOfKin[0].Name.GivenName = "Gunther"; msg.NextOfKin[0].Name.FamName = "Schadow"; msg.NextOfKin[0].PhoneNum[0] = "+49 30 815 33 55"; msg.NextOfKin[0].ConTactRole.Text = "call if pat. is found despaired with ProtoGen/HL7"; // 12. Another NK1 msg.NextOfKin[1].Name.GivenName = "Bill"; msg.NextOfKin[1].Name.FamName = "Gates"; msg.NextOfKin[1].Add.City = "Seattle"; msg.NextOfKin[1].ConTactRole.Text = "call if pat. is found despaired with Windows NT"; // END OF DATA // Now, the whole message must be checked into a consistent state: msg.commit(); // Prepare a channel to send // 1. use the named file fstream chan(filename, ios::out | ios::ate, 0644); // NOTE: permission bits `0644' might be different on non-Unix platforms // 2. add the HL7 iostream extensions xios _chan(chan); // And send the message in HL7 encoding rules. chan << hl7er << msg << flush; // READY! } void recv_it(const char *filename) { // declare the message ADT_A04msg msg; // Prepare a channel to receive // 1. use the named file fstream chan(filename, ios::in); // 2. add the HL7 iostream extensions xios _chan(chan); // And receive the message in HL7 encoding rules. chan >> hl7er >> msg; // Print our dummy data; // instead of casting each value to (const char*) before printing, // I extend the cout stream: xios _cout(cout); cout << hl7er; // THE DATA STARTS: cout << "SENDING APPLICATION : " << msg.MesHea.SenApp << endl; cout << "DATE/TIME OF MESSAGE: " << msg.MesHea.DateTimeOfMes << endl; cout << "MESSAGE TYPE : " << msg.MesHea.MesType.MesId << " - " << msg.MesHea.MesType.EventType << endl; cout << "CONTROL/PROC./VERS. : " << msg.MesHea.MesConTrolId << "/" << msg.MesHea.ProId << "/" << msg.MesHea.VerId << endl; cout << "EXTERNAL PATIENT ID : " << msg.PatIde.PatIdExtId.IdNum << endl; cout << "INTERNAL PATIENT ID : " << flush; // here comes an example of iteration over a repeatable field: for(repfield *i = &msg.PatIde.PatIdIntId; ! i->end(); i = i->next()) { CKtyp &id = i->first(); if(id.ispresent() && ! id.isnull()) cout << id.IdNum << " " << flush; } cout << endl; cout << "PATIENT NAME : " << msg.PatIde.PatName.Deg << " " << msg.PatIde.PatName.GivenName << " " << msg.PatIde.PatName.MidIniOrName << " " << msg.PatIde.PatName.Pre << " " << msg.PatIde.PatName.FamName << " " << msg.PatIde.PatName.Suf << endl; cout << "SEX : " << flush; // now we show how to use codes in switch() statements switch(msg.PatIde.Sex) { case SexCode::Fem: cout << "fe" << flush; case SexCode::Male: cout << "male" << flush; break; case SexCode::Other: cout << "a third sex?" << flush; break; case SexCode::Unk: cout << "who knows?" << flush; break; } cout << endl; // The NK1 segments: cout << "NEXT OF KIN" << endl; // here comes an example of iteration over a repeatable segment/group: for(repstruc *i = &msg.NextOfKin; ! i->end(); i = i->next()) { NK1seg &nk = i->first(); if(nk.ispresent()) { cout << " NAME : " << nk.Name.GivenName << " " << nk.Name.FamName << endl << " CITY : " << nk.Add.City << endl << " PHONE # : " << nk.PhoneNum << endl << " CONTACT ROLE: " << nk.ConTactRole.Text << endl << endl; } } } main(int argc, char *argv[]) { if(argc != 3) goto usage; else { if(strcmp(argv[1],"send") == 0) send_it(argv[2]); else if(strcmp(argv[1],"recv") == 0) recv_it(argv[2]); else goto usage; } return 0; usage: cerr << "usage: " << argv[0] << " send filename" << endl; cerr << " " << argv[0] << " recv filename" << endl; return 1; }