1/*
2******************************************************************************
3*
4*   Copyright (C) 2009-2010, International Business Machines
5*   Corporation and others.  All Rights Reserved.
6*
7******************************************************************************
8*
9*  FILE NAME : testplug.c
10*
11*   Date         Name        Description
12*   10/29/2009   srl          New.
13******************************************************************************
14*
15*
16* This file implements a number of example ICU plugins.
17*
18*/
19
20#include "unicode/icuplug.h"
21#include <stdio.h> /* for fprintf */
22#include <stdlib.h> /* for malloc */
23#include "udbgutil.h"
24#include "unicode/uclean.h"
25#include "cmemory.h"
26
27/**
28 * Prototypes
29 */
30#define DECLARE_PLUGIN(x) U_CAPI UPlugTokenReturn U_EXPORT2 x (UPlugData *data, UPlugReason reason, UErrorCode *status)
31
32DECLARE_PLUGIN(myPlugin);
33DECLARE_PLUGIN(myPluginLow);
34DECLARE_PLUGIN(myPluginFailQuery);
35DECLARE_PLUGIN(myPluginFailToken);
36DECLARE_PLUGIN(myPluginBad);
37DECLARE_PLUGIN(myPluginHigh);
38DECLARE_PLUGIN(debugMemoryPlugin);
39
40/**
41 * A simple, trivial plugin.
42 */
43
44U_CAPI
45UPlugTokenReturn U_EXPORT2 myPlugin (
46                  UPlugData *data,
47                  UPlugReason reason,
48                  UErrorCode *status) {
49	/* Just print this for debugging */
50    fprintf(stderr,"MyPlugin: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
51
52    if(reason==UPLUG_REASON_QUERY) {
53        uplug_setPlugName(data, "Just a Test High-Level Plugin"); /* This call is optional in response to UPLUG_REASON_QUERY, but is a good idea. */
54        uplug_setPlugLevel(data, UPLUG_LEVEL_HIGH); /* This call is Mandatory in response to UPLUG_REASON_QUERY */
55    }
56
57    return UPLUG_TOKEN; /* This must always be returned, to indicate that the entrypoint was actually a plugin. */
58}
59
60
61U_CAPI
62UPlugTokenReturn U_EXPORT2 myPluginLow (
63                  UPlugData *data,
64                  UPlugReason reason,
65                  UErrorCode *status) {
66    fprintf(stderr,"MyPluginLow: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
67
68    if(reason==UPLUG_REASON_QUERY) {
69        uplug_setPlugName(data, "Low Plugin");
70        uplug_setPlugLevel(data, UPLUG_LEVEL_LOW);
71    }
72
73    return UPLUG_TOKEN;
74}
75
76/**
77 * Doesn't respond to QUERY properly.
78 */
79U_CAPI
80UPlugTokenReturn U_EXPORT2 myPluginFailQuery (
81                  UPlugData *data,
82                  UPlugReason reason,
83                  UErrorCode *status) {
84    fprintf(stderr,"MyPluginFailQuery: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
85
86	/* Should respond to UPLUG_REASON_QUERY here. */
87
88    return UPLUG_TOKEN;
89}
90
91/**
92 * Doesn't return the proper token.
93 */
94U_CAPI
95UPlugTokenReturn U_EXPORT2 myPluginFailToken (
96                  UPlugData *data,
97                  UPlugReason reason,
98                  UErrorCode *status) {
99    fprintf(stderr,"MyPluginFailToken: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
100
101    if(reason==UPLUG_REASON_QUERY) {
102        uplug_setPlugName(data, "myPluginFailToken Plugin");
103        uplug_setPlugLevel(data, UPLUG_LEVEL_LOW);
104    }
105
106    return 0; /* Wrong. */
107}
108
109
110
111/**
112 * Says it's low, but isn't.
113 */
114U_CAPI
115UPlugTokenReturn U_EXPORT2 myPluginBad (
116                  UPlugData *data,
117                  UPlugReason reason,
118                  UErrorCode *status) {
119    fprintf(stderr,"MyPluginLow: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
120
121    if(reason==UPLUG_REASON_QUERY) {
122        uplug_setPlugName(data, "Bad Plugin");
123        uplug_setPlugLevel(data, UPLUG_LEVEL_LOW);
124    } else if(reason == UPLUG_REASON_LOAD) {
125        void *ctx = uprv_malloc(12345);
126
127        uplug_setContext(data, ctx);
128        fprintf(stderr,"I'm %p and I did a bad thing and malloced %p\n", (void*)data, (void*)ctx);
129    } else if(reason == UPLUG_REASON_UNLOAD) {
130        void * ctx = uplug_getContext(data);
131
132        uprv_free(ctx);
133    }
134
135
136    return UPLUG_TOKEN;
137}
138
139U_CAPI
140UPlugTokenReturn U_EXPORT2 myPluginHigh (
141                  UPlugData *data,
142                  UPlugReason reason,
143                  UErrorCode *status) {
144    fprintf(stderr,"MyPluginHigh: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
145
146    if(reason==UPLUG_REASON_QUERY) {
147        uplug_setPlugName(data, "High Plugin");
148        uplug_setPlugLevel(data, UPLUG_LEVEL_HIGH);
149    }
150
151    return UPLUG_TOKEN;
152}
153
154
155/*  Debug Memory Plugin (see hpmufn.c) */
156static void * U_CALLCONV myMemAlloc(const void *context, size_t size) {
157  void *retPtr = (void *)malloc(size);
158  (void)context; /* unused */
159  fprintf(stderr, "MEM: malloc(%d) = %p\n", (int32_t)size, retPtr);
160  return retPtr;
161}
162
163static void U_CALLCONV myMemFree(const void *context, void *mem) {
164  (void)context; /* unused */
165
166  free(mem);
167  fprintf(stderr, "MEM: free(%p)\n", mem);
168}
169
170static void * U_CALLCONV myMemRealloc(const void *context, void *mem, size_t size) {
171    void *retPtr;
172    (void)context; /* unused */
173
174
175    if(mem==NULL) {
176        retPtr = NULL;
177    } else {
178        retPtr = realloc(mem, size);
179    }
180    fprintf(stderr, "MEM: realloc(%p, %d) = %p\n", mem, (int32_t)size, retPtr);
181    return retPtr;
182}
183
184U_CAPI
185UPlugTokenReturn U_EXPORT2 debugMemoryPlugin (
186                  UPlugData *data,
187                  UPlugReason reason,
188                  UErrorCode *status) {
189    fprintf(stderr,"debugMemoryPlugin: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
190
191    if(reason==UPLUG_REASON_QUERY) {
192        uplug_setPlugLevel(data, UPLUG_LEVEL_LOW);
193        uplug_setPlugName(data, "Memory Plugin");
194    } else if(reason==UPLUG_REASON_LOAD) {
195        u_setMemoryFunctions(uplug_getContext(data), &myMemAlloc, &myMemRealloc, &myMemFree, status);
196        fprintf(stderr, "MEM: status now %s\n", u_errorName(*status));
197    } else if(reason==UPLUG_REASON_UNLOAD) {
198        fprintf(stderr, "MEM: not possible to unload this plugin (no way to reset memory functions)...\n");
199        uplug_setPlugNoUnload(data, TRUE);
200    }
201
202    return UPLUG_TOKEN;
203}
204
205