コード例 #1
2
public class Xoa_meta_mgr {
  private final Xoa_app app;
  private final Hash_adp_bry ns__hash = Hash_adp_bry.cs();
  private Site_core_db core_db;

  public Xoa_meta_mgr(Xoa_app app) {
    this.app = app;
  }

  public void Ns__add(byte[] wiki_domain, Xow_ns_mgr ns_mgr) {
    ns__hash.Add(wiki_domain, ns_mgr);
  } // TEST:public

  public Xow_ns_mgr Ns__get_or_load(byte[] wiki_domain) {
    Xow_ns_mgr rv = (Xow_ns_mgr) ns__hash.Get_by_bry(wiki_domain);
    if (rv == null) {
      Core_db__assert();
      rv = core_db.Load_namespace(wiki_domain);
      Ns__add(wiki_domain, rv);
    }
    return rv;
  }

  private void Core_db__assert() {
    if (core_db == null) core_db = new Site_core_db(app.Fsys_mgr().Cfg_site_meta_fil());
  }
}
コード例 #2
0
 public Xow_special_mgr(Xowe_wiki wiki, Xol_lang_itm lang) {
   this.app = wiki.App();
   hash = Hash_adp_bry.ci_u8(lang.Case_mgr());
   page_allpages = new Xows_page_allpages(wiki);
   page_search = new Srch_special_page(wiki);
   Evt_lang_changed(wiki.Lang());
 }
コード例 #3
0
 public void Special__gen(Xoa_app app, Xow_wiki wiki, Xoa_page page, Xoa_url url, Xoa_ttl ttl) {
   int slash_pos =
       Bry_find_.Find_fwd(ttl.Page_txt_wo_qargs(), Xoa_ttl.Subpage_spr); // check for slash
   byte[] special_name =
       slash_pos == Bry_find_.Not_found
           ? ttl
               .Base_txt_wo_qarg() // no slash found; use base_txt; ignore qry args and just get
                                   // page_names; EX: Search/Earth?fulltext=y;
                                   // Allpages?from=Earth...
           : Bry_.Mid(
               ttl.Page_txt_wo_qargs(),
               0,
               slash_pos); // slash found; use root page; EX: Special:ItemByTitle/enwiki/Earth
   special_name =
       Xoa_ttl.Replace_spaces(special_name); // handle spaces; EX:Spezial:Zufällige_Seite
   Xow_special_page special = (Xow_special_page) hash.Get_by_bry(special_name);
   if (special != null) { // special found; generate it;
     special = special.Special__clone();
     page.Db().Page().Modified_on_(Datetime_now.Get());
     try {
       special.Special__gen(wiki, page, url, ttl);
     } catch (Exception e) {
       Gfo_log_.Instance.Warn(
           "failed to generate special page",
           "url",
           url.To_str(),
           "err",
           Err_.Message_gplx_log(e));
     }
   }
 }
コード例 #4
0
ファイル: Xob_import_marker.java プロジェクト: qq98982/xowa
 public boolean Chk(Xowe_wiki wiki) {
   if (!wiki.App().App_type().Uid_is_gui())
     return true; // NOTE: ignore during Server / Console modes; DATE:2015-04-01
   if (in_progress_hash.Has(wiki.Domain_bry()))
     return true; // NOTE: ignore if currently building; different bldr commands call
                  // wiki.Init_assert() which may lead to fals checks;
   Io_url url = url_(wiki);
   if (!Io_mgr.I.ExistsFil(url)) return true;
   Xoae_app app = wiki.Appe();
   app.Usr_dlg().Log_many("", "", "import.marker: marker found: url=~{0}", url.Raw());
   byte[] incompete_msg_bry =
       app.Usere()
           .Msg_mgr()
           .Val_by_key_args(Bry_.new_a7("api-xowa.import.core.incomplete"), wiki.Domain_str());
   int rslt = app.Gui_mgr().Kit().Ask_yes_no_cancel("", "", String_.new_u8(incompete_msg_bry));
   switch (rslt) {
     case Gfui_dlg_msg_.Btn_yes:
       Xob_cleanup_cmd.Delete_wiki_sql(wiki);
       End(wiki);
       return false; // delete wiki
     case Gfui_dlg_msg_.Btn_no:
       End(wiki);
       return true; // delete marker
     case Gfui_dlg_msg_.Btn_cancel:
       return true; // noop
     default:
       throw Err_.unhandled(rslt);
   }
 }
