WEBVTT

1
00:00:00.000 --> 00:00:00.847
こんにちは。

2
00:00:00.847 --> 00:00:06.772
今回はジャバスクリプトのデータビューにある、ゲットユーイントじゅうろくを紹介します。

3
00:00:06.772 --> 00:00:12.275
これは、バイナリデータの中から二バイトを取り出し、整数として読むメソッドです。

4
00:00:12.275 --> 00:00:19.189
通信データやファイルの先頭部分では、件数や識別番号が二バイトの整数で記録されることがよくあります。

5
00:00:19.189 --> 00:00:24.409
受け取ったバイトを文字列としてつなげただけでは、正しい数値は得られません。

6
00:00:24.409 --> 00:00:31.181
このメソッドは、読む位置とバイトの並び順を指定して、データ形式の仕様どおりに数値を取り出せます。

7
00:00:31.181 --> 00:00:36.684
この動画では、引数と戻り値、バイト順の違い、実例と注意点までを順に解説します。

8
00:00:36.684 --> 00:00:42.892
バイナリは難しそうに見えますが、読む位置と順序さえ分かれば、一つずつ確実に取り出せます。

9
00:00:42.892 --> 00:00:44.641
まず土台を押さえましょう。

10
00:00:44.641 --> 00:00:48.811
バイナリデータの入れ物は、アレイバッファーというバイト列です。

11
00:00:48.811 --> 00:00:53.923
そのままでは数値として読めないので、データビューという窓口を通して読みます。

12
00:00:53.923 --> 00:00:58.363
データビューを使えば、好きな位置から、好きな型で値を取り出せます。

13
00:00:58.363 --> 00:01:03.609
似た仕組みに型付き配列がありますが、そちらは実行環境のバイト順に左右されます。

14
00:01:03.609 --> 00:01:07.645
データビューはバイト順を自分で指定できる点が大きな違いです。

15
00:01:07.645 --> 00:01:14.237
ファイル形式や通信の仕様が決まっている場面では、この指定できることが正確な読み取りにつながります。

16
00:01:14.237 --> 00:01:17.600
まずは窓口を用意する、という流れを覚えてください。

17
00:01:17.600 --> 00:01:19.658
基本の書き方を見ましょう。

18
00:01:19.658 --> 00:01:26.623
呼び出しは、ビューに続けてゲットユーイントじゅうろく、かっこの中に二つの引数を書きます。

19
00:01:26.623 --> 00:01:32.797
第一引数のバイトオフセットは、ビューの先頭から何バイト進んだ位置を読むかです。

20
00:01:32.797 --> 00:01:34.063
先頭はゼロです。

21
00:01:34.063 --> 00:01:38.970
第二引数のリトルエンディアンは省略でき、トゥルーならリトルエンディアン、

22
00:01:38.970 --> 00:01:43.878
フォルスか省略ならビッグエンディアンとして読みます。

23
00:01:43.878 --> 00:01:48.468
戻り値はゼロ以上六五五三五以下の整数で、型はナンバーです。

24
00:01:48.468 --> 00:01:51.160
符号がないので負の値は返りません。

25
00:01:51.160 --> 00:01:56.700
開始位置を二の倍数にそろえる必要はなく、奇数の位置からも読み取れます。

26
00:01:56.700 --> 00:01:59.206
ここが一番大切なポイントです。

27
00:01:59.206 --> 00:02:04.887
バイト順とは、二バイトのどちらを上位の桁として扱うかという約束です。

28
00:02:04.887 --> 00:02:09.899
ビッグエンディアンでは、先にあるバイトを上位として読みます。

29
00:02:09.899 --> 00:02:16.416
たとえばゼロイチとゼロニの並びなら、一かける二五六たす二で、二五八になります。

30
00:02:16.416 --> 00:02:23.767
リトルエンディアンでは逆に、後ろのバイトを上位にするので、同じ並びでも五一三になります。

31
00:02:23.767 --> 00:02:28.446
どちらが正しいかは、データを書いた側の仕様で決まります。

