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_; get_metaclass_reg()54 class CVmMetaclass *get_metaclass_reg() const { return metaclass_reg_; } 55 56 /* am I of the given metaclass? */ is_of_metaclass(class CVmMetaclass * meta)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 */ call_stat_prop(VMG_ vm_val_t * result,const uchar ** pc_ptr,uint * argc,vm_prop_id_t prop)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 */ reserve_const_data(VMG_ class CVmConstMapper *,vm_obj_id_t)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 */ convert_to_const_data(VMG_ class CVmConstMapper *,vm_obj_id_t)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 */ is_charset(VMG_ vm_obj_id_t obj)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 */ notify_new_savept()120 void notify_new_savept() { } apply_undo(VMG_ struct CVmUndoRecord *)121 void apply_undo(VMG_ struct CVmUndoRecord *) { } 122 123 /* we reference nothing */ mark_undo_ref(VMG_ struct CVmUndoRecord *)124 void mark_undo_ref(VMG_ struct CVmUndoRecord *) { } remove_stale_undo_weak_ref(VMG_ struct CVmUndoRecord *)125 void remove_stale_undo_weak_ref(VMG_ struct CVmUndoRecord *) { } mark_refs(VMG_ uint)126 void mark_refs(VMG_ uint /*state*/) { } remove_stale_weak_refs(VMG0_)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 */ is_changed_since_load()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 */ CVmObjCharSet()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 */ get_ext_ptr()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 */ getp_undef(VMG_ vm_obj_id_t,vm_val_t *,uint *)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 */ get_meta_name()233 const char *get_meta_name() const { return "character-set/030001"; } 234 235 /* create from image file */ create_for_image_load(VMG_ vm_obj_id_t id)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 */ create_for_restore(VMG_ vm_obj_id_t id)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 */ create_from_stack(VMG_ const uchar ** pc_ptr,uint argc)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 */ call_stat_prop(VMG_ vm_val_t * result,const uchar ** pc_ptr,uint * argc,vm_prop_id_t prop)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) 268