コード例 #5
0
 public Xow_ns_mgr Ns__get_or_load(byte[] wiki_domain) {
   Xow_ns_mgr rv = (Xow_ns_mgr) ns__hash.Get_by_bry(wiki_domain);
   if (rv == null) {
     Core_db__assert();
     rv = core_db.Load_namespace(wiki_domain);
     Ns__add(wiki_domain, rv);
   }
   return rv;
 }
コード例 #6
0
 public void Get_by_url1(Xow_wiki wiki, Xoa_page page, Xoa_url url, Xoa_ttl ttl) {
   int slash_pos =
       Bry_find_.Find_fwd(ttl.Page_txt_wo_qargs(), Xoa_ttl.Subpage_spr); // check for slash
   byte[] special_name =
       slash_pos == Bry_find_.Not_found
           ? ttl.Base_txt_wo_qarg() // no slash found; use base_txt; ignore qry args and just get
           // page_names; EX: Search/Earth?fulltext=y;
           // Allpages?from=Earth...
           : Bry_.Mid(
               ttl.Page_txt_wo_qargs(),
               0,
               slash_pos); // slash found; use root page; EX: Special:ItemByTitle/enwiki/Earth
   Object o = hash.Get_by_bry(special_name);
   if (o == null) {
     Xol_specials_itm special_itm = wiki.Lang().Specials_mgr().Get_by_alias(special_name);
     if (special_itm != null) o = hash.Get_by_bry(special_itm.Special());
   }
   if (o != null) {
     // Xow_special_page special = (Xow_special_page)o;
     // page.Revision_data().Modified_on_(Datetime_now.Get());
     // special.Special__gen(wiki, page, url, ttl);
   }
 }
コード例 #7
0
ファイル: Xob_import_marker.java プロジェクト: qq98982/xowa
public class Xob_import_marker {
  private final Hash_adp_bry in_progress_hash = Hash_adp_bry.cs_();

  public void Bgn(Xowe_wiki wiki) {
    in_progress_hash.Add_as_key_and_val(wiki.Domain_bry());
    Io_mgr.I.SaveFilStr(
        url_(wiki),
        "XOWA has created this file to indicate that an import is in progress. This file will be deleted once the import is completed.");
  }

  public void End(Xowe_wiki wiki) {
    in_progress_hash.Del(wiki.Domain_bry());
    Io_mgr.I.DeleteFil_args(url_(wiki)).MissingFails_off().Exec();
  }

  public boolean Chk(Xowe_wiki wiki) {
    if (!wiki.App().App_type().Uid_is_gui())
      return true; // NOTE: ignore during Server / Console modes; DATE:2015-04-01
    if (in_progress_hash.Has(wiki.Domain_bry()))
      return true; // NOTE: ignore if currently building; different bldr commands call
                   // wiki.Init_assert() which may lead to fals checks;
    Io_url url = url_(wiki);
    if (!Io_mgr.I.ExistsFil(url)) return true;
    Xoae_app app = wiki.Appe();
    app.Usr_dlg().Log_many("", "", "import.marker: marker found: url=~{0}", url.Raw());
    byte[] incompete_msg_bry =
        app.Usere()
            .Msg_mgr()
            .Val_by_key_args(Bry_.new_a7("api-xowa.import.core.incomplete"), wiki.Domain_str());
    int rslt = app.Gui_mgr().Kit().Ask_yes_no_cancel("", "", String_.new_u8(incompete_msg_bry));
    switch (rslt) {
      case Gfui_dlg_msg_.Btn_yes:
        Xob_cleanup_cmd.Delete_wiki_sql(wiki);
        End(wiki);
        return false; // delete wiki
      case Gfui_dlg_msg_.Btn_no:
        End(wiki);
        return true; // delete marker
      case Gfui_dlg_msg_.Btn_cancel:
        return true; // noop
      default:
        throw Err_.unhandled(rslt);
    }
  }