32
00:02:28.446 --> 00:02:33.959
それらしい数になるまで切り替える運用は、別の入力で誤読のもとです。

33
00:02:33.959 --> 00:02:39.640
仕様にバイト順を明記し、コードでも引数を明示して意図を残しましょう。

34
00:02:39.640 --> 00:02:41.280
対応環境を確認しましょう。

35
00:02:41.280 --> 00:02:48.850
ゲットユーイントじゅうろくは広く利用できる機能で、二千十五年以降、主要ブラウザーの間で使えるようになったとされています。

36
00:02:48.850 --> 00:02:53.140
現在のクローム、エッジ、ファイアフォックス、サファリで使用できます。

37
00:02:53.140 --> 00:02:58.312
ジャバスクリプトの組み込み機能なので、ブラウザーでもノードジェイエスでも動きます。

38
00:02:58.312 --> 00:03:00.709
外部パッケージやビルド処理は不要です。

39
00:03:00.709 --> 00:03:04.747
ブラウザーでは開発者ツールのコンソールにコードを貼って試せます。

40
00:03:04.747 --> 00:03:09.036
ノードジェイエスでは、ファイルを保存してノードコマンドで実行します。

41
00:03:09.036 --> 00:03:12.190
今回の記事ではノードの二十四系を対象にしています。

42
00:03:12.190 --> 00:03:15.092
まずは手元の環境で小さく試すのがおすすめです。

43
00:03:15.092 --> 00:03:19.508
古い環境を対象にする場合は、公開前に対応状況を改めて確認してください。

44
00:03:19.508 --> 00:03:21.216
ここからは実例です。

45
00:03:21.216 --> 00:03:27.875
先頭の二バイトが件数、続く二バイトが識別番号という、架空のヘッダーを読みます。

46
00:03:27.875 --> 00:03:33.510
実ファイルやネットワークは使わず、データはコードの中で用意します。

47
00:03:33.510 --> 00:03:40.340
パケットというバイト列には、対象の前後に読み取り対象外のバイトを置いてあります。

48
00:03:40.340 --> 00:03:45.804
ヘッダーは、サブアレイで中央の四バイトだけを切り出したものです。

49
00:03:45.804 --> 00:03:52.805
こうすることで、部分データを扱うときの開始位置と長さの考え方も一緒に確認できます。

50
00:03:52.805 --> 00:03:58.270
件数のバイトはゼロゼロとゼロ三、識別番号はゼロイチとゼロニです。

51
00:03:58.270 --> 00:04:02.880
この四バイトを正しく読めるかが、この実例のゴールです。

52
00:04:02.880 --> 00:04:05.166
読み取り関数の流れを見ましょう。

53
00:04:05.166 --> 00:04:09.882
パースヘッダーという独自関数では、まず入力の型と長さを確かめます。

54
00:04:09.882 --> 00:04:16.455
ユーイントはちアレイでなければタイプエラー、四バイトでなければレンジエラーを投げて止めます。

55
00:04:16.455 --> 00:04:18.456
次にデータビューを作ります。

56
00:04:18.456 --> 00:04:24.029
このとき、元のバッファーだけでなく、開始位置と長さも一緒に渡すことが重要です。

57
00:04:24.029 --> 00:04:30.602
最後に、位置ゼロを件数として、位置二を識別番号として、どちらもビッグエンディアンで読みます。

58
00:04:30.602 --> 00:04:37.033
チェックを先に済ませておくことで、読み取り部分は短く、意図が分かりやすいコードになります。

59
00:04:37.033 --> 00:04:39.748
スライドでは検証部分を省略しています。

60
00:04:39.748 --> 00:04:41.712
実行結果を確認しましょう。

61
00:04:41.712 --> 00:04:45.792
件数は、バイト列がゼロゼロとゼロ三なので三になります。

62
00:04:45.792 --> 00:04:51.081
識別番号は、ゼロイチとゼロニをビッグエンディアンで読むので二五八です。

