@@ -103,29 +103,47 @@ class FileTransferService(Service):
103103
104104 ERR_NO_FILE = 0xb0
105105
106+
106107class FileTransferClient :
107108 def __init__ (self , service ):
108109 self ._service = service
109110
111+ def _write (self , buffer ):
112+ sent = 0
113+ while sent < len (buffer ):
114+ remaining = len (buffer ) - sent
115+ next_send = min (self ._service .raw .outgoing_packet_length , remaining )
116+ self ._service .raw .write (buffer [sent :sent + next_send ])
117+ sent += next_send
118+
119+ def _readinto (self , buffer ):
120+ read = 0
121+ # Read back how much we can write
122+ while read == 0 :
123+ try :
124+ read = self ._service .raw .readinto (buffer )
125+ except ValueError :
126+ long_buffer = bytearray (512 )
127+ read = self ._service .raw .readinto (long_buffer )
128+ print ("long packet" , long_buffer [:read ])
129+ return read
130+
110131 def read (self , path ):
111132 print ("read" , path )
112133 path = path .encode ("utf-8" )
113134 chunk_size = 10
114135 encoded = struct .pack (">BIH" , FileTransferService .READ , chunk_size , len (path )) + path
115- # TODO: we may need to split this packet up.
116- r = self ._service .raw .write (encoded )
136+ r = self ._write (encoded )
117137 b = bytearray (struct .calcsize (">BBII" ) + chunk_size )
118- print ("write" , r , encoded )
119138 contents_read = 0
120139 content_length = None
121140 buf = None
122141 while content_length is None or contents_read < content_length :
123- read = 0
124- # Read back how much we can write
125- while read == 0 :
126- read = self ._service .raw .readinto (b )
142+ read = self ._readinto (b )
127143 cmd , status , content_length , chunk_length = struct .unpack_from (">BBII" , b )
128144 print ("got reply" , cmd , status , content_length , chunk_length )
145+ if status != FileTransferService .OK :
146+ raise ValueError ("Missing file" )
129147 if buf is None :
130148 buf = bytearray (content_length )
131149 header_size = struct .calcsize (">BBII" )
@@ -144,16 +162,12 @@ def write(self, path, contents):
144162 print ("write" , path , contents )
145163 path = path .encode ("utf-8" )
146164 encoded = struct .pack (">BIH" , FileTransferService .WRITE , len (contents ), len (path )) + path
147- # TODO: we may need to split this packet up.
148- r = self ._service .raw .write (encoded )
165+ r = self ._write (encoded )
149166 b = bytearray (struct .calcsize (">BBI" ))
150167 print ("write" , r , encoded )
151168 written = 0
152169 while written < len (contents ):
153- read = 0
154- # Read back how much we can write
155- while read == 0 :
156- read = self ._service .raw .readinto (b )
170+ read = self ._readinto (b )
157171 cmd , status , free_space = struct .unpack (">BBI" , b )
158172 print (cmd , status , free_space )
159173 self ._service .raw .write (contents [written :written + free_space ])
@@ -163,19 +177,32 @@ def mkdir(self, path):
163177 print ("mkdir" , path )
164178 path = path .encode ("utf-8" )
165179 encoded = struct .pack (">BH" , FileTransferService .MKDIR , len (path )) + path
166- # TODO: we may need to split this packet up.
167- r = self ._service .raw .write (encoded )
180+ r = self ._write (encoded )
168181
169182 b = bytearray (struct .calcsize (">BB" ))
170- read = 0
171- # Read back how much we can write
172- while read == 0 :
173- read = self ._service .raw .readinto (b )
183+ read = self ._readinto (b )
174184 cmd , status = struct .unpack (">BB" , b )
175185 print (cmd , status )
176186
177187 def listdir (self , path ):
178188 print ("listdir" , path )
189+ path = path .encode ("utf-8" )
190+ chunk_size = 10
191+ encoded = struct .pack (">BH" , FileTransferService .LISTDIR , len (path )) + path
192+ r = self ._write (encoded )
193+ b = bytearray (struct .calcsize (">BBIIBIH" ))
194+ i = 0
195+ total = 10
196+ while i < total :
197+ read = self ._readinto (b )
198+ cmd , status , i , total , flags , file_size , path_length = struct .unpack (">BBIIBIH" , b )
199+ if i >= total :
200+ break
201+ if len (b ) < path_length :
202+ b = bytearray (path_length )
203+ read = self ._readinto (b )
204+ path = str (b [:read ], "utf-8" )
205+ print (i , total , flags , file_size , path )
179206
180207 def delete (self , path ):
181208 print ("delete" , path )
0 commit comments