OSDN Git Service

暫定で記録。
[gokigen/A01d.git] / app / src / main / java / net / osdn / gokigen / a01d / camera / nikon / wrapper / liveview / NikonLiveViewImageReceiver.kt
1 package net.osdn.gokigen.a01d.camera.nikon.wrapper.liveview
2
3 import android.util.Log
4 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandCallback
5 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.liveview.IPtpIpLiveViewImageCallback
6 import net.osdn.gokigen.a01d.camera.utils.SimpleLogDumper
7 import java.io.ByteArrayOutputStream
8
9 class NikonLiveViewImageReceiver(private var callback: IPtpIpLiveViewImageCallback) : IPtpIpCommandCallback
10 {
11     private val isDumpLog = true
12     private var receivedTotalBytes = 0
13     private var receivedRemainBytes = 0
14     private var receivedFirstData = false
15     private var byteStream = ByteArrayOutputStream()
16
17     override fun receivedMessage(id: Int, rx_body: ByteArray?)
18     {
19         if (rx_body == null)
20         {
21             Log.v(TAG, " NikonLiveViewImageReceiver: MSG BODY IS NULL. (ID:$id)")
22             callback.onCompleted(rx_body, null)
23             return
24         }
25         if (isReceiveMulti)
26         {
27             receivedMessageMulti(id, rx_body)
28         }
29         else
30         {
31             receivedMessageSingle(id, rx_body)
32         }
33     }
34
35     override fun onReceiveProgress(currentBytes: Int, totalBytes: Int, rx_body: ByteArray?)
36     {
37         if (rx_body == null)
38         {
39             Log.v(TAG, " NikonLiveViewImageReceiver: MSG BODY IS NULL.")
40             return
41         }
42         Log.v(TAG, " onReceiveProgress() $currentBytes/$totalBytes LENGTH: ${rx_body.size} bytes.")
43         if ((currentBytes > totalBytes)&&((currentBytes - totalBytes) < (32 + 14)))
44         {
45             // Operation Response Packet を受信していないとき...
46             Log.v(TAG, " ===== DO NOT RECEIVE RESPONSE MESSAGE YET. =====")
47         }
48
49         // 受信したデータから、通信のヘッダ部分を削除する
50         cutHeader(rx_body)
51     }
52
53     private fun receivedMessageSingle(id: Int, rx_body: ByteArray)
54     {
55         try
56         {
57             Log.v(TAG, "receivedMessage_single() : " + rx_body.size + " bytes. id:$id")
58             if ((isDumpLog)&&(rx_body.size > 64))
59             {
60                 SimpleLogDumper.dump_bytes(" LV (FIRST) : ", rx_body.copyOfRange(0, 64))
61                 SimpleLogDumper.dump_bytes(" LV (-END-) : ", rx_body.copyOfRange(rx_body.size - 64, rx_body.size))
62             }
63             callback.onCompleted(rx_body, null)
64         }
65         catch (e: Exception)
66         {
67             e.printStackTrace()
68         }
69     }
70
71     private fun receivedMessageMulti(id: Int, rx_body: ByteArray)
72     {
73         try
74         {
75             Log.v(TAG, " receivedMessage_multi()  id[$id] size : ${rx_body.size}  id:$id")
76
77             callback.onCompleted(byteStream.toByteArray(), null)
78             receivedFirstData = false
79             receivedRemainBytes = 0
80             receivedTotalBytes = 0
81             byteStream.reset()
82         }
83         catch (e: Exception)
84         {
85             e.printStackTrace()
86             run { callback.onErrorOccurred(e) }
87         }
88     }
89
90     private fun cutHeader(rx_body: ByteArray)
91     {
92         val length = rx_body.size
93         var dataPosition = 0
94         if (!receivedFirstData)
95         {
96             // データを最初に読んだとき。ヘッダ部分を読み飛ばす
97             receivedFirstData = true
98             dataPosition = rx_body[0].toUByte().toInt()
99             if (isDumpLog)
100             {
101                 Log.v(TAG, " FIRST DATA POS. : $dataPosition len: $length ");
102                 SimpleLogDumper.dump_bytes(" [1stData]", rx_body.copyOfRange(0, (32)))
103             }
104         }
105         else
106         {
107             // 2回目以降の受信データ
108             if (receivedRemainBytes > 0)
109             {
110                 // データの読み込みが途中だった場合...
111                 if (length < receivedRemainBytes)
112                 {
113                     // 全部コピーする、足りないバイト数は残す
114                     receivedRemainBytes -= length
115                     receivedTotalBytes += rx_body.size
116                     byteStream.write(rx_body, 0, rx_body.size)
117                     return
118                 }
119                 else
120                 {
121                     byteStream.write(rx_body, dataPosition, receivedRemainBytes)
122                     dataPosition = receivedRemainBytes
123                     receivedRemainBytes = 0
124                 }
125             }
126         }
127         while (dataPosition <= length - 12)
128         {
129             val body_size = (rx_body[dataPosition].toUByte()).toInt() + ((rx_body[dataPosition + 1].toUByte()).toInt() * 256) + ((rx_body[dataPosition + 2].toUByte()).toInt() * 256 * 256) + ((rx_body[dataPosition + 3].toUByte()).toInt() * 256 * 256 * 256)
130             //Log.v(TAG, " <> body_size : ${body_size} [$dataPosition] ($length)  aa: ${rx_body[dataPosition].toUByte().toInt()}  ${rx_body[dataPosition + 1].toUByte().toInt()} + ${rx_body[dataPosition + 2].toUByte().toInt()}")
131             if (body_size <= 12)
132             {
133                 Log.v(TAG, " ----- BODY SIZE IS SMALL : " + dataPosition + " (" + body_size + ") [" + receivedRemainBytes + "] " + rx_body.size + " ")
134                 break
135             }
136
137             //Log.v(TAG, " RX DATA : " + dataPosition + " (" + body_size + ") [" + receivedRemainBytes + "] (" + receivedTotalBytes + ")");
138             if (dataPosition + body_size > length)
139             {
140                 // データがすべてバッファ内になかったときは、バッファすべてコピーして残ったサイズを記憶しておく。
141                 val copysize = length - (dataPosition + 12)
142                 byteStream.write(rx_body, dataPosition + 12, copysize)
143                 receivedRemainBytes = body_size - copysize - 12 // マイナス12は、ヘッダ分
144                 receivedTotalBytes += copysize
145                 //Log.v(TAG, " ----- copy : " + (data_position + (12)) + " " + copysize + " remain : " + received_remain_bytes + "  body size : " + body_size);
146                 break
147             }
148             try
149             {
150                 byteStream.write(rx_body, dataPosition + 12, body_size - 12)
151                 dataPosition += body_size
152                 receivedTotalBytes += 12
153                 //Log.v(TAG, " --- COPY : " + (data_position + 12) + " " + (body_size - (12)) + " remain : " + received_remain_bytes);
154             }
155             catch (e: Exception)
156             {
157                 Log.v(TAG, "  pos : $dataPosition  size : $body_size length : $length")
158                 e.printStackTrace()
159             }
160         }
161     }
162
163     override fun isReceiveMulti(): Boolean
164     {
165         return (true)
166     }
167
168     companion object
169     {
170         private val TAG = "NikonLiveViewImageReceiver"
171     }
172 }