Esempio n. 1
0
/* 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);
}
Esempio n. 2
0
/* 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);
}