  private static Io_url url_(Xowe_wiki wiki) {
    return wiki.Fsys_mgr().Root_dir().GenSubFil(wiki.Domain_str() + "-import.lock");
  }
}
コード例 #8
0
 public static Xoa_app_mode parse(String s) {
   Object o = type_hash.Get_by(Bry_.new_u8(s));
   if (o == null)
     return Itm_cmd; // default to cmd as per early behaviour; handles mistaken "--app_mode wrong"
   int tid = ((Int_obj_val) o).Val();
   switch (tid) {
     case Tid_cmd:
       return Itm_cmd;
     case Tid_gui:
       return Itm_gui;
     case Tid_http:
       return Itm_http;
     case Tid_tcp:
       return Itm_tcp;
     case Tid_file:
       return Itm_file;
     default:
       throw Err_.new_unhandled(tid);
   }
 }
コード例 #9
0
public class Xop_lnki_align_h_ {
  public static final byte Null = 0, None = 1, Left = 2, Center = 3, Right = 4; // SERIALIZED
  public static final byte[][] Html_names =
      new byte[][] {
        Object_.Bry__null,
        Bry_.new_a7("none"),
        Bry_.new_a7("left"),
        Bry_.new_a7("center"),
        Bry_.new_a7("right")
      };
  public static final Hash_adp_bry Hash =
      Hash_adp_bry.ci_a7()
          .Add_str_byte("tnone", None)
          .Add_str_byte("tleft", Left)
          .Add_str_byte("tcenter", Center)
          .Add_str_byte("tright", Right);

  public static byte[] To_bry(int v) {
    return Html_names[v];
  }
}
コード例 #10
0
 public Xosp_special_mgr(Xowv_wiki wiki) {
   //			this.wiki = wiki;
   // hash.Add_str_obj(Xow_special_meta_.Ttl__statistics				, page_statistics);
   this.hash = Hash_adp_bry.cs();
 }
コード例 #11
0
public class Pfunc_gender extends Pf_func_base {
  @Override
  public int Id() {
    return Xol_kwd_grp_.Id_i18n_gender;
  }

  @Override
  public boolean Func_require_colon_arg() {
    return true;
  }

  @Override
  public Pf_func New(int id, byte[] name) {
    return new Pfunc_gender().Name_(name);
  }

  @Override
  public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {
    byte[] user_name = Eval_argx(ctx, src, caller, self);
    byte[] when_m = Bry_.Empty, when_f = Bry_.Empty, when_u = Bry_.Empty;
    int self_args_len = self.Args_len();
    if (self_args_len == 0) return; // per MW: EX: {{gender:name}} -> ""
    else {
      if (self_args_len > 0) {
        when_m =
            when_u =
                Pf_func_.Eval_arg_or_empty(
                    ctx, src, caller, self, self_args_len, 0); // default when_u to when_m
        if (self_args_len > 1) {
          when_f = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 1);
          if (self_args_len > 2) {
            when_u = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 2);
          }
        }
      }
    }
    if (self_args_len == 1) {
      bfr.Add(when_m);
      return;
    } // per MW: EX: {{gender:name|a}} -> "a"
    int gender = Get_gender(ctx.App().User(), user_name);
    Xol_lang_itm lang = ctx.Page().Lang();
    bfr.Add(lang.Gender().Gender_eval(gender, when_m, when_f, when_u));
  }

  private static int Get_gender(Xou_user user, byte[] user_name) {
    int user_name_len = user_name.length;
    switch (user_name_len) {
      case 0:
        return Xol_gender_.Tid_unknown; // EX: {{gender:|m|f}}
      case 1:
        if (user_name[0] == Byte_ascii.Dot) return Xol_gender_.Tid_unknown;
        break; // EX: {{gender:.|m|f}}; TODO_OLD: should define default gender for wiki
    }
    Object o = gender_cache.Get_by_bry(user_name);
    return o == null ? user.Gender() : ((Int_obj_val) o).Val();
  }

  private static final Hash_adp_bry gender_cache =
      Hash_adp_bry.cs() // for tests
          .Add_str_int("xowa_male", Xol_gender_.Tid_male)
          .Add_str_int("xowa_female", Xol_gender_.Tid_female);
}
コード例 #12
0
 public void Ns__add(byte[] wiki_domain, Xow_ns_mgr ns_mgr) {
   ns__hash.Add(wiki_domain, ns_mgr);
 } // TEST:public