63
00:04:51.081 --> 00:04:56.067
同じ位置をあえてリトルエンディアンで読むと、五一三と表示されます。

64
00:04:56.067 --> 00:05:01.658
これは間違いではなく、バイト順を変えれば値が変わることを示すための行です。

65
00:05:01.658 --> 00:05:06.342
結果が仕様と合っているかは、期待する出力と見比べて確かめます。

66
00:05:06.342 --> 00:05:15.710
なお記事の期待出力は、公式仕様と数値計算に基づくもので、例外については環境差を避けるため名前だけを出力する形になっています。

67
00:05:15.710 --> 00:05:18.128
計算の根拠まで追えると安心です。

68
00:05:18.128 --> 00:05:19.508
よくある失敗例です。

69
00:05:19.508 --> 00:05:24.201
データビューを作るときに、バッファーだけを渡してしまうと、読み取り範囲はヘッダーの四バイトではなく、

70
00:05:24.201 --> 00:05:28.893
元のパケット全体になってしまいます。

71
00:05:28.893 --> 00:05:36.760
その状態で位置ゼロを読むと、対象外のエフエフと次のゼロゼロから、六五二八ゼロというまったく違う値を得てしまいます。

72
00:05:36.760 --> 00:05:42.005
防ぐには、生成時に元のバッファー内での開始位置と対象の長さを渡してください。

73
00:05:42.005 --> 00:05:47.249
一方、ゲットユーイントじゅうろくに渡す位置は、作ったビューの先頭が基準です。

74
00:05:47.249 --> 00:05:50.148
そこで再び開始位置を足す必要はありません。

75
00:05:50.148 --> 00:05:53.460
この二つの基準の違いを混同しないことが大切です。

76
00:05:53.460 --> 00:05:56.115
範囲外の扱いも知っておきましょう。

77
00:05:56.115 --> 00:06:03.454
二バイトを読むため、開始位置だけが範囲内でも、次の一バイトが不足すればレンジエラーになります。

78
00:06:03.454 --> 00:06:09.388
たとえば長さ四のビューで位置三から読むと、位置三と四が必要になり失敗します。

79
00:06:09.388 --> 00:06:14.854
通信途中のデータを扱うなら、必要な長さがそろってから解析してください。

80
00:06:14.854 --> 00:06:18.758
また、読み取れた整数が業務上正しいとは限りません。

81
00:06:18.758 --> 00:06:25.160
件数の上限が百件なら、百一は読み取り自体は成功しても受け付けるべきではありません。

82
00:06:25.160 --> 00:06:28.439
構造の検査と値の検査は分けて考えましょう。

83
00:06:28.439 --> 00:06:32.968
なお、このメソッドは同期処理なので、アウェイトは不要です。

84
00:06:32.968 --> 00:06:34.957
最後に活用場面とまとめです。

85
00:06:34.957 --> 00:06:40.568
ゲットユーイントじゅうろくは、独自通信形式の件数、バイナリファイルの形式番号、

86
00:06:40.568 --> 00:06:46.180
機器から届く十六ビットの測定値など、二バイトの符号なし整数を読む場面で使えます。

87
00:06:46.180 --> 00:06:51.294
負の値や六五五三五を超える値を表す項目には、そのまま当てはめられません。

88
00:06:51.294 --> 00:06:55.272
実装を育てるなら、まずデータ形式の各項目について、開始位置、必要バイト数、

89
00:06:55.272 --> 00:06:59.250
バイト順、許容値を書き出してください。

90
00:06:59.250 --> 00:07:05.642
その定義に合わせて読み取り位置を固定すると、形式が変わったときの修正箇所が明確になります。

91
00:07:05.642 --> 00:07:11.609
正常なデータだけでなく、一バイト不足した入力や上下限の入力でも確かめてみてください。

92
00:07:11.609 --> 00:07:12.888
お疲れさまでした。

93
00:07:12.888 --> 00:07:14.166
位置、順序、範囲。

94
00:07:14.166 --> 00:07:18.428
この三つをそろえることが、安定した読み取りの土台になります。
