#!/usr/bin/env ruby # # Honyakudamashii client script # $Id: honyaku-19991129,v 1.1.1.1 2000/03/06 11:30:30 sakamoto Exp $ require "socket" require "getopts" require "kconv" class HDconnect BUFFER_SIZE = 65536 INT_MAX = 0x7fffffff UINT_MAX = 0xffffffff HEADER = 0xaabbccdd DICT_EJ = 0x1 DICT_JE = 0x2 EG_INIT = 0xf00001 EG_END = 0xf00002 EG_TRANSLATE_ONE = 0xf00004 EG_GETEQUIV = 0xf00007 EG_GETWORD = 0xf00008 EG_SETWORD = 0xf00009 EG_GETHINSHI = 0xf0000a EG_SETHINSHI = 0xf0000b EG_GETTRNTXT = 0xf0000c EG_SETMODE = 0xf00011 EG_SETDICTNAME = 0xf00013 EG_CLEAR_CACHE = 0xf00014 EG_BROWSE_DICT = 0xf00015 TRNS_GET_STATUS = 0xf0001a TRNS_DIVIDE_SENTENCE = 0xf0001b def initialize(server, port, dict, username) @server = server @port = port @opened_dict = get_dict(dict) @socket = TCPSocket.open(@server, @port) eg_init(username) end def close eg_end @socket.close end def get_dict(d) return DICT_JE if d =~ /je/i return DICT_EJ end def request(data) format = data.shift packed_data = data.pack(format) packet = [HEADER, packed_data.length].pack("NN") + packed_data @socket.send(packet, 0) header = @socket.recv(8).unpack("NN") if header[0] != HEADER # protocol error return [-1] end response = @socket.recv(header[1]) if header[1] != response.length # protocol error return [-1] end respdata = response.unpack("Na*") status = respdata.shift status = status - UINT_MAX if status > INT_MAX return [status, respdata.shift] end def eg_init(username) response = request ["NNNa*c", EG_INIT, @opened_dict, 0xe001, username, 0] return response.shift end def eg_end response = request ["NN", EG_END, @opened_dict] return response.shift end def eg_translate_one(string) response = request ["NNNNnnNa*c", EG_TRANSLATE_ONE, @opened_dict, 0, BUFFER_SIZE, 0, 0, 0, string, 0] return "" if response[0] < 0 return response.pop.unpack("na*").pop end Equiv = Struct.new("Equiv", :start, :length) def eg_getequiv(which, start) response = request ["NNNN", EG_GETEQUIV, @opened_dict, which, start] return response if response[0] < 0 pequiv = response.pop.unpack("n*") orignum = pequiv.shift trannum = pequiv.shift origequiv = [] tranequiv = [] for i in 1..orignum origequiv.push(Equiv.new(pequiv.shift, pequiv.shift)) end for i in 1..trannum tranequiv.push(Equiv.new(pequiv.shift, pequiv.shift)) end return [response.shift, origequiv, tranequiv] end def eg_getword(wordno, all) response = request ["NNNNN", EG_GETWORD, @opened_dict, wordno, BUFFER_SIZE, all] return [] if response[0] < 0 wordsdata = response.pop.unpack("Na*") words = [] wordsdata.pop.split(/\0/).each do |w| words.push(w.unpack("na*").pop) end return words end def eg_setword(wordno, twordno) response = request ["NNNN", EG_SETWORD, @opened_dict, wordno, twordno] return response.shift end def eg_gethinshi(wordno) return [] if @opened_dict != DICT_EJ response = request ["NNNN", EG_GETHINSHI, @opened_dict, wordno, BUFFER_SIZE] return [] if response[0] < 0 hinshidata = response.pop.unpack("Na*") hinshi = [] hinshidata.pop.split(/\0/).each do |w| hinshi.push(w.unpack("na*").pop) end return hinshi end def eg_sethinshi(wordno, hinshino) response = request ["NNNN", EG_SETHINSHI, @opened_dict, wordno, hinshino] return response.shift end def eg_gettrntxt response = request ["NNNN", EG_GETTRNTXT, @opened_dict, BUFFER_SIZE] return "" if response[0] < 0 return response.pop end def eg_setmode(mode) response = request ["NNa*c", EG_SETMODE, @opened_dict, mode] return response[0] end def make_usedict(kind, id, name) return [kind, id, name].pack("na2a256") end def eg_setdictname(compdict, studydict, ndict, usedict) response = request ["NNNNNa*", EG_SETDICTNAME, @opened_dict, compdict, studydict, ndict, usedict] return [] if response[0] < 0 return response.pop.unpack("N*") end def eg_clear_cache response = request ["NN", EG_CLEAR_CACHE, @opened_dict] return response[0] end def eg_browse_dict(index) response = request ["NNNa*c", EG_BROWSE_DICT, @opened_dict, BUFFER_SIZE, index, 0] return "" if response[0] < 0 return response.pop end def trns_get_status response = request ["NN", TRNS_GET_STATUS, 1] return [] if response[0] < 0 infodata = response.pop.unpack("Na*") infostring = infodata.pop info = [] for i in 1..infodata[0] infos = infostring.split(/\0/, 7) infos += infos.pop.unpack("NNNNNNNNNNNNNa*") infostring = infos.pop info.push(infos) end return info end def trns_divide_sentence(strings) response = request ["NNNa*c", TRNS_DIVIDE_SENTENCE, @opened_dict, 0, strings, 0] return "" if response[0] < 0 && response[0] != -205 && response[0] != -206 strings = response.pop.unpack("Na*") return strings.pop.split(/\n/) end end server = ENV['HONYAKUSERVER'] ? ENV['HONYAKUSERVER'] : "localhost" port = ENV['HONYAKUPORT'] ? ENV['HONYAKUPORT'] : "2744" dict = ENV['HONYAKUDICT'] ? ENV['HONYAKUDICT'] : "ej" username = ENV['USER'] ? ENV['USER'] : "anonymous" kanjicode = RUBY_PLATFORM =~ /mswin32/ ? "SJIS" : "EUC" unless getopts(nil, "s:#{server}", "p:#{port}", "d:#{dict}", "u:#{username}", "k:#{kanjicode}") $stderr.puts("usage: honyaku [-s server] [-p port] [-d ej | je] [-u username] [-k kanjicode(SJIS,EUC,JIS)]") exit(1) end kanjicode = eval("Kconv::#{$OPT_k.upcase}") fd = HDconnect.new($OPT_s, $OPT_p, $OPT_d, $OPT_u) #fd.eg_setdictname(1, 1, 0, "") #fd.eg_clear_cache while gets chop print Kconv::kconv(fd.eg_translate_one(Kconv::toeuc($_)), kanjicode, Kconv::EUC), "\n" # start = 0 # equiv = [] # while TRUE # break if start >= $_.length # eq = fd.eg_getequiv(0, start) # if eq[0] < 0 # start += 1 # next # end # equiv.push(eq) # start += eq[1][0].length # end # equiv.each do |eq| # print "* ", $_[eq[1][0].start, eq[1][0].length], "\n" # p fd.eg_getword(eq[0], 1) # p fd.eg_gethinshi(eq[0]) # end end fd.close