コード例 #13
0
  public void Evt_lang_changed(Xol_lang_itm lang) {
    // add special pages by old manual method; DEPRECATED
    hash.Clear();
    hash.Add_str_obj(Xow_special_meta_.Ttl__search, page_search);
    hash.Add_str_obj(Xow_special_meta_.Ttl__all_pages, page_allpages);
    hash.Add_str_obj("prefixindex", page_allpages);
    hash.Add_bry_obj(Xou_history_mgr.Ttl_name, page_history);
    hash.Add_str_obj(Xow_special_meta_.Ttl__page_history, page_history2);
    hash.Add_str_obj(Xow_special_meta_.Ttl__nearby, page_nearby);
    hash.Add_str_obj(Xow_special_meta_.Ttl__my_language, page_mylanguage);
    hash.Add_str_obj(Xow_special_meta_.Ttl__item_by_title, page_itemByTitle);
    hash.Add_str_obj(Xow_special_meta_.Ttl__statistics, page_statistics);
    hash.Add_str_obj(Xow_special_meta_.Ttl__move_page, page_movePage);
    hash.Add_str_obj(Xow_special_meta_.Ttl__system_data, page_system_data);
    hash.Add_str_obj(Xow_special_meta_.Ttl__default_tab, page_default_tab);
    hash.Add_str_obj(Xow_special_meta_.Ttl__popup_history, page_popup_history);
    hash.Add_str_obj(Xow_special_meta_.Ttl__bookmarks, page_bmk);
    hash.Add_str_obj(Xow_special_meta_.Ttl__diag, page_diag);

    // add app's Special_regy to hash table; needed for case insensitivity by wiki's lang; EX:
    // Special:rANDom; NOTE: needs to go before lang aliases
    Xoa_special_regy special_regy = app.Special_regy();
    int len = special_regy.Len();
    for (int i = 0; i < len; ++i) {
      Xow_special_page proto = special_regy.Get_at(i);
      Xow_special_meta proto_meta = proto.Special__meta();
      hash.Add_if_dupe_use_1st(proto_meta.Key_bry(), proto);
      for (byte[] alias : proto_meta.Aliases()) hash.Add_if_dupe_use_1st(alias, proto);
    }

    // add lang's special aliases to hash table; EX: Special:Recherche
    Xol_specials_mgr lang_mgr = lang.Specials_mgr();
    len = lang_mgr.Len();
    for (int i = 0; i < len; ++i) {
      Xol_specials_itm lang_itm = lang_mgr.Get_at(i);
      Xow_special_page page = (Xow_special_page) hash.Get_by_bry(lang_itm.Special());
      if (page == null)
        continue; // NOTE: ignore specials that are not in XOWA; EX: Special:ChangeEmail
      for (byte[] alias : lang_itm.Aliases()) hash.Add_if_dupe_use_1st(alias, page);
    }
  }
コード例 #14
0
ファイル: Xob_import_marker.java プロジェクト: qq98982/xowa
 public void End(Xowe_wiki wiki) {
   in_progress_hash.Del(wiki.Domain_bry());
   Io_mgr.I.DeleteFil_args(url_(wiki)).MissingFails_off().Exec();
 }
コード例 #15
0
ファイル: Xob_import_marker.java プロジェクト: qq98982/xowa
 public void Bgn(Xowe_wiki wiki) {
   in_progress_hash.Add_as_key_and_val(wiki.Domain_bry());
   Io_mgr.I.SaveFilStr(
       url_(wiki),
       "XOWA has created this file to indicate that an import is in progress. This file will be deleted once the import is completed.");
 }
コード例 #16
0
public class Indicator_xnde implements Xox_xnde, Mwh_atr_itm_owner1 {
  public String Name() {
    return name;
  }

  private String name;

  public byte[] Html() {
    return html;
  }

  private byte[] html;

  public void Init_for_test(String name, byte[] html) {
    this.name = name;
    this.html = html;
  } // TEST

  public void Xatr__set(Xowe_wiki wiki, byte[] src, Mwh_atr_itm xatr, Object xatr_id_obj) {
    if (xatr_id_obj == null) return;
    Byte_obj_val xatr_id = (Byte_obj_val) xatr_id_obj;
    switch (xatr_id.Val()) {
      case Xatr_name:
        this.name = xatr.Val_as_str();
        break;
    }
  }

