2 * @fileOverview 低レベルAPIを定義する。低レベルAPIは、MiMicRemoteMcuをインストールしたMCUとの通信クラスを提供する。
\r
13 * MiMicJsAPIのバージョン文字列。
\r
14 * @name MiMicJS#VERSION
\r
16 NS.VERSION="MiMicJsAPI/2.0.3";
\r
18 * 配列要素、又は値がすべてInt値でない場合に例外を起こします。
\r
19 * @name MiMicJS.assertInt
\r
21 * @param {[array]} v
\r
24 NS.assertInt=function assertInt(v){
\r
26 if(!NS.isInt(v)){throw new NS.MiMicException();}
\r
28 for(var i=0;i<v.length;i++){
\r
32 throw new NS.MiMicException('"'+v[i]+'" is not integer.');
\r
36 * 配列要素、、又は値がすべて数値でない場合に例外を起こします。
\r
37 * @name MiMicJS.assertNumber
\r
39 * @param {[array]} v
\r
42 NS.assertNumber=function assertNumber(v){
\r
44 if(!NS.isNumber(v)){ throw new NS.MiMicException();}
\r
46 for(var i=0;i<v.length;i++){
\r
47 if(NS.isNumber(v[i])){
\r
50 throw new NS.MiMicException('"'+v[i]+'" is not number.');
\r
57 NS.isUndefined=function(v,def){
\r
58 if(arguments.length==1){return v === void 0;}
\r
59 return (v === void 0)?def:v;
\r
65 NS.isNumber=function isNumber(o)
\r
67 return (typeof o=='number');
\r
73 NS.isInt=function isInt(o)
\r
75 return (typeof o=='number') && (o-Math.round(o)==0);
\r
79 * オブジェクトがジェネレータクラスであるかを返します。
\r
82 NS.isGenerator=function isGenerator(o)
\r
84 if(!o){return false;}
\r
85 return o.toString().indexOf('Generator')!=-1;
\r
88 * オブジェクトが関数であるかを返します。
\r
91 NS.isFunction=function isFunction(o){
\r
92 return (typeof o == 'function');
\r
98 NS.getNow=function getNow(){
\r
99 return (new Date()).getTime();
\r
105 NS.isArray=function isArray(a){
\r
106 return a instanceof Array;
\r
112 NS.isHashArray=function isHashArray(a){
\r
113 return (!(a instanceof Array)) && (typeof a == "object");
\r
116 * 連想配列をシャローコピーして複製します。
\r
119 NS.cloneAssoc=function cloneAssoc(a)
\r
129 * 桁数を指定して、int値を16進数に変換します。
\r
130 * @param {int} i_val
\r
132 * @param {int} i_digit
\r
137 NS.hexout=function hexout(i_val,i_digit)
\r
139 var dt=["","0","00","000","0000","00000","000000","0000000"];
\r
140 var s=(i_val>>>0).toString(16).toLowerCase();
\r
141 if(s.length>i_digit){
\r
143 throw new NS.MiMicException(EE.NG);
\r
145 var l=i_digit-s.length;
\r
152 NS.assocToStr=function assocToStr(a)
\r
155 for(k in a){s+=k+":"+a[k]+",";}
\r
160 * 32bit値のエンディアンを交換します。
\r
166 NS.bswap32=function bswap32(v)
\r
168 return ((v<<24)&0xff000000)|((v<<8)&0xff0000)|((v>>8)&0xff00)|((v>>24)&0xff);
\r
172 * バイナリ文字列をバイト値として配列に変換します。
\r
176 NS.bstr2byteArray=function bstr2byteArray(v)
\r
180 throw new NS.MiMicException();
\r
182 for(var i=0;i<v.length;i+=2){
\r
183 r.push(parseInt(v.substr(i,2),16));
\r
189 * バイナリ文字列を32bitUInt数値配列に変換します。
\r
190 * Uint値はLittleEndianとして解釈します。
\r
194 NS.bstr2uintArray=function bstr2uintArray(v)
\r
198 throw new NS.MiMicException();
\r
200 for(var i=0;i<v.length;i+=8){
\r
201 r.push(NS.bswap32(parseInt(v.substr(i,8),16)));
\r
206 * ByteArrayをBinarayStringに変換します。
\r
207 * @name MiMicJS.byteArray2bstr
\r
212 NS.byteArray2bstr=function byteArray2bstr(v)
\r
214 var s=NS.isArray(v)?v:[v];
\r
216 for(var i=0;i<s.length;i++){
\r
217 r+=NS.hexout(s[i],2,16);
\r
222 * UInt32ArrayをBinarayStringに変換します。
\r
223 * 出力はLittleEndianの配列です。
\r
224 * @name MiMicJS.uintArray2bstr
\r
230 NS.uintArray2bstr=function uintArray2bstr(v)
\r
232 var s=NS.isArray(v)?v:[v];
\r
234 for(var i=0;i<s.length;i++){
\r
235 r+=NS.hexout(NS.bswap32(s[i]),8,16);
\r
241 * 連想配列の内容をルートオブジェクト直下に展開します。
\r
242 * この関数は名前空間を汚染します。十分に注意して使用してください。
\r
243 * @name MiMicJS.using
\r
245 * @param {HashMap} v
\r
248 * MiMicJS.using(mbedJS);
\r
249 * MiMicJS.using(mbedJS.PinName);
\r
251 NS.using=function using(v)
\r
253 for (var key in v) {
\r
254 window[key]=v[key];
\r
258 * MiMicSDK向けの内部関数です。
\r
259 * 末尾引数が関数の場合にはその関数を、異なる場合はi_cbを返却します。
\r
263 * @param i_default_cb
\r
264 * 引数配列に関数がなかった場合に返す値を指定します。
\r
266 NS._getCb=function _getCb(i_arg,i_default_cb)
\r
268 if(i_arg.length==0){
\r
269 return i_default_cb;
\r
271 return NS.isFunction(i_arg[i_arg.length-1])?i_arg[i_arg.length-1]:i_default_cb;
\r
275 * 末尾の拡張変数を取り除いたarguments引数の数を返します。
\r
278 NS._getBaseArgsLen=function _getBaseArgsLen(i_arg)
\r
280 if(i_arg.length==0 || (!NS.isFunction(i_arg[i_arg.length-1]))){
\r
281 return i_arg.length;
\r
283 return i_arg.length==1?0:i_arg.length-1;
\r
288 * インスタンスがyieldコール可能かをチェックし、可能ならコール関数を記録します。
\r
289 * 関数は、インスタンスの_gen,_lcをチェックして、yieldが不可能な場合に例外を発生します。
\r
290 * _assertYield.call(this)でコールして下さい。
\r
293 NS._assertYield=function _assertYield()
\r
295 if(this._gen && this._lc){
\r
296 throw new NS.MiMicException(NS.Error.NG_YIELD_NOT_COMPLETED);
\r
300 * MiMicSDK向けの関数です。コンストラクタでイベントハンドラをセットアップする定型処理です。
\r
301 * i_handlerにセットされたオブジェクトに従って_gen,_eventメンバをセットします。
\r
302 * _initHandler.call(this,i_handler)でコールして下さい。
\r
305 NS._initHandler=function _initHandler(i_handler)
\r
307 if(NS.isGenerator(i_handler)){
\r
308 this._gen=i_handler;
\r
309 }else if(NS.isFunction(i_handler)){
\r
311 }else if(i_handler){
\r
312 this._event=i_handler;
\r
313 return i_handler.onNew;
\r
325 * MiMicExceptionが使用するエラーコードと、その判定関数を定義する。
\r
326 * エラーコードは、以下の形式の配列オブジェクトで表現する。
\r
328 * [code:int,message:string]
\r
331 * codeは31ビットのエラーコードである。ビットフィールドの意味は以下の通りである。
\r
333 * <tr><th>bit</th><th>name</th><th>discription</th></tr>
\r
334 * <tr><td>30</td><td>ErrorBit</td><td>Error:1,OK:0</td></tr>
\r
335 * <tr><td>29-24</td><td>Reserved</td><td>-</td></tr>
\r
336 * <tr><td>23-16</td><td>ModuleID</td><td>0x00:unknown<br/>0x39:MiMic<br/>0xF0-0xFF: user define<br/>Other:Reserved<br/></td></tr>
\r
337 * <tr><td>15-8</td><td>ClassID</td><td>0x00:unknown</td></tr>
\r
338 * <tr><td>7-0</td><td>ErrorID</td><td></td></tr>
\r
341 * @name MiMicJS.Error
\r
343 * throw new MiMicException(MiMicError.NG);
\r
349 * @name MiMicJS.Error.OK
\r
351 OK:[0x00000000,"OK"],
\r
354 * @name MiMicJS.Error.NG
\r
356 NG:[0x40000000,"NG"],
\r
357 /** Generatorを用いたコードで、前回のyieldが終了していないことを示します。
\r
359 * @name MiMicJS.Error.NG_YIELD_NOT_COMPLETED
\r
361 NG_YIELD_NOT_COMPLETED:[0x40001001,"The previous function has not been completed."],
\r
362 /** 関数の呼び出し順序が正しくないことを示します。
\r
364 * @name MiMicJS.Error.NG_ILLEGAL_CALL
\r
366 NG_ILLEGAL_CALL:[0x40001002,"Illegal procedure call."],
\r
367 /** 引数型の不一致を検出したことを示します。
\r
369 * @name MiMicJS.Error.NG_INVALID_ARG
\r
371 NG_INVALID_ARG:[0x40001003,"Invalid arguments."],
\r
375 * @name MiMicJS.Error.isOK
\r
376 * @param {Object as [MiMicErrorCode]} v
\r
378 * @return {Boolean}
\r
379 * エラーコードでなければ、trueを返す。
\r
381 * MiMicError.isOK(MiMicError.OK);//true
\r
384 return (0x40000000 & v)==0x00000000;
\r
394 * @name MiMicJS.MiMicException:2
\r
396 * @param {object} e
\r
399 * <li>{string} - MiMicException(Error.NG,e)と等価である。</li>
\r
400 * <li>{object as [MiMicErrorCode]} - エラーコードを指定して例外を生成する。エラーコードについては、MiMicJs.Errorを参照</li>
\r
401 * <li>{object} - MiMicException(MiMicError.NG,e.toString())と等価である。objectを文字列化して例外を生成する。</li>
\r
402 * <li>{MiMicException} - codeとmessageを継承して例外を生成する。コールスタックを生成するときは、このパターンを使うこと。</li>
\r
405 * throw new MiMicException(MiMicError.NG);
\r
406 * throw new MiMicException("Error");
\r
408 * throw new MiMicException("Error");
\r
410 * throw new MiMicException(e);
\r
414 * MiMic javascript APIが生成する例外クラスのコンストラクタである。関数ごとにMiMicExceptionを使ったtry-catchを導入することにより、例外発生時にスタックトレースメッセージを得ることが出来る。
\r
415 * スタックトレースは改行で連結された文字列である。messageプロパティに格納される。alert関数で表示することで、効率的なデバックが可能である。
\r
416 * 引数の違いにより、数種類の呼び出し方がある。
\r
418 * @name MiMicJS.MiMicException
\r
420 * 詳細は、MiMicException:nを参照。
\r
422 NS.MiMicException=function MiMicException(/*...*/)
\r
425 if(typeof arguments.callee.caller=="function"){
\r
426 if(arguments.callee.caller.name.toString().length>0){
\r
427 pfx="function '"+arguments.callee.caller.name+'.';
\r
429 var s=arguments.callee.caller.toString();
\r
430 pfx="closure '"+s.substring(0,s.indexOf("{"))+"...'";
\r
433 pfx="root document";
\r
436 switch(arguments.length){
\r
439 this.code=NS.Error.NG[0];
\r
440 this.message=pfx+" code(0x"+this.code.toString(16)+")"+NS.Error.NG[1];
\r
443 var v=arguments[0];
\r
444 if(v instanceof NS.MiMicException){
\r
447 sfx=" \nfrom "+v.message;
\r
448 }else if(typeof v=="object" && v.length==2){
\r
454 this.code=NS.Error.NG[0];
\r
455 sfx=NS.Error.NG[1]+" "+(((typeof v)!='undefined')?v.toString():"v==undefined");
\r
457 this.message=pfx+" code(0x"+this.code.toString(16)+")"+sfx;
\r
462 throw new NS.MiMicException("Invalid MiMicException argument.");
\r
465 NS.MiMicException.prototype=
\r
469 * MiMicErrorCode形式のエラーコードを保持する。
\r
470 * @field {object as MiMicErrorCode}
\r
471 * @name MiMicJS.MiMicException#code
\r
475 * エラーメッセージを保持する。この値は、改行区切りのコールスタックである。
\r
477 * @name MiMicJS.MiMicException#message
\r
481 * messageフィールドをalertで表示する。
\r
482 * @name MiMicJS.MiMicException#alert
\r
486 * throw new MiMicException();
\r
492 alert(this.message);
\r
495 * toStringを上書きする。オブジェクトを文字列化する。
\r
496 * 文字列は例外のコールスタックであり、デバックで役立つ。
\r
498 * @name MiMicJS.MiMicException#toString
\r
500 * 現在のオブジェクトの状態(例外のコールスタック)
\r
503 * throw new MiMicException();
\r
505 * alert(e.toString());
\r
508 toString:function()
\r
510 return "MiMicException:"+this.message;
\r
519 * MiMicRPCのクライアントクラスです。
\r
521 * @name MiMicJS.Rpc
\r
523 * @param {HashMap} i_event
\r
524 * 非同期イベントハンドラの連想配列です。登録できるメンバは以下の通りです。
\r
526 * <li>onOpen:function() -
\r
527 * open関数のコールバック関数です。
\r
528 * <li>onClose:function() -
\r
529 * close関数のコールバック関数です。
\r
530 * <li>onError:function() -
\r
531 * 何らかの異常で通信を継続できないエラーが発生し、コネクションを維持できない時に発生します。
\r
532 * このイベントが発生するとコネクションは閉じられます。
\r
535 NS.Rpc=function Rpc(i_event)
\r
537 this._event=(i_event)?i_event:null;
\r
544 * Websocketインスタンスです。
\r
551 * @name MiMicJs.Rpc#RTT
\r
554 /** メソッドIDカウンタ。sendJsonを実行する毎にインクリメントされます。*/
\r
558 * 関数が終了するとonOpenイベントをコールバックします。
\r
559 * @name MiMicJS.Rpc#open
\r
562 * ws://から始まるWebsocketサービスURLを指定します。
\r
564 open:function open(i_url)
\r
568 throw new MiMicException();
\r
572 var ev=this._event;
\r
573 var ws=new WebSocket(i_url);
\r
574 ws.onopen = function(){
\r
575 if(ev.onOpen){ev.onOpen();}
\r
577 ws.onclose = function(){
\r
578 if(ev.onClose){ev.onClose();}
\r
580 ws.error = function(){
\r
582 if(ev.onClose){ev.onError();}
\r
587 ws.onmessage = function (e)
\r
589 //ストリームからJSONを抽出。"のエスケープには対応しない。
\r
590 for(var i=0;i<e.data.length;i++){
\r
617 for(var i2=q.length-1;i2>=0;i2--){
\r
618 if(q[i2][0]==j.id){
\r
623 if(qi[1]){qi[1](j);}
\r
639 * 接続中のRPCコネクションを閉じます。
\r
640 * 関数が終了するとonCloseイベントをコールバックします。
\r
641 * @name MiMicJS.Rpc#close
\r
644 close:function close()
\r
646 if(this._ws && this._ws.readyState==1){
\r
653 * この関数を実行すると、すべてのコールバックイベントはキャンセルされます。
\r
654 * @name MiMicJS.Rpc#shutdown
\r
657 shutdown:function shutdown()
\r
661 _t._ws.onopen=function(){_t._ws.close();};
\r
662 _t._ws.onmessage=function(){_t._ws.close();};
\r
663 _t._ws.onclose=function(){_t._ws=null;};
\r
664 _t._ws.onerror=function(){_t._ws=null;};
\r
668 * 非同期でJSON RPCメソッドを送信します。
\r
669 * @name MiMicJS.Rpc#sendMethod
\r
671 * @param {string} i_method
\r
673 * @param {string} i_params
\r
674 * カンマ区切りのJSONスタイルの文字列です。この文字列は[....]に埋め込まれます。エスケープ文字列は使用できません。
\r
675 * @param {function(json)}i_callback
\r
676 * Resultを受け取るコールバック関数です。jsonにはResult JSONをパースしたオブジェクトが入ります。
\r
680 sendMethod:function callJsonRpc(i_method,i_params,i_callback)
\r
682 var v="{\"jsonrpc\":\"2.0\",\"method\":\""+i_method+"\",\"params\":["+i_params+"],\"id\":"+this._method_id+"}";
\r
685 this._q.push([this._method_id,i_callback]);//キューに記録
\r
686 this._method_id=(this._method_id+1)&0x0fffffff;//IDインクリメント
\r
687 return this._method_id;
\r