/************************************************************************* 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. */ /************************************************************************** EXSBFUNC.C *************************************************************************** This example shows how to replace the byte 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: Unmappable byte 0x81 is converted to the unicode sequence "{81}". The Scan/Parse functions will convert byte string "{2620}" to the single unicode character 0x2620. **************************************************************************/ #include <nunicode.h> #include <nwlocale.h> #include <stdio.h> #include <assert.h> static nint N_API MyNoMapByteFunc( /* My unmappable byte handler */ pCONVERT convert, /* Converter handle */ punicode output, /* Pointer to current output position */ nuint outputLeft, /* Space left in output buffer */ pnuint outputUsed, /* Space used in output buffer */ pnuint8 badInput, /* Pointer to unmappable bytes */ nuint badInputSize); /* Size of unmappable input */ static pnuint8 N_API MyScanByteFunc( /* My byte scanner function */ pCONVERT convert, /* Converter handle */ pnuint8 in, /* Input to be scanned */ nint scanMax); static nint N_API MyParseByteFunc( /* My byte parser function */ pCONVERT convert, /* Converter handle */ punicode output, /* Buffer for Unicode output */ nuint outputleft, /* Space left in output buf, excl null */ pnuint outputUsed, /* Space used in output buffer */ pnuint8 input, /* Buffer containing byte input */ pnuint inputUsed); /* Number of bytes of input used */ void main(void) { pCONVERT pconv; nint icode; nuint actualLen; nuint8 byteIn1[5] = { 'a', 'b', 'c', 0x81, 0 }; /* Test string */ nuint8 byteIn2[] = "xyz{2620}"; unicode uniOut[80]; /* Load a byte/uni converter for the code page 1252, which contains some unmappable bytes. Error checking not shown. */ icode = NWUXLoadByteUnicodeConverter(1252, &pconv); icode = NWUXSetByteFunctions(pconv, MyNoMapByteFunc, MyScanByteFunc, MyParseByteFunc); if (icode) printf("NWUXSetByteFunctions returned error 0x%04X\n",icode); /* Set the NoMapByte action to call our handler. Leave the NoMapUni action unchanged. The default ScanByte action already calls the handler so we don't need to call NWUXScanAction. */ icode = NWUXSetNoMapAction(pconv, NWU_CALL_HANDLER, NWU_UNCHANGED_ACTION); /* This conversion uses our NoMap handler to produce the unicode string "abc{81}". */ icode = NWUXByteToUnicode(pconv, uniOut, 80, byteIn1, &actualLen); assert( icode == 0 && uniOut[3] == '{' && actualLen == 7); /* This conversion uses our Byte/Parse functions to produce the unicode string { 'x', 'y', 'z', 0x2620, 0 } */ icode = NWUXByteToUnicode(pconv, uniOut, 80, byteIn2, &actualLen); assert( icode == 0 && uniOut[3] == 0x2620 && actualLen == 4); NWUXUnloadConverter(pconv); } /*----------------------------------------------------------------------*/ /* User-defined unmappable byte handler. The converter calls this routine when an unmappable byte is encountered during byte-to-uni conversion. This example converts an unmappable byte to a 4 character unicode sequence "{nn}". The amount of output generated by a single call to this function should not exceed 256 characters. */ static nint N_API MyNoMapByteFunc( /* My unmappable byte handler */ pCONVERT convert, /* Converter handle */ punicode output, /* Pointer to current output position */ nuint outputLeft, /* Space left in output buffer */ pnuint outputUsed, /* Space used in output buffer */ pnuint8 badInput, /* Pointer to unmappable bytes */ nuint badInputSize) /* Size 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 four Unicodes each bad byte. */ *outputUsed = badInputSize * 4; /* Process each bad character separately. Convert to "{nn}" */ for ( i = 0 ; i < badInputSize ; i++ ) { *output++ = '{'; *output++ = ((badInput[i] & 0xF0) >> 4) + 0x0030; *output++ = (badInput[i] & 0x0F) + 0x0030; *output++ = '}'; } } else /* It won't fit. Don't write anything to output buffer. */ { *outputUsed = 0; ccode = NWU_BUFFER_FULL; } return (ccode); } /*----------------------------------------------------------------------*/ /* User-defined byte scan function. The converter calls this routine to scan an input byte string for special sequences. If one is found return a pointer to the start of the sequence. This example scans for the special byte sequence "{nnnn}". */ static pnuint8 N_API MyScanByteFunc(pCONVERT convert, pnuint8 in, nint scanMax) { /* scanMax is not used */ scanMax = scanMax; /* Look for {nnnn}, 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 (NWisxdigit(in[3])) /* Got 3rd hex digit? */ if (NWisxdigit(in[4])) /* Got 4th hex digit? */ if (in[5] == '}') /* Got closing '}' ? */ break; /* Match! */ in++; /* Try the next character */ } /* Did we exit because we hit the end of the string? */ if (*in == '\0') 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(nuint8 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 MyParseByteFunc( /* My byte parser function */ pCONVERT convert, /* Converter handle */ punicode output, /* Buffer for Unicode output */ nuint outputleft, /* Space left in output buf, excl null */ pnuint outputUsed, /* Space used in output buffer */ pnuint8 input, /* Buffer containing byte input */ pnuint inputUsed) /* Number of bytes of input used */ { if (outputleft) { *output = DigitValue(input[1]) * 0x1000 + DigitValue(input[2]) * 0x0100 + DigitValue(input[3]) * 0x0010 + DigitValue(input[4]); *outputUsed = 1; *inputUsed = 6; return (0); } else return(NWU_BUFFER_FULL); }