\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7<F<2PFAFZUP_xxnnx\F5\AF\B9\91\C8\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\DB\00CUZZxix‚\EB\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\C0\00\00b\00d\00\FF\C4\00\00\00\00\00\00\00\00\00\00\00\00\00\00\FF\C4\00\00\00\00\00\00\00\00\00\00\001A!Q\FF\C4\00\00\00\00\00\00\00\00\00\00\00\00\00\FF\C4\00\00\00\00\00\00\00\00\00\00!1AQ\FF\DA\00\00\00?\00\F6\00\00\00\00\00\00\00\00\00\00\A0\00\00\C5\CF\F8\E7Ó\FCjD~\B9^\AD\%\B3]\D8cs-\BBs,-\A0\00"\80\00%\B83rÏ^K~F\A4ea\00E\00\C6\EE=u\B1\9B\D1\00@\00r\BE8\F9:\FE5#.M\00\E7\CB\C9q\CBq\D6\F2\BE\B7\C7>\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7	\8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh
\00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€
\00$\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95
59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>C///</title>
</head>
/**************************************************************************
 * Â© 2016 and later: Unicode, Inc. and others.
 * License & terms of use: http://www.unicode.org/copyright.html
 **************************************************************************
 **************************************************************************
 * COPYRIGHT:
 * Copyright (c) 1999-2007, International Business Machines Corporation and
 * others. All Rights Reserved.
 **************************************************************************/

#include "unicode/utypes.h"
#include "unicode/ucnv.h"
#include "flagcb.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define DEBUG_TMI 0  /* set to 1 for Too Much Information (TMI) */

U_CAPI FromUFLAGContext* U_EXPORT2  flagCB_fromU_openContext()
{
    FromUFLAGContext *ctx;

    ctx = (FromUFLAGContext*) malloc(sizeof(FromUFLAGContext));

    ctx->subCallback = NULL;
    ctx->subContext  = NULL;
    ctx->flag        = false;

    return ctx;
}

U_CAPI void U_EXPORT2 flagCB_fromU(
                  const void *context,
                  UConverterFromUnicodeArgs *fromUArgs,
                  const UChar* codeUnits,
                  int32_t length,
                  UChar32 codePoint,
                  UConverterCallbackReason reason,
				  UErrorCode * err)
{
  /* First step - based on the reason code, take action */

  if(reason == UCNV_UNASSIGNED) { /* whatever set should be trapped here */
    ((FromUFLAGContext*)context)->flag = true;
  }

  if(reason == UCNV_CLONE) {
      /* The following is the recommended way to implement UCNV_CLONE
         in a callback. */
      UConverterFromUCallback   saveCallback;
      const void *saveContext;
      FromUFLAGContext *old, *cloned;
      UErrorCode subErr = U_ZERO_ERROR;

#if DEBUG_TMI
      printf("*** FLAGCB: cloning %p ***\n", context);
#endif
      old = (FromUFLAGContext*)context;
      cloned = flagCB_fromU_openContext();
      
      memcpy(cloned, old, sizeof(FromUFLAGContext));

#if DEBUG_TMI
      printf("%p: my subcb=%p:%p\n", old, old->subCallback, 
             old->subContext);
      printf("%p: cloned subcb=%p:%p\n", cloned, cloned->subCallback, 
             cloned->subContext);
#endif

      /* We need to get the sub CB to handle cloning, 
       * so we have to set up the following, temporarily:
       *
       *   - Set the callback+context to the sub of this (flag) cb
       *   - preserve the current cb+context, it could be anything
       *
       *   Before:
       *      CNV  ->   FLAG ->  subcb -> ...
       *
       *   After:
       *      CNV  ->   subcb -> ...
       *
       *    The chain from 'something' on is saved, and will be restored
       *   at the end of this block.
       *
       */
      
      ucnv_setFromUCallBack(fromUArgs->converter,
                            cloned->subCallback,
                            cloned->subContext,
                            &saveCallback,
                            &saveContext,
                            &subErr);
      
      if( cloned->subCallback != NULL ) {
          /* Now, call the sub callback if present */
          cloned->subCallback(cloned->subContext, fromUArgs, codeUnits,
                              length, codePoint, reason, err);
      }
      
      ucnv_setFromUCallBack(fromUArgs->converter,
                            saveCallback,  /* Us */
                            cloned,        /* new context */
                            &cloned->subCallback,  /* IMPORTANT! Accept any change in CB or context */
                            &cloned->subContext,
                            &subErr);

      if(U_FAILURE(subErr)) {
          *err = subErr;
      }
  }

  /* process other reasons here if need be */

  /* Always call the subCallback if present */
  if(((FromUFLAGContext*)context)->subCallback != NULL &&
      reason != UCNV_CLONE) {
      ((FromUFLAGContext*)context)->subCallback(  ((FromUFLAGContext*)context)->subContext,
                                                  fromUArgs,
                                                  codeUnits,
                                                  length,
                                                  codePoint,
                                                  reason,
                                                  err);
  }

  /* cleanup - free the memory AFTER calling the sub CB */
  if(reason == UCNV_CLOSE) {
      free((void*)context);
  }
}

