#include "z3950parser.h" void Z_AttributeList_parse(bend_search_rr *rr, Z_AttributeList *Z, text_t &GSQuery) { /* struct Z_AttributeList { int num_attributes; Z_AttributeElement **attributes; }; */ /* struct Z_AttributeElement { Z_AttributeSetId *attributeSet; // OPT int *attributeType; int which; union { int *numeric; Z_ComplexAttribute *complex; #define Z_AttributeValue_numeric 1 #define Z_AttributeValue_complex 2 } value; }; */ } void Z_Term_parse(bend_search_rr *rr, Z_Term *Z, text_t &GSQuery) { /* struct Z_Term { int which; union { Odr_oct *general; int *numeric; Z_InternationalString *characterString; Odr_oid *oid; char *dateTime; Z_External *external; Z_IntUnit *integerAndUnit; Odr_null *null; #define Z_Term_general 1 #define Z_Term_numeric 2 #define Z_Term_characterString 3 #define Z_Term_oid 4 #define Z_Term_dateTime 5 #define Z_Term_external 6 #define Z_Term_integerAndUnit 7 #define Z_Term_null 8 } u; }; */ char *term; switch(Z->which){ case Z_Term_general: { // must copy no more than len bytes from buf, or else previous query terms may be included int buflen = Z->u.general->len; term = new char[buflen+1]; memset(term, '\0', buflen+1); strncpy(term, (const char*)(Z->u.general->buf), buflen); GSQuery += term; break; } case Z_Term_numeric: GSQuery += *(Z->u.numeric); // int* break; case Z_Term_characterString: GSQuery += Z->u.characterString; // what is this type? break; case Z_Term_oid: GSQuery += *(Z->u.oid); // int* break; case Z_Term_dateTime: GSQuery += Z->u.dateTime; // char* break; case Z_Term_external: GSQuery += " "; // ignore this for now break; case Z_Term_integerAndUnit: GSQuery += " "; // ignore this for now break; case Z_Term_null: GSQuery += " "; // void break; default: cerr << "Error in Z_Term_parse" << endl; exit(1); } } void Z_ProximityOperator_parse(bend_search_rr *rr, Z_ProximityOperator *Z, text_t &GSQuery) { /* struct Z_ProximityOperator { bool_t *exclusion; // OPT int *distance; bool_t *ordered; #define Z_ProximityOperator_Prox_lessThan 1 #define Z_ProximityOperator_Prox_lessThanOrEqual 2 #define Z_ProximityOperator_Prox_equal 3 #define Z_ProximityOperator_Prox_greaterThanOrEqual 4 #define Z_ProximityOperator_Prox_greaterThan 5 #define Z_ProximityOperator_Prox_notEqual 6 int *relationType; int which; union { Z_ProxUnit *known; int *zprivate; #define Z_ProximityOperator_known 1 #define Z_ProximityOperator_private 2 } u; }; #define Z_ProxUnit_character 1 #define Z_ProxUnit_word 2 #define Z_ProxUnit_sentence 3 #define Z_ProxUnit_paragraph 4 #define Z_ProxUnit_section 5 #define Z_ProxUnit_chapter 6 #define Z_ProxUnit_document 7 #define Z_ProxUnit_element 8 #define Z_ProxUnit_subelement 9 #define Z_ProxUnit_elementType 10 #define Z_ProxUnit_byte 11 */ // Greenstone (actually mgpp) supports proximity, but only // to n words either side. // A more complete implementation of proximity can be added // by parsing the other fields in Z_ProximityOperator. // Note: this only works properly with MGPP collections GSQuery += " NEAR"; GSQuery += *(Z->distance); GSQuery += " "; } void Z_Operator_parse(bend_search_rr *rr, Z_Operator *Z, text_t &GSQuery) { /* struct Z_Operator { int which; union { Odr_null *and; Odr_null *or; Odr_null *and_not; Z_ProximityOperator *prox; #define Z_Operator_and 1 #define Z_Operator_or 2 #define Z_Operator_and_not 3 #define Z_Operator_prox 4 } u; }; */ switch(Z->which){ case Z_Operator_and: GSQuery += " & "; break; case Z_Operator_or: GSQuery += " | "; break; case Z_Operator_and_not: GSQuery += " ! "; break; case Z_Operator_prox: Z_ProximityOperator_parse(rr, Z->u.prox, GSQuery); break; default: cerr << "Error in Z_Operator_parse" << endl; exit(1); } } void Z_Operand_parse(bend_search_rr *rr, Z_Operand *Z, text_t &GSQuery) { /* struct Z_Operand { int which; union { Z_AttributesPlusTerm *attributesPlusTerm; Z_ResultSetId *resultSetId; Z_ResultSetPlusAttributes *resultAttr; #define Z_Operand_APT 1 #define Z_Operand_resultSetId 2 #define Z_Operand_resultAttr 3 } u; }; */ switch(Z->which) { case Z_Operand_APT: { /* struct Z_AttributesPlusTerm { Z_AttributeList *attributes; Z_Term *term; }; */ /* struct Z_AttributeList { int num_attributes; Z_AttributeElement **attributes; }; */ /* struct Z_AttributeElement { Z_AttributeSetId *attributeSet; // OPT int *attributeType; int which; union { int *numeric; Z_ComplexAttribute *complex; #define Z_AttributeValue_numeric 1 #define Z_AttributeValue_complex 2 } value; }; */ char *term; if (Z->u.attributesPlusTerm->attributes->num_attributes > 0) { int Bib1_relation = *(Z->u.attributesPlusTerm->attributes->attributes[0]->attributeType); int Bib1_use = *(Z->u.attributesPlusTerm->attributes->attributes[0]->value.numeric); // if use value is 1010 ("Body of text"), is not a fielded search if (Bib1_use == 1010) { // if relation value is 6 ("not"), add a "not" to GSQuery if (Bib1_relation == 6) { GSQuery += "! "; } Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery); } // for other use values, is a fielded search else { text_t Short; // only add [ ]: if the index exists in the collection, // note: only the index names in the first collection of a // multi-collection search are used at the moment if ((Collection_map[rr->basenames[0]]).getFieldArg(Bib1_use, Short)) { GSQuery += "["; cerr << "Supressing square brackets for the moment!\n"; Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery); GSQuery += "]"; GSQuery += ":"; GSQuery += Short; } // if it doesn't, add it as an unfielded search term else { cerr << "[" << rr->basenames[0] << "]: failed to find index" << endl; Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery); } } } else { Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery); } break; } case Z_Operand_resultSetId: { GSQuery += "("; GSQuery += Resultsets[Z->u.resultSetId]; GSQuery += ")"; break; } case Z_Operand_resultAttr: GSQuery += " "; // ignore this for now break; default: cerr << "Error in Z_Operand_parse" << endl; exit(1); } } void Z_RPNStructure_parse(bend_search_rr *rr, Z_RPNStructure *Z, text_t &GSQuery) { /* struct Z_RPNStructure { int which; union { Z_Operand *simple; Z_Complex *complex; #define Z_RPNStructure_simple 1 #define Z_RPNStructure_complex 2 } u; }; */ switch(Z->which){ case Z_RPNStructure_simple: Z_Operand_parse(rr, Z->u.simple, GSQuery); break; case Z_RPNStructure_complex: GSQuery += "("; Z_RPNStructure_parse(rr, Z->u.complex->s1, GSQuery); Z_Operator_parse(rr, Z->u.complex->roperator, GSQuery); Z_RPNStructure_parse(rr, Z->u.complex->s2, GSQuery); GSQuery += ")"; break; default: cerr << "Error in Z_RPNStructure_parse" << endl; exit(1); } } text_t ZQueryToGSQuery(bend_search_rr *rr) { text_t GSQuery; switch(rr->query->which){ case Z_Query_type_0: cerr << "querytype = 0" << endl; // this is a void*, pretend it's a Greenstone-type query GSQuery += (char*)(rr->query->u.type_0); break; case Z_Query_type_1: { cerr << "querytype = 1" << endl; /* struct Z_RPNQuery { Z_AttributeSetId *attributeSetId; Z_RPNStructure *RPNStructure; }; */ // parse attributeSetId cerr << "attributeSetId = "; int c, d = 0; do { c = rr->query->u.type_1->attributeSetId[d]; cerr << c; d++; } while (c >= 0); cerr << endl; Z_RPNStructure_parse(rr, rr->query->u.type_1->RPNStructure, GSQuery); break; } case Z_Query_type_2: { cerr << "querytype = 2" << endl; // this is just a buf (unsigned char*), pretend it's a Greenstone-type query GSQuery += (char*)(rr->query->u.type_2->buf); break; } case Z_Query_type_100: { cerr << "querytype = 100" << endl; // this is just a buf (unsigned char*), pretend it's a Greenstone-type query GSQuery += (char*)(rr->query->u.type_100->buf); break; } case Z_Query_type_101: { cerr << "querytype = 101" << endl; // check: is this really the same as a type 1 query? Z_RPNStructure_parse(rr, rr->query->u.type_101->RPNStructure, GSQuery); break; } case Z_Query_type_102: { cerr << "querytype = 102" << endl; // this is just a buf (unsigned char*), pretend it's a Greenstone-type query GSQuery += (char*)(rr->query->u.type_102->buf); break; } default: { cerr << "Error in ZQueryToGSQuery" << endl; exit(1); } } // override GSQuery (test code) //GSQuery = "[the]:TX"; cerr << "GSQuery = `" << GSQuery << "'" << endl; return GSQuery; }