  public void Xtn_parse(
      Xowe_wiki wiki, Xop_ctx ctx, Xop_root_tkn root, byte[] src, Xop_xnde_tkn xnde) {
    Xox_xnde_.Xatr__set(wiki, this, xatrs_hash, src, xnde);
    this.html =
        Xop_parser_.Parse_text_to_html(
            wiki,
            ctx,
            ctx.Page(),
            ctx.Page().Ttl(),
            Bry_.Mid(src, xnde.Tag_open_end(), xnde.Tag_close_bgn()),
            false);
    Indicator_html_bldr html_bldr = ctx.Page().Html_data().Indicators();
    if (this.name != null)
      html_bldr.Add(this); // NOTE: must do null-check b/c Add will use Name as key for hashtable
  }

  public void Xtn_write(
      Bry_bfr bfr,
      Xoae_app app,
      Xop_ctx ctx,
      Xoh_html_wtr html_wtr,
      Xoh_wtr_ctx hctx,
      Xoae_page wpg,
      Xop_xnde_tkn xnde,
      byte[] src) {
    if (this.name == null)
      bfr.Add_str_a7("Error: Page status indicators' name attribute must not be empty.");
  }

  private static final byte Xatr_name = 0;
  private static final Hash_adp_bry xatrs_hash =
      Hash_adp_bry.ci_a7().Add_str_obj("name", Byte_obj_val.new_(Xatr_name));
}
コード例 #17
0
 public byte[] Convert_to_local_urls(byte[] rel_url_prefix, byte[] src, List_adp list) {
   try {
     int src_len = src.length;
     int prv_pos = 0;
     Bry_bfr bfr = Bry_bfr_.New_w_size(src_len);
     Hash_adp img_hash = Hash_adp_bry.cs();
     while (true) {
       int url_pos = Bry_find_.Find_fwd(src, Bry_url, prv_pos);
       if (url_pos == Bry_find_.Not_found) {
         bfr.Add_mid(src, prv_pos, src_len);
         break;
       } // no more "url("; exit;
       int bgn_pos = url_pos + Bry_url_len; // set bgn_pos after "url("
       byte bgn_byte = src[bgn_pos];
       byte end_byte = Byte_ascii.Null;
       boolean quoted = true;
       switch (bgn_byte) { // find end_byte
         case Byte_ascii.Quote:
         case Byte_ascii.Apos: // quoted; end_byte is ' or "
           end_byte = bgn_byte;
           ++bgn_pos;
           break;
         default: // not quoted; end byte is ")"
           end_byte = Byte_ascii.Paren_end;
           quoted = false;
           break;
       }
       int end_pos = Bry_find_.Find_fwd(src, end_byte, bgn_pos, src_len);
       if (end_pos
           == Bry_find_.Not_found) { // unclosed "url("; exit since nothing else will be found
         usr_dlg.Warn_many(
             GRP_KEY,
             "parse.invalid_url.end_missing",
             "could not find end_sequence for 'url(': bgn='~{0}' end='~{1}'",
             prv_pos,
             String_.new_u8__by_len(src, prv_pos, prv_pos + 25));
         bfr.Add_mid(src, prv_pos, src_len);
         break;
       }
       if (end_pos - bgn_pos == 0) { // empty; "url()"; ignore
         usr_dlg.Warn_many(
             GRP_KEY,
             "parse.invalid_url.empty",
             "'url(' is empty: bgn='~{0}' end='~{1}'",
             prv_pos,
             String_.new_u8__by_len(src, prv_pos, prv_pos + 25));
         bfr.Add_mid(src, prv_pos, bgn_pos);
         prv_pos = bgn_pos;
         continue;
       }
       byte[] img_raw = Bry_.Mid(src, bgn_pos, end_pos);
       int img_raw_len = img_raw.length;
       if (Bry_.Has_at_bgn(img_raw, Bry_data_image, 0, img_raw_len)) { // base64
         bfr.Add_mid(src, prv_pos, end_pos); // nothing to download; just add entire String
         prv_pos = end_pos;
         continue;
       }
       int import_url_end =
           Import_url_chk(
               rel_url_prefix,
               src,
               src_len,
               prv_pos,
               url_pos,
               img_raw,
               bfr); // check for embedded stylesheets via @import tag
       if (import_url_end != Bry_find_.Not_found) {
         prv_pos = import_url_end;
         continue;
       }
       byte[] img_cleaned = Xob_url_fixer.Fix(wiki_domain, img_raw, img_raw_len);
       if (img_cleaned == null) { // could not clean img
         usr_dlg.Warn_many(
             GRP_KEY,
             "parse.invalid_url.clean_failed",
             "could not extract valid http src: bgn='~{0}' end='~{1}'",
             prv_pos,
             String_.new_u8(img_raw));
         bfr.Add_mid(src, prv_pos, bgn_pos);
         prv_pos = bgn_pos;
         continue;
       }
       if (!img_hash.Has(img_cleaned)) { // only add unique items for download;
         img_hash.Add_as_key_and_val(img_cleaned);
         list.Add(String_.new_u8(img_cleaned));
       }
       img_cleaned =
           Replace_invalid_chars(
               Bry_.Copy(
                   img_cleaned)); // NOTE: must call ByteAry.Copy else img_cleaned will change
                                  // *inside* hash
       bfr.Add_mid(src, prv_pos, bgn_pos);
       if (!quoted) bfr.Add_byte(Byte_ascii.Quote);
       bfr.Add(img_cleaned);
       if (!quoted) bfr.Add_byte(Byte_ascii.Quote);
       prv_pos = end_pos;
     }
     return bfr.To_bry_and_clear();
   } catch (Exception e) {
     usr_dlg.Warn_many(
         "",
         "",
         "failed to convert local_urls: ~{0} ~{1}",
         String_.new_u8(rel_url_prefix),
         Err_.Message_gplx_full(e));
     return src;
   }
 }