/* Debugging callback, just outputs what happens */

/* Test safe clone callback */

static uint32_t    debugCB_nextSerial()
{
    static uint32_t n = 1;
    
    return (n++);
}

static void debugCB_print_log(debugCBContext *q, const char *name)
{
    if(q==NULL) {
        printf("debugCBontext: %s is NULL!!\n", name);
    } else {
        if(q->magic != 0xC0FFEE) {
            fprintf(stderr, "debugCBContext: %p:%d's magic is %x, supposed to be 0xC0FFEE\n",
                    q,q->serial, q->magic);
        }
        printf("debugCBContext %p:%d=%s - magic %x\n",
                    q, q->serial, name, q->magic);
    }
}

static debugCBContext *debugCB_clone(debugCBContext *ctx)
{
    debugCBContext *newCtx;
    newCtx = malloc(sizeof(debugCBContext));
    
    newCtx->serial = debugCB_nextSerial();
    newCtx->magic = 0xC0FFEE;

    newCtx->subCallback = ctx->subCallback;
    newCtx->subContext = ctx->subContext;
    
#if DEBUG_TMI
    printf("debugCB_clone: %p:%d -> new context %p:%d\n", ctx, ctx->serial, newCtx, newCtx->serial);
#endif
    
    return newCtx;
}

void debugCB_fromU(const void *context,
                   UConverterFromUnicodeArgs *fromUArgs,
                   const UChar* codeUnits,
                   int32_t length,
                   UChar32 codePoint,
                   UConverterCallbackReason reason,
                   UErrorCode * err)
{
    debugCBContext *ctx = (debugCBContext*)context;
    /*UConverterFromUCallback junkFrom;*/
    
#if DEBUG_TMI
    printf("debugCB_fromU: Context %p:%d called, reason %d on cnv %p [err=%s]\n", ctx, ctx->serial, reason, fromUArgs->converter, u_errorName(*err));
#endif

    if(ctx->magic != 0xC0FFEE) {
        fprintf(stderr, "debugCB_fromU: Context %p:%d magic is 0x%x should be 0xC0FFEE.\n", ctx,ctx->serial, ctx->magic);
        return;
    }

    if(reason == UCNV_CLONE) {
        /* see comments in above flagCB clone code */

        UConverterFromUCallback   saveCallback;
        const void *saveContext;
        debugCBContext *cloned;
        UErrorCode subErr = U_ZERO_ERROR;

        /* "recreate" it */
#if DEBUG_TMI
        printf("debugCB_fromU: cloning..\n");
#endif
        cloned = debugCB_clone(ctx);

        if(cloned == NULL) {
            fprintf(stderr, "debugCB_fromU: internal clone failed on %p\n", ctx);
            *err = U_MEMORY_ALLOCATION_ERROR;
            return;
        }

        ucnv_setFromUCallBack(fromUArgs->converter,
                              cloned->subCallback,
                              cloned->subContext,
                              &saveCallback,
                              &saveContext,
                              &subErr);
        
        if( cloned->subCallback != NULL) {
#if DEBUG_TMI
            printf("debugCB_fromU:%p calling subCB %p\n", ctx, cloned->subCallback);
#endif
            /* call subCB if present */
            cloned->subCallback(cloned->subContext, fromUArgs