cfad47cfa3/tads3/vmcset.h

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
/* 
2
 *   Copyright (c) 2001, 2002 Michael J. Roberts.  All Rights Reserved.
3
 *   
4
 *   Please see the accompanying license file, LICENSE.TXT, for information
5
 *   on using and copying this software.  
6
 */
7
/*
8
Name
9
  vmcset.h - T3 CharacterSet metaclass
10
Function
11
  
12
Notes
13
  
14
Modified
15
  06/06/01 MJRoberts  - Creation
16
*/
17
18
#ifndef VMCSET_H
19
#define VMCSET_H
20
21
#include <stdlib.h>
22
#include "vmtype.h"
23
#include "vmobj.h"
24
#include "vmglob.h"
25
26
/* ------------------------------------------------------------------------ */
27
/*
28
 *   A CharacterSet is a simple encapsulation of a pair of CCharmap
29
 *   character mappings: one mapping from Unicode to a local character set,
30
 *   and one mapping in the reverse direction.  A CharacterSet is
31
 *   parameterized on creation by the name of the mapping, using the
32
 *   standard CCharmap names.
33
 *   
34
 *   In an image file, a CharacterSet contains simply the standard CCharmap
35
 *   name of the mapping:
36
 *   
37
 *   UINT2 length-in-bytes
38
 *.  BYTE name[]
39
 *   
40
 *   On creation, we will create the pair of CCharmap objects, if the name
41
 *   of the mapping is valid.  It is legal to create a CharacterSet with an
42
 *   unknown mapping, but such a character set object cannot be used to
43
 *   perform mappings.
44
 *   
45
 *   CharacterSet objects are constants at run-time.  
46
 */
47
class CVmObjCharSet: public CVmObject
48
{
49
    friend class CVmMetaclassCharSet;
50
    
51
public:
52
    /* metaclass registration object */
53
    static class CVmMetaclass *metaclass_reg_;
54
    class CVmMetaclass *get_metaclass_reg() const { return metaclass_reg_; }
55
56
    /* am I of the given metaclass? */
57
    virtual int is_of_metaclass(class CVmMetaclass *meta) const
58
    {
59
        /* try my own metaclass and my base class */
60
        return (meta == metaclass_reg_
61
                || CVmObject::is_of_metaclass(meta));
62
    }
63
64
    /* create dynamically using stack arguments */
65
    static vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr,
66
                                         uint argc);
67
68
    /* 
69
     *   call a static property - we don't have any of our own, so simply
70
     *   "inherit" the base class handling 
71
     */
72
    static int call_stat_prop(VMG_ vm_val_t *result,
73
                              const uchar **pc_ptr, uint *argc,
74
                              vm_prop_id_t prop)
75
    {
76
        /* explicitly inherit our superclass handling */
77
        return CVmObject::call_stat_prop(vmg_ result, pc_ptr, argc, prop);
78
    }
79
80
    /* reserve constant data */
81
    virtual void reserve_const_data(VMG_ class CVmConstMapper *,
82
                                    vm_obj_id_t /*self*/)
83
    {
84
        /* we can't be converted to constant data */
85
    }
86
87
    /* convert to constant data */
88
    virtual void convert_to_const_data(VMG_ class CVmConstMapper *,
89
                                       vm_obj_id_t /*self*/)
90
    {
91
        /* 
92
         *   we don't reference any data and can't be converted to constant
93
         *   data ourselves, so there's nothing to do here 
94
         */
95
    }
96
97
    /* create with no initial contents */
98
    static vm_obj_id_t create(VMG_ int in_root_set);
99
100
    /* create with the given character set name */
101
    static vm_obj_id_t create(VMG_ int in_root_set, const char *charset_name,
102
                              size_t charset_name_len);
103
104
    /* determine if an object is a CharacterSet */
105
    static int is_charset(VMG_ vm_obj_id_t obj)
106
        { return vm_objp(vmg_ obj)->is_of_metaclass(metaclass_reg_); }
107
108
    /* notify of deletion */
109
    void notify_delete(VMG_ int in_root_set);
110
111
    /* set a property */
112
    void set_prop(VMG_ class CVmUndo *undo,
113
                  vm_obj_id_t self, vm_prop_id_t prop, const vm_val_t *val);
114
115
    /* get a property */
116
    int get_prop(VMG_ vm_prop_id_t prop, vm_val_t *val,
117
                 vm_obj_id_t self, vm_obj_id_t *source_obj, uint *argc);
118
119
    /* undo operations */
120
    void notify_new_savept() { }
121
    void apply_undo(VMG_ struct CVmUndoRecord *) { }
122
123
    /* we reference nothing */
124
    void mark_undo_ref(VMG_ struct CVmUndoRecord *) { }
125
    void remove_stale_undo_weak_ref(VMG_ struct CVmUndoRecord *) { }
126
    void mark_refs(VMG_ uint /*state*/) { }
127
    void remove_stale_weak_refs(VMG0_) { }
128
129
    /* load from an image file */
130
    void load_from_image(VMG_ vm_obj_id_t self, const char *ptr, size_t siz);
131
132
    /* rebuild for image file */
133
    virtual ulong rebuild_image(VMG_ char *buf, ulong buflen);
134
135
    /* save to a file */
136
    void save_to_file(VMG_ class CVmFile *fp);
137
138
    /* restore from a file */
139
    void restore_from_file(VMG_ vm_obj_id_t self,
140
                           class CVmFile *fp, class CVmObjFixup *fixups);
141
142
    /* 
143
     *   Check a value for equality.  We will match another byte array with
144
     *   the same number of elements and the same value for each element.  
145
     */
146
    int equals(VMG_ vm_obj_id_t self, const vm_val_t *val, int depth) const;
147
148
    /* calculate a hash value for the array */
149
    uint calc_hash(VMG_ vm_obj_id_t self, int depth) const;
150
151
    /* our data are constant - we never change */
152
    int is_changed_since_load() const { return FALSE; }
153
154
    /*
155
     *   Get the to-local and to-unicode mappers.  If the mapper isn't
156
     *   available, we'll throw an UnknownCharacterSetException. 
157
     */
158
    class CCharmapToLocal *get_to_local(VMG0_) const;
159
    class CCharmapToUni *get_to_uni(VMG0_) const;
160
161
protected:
162
    /* create with no initial contents */
163
    CVmObjCharSet() { ext_ = 0; }
164
165
    /* create from the given character set name */
166
    CVmObjCharSet(VMG_ const char *charset_name, size_t charset_name_len);
167
168
    /* allocate and initialize */
169
    void alloc_ext(VMG_ const char *charset_name, size_t charset_name_len);
170
171
    /* get a pointer to my extension */
172
    const struct vmobj_charset_ext_t *get_ext_ptr() const
173
        { return (vmobj_charset_ext_t *)ext_; }
174
175
    /* does the given unicode character have a round-trip mapping? */
176
    static int is_rt_mappable(wchar_t c, class CCharmapToLocal *to_local,
177
                              class CCharmapToUni *to_uni);
178
179
    /* property evaluator - undefined function */
180
    int getp_undef(VMG_ vm_obj_id_t, vm_val_t *, uint *) { return FALSE; }
181
182
    /* property evaluator - get the character set name */
183
    int getp_get_name(VMG_ vm_obj_id_t self, vm_val_t *val, uint *argc);
184
185
    /* determine if the mapping is known */
186
    int getp_is_known(VMG_ vm_obj_id_t self, vm_val_t *val, uint *argc);
187
    
188
    /* 
189
     *   property evaluator - determine if the a character code (given as an
190
     *   integer) or the characters in a string can be mapped from Unicode
191
     *   to this local character set 
192
     */
193
    int getp_is_mappable(VMG_ vm_obj_id_t self, vm_val_t *val, uint *argc);
194
195
    /* 
196
     *   property evaluator - determine if the character code (given as an
197
     *   integer) or the characters in a string have a round-trip mapping
198
     *   from Unicode to local and back 
199
     */
200
    int getp_is_rt_mappable(VMG_ vm_obj_id_t self, vm_val_t *val, uint *argc);
201
202
    /* property evaluation function table */
203
    static int (CVmObjCharSet::*func_table_[])(
204
        VMG_ vm_obj_id_t self, vm_val_t *retval, uint *argc);
205
};
206
207
/*
208
 *   Our extension structure 
209
 */
210
struct vmobj_charset_ext_t
211
{
212
    /* unicode-to-local mapping object */
213
    class CCharmapToLocal *to_local;
214
215
    /* local-to-unicode mapping object */
216
    class CCharmapToUni *to_uni;
217
218
    /* length of character set name */
219
    size_t charset_name_len;
220
221
    /* name of the character set */
222
    char charset_name[1];
223
};
224
225
/* ------------------------------------------------------------------------ */
226
/*
227
 *   Registration table object 
228
 */
229
class CVmMetaclassCharSet: public CVmMetaclass
230
{
231
public:
232
    /* get the global name */
233
    const char *get_meta_name() const { return "character-set/030001"; }
234
235
    /* create from image file */
236
    void create_for_image_load(VMG_ vm_obj_id_t id)
237
    {
238
        new (vmg_ id) CVmObjCharSet();
239
        G_obj_table->set_obj_gc_characteristics(id, FALSE, FALSE);
240
    }
241
242
    /* create from restoring from saved state */
243
    void create_for_restore(VMG_ vm_obj_id_t id)
244
    {
245
        new (vmg_ id) CVmObjCharSet();
246
        G_obj_table->set_obj_gc_characteristics(id, FALSE, FALSE);
247
    }
248
249
    /* create dynamically using stack arguments */
250
    vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr, uint argc)
251
        { return CVmObjCharSet::create_from_stack(vmg_ pc_ptr, argc); }
252
253
    /* call a static property */
254
    int call_stat_prop(VMG_ vm_val_t *result,
255
                       const uchar **pc_ptr, uint *argc,
256
                       vm_prop_id_t prop)
257
    {
258
        return CVmObjCharSet::call_stat_prop(vmg_ result, pc_ptr, argc, prop);
259
    }
260
};
261
262
#endif /* VMCSET_H */
263
264
/*
265
 *   Register the class 
266
 */
267
VM_REGISTER_METACLASS(CVmObjCharSet)