コード例 #18
0
public class Xoa_app_mode {
  Xoa_app_mode(int tid) {
    this.tid = tid;
  }

  public int Tid() {
    return tid;
  }

  private final int tid;

  public boolean Tid_is_gui() {
    return tid == Tid_gui;
  }

  public boolean Tid_is_tcp() {
    return tid == Tid_tcp;
  }

  public boolean Tid_is_cmd() {
    return tid == Tid_cmd;
  }

  public boolean Tid_is_http() {
    return tid == Tid_http;
  }

  public boolean Tid_supports_js() {
    switch (tid) {
      case Tid_gui:
      case Tid_tcp:
        return true;
      default:
        return false;
    }
  }

  public byte[] Name() {
    switch (tid) {
      case Tid_cmd:
        return Key_cmd;
      case Tid_gui:
        return Key_gui;
      case Tid_http:
        return Key_http;
      case Tid_tcp:
        return Key_tcp;
      case Tid_file:
        return Key_file;
      default:
        return Key_cmd; // see parse
    }
  }

  private static final int Tid_cmd = 1, Tid_gui = 2, Tid_tcp = 3, Tid_http = 4, Tid_file = 5;
  private static final byte[] Key_cmd = Bry_.new_a7("cmd"),
      Key_gui = Bry_.new_a7("gui"),
      Key_tcp = Bry_.new_a7("server"),
      Key_http = Bry_.new_a7("http_server"),
      Key_file = Bry_.new_a7("file");
  public static final Xoa_app_mode Itm_cmd = new Xoa_app_mode(Tid_cmd),
      Itm_gui = new Xoa_app_mode(Tid_gui),
      Itm_tcp = new Xoa_app_mode(Tid_tcp),
      Itm_http = new Xoa_app_mode(Tid_http),
      Itm_file = new Xoa_app_mode(Tid_file);
  private static final Hash_adp_bry type_hash =
      Hash_adp_bry.cs()
          .Add_bry_int(Key_cmd, Tid_cmd)
          .Add_bry_int(Key_gui, Tid_gui)
          .Add_bry_int(Key_http, Tid_http)
          .Add_bry_int(Key_tcp, Tid_tcp)
          .Add_bry_int(Key_file, Tid_file);

  public static Xoa_app_mode parse(String s) {
    Object o = type_hash.Get_by(Bry_.new_u8(s));
    if (o == null)
      return Itm_cmd; // default to cmd as per early behaviour; handles mistaken "--app_mode wrong"
    int tid = ((Int_obj_val) o).Val();
    switch (tid) {
      case Tid_cmd:
        return Itm_cmd;
      case Tid_gui:
        return Itm_gui;
      case Tid_http:
        return Itm_http;
      case Tid_tcp:
        return Itm_tcp;
      case Tid_file:
        return Itm_file;
      default:
        throw Err_.new_unhandled(tid);
    }
  }
}