| | 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) |