HL7 消息解析库 - C语言实现
#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 */
/* 从消息中删除分隔符,以免混淆 */
/* 该代码段的含义是将HL7消息中的分隔符替换为其他字符,以避免在后续处理过程中混淆分隔符和消息内容。
在HL7消息中,分隔符用于分隔不同的字段、组件和子组件,因此在处理消息时需要保证分隔符的正确解析和使用。
该代码段中的操作可能是为了避免在具体的处理过程中出现分隔符被错误解析的问题。*/
代码中使用 strset() 函数将字符串复制到新的内存空间中,以确保数据不会被修改。在 str2hl7() 函数中,将 HL7 消息中的分隔符替换为其他字符,目的是为了在后续处理过程中避免混淆分隔符和消息内容。
该库提供了一套完整的 HL7 消息解析和操作函数,可以帮助开发者更方便地处理 HL7 消息。
原文地址: https://www.cveoy.top/t/topic/npeF 著作权归作者所有。请勿转载和采集!