HL7 Message Manipulation Functions in C
This code is an implementation of functions for manipulating HL7 messages. It includes functions for counting segments and fields, deleting and inserting segments and fields, getting and setting values, and converting between string and HL7 message formats. The code uses a tree data structure to represent the hierarchical structure of HL7 messages. The functions traverse the tree to perform the desired operations. The code also includes helper functions for concatenating strings and freeing memory. Overall, the code provides a useful toolkit for working with HL7 messages.
#include 'hl7.h'
#include <string.h>
char *
concat(char *string1, char *string2){
int length1, length2;
length2 = strlen(string2);
if (length2==0)
return string1;
length1 = strlen(string1);
if (string1 = (char *) realloc(string1, length1 + length2 +1)){
strncpy(&string1[length1], string2, length2);
string1[length1 + length2] = '\000';
return string1;
} else {
exit(1);
}
}
char *
strset (char *string)
{
char *pointer_to_string;
if (pointer_to_string = (char *) malloc (strlen (string)+1))
{
strcpy (pointer_to_string, string);
return (pointer_to_string);
}
else
{
/* die */
exit (1);
}
} /* end strset */
void hl7count (struct hl7_part_t *message, char *seg_location) {
} /* end hl7count */
void hl7rawcount (struct hl7_part_t *message, char *location) {
} /* end hl7rawcount */
void hl7delete (struct hl7_part_t *message, char *seg_location, char *string){
} /* end hl7delete */
void hl7insert (struct hl7_part_t *message, char *seg_location, char *string){
} /* end hl7insert */
void hl7rawdelete (struct hl7_part_t *message, struct hl7_location_t *location){
} /* end hl7rawdelete */
void hl7rawinsert (struct hl7_part_t *message, struct hl7_location_t *location, char *string){
} /* end hl7rawinsert */
void hl7set (struct hl7_part_t *message, char *seg_location, char *string){
} /* end hl7set */
void hl7get (struct hl7_part_t *message, char *seg_location){
} /* end hl7get */
void hl7rawset (struct hl7_part_t *message, struct hl7_location_t *location, char *string){
/* this one is a little harder, you have to traverse the string to the given
location, creating missing nodes as you go and then set the final portion
to the given string. */
} /* end hl7rawset */
char *hl7rawget (struct hl7_part_t *message, struct hl7_location_t *given_location){
struct hl7_part_t *hl7_part;
struct hl7_location_t *location;
char *msg_string; /* points to the message string */
char separators[8]; /* list of separators in proper order */
int i,
depth = 0;
/* initialize the pointer to the string that is returning the value */
msg_string = strset('');
/* Traverse the tree */
hl7_part = message->lower;
for (location = given_location ; location->next ; location=location->next){
/*next for the count */
for(i=location->count; i ; i--) {
if(hl7_part->next){
hl7_part=hl7_part->next;
} else {
return msg_string;
}
}
/* lower each level */
if(hl7_part->lower){
depth++;
hl7_part=hl7_part->lower;
} else {
/*
return msg_string;
*/
}
}
/* this needs to be a subroutine because we just did it twice */
/* build the seperators string */
separators[0] = '\n';
separators[1] = '\n';
separators[2] = '\r';
separators[3] = message->lower->lower->lower->next->lower->lower->lower->data[0];
separators[4] = message->lower->lower->lower->next->next->lower->lower->lower->data[3];
separators[5] = message->lower->lower->lower->next->next->lower->lower->lower->data[0];
separators[6] = message->lower->lower->lower->next->next->lower->lower->lower->data[1];
separators[7] = '\000';
printf('The depth is >%d<
', depth);
hl7printlocation(given_location);
/* Call the join function, */
msg_string=join(hl7_part, msg_string, &separators[depth+1]);
/* return the string that we found */
return msg_string;
} /* end hl7rawget */
char *join (struct hl7_part_t *hl7_part, char *msg_string, char *separators){
char current_separator[2];
if (separators==''\000'')
exit(1);
current_separator[0] = separators[0];
current_separator[1] = '\000';
if (hl7_part->data){
msg_string = concat(msg_string, hl7_part->data);
}
if (hl7_part->lower){
msg_string = join(hl7_part->lower, msg_string, &separators[1]);
}
if (hl7_part->next){
msg_string = concat(msg_string, current_separator);
msg_string = join(hl7_part->next, msg_string, separators);
}
return msg_string;
} /* end join */
char *hl72str (struct hl7_part_t *message){
char separators[8]; /* list of separators in proper order */
char *msg_string; /* points to the message string */
int length;
msg_string=strset('');
/* build the seperators string */
separators[0] = '\n';
separators[1] = '\n';
separators[2] = '\r';
separators[3] = message->lower->lower->lower->next->lower->lower->lower->data[0];
separators[4] = message->lower->lower->lower->next->next->lower->lower->lower->data[3];
separators[5] = message->lower->lower->lower->next->next->lower->lower->lower->data[0];
separators[6] = message->lower->lower->lower->next->next->lower->lower->lower->data[1];
separators[7] = '\000';
/* turn the message into a string */
msg_string = join(message, msg_string, separators);
/* fix the field separator field */
length=strlen(msg_string);
strncpy(&msg_string[4], &msg_string[6], length-5);
if (!(msg_string=(char *) realloc(msg_string, length-2))){
/* not enough memory, die */
exit(1);
}
return msg_string;
} /* end hl72str */
struct hl7_part_t *split (struct hl7_part_t *hl7_part, char *separators)
{
struct hl7_part_t *head, /* begining of the data list */
*current; /* tail of the data list */
int begin = 0, /* start of the current string */
scan = 0; /* current position in string */
/* if the list of separators is empty, we have reached a leaf, return null */
if (separators[0] == '\000'){
return (struct hl7_part_t *) 0;
}
/* setup structure for current level of operations */
if (!(current = head = (struct hl7_part_t *) malloc (sizeof (struct hl7_part_t))))
exit (1);
/* initialize the structure to some sane values */
current->data = (char *) 0;
current->next = (struct hl7_part_t *) 0;
current->lower = (struct hl7_part_t *) 0;
/* start looking thru the string for current seperator */
for (; hl7_part->data[scan]; scan++)
{
/* when we find the current seperator */
if (hl7_part->data[scan] == separators[0])
{
/* replace the seperator with a NULL */
hl7_part->data[scan] = '\000';
/* set a copy of the string that we found to current data element */
current->data = strset (&hl7_part->data[begin]);
/* split the string into substrings */
/* this is a little tricky */
/* I send the seperator string starting with its _second_ element */
current->lower = split (current, &separators[1]);
/* setup for the next string that we find */
if (!(current->next = (struct hl7_part_t *) malloc (sizeof (struct hl7_part_t))))
exit (1);
/* move the current pointer to the node that we just created */
current = current->next;
/* initialize the data to some sane values */
current->data = (char *) 0;
current->next = (struct hl7_part_t *) 0;
current->lower = (struct hl7_part_t *) 0;
/* set the begining of the string to follow the found string */
begin = scan + 1;
}
}
/* We reached the end of the string without finding (another) seperator.
But there is still a string that we need to take care of. */
/* put a copy of the string in the current data element */
current->data = strset (&hl7_part->data[begin]);
/* split the data element into substrings */
/* this is a little tricky */
/* I send the seperator string starting with its _second_ element */
current->lower = split (current, &separators[1]);
/* get rid of the string from the parent, we stored it safely at this level */
free (hl7_part->data);
/* set the parent data element to the null pointer so that it won't be
pointing to the place where the string used to be. */
hl7_part->data = (char *) 0;
/* return the list of substrings found to the parent. */
return head;
} /* end split */
struct hl7_part_t *str2hl7 (char *message_string)
{
struct hl7_part_t *message; /* Message structure that we are working on */
char delimiters[6], /* list of delimiters from the message */
separators[7], /* list of separators in proper order */
temp[6]; /* used to set the correct delimiters
in the final message structure */
/* probably should check that the message begins with MSH
and is longer than a minimum length... */
if (!(message = (struct hl7_part_t *) malloc (sizeof (struct hl7_part_t)))){
/* If we don't have enough memory, quit.
/* This is kind of abrupt and needs to be more elegant. */
exit (1);
}
/* put some sane values into the clean new structure */
message->lower=(struct hl7_part_t *)0;
message->next=(struct hl7_part_t *)0;
/* put a copy of hl7_string into the proper place in the message structure */
message->data = strset (message_string);
/* copy the hl7 delimiters to a string to hold them for processing */
strncpy (delimiters, &message->data[3], 5);
/* close the end of the string with a terminator so that we don't dump core */
delimiters[5] = '\000';
/* reorder the delimiters into the proper order for seperation */
separators[0] = '\n';
separators[1] = '\r';
separators[2] = delimiters[0];
separators[3] = delimiters[1];
separators[4] = delimiters[2];
separators[5] = delimiters[4];
separators[6] = '\000';
/* remove the delimiters from the message so that we don't get confused */
message->data[4] = 'X';
message->data[5] = '|';
message->data[6] = 'Z';
message->data[7] = 'K';
/* recursively call split to split the message on each seperator */
message->lower = split (message, separators);
free (message->lower->lower->lower->next->lower->lower->lower->data);
strncpy (temp, &delimiters[0], 1);
temp[1] = '\000';
message->lower->lower->lower->next->lower->lower->lower->data = strset (temp);
free (message->lower->lower->lower->next->next->lower->lower->lower->data);
strncpy (temp, &delimiters[1], 4);
temp[4] = '\000';
message->lower->lower->lower->next->next->lower->lower->lower->data = strset (temp);
/* we are done, return the results */
return message;
} /* end str2hl7 */
void hl7printlocation(struct hl7_location_t *location){
for(; location->next; location=location->next) {
printf('%d', location->count);
if (location->next->next){
printf('.');
}
}
} /* end hl7printlocation */
void hl7rawprint(struct hl7_part_t *hl7_part, struct hl7_location_t *location, struct hl7_location_t * current, int state)
{
/* recursively traverse the tree, keep track of where you are and print out the data */
if (!(current->next)){
if (!(current->next = (struct hl7_location_t *) malloc(sizeof(struct hl7_location_t)))){
exit (1);
}
current->next->next = (struct hl7_location_t *) 0;
current->next->count = 0;
}
if ((hl7_part->data) &&(strlen(hl7_part->data))){
hl7printlocation(location);
printf(' >%s<
', hl7_part->data);
}
if (hl7_part->lower){
hl7rawprint(hl7_part->lower, location, current->next, LOWER);
}
if (hl7_part->next){
current->count++;
hl7rawprint(hl7_part->next, location, current, NEXT);
}
if (state==LOWER)
current->count=0;
return;
} /* end hl7rawprint */
void hl7print (struct hl7_part_t *message)
{
struct hl7_location_t *location;
/* setup some data structures and call the real function */
if (!(location = (struct hl7_location_t *) malloc(sizeof(struct hl7_location_t)))){
exit (1);
}
location->count = 0;
location->next = (struct hl7_location_t *) 0;
hl7rawprint(message->lower, location, location, BEGIN);
hl7freelocation(location);
/* need to free the memory that was allocated for the location! */
} /* end hl7print */
void hl7freelocation(struct hl7_location_t *location){
/* if we aren't at the end of the list, */
/* move to the next element in the list */
if(location->next)
hl7freelocation(location->next);
/* free the current element of the list */
free(location);
/* return to the previous element in the list */
return ;
} /* hl7freelocation */
void hl7free (struct hl7_part_t *hl7_part)
{
/* free data, if it is present */
if (hl7_part->data){
free(hl7_part->data);
}
/* look in each lower branch first, if present */
if (hl7_part->lower)
{
hl7free (hl7_part->lower);
}
/* then look in each next branch, if present */
if (hl7_part->next)
{
hl7free (hl7_part->next);
}
/* free the current node */
free(hl7_part);
/* return to previous node */
return;
} /* end hl7free */
原文地址: https://www.cveoy.top/t/topic/nocp 著作权归作者所有。请勿转载和采集!