/************************************************************************* Copyright (c) 1997 Novell, Inc. All Rights Reserved. With respect to this file, Novell hereby grants to Developer a royalty-free, non-exclusive license to include this sample code and derivative binaries in its product. Novell grants to Developer worldwide distribution rights to market, distribute or sell this sample code file and derivative binaries as a component of Developer's product(s). Novell shall have no obligations to Developer or Developer's customers with respect to this code. DISCLAIMER: Novell disclaims and excludes any and all express, implied, and statutory warranties, including, without limitation, warranties of good title, warranties against infringement, and the implied warranties of merchantibility and fitness for a particular purpose. Novell does not warrant that the software will satisfy customer's requirements or that the licensed works are without defect or error or that the operation of the software will be uninterrupted. Novell makes no warranties respecting any technical services or support tools provided under the agreement, and disclaims all other warranties, including the implied warranties of merchantability and fitness for a particular purpose. */ /************************************************************************** EXSUFUNC.C *************************************************************************** This example shows how to replace the unicode NoMap, Scan, and Parse functions with user-defined handlers. The handlers in this example are similar to the system default handlers, except they use curly braces instead of square brackets in the conversion. For example: The unmappable unicode character 0x2620 is converted to the byte sequence "{2620}". The Scan/Parse functions will convert unicode string "{81}" to the single byte 0x81. **************************************************************************/ #include <nunicode.h> #include <nwlocale.h> #include <stdio.h> #include <assert.h> #include <string.h> static nint N_API MyNoMapUniFunc( /* My unmappable uni handler */ pCONVERT convert, /* Converter handle */ pnuint8 output, /* Buffer for byte output */ nuint outputLeft, /* Space left in output buffer */ pnuint outputUsed, /* Space used in output buffer */ punicode badInput, /* Input buffer */ nuint badInputSize); /* Length of unmappable input */ static punicode N_API MyScanUniFunc( /* My uni scanner function */ pCONVERT convert, /* Converter handle */ punicode in, /* Input to be scanned */ nint scanMax); /* Maximum characters to scan */ static nint N_API MyParseUniFunc( /* My uni parser function */ pCONVERT convert, /* Converter handle */ pnuint8 output, /* Buffer for byte output */ nuint outputleft, /* Space left in output buf, excl null */ pnuint outputUsed, /* Space used in output buffer */ punicode input, /* Buffer containing unicode input */ pnuint inputUsed); /* Number of uni chars of input used */ void main(void) { pCONVERT pconv; nint icode; nuint actualLen; unicode uniIn1[5] = { 'a', 'b', 'c', 0x2620, 0 }; /* Test string */ unicode uniIn2[8] = { 'x', 'y', 'z', '{', '8', '1', '}', 0 }; nuint8 byteOut[80]; /* Load a byte/uni converter for the current codepage. Error checking not shown. */ icode = NWUXLoadByteUnicodeConverter(0, &pconv); icode = NWUXSetUniFunctions(pconv, MyNoMapUniFunc, MyScanUniFunc, MyParseUniFunc); if (icode) printf("NWUXSetUniFunctions returned error 0x%04X\n",icode); /* Set the ScanUni action to call our handler. Leave the ScanByte action unchanged. The default NoMapUni action already calls the handler so we don't need to call NWUXNoMapAction. */ icode = NWUXSetScanAction(pconv, NWU_UNCHANGED_ACTION, NWU_CALL_HANDLER); /* This conversion uses our NoMap handler to produce the byte string "abc{2620}". */ icode = NWUXUnicodeToByte(pconv, byteOut, 80, uniIn1, &actualLen); assert( icode == 0 && strcmp(byteOut,"abc{2620}") == 0 && actualLen == 9 ); /* This conversion uses our Byte/Parse functions to produce the byte string { 'x', 'y', 'z', 0x81, 0 } */ icode = NWUXUnicodeToByte(pconv, byteOut, 80, uniIn2, &actualLen); assert( icode == 0 && byteOut[3] == 0x81 && actualLen == 4); NWUXUnloadConverter(pconv); } /*----------------------------------------------------------------------*/ /* User-defined unmappable unicode handler. The converter calls this routine when an unmappable unicode character is encountered during uni-to-byte conversion. This example converts an unmappable unicode character to a 6 byte sequence "{nnnn}". The amount of output generated by a single call to this function should not exceed 256 characters. */ static nint N_API MyNoMapUniFunc( /* My unmappable uni handler */ pCONVERT convert, /* Converter handle */ pnuint8 output, /* Buffer for byte output */ nuint outputLeft, /* Space left in output buffer */ pnuint outputUsed, /* Space used in output buffer */ punicode badInput, /* Input buffer */ nuint badInputSize) /* Length of unmappable input */ { nint ccode = 0; /* Error code */ nuint i; /* Loop variable */ /* Is there enough room to write our output? */ if (outputLeft >= *outputUsed) { /* We will use six bytes for each bad Unicode character. */ *outputUsed = badInputSize * 6; /* Process each bad character separately. */ for ( i = 0 ; i < badInputSize ; i++ ) { *output++ = '{'; *output++ = ( (badInput[i] & 0xF000) >> 12) + 0x0030; *output++ = ( (badInput[i] & 0x0F00) >> 8) + 0x0030; *output++ = ( (badInput[i] & 0x00F0) >> 4) + 0x0030; *output++ = ( badInput[i] & 0x000F ) + 0x0030; *output++ = '}'; } } else /* It won't fit. Don't write anything to output. */ { ccode = NWU_BUFFER_FULL; *outputUsed = 0; } return (ccode); } /*----------------------------------------------------------------------*/ /* User-defined unicode scan function. The converter calls this routine to scan an input uni string for special sequences. If one is found return a pointer to the start of the sequence. This example scans for the special unicode sequence "{nn}". */ static punicode N_API MyScanUniFunc(pCONVERT convert, punicode in, nint scanMax) { /* scanMax is not used */ scanMax = scanMax; /* Look for {nn}, where n are hex digits */ while (*in) { if (in[0] == '{') /* Got opening '{' ? */ if (NWisxdigit(in[1])) /* Got 1st hex digit? */ if (NWisxdigit(in[2])) /* Got 2nd hex digit? */ if (in[3] == '}') /* Got closing '}' ? */ break; /* Match! */ in++; /* Try the next character */ } /* Did we exit because we hit the end of the string? */ if (*in == 0x0000) in = NULL; return (in); } /*----------------------------------------------------------------------*/ /* User-defined byte parse function. The converter calls this routine to process a special sequence previously found by the scan function. This example converts the special byte sequence "{nnnn}" into a single unicode character. The amount of output generated by a single call to this function should not exceed 256 characters. */ /* Utility routine used by the parse function. */ static nint DigitValue(unicode c) { nint value; /* Value of this hex digit */ if (c >= '0' && c <= '9') value = c - '0'; else value = c - 'A' + 10; return (value); } static nint N_API MyParseUniFunc( /* My uni parser function */ pCONVERT convert, /* Converter handle */ pnuint8 output, /* Buffer for byte output */ nuint outputleft, /* Space left in output buf, excl null */ pnuint outputUsed, /* Space used in output buffer */ punicode input, /* Buffer containing unicode input */ pnuint inputUsed) /* Number of uni chars of input used */ { if (outputleft) { *output = DigitValue(input[1]) * 0x0010 + DigitValue(input[2]); *outputUsed = 1; *inputUsed = 4; return (0); } else return(NWU_BUFFER_FULL); }