/* Name: adu_readmap - Reads and processes a coercion map table. ** ** Description: ** This routine reads a compiled coercion map table and ** initializes the in memory table structures for the map ** table. ** ** Input: ** chset: character set to read from. ** ** Output: ** E_DB_OK if the maptable is opened and initialized. ** E_DB_ERROR if it fails. ** ** History: ** 23-Jan-2004 (gupsh01) ** Created. ** 18-Feb-2004 (gupsh01) ** Added handling of CM_DEFAULTFILE_LOC, so that ingbuld ** at install time when no characterset info is avaliable ** reads the default mapping file from $II_CONFIG location. ** 22-Oct-2004 (gupsh01) ** Fixed for correctly reading the mapping files. ** 11-May-2009 (kschendel) b122041 ** Compiler warning fixes. ** */ DB_STATUS adu_readmap(char *charset) { CL_ERR_DESC syserr; char *buf = NULL; char *bufptr = NULL; i4 bytes_read = 0; DB_STATUS stat = OK; ADU_MAP_HEADER *header; ADU_MAP_ASSIGNMENT *assignments; char *aptr; ADU_MAP_VALIDITY *validities; char *vptr; i4 buf_rem; i4 val_rem; i4 assn_rem; if (CMopen_col(charset, &syserr, CM_UCHARMAPS_LOC) != OK) { /* If we are opening the default file then check and return ** an ERROR if we are unable to open the file */ if (STbcompare (charset, 0, "default", 0, 1) == 0) { if (CMopen_col(charset, &syserr, CM_DEFAULTFILE_LOC) != OK) return (FAIL); } else return (FAIL); } /* allocate memory for buffer */ buf = MEreqmem(0, COL_BLOCK, TRUE, &stat); if (buf == NULL || stat != OK) { CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } /* First file buffer has header information. */ stat = CMread_col(buf, &syserr); if (stat != OK) { MEfree((char *)buf); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } bytes_read = COL_BLOCK; header = (ADU_MAP_HEADER *) MEreqmem(0, sizeof(ADU_MAP_HEADER), TRUE, &stat); if (stat != OK) { MEfree((char *)buf); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return FAIL; } MEcopy (buf, sizeof(ADU_MAP_HEADER), header); bufptr = buf + sizeof(ADU_MAP_HEADER); bufptr = ME_ALIGN_MACRO (bufptr, sizeof(PTR)); if (header->validity_size > 0) { validities = (ADU_MAP_VALIDITY *)MEreqmem(0, (u_i4) header->validity_size, FALSE, &stat); if (validities == NULL || stat != OK) { MEfree((char *)buf); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return FAIL; } vptr = (char *) validities; } else { /* ERROR: validity information is required */ CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } if (header->assignment_size > 0) { assignments = (ADU_MAP_ASSIGNMENT *)MEreqmem (0, (u_i4) header->assignment_size , FALSE, &stat); if (assignments == NULL || stat != OK) { MEfree((char *)buf); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return FAIL; } aptr = (char *) assignments; } else { /* ERROR: assignment information is required */ CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } buf_rem = COL_BLOCK - sizeof(ADU_MAP_HEADER); val_rem = header->validity_size; assn_rem = header->assignment_size; for ( ;(bytes_read < (header->validity_size + header->assignment_size + sizeof(ADU_MAP_HEADER))) || (assn_rem > 0); ) { if (val_rem > 0) { if (buf_rem >= val_rem) { /* Validation table was read completely */ MEcopy (bufptr, val_rem, vptr); bufptr += val_rem; bufptr = ME_ALIGN_MACRO (bufptr, sizeof(PTR)); buf_rem -= val_rem; val_rem = 0; if ((assn_rem > 0) && (buf_rem <= assn_rem)) { MEcopy (bufptr, buf_rem, aptr); bufptr = ME_ALIGN_MACRO (bufptr, sizeof(PTR)); bufptr += buf_rem; aptr +=buf_rem; assn_rem -= buf_rem; buf_rem = 0; } else { MEcopy (bufptr, assn_rem, aptr); bufptr += assn_rem; bufptr = ME_ALIGN_MACRO (bufptr, sizeof(PTR)); aptr +=assn_rem; buf_rem -= assn_rem; assn_rem = 0; } } else { /* read more validities before proceeding */ MEcopy (bufptr, buf_rem, vptr); bufptr = ME_ALIGN_MACRO (bufptr, sizeof(PTR)); vptr += buf_rem; val_rem -= buf_rem; buf_rem = 0 ; } } else if (assn_rem > 0) { if (buf_rem <= assn_rem) { MEcopy (bufptr, buf_rem, aptr); aptr += buf_rem; assn_rem -= buf_rem; buf_rem = 0; } else { MEcopy (bufptr, assn_rem, aptr); aptr += assn_rem; buf_rem -= assn_rem; assn_rem = 0; } } /* read next buffer if more data is needed to be read */ if (assn_rem > 0) { stat = CMread_col(buf, &syserr); if (stat != OK) { /* FIXME: either we are have got an error or we have ** found the end of the file in either case ** free the buf and exit. should report ** ERROR condition. */ break; } bufptr = buf; /* initialize bufptr */ bytes_read += COL_BLOCK; buf_rem = COL_BLOCK; } } /* check if we have read the whole file */ if (bytes_read < (header->validity_size + header->assignment_size + sizeof(ADU_MAP_HEADER))) { /* we had to exit for some unknown reason */ MEfree((char *)buf); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return FAIL; } /* done with the file so close it now */ if (CMclose_col(&syserr, CM_UCHARMAPS_LOC) != OK) { MEfree ((char *)buf); /* free the buffer */ return FAIL; } /* set up the pointers in the ADF memory ** from the information obtained from mapfile. */ stat = adu_initmap (header, validities, assignments); if (stat) return (E_DB_ERROR); if (header) MEfree ((char *)header); if (validities) MEfree ((char *)validities); if (assignments) MEfree ((char *)assignments); if (buf) MEfree ((char *)buf); return (E_DB_OK); }
/* Name: adu_getconverter - Obtains the name of converter mapping file ** to use for unicode coercion. ** Description: ** ** To obtain the mapping file to be used for carrying out unicode-local ** character conversion. The following mechanism is followed: ** ** 1. Check symbol table for user defined converter setting ** II_UNICODE_CONVERTER. If set then return this setting ** 2. If the variable is not set then ** 2.a Get the platform character set ** 2.b Read the aliasmaptbl file. ** 2.c Search the alias file for platform charset. ** 3. If still not found then find the II_CHARSETxx value ** for ingres installation and search the alias file for ** this value. ** 4. If none of these attempts succeed then return default ** with a warning to the errorlog if this happens ** ** Input: ** converter - Place holder for the output string, ** It is assumed that the area is at least MAX_LOC ** chars in size. ** Output: ** converter - Pointer to string where the output ** converter name is stored. ** History: ** ** 22-jan-2004 (gupsh01) ** Added. ** 14-Jun-2004 (schka24) ** Safe charset name handling. */ STATUS adu_getconverter( char *converter) { STATUS stat; char *tptr; char *env = 0; char chset[CM_MAXATTRNAME+1]; char pcs[CM_MAXLOCALE+1]; /* platform character set */ char norm_pcs[CM_MAXLOCALE+1]; CL_ERR_DESC syserr; char *alias_buffer = NULL; char *bufptr = NULL; char *buf = NULL; ADU_ALIAS_MAPPING *aliasmapping; ADU_ALIAS_DATA *aliasdata; char *datasize; SIZE_TYPE filesize = 0; SIZE_TYPE sizemap = 0; SIZE_TYPE sizedata = 0; i4 bytes_read; char *abufptr; i4 i = 0; i4 index = 0; /* STEP 1 */ NMgtAt(ERx("II_UNICODE_CONVERTER"), &env); if (env && *env) { STlcopy(env, converter, MAX_LOC-1); return OK; } /* STEP 2 */ stat = CM_getcharset(pcs); if (CMopen_col("aliasmaptbl", &syserr, CM_UCHARMAPS_LOC) != OK) { /* return an ERROR if we are unable to open the file */ return FAIL; } /* initialize buf to help read from the aliasmaptbl file */ buf = MEreqmem(0, COL_BLOCK, TRUE, &stat); if (buf == NULL || stat != OK) { CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } /* First file buffer has size information. */ stat = CMread_col(buf, &syserr); if (stat != OK) { MEfree((char *)buf); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } tptr = buf; bytes_read = COL_BLOCK; /* filesize is the first entry of the map file */ filesize = *(SIZE_TYPE *) buf; tptr += sizeof(SIZE_TYPE); tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR)); /* allocate working space for the data */ alias_buffer = (char *)MEreqmem(0, filesize, TRUE, &stat); if (alias_buffer == NULL || stat != OK) { CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } abufptr = alias_buffer; MEcopy (buf, COL_BLOCK, abufptr); abufptr += COL_BLOCK; /* Read the file till it is read completely */ for ( ;bytes_read < filesize;) { stat = CMread_col(buf, &syserr); if (stat != OK) { MEfree((char *)buf); MEfree((char *)alias_buffer); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } bytes_read += COL_BLOCK; MEcopy (buf, COL_BLOCK, abufptr); abufptr += COL_BLOCK; } if (bytes_read < filesize) { /* we had to exit for some unknown reason */ MEfree((char *)buf); MEfree((char *)alias_buffer); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } tptr = alias_buffer; tptr += sizeof(SIZE_TYPE); tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR)); /* Read the size of the MappingArray nodes */ sizemap = *(SIZE_TYPE *) tptr; tptr += sizeof(SIZE_TYPE); tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR)); /* initialize buffer for ADU_ALIAS_MAPPING buffer */ aliasmapping = (ADU_ALIAS_MAPPING *) MEreqmem(0, sizemap, TRUE, &stat); if (aliasmapping == NULL) { MEfree((char *)buf); MEfree((char *)alias_buffer); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } /* Copy data for ADU_ALIAS_MAPPING array */ MEcopy(tptr, sizemap, aliasmapping); tptr += sizemap; tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR)); /* Get size for the aliasdata */ sizedata = *(SIZE_TYPE *) tptr; tptr += sizeof(SIZE_TYPE); tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR)); /* Initialize buffer for ADU_ALIAS_MAPPING buffer */ aliasdata = (ADU_ALIAS_DATA *) MEreqmem(0, sizedata, TRUE, &stat); if (aliasdata == NULL) { MEfree((char *)buf); MEfree((char *)alias_buffer); MEfree((char *)aliasmapping); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } /* Copy the ADU_ALIAS_DATA array */ MEcopy(tptr, sizedata, aliasdata); tptr += sizedata; tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR)); /* Close the "aliasmaptbl" file */ CMclose_col(&syserr, CM_UCHARMAPS_LOC); /* Normalize pcs */ adu_csnormalize (pcs, STlength(pcs), norm_pcs); /* Retrieve the pcs value */ for (i=0; i < sizedata/sizeof(ADU_ALIAS_DATA); i++) { if ((STcompare (aliasdata[i].aliasNameNorm, norm_pcs)) == 0) { index = aliasdata[i].aliasMapId; /* found */ STcopy (aliasmapping[index].mapping_id, converter); /* cleanup */ MEfree((char *)buf); MEfree((char *)alias_buffer); MEfree((char *)aliasmapping); MEfree((char *)aliasdata); return (OK); } } /* STEP 3 */ /* Obtain Ingres characterset */ STcopy("default", converter); CMget_charset_name(&chset[0]); if (STcasecmp(chset, "UTF8") != 0) { /* search maptable for env */ for (i=0; i < sizedata/sizeof(ADU_ALIAS_DATA); i++) { if ((STcompare (aliasdata[i].aliasNameNorm, norm_pcs)) == 0) { index = aliasdata[i].aliasMapId; /* found */ STcopy (aliasmapping[index].mapping_id, converter); break; } } } /* cleanup */ MEfree((char *)buf); MEfree((char *)alias_buffer); MEfree((char *)aliasmapping); MEfree((char *)aliasdata); /* FIXME warning or error if still "default" ? */ return (OK); }