/* * Copyright (c) 2001, 2002 Michael J. Roberts. All Rights Reserved. * * Please see the accompanying license file, LICENSE.TXT, for information * on using and copying this software. */ /* Name vmcset.h - T3 CharacterSet metaclass Function Notes Modified 06/06/01 MJRoberts - Creation */ #ifndef VMCSET_H #define VMCSET_H #include #include "vmtype.h" #include "vmobj.h" #include "vmglob.h" /* ------------------------------------------------------------------------ */ /* * A CharacterSet is a simple encapsulation of a pair of CCharmap * character mappings: one mapping from Unicode to a local character set, * and one mapping in the reverse direction. A CharacterSet is * parameterized on creation by the name of the mapping, using the * standard CCharmap names. * * In an image file, a CharacterSet contains simply the standard CCharmap * name of the mapping: * * UINT2 length-in-bytes *. BYTE name[] * * On creation, we will create the pair of CCharmap objects, if the name * of the mapping is valid. It is legal to create a CharacterSet with an * unknown mapping, but such a character set object cannot be used to * perform mappings. * * CharacterSet objects are constants at run-time. */ class CVmObjCharSet: public CVmObject { friend class CVmMetaclassCharSet; public: /* metaclass registration object */ static class CVmMetaclass *metaclass_reg_; class CVmMetaclass *get_metaclass_reg() const { return metaclass_reg_; } /* am I of the given metaclass? */ virtual int is_of_metaclass(class CVmMetaclass *meta) const { /* try my own metaclass and my base class */ return (meta == metaclass_reg_ || CVmObject::is_of_metaclass(meta)); } /* create dynamically using stack arguments */ static vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr, uint argc); /* * call a static property - we don't have any of our own, so simply * "inherit" the base class handling */ static int call_stat_prop(VMG_ vm_val_t *result, const uchar **pc_ptr, uint *argc, vm_prop_id_t prop) { /* explicitly inherit our superclass handling */ return CVmObject::call_stat_prop(vmg_ result, pc_ptr, argc, prop); } /* reserve constant data */ virtual void reserve_const_data(VMG_ class CVmConstMapper *, vm_obj_id_t /*self*/) { /* we can't be converted to constant data */ } /* convert to constant data */ virtual void convert_to_const_data(VMG_ class CVmConstMapper *, vm_obj_id_t /*self*/) { /* * we don't reference any data and can't be converted to constant * data ourselves, so there's nothing to do here */ } /* create with no initial contents */ static vm_obj_id_t create(VMG_ int in_root_set); /* create with the given character set name */ static vm_obj_id_t create(VMG_ int in_root_set, const char *charset_name, size_t charset_name_len); /* determine if an object is a CharacterSet */ static int is_charset(VMG_ vm_obj_id_t obj) { return vm_objp(vmg_ obj)->is_of_metaclass(metaclass_reg_); } /* notify of deletion */ void notify_delete(VMG_ int in_root_set); /* set a property */ void set_prop(VMG_ class CVmUndo *undo, vm_obj_id_t self, vm_prop_id_t prop, const vm_val_t *val); /* get a property */ int get_prop(VMG_ vm_prop_id_t prop, vm_val_t *val, vm_obj_id_t self, vm_obj_id_t *source_obj, uint *argc); /* undo operations */ void notify_new_savept() { } void apply_undo(VMG_ struct CVmUndoRecord *) { } /* we reference nothing */ void mark_undo_ref(VMG_ struct CVmUndoRecord *) { } void remove_stale_undo_weak_ref(VMG_ struct CVmUndoRecord *) { } void mark_refs(VMG_ uint /*state*/) { } void remove_stale_weak_refs(VMG0_) { } /* load from an image file */ void load_from_image(VMG_ vm_obj_id_t self, const char *ptr, size_t siz); /* rebuild for image file */ virtual ulong rebuild_image(VMG_ char *buf, ulong buflen); /* save to a file */ void save_to_file(VMG_ class CVmFile *fp); /* restore from a file */ void restore_from_file(VMG_ vm_obj_id_t self, class CVmFile *fp, class CVmObjFixup *fixups); /* * Check a value for equality. We will match another byte array with * the same number of elements and the same value for each element. */ int equals(VMG_ vm_obj_id_t self, const vm_val_t *val, int depth) const; /* calculate a hash value for the array */ uint calc_hash(VMG_ vm_obj_id_t self, int depth) const; /* our data are constant - we never change */ int is_changed_since_load() const { return FALSE; } /* * Get the to-local and to-unicode mappers. If the mapper isn't * available, we'll throw an UnknownCharacterSetException. */ class CCharmapToLocal *get_to_local(VMG0_) const; class CCharmapToUni *get_to_uni(VMG0_) const; protected: /* create with no initial contents */ CVmObjCharSet() { ext_ = 0; } /* create from the given character set name */ CVmObjCharSet(VMG_ const char *charset_name, size_t charset_name_len); /* allocate and initialize */ void alloc_ext(VMG_ const char *charset_name, size_t charset_name_len); /* get a pointer to my extension */ const struct vmobj_charset_ext_t *get_ext_ptr() const { return (vmobj_charset_ext_t *)ext_; } /* does the given unicode character have a round-trip mapping? */ static int is_rt_mappable(wchar_t c, class CCharmapToLocal *to_local, class CCharmapToUni *to_uni); /* property evaluator - undefined function */ int getp_undef(VMG_ vm_obj_id_t, vm_val_t *, uint *) { return FALSE; } /* property evaluator - get the character set name */ int getp_get_name(VMG_ vm_obj_id_t self, vm_val_t *val, uint *argc); /* determine if the mapping is known */ int getp_is_known(VMG_ vm_obj_id_t self, vm_val_t *val, uint *argc); /* * property evaluator - determine if the a character code (given as an * integer) or the characters in a string can be mapped from Unicode * to this local character set */ int getp_is_mappable(VMG_ vm_obj_id_t self, vm_val_t *val, uint *argc); /* * property evaluator - determine if the character code (given as an * integer) or the characters in a string have a round-trip mapping * from Unicode to local and back */ int getp_is_rt_mappable(VMG_ vm_obj_id_t self, vm_val_t *val, uint *argc); /* property evaluation function table */ static int (CVmObjCharSet::*func_table_[])( VMG_ vm_obj_id_t self, vm_val_t *retval, uint *argc); }; /* * Our extension structure */ struct vmobj_charset_ext_t { /* unicode-to-local mapping object */ class CCharmapToLocal *to_local; /* local-to-unicode mapping object */ class CCharmapToUni *to_uni; /* length of character set name */ size_t charset_name_len; /* name of the character set */ char charset_name[1]; }; /* ------------------------------------------------------------------------ */ /* * Registration table object */ class CVmMetaclassCharSet: public CVmMetaclass { public: /* get the global name */ const char *get_meta_name() const { return "character-set/030001"; } /* create from image file */ void create_for_image_load(VMG_ vm_obj_id_t id) { new (vmg_ id) CVmObjCharSet(); G_obj_table->set_obj_gc_characteristics(id, FALSE, FALSE); } /* create from restoring from saved state */ void create_for_restore(VMG_ vm_obj_id_t id) { new (vmg_ id) CVmObjCharSet(); G_obj_table->set_obj_gc_characteristics(id, FALSE, FALSE); } /* create dynamically using stack arguments */ vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr, uint argc) { return CVmObjCharSet::create_from_stack(vmg_ pc_ptr, argc); } /* call a static property */ int call_stat_prop(VMG_ vm_val_t *result, const uchar **pc_ptr, uint *argc, vm_prop_id_t prop) { return CVmObjCharSet::call_stat_prop(vmg_ result, pc_ptr, argc, prop); } }; #endif /* VMCSET_H */ /* * Register the class */ VM_REGISTER_METACLASS(CVmObjCharSet)