@@ -306,6 +306,10 @@ static void _send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int l
306
306
}
307
307
}
308
308
309
+ STATIC void _print_raw (void * env , const char * str , size_t len ) {
310
+ _send_raw ((socketpool_socket_obj_t * )env , (const uint8_t * )str , (size_t )len );
311
+ }
312
+
309
313
static void _send_str (socketpool_socket_obj_t * socket , const char * str ) {
310
314
_send_raw (socket , (const uint8_t * )str , strlen (str ));
311
315
}
@@ -324,14 +328,19 @@ static void _send_strs(socketpool_socket_obj_t *socket, ...) {
324
328
}
325
329
326
330
static void _send_chunk (socketpool_socket_obj_t * socket , const char * chunk ) {
327
- char encoded_len [sizeof (size_t ) * 2 + 1 ];
328
- int len = snprintf (encoded_len , sizeof (encoded_len ), "%X" , strlen (chunk ));
329
- _send_raw (socket , (const uint8_t * )encoded_len , len );
330
- _send_raw (socket , (const uint8_t * )"\r\n" , 2 );
331
+ mp_print_t _socket_print = {socket , _print_raw };
332
+ mp_printf (& _socket_print , "%X\r\n" , strlen (chunk ));
331
333
_send_raw (socket , (const uint8_t * )chunk , strlen (chunk ));
332
334
_send_raw (socket , (const uint8_t * )"\r\n" , 2 );
333
335
}
334
336
337
+ STATIC void _print_chunk (void * env , const char * str , size_t len ) {
338
+ mp_print_t _socket_print = {socket , _print_raw };
339
+ mp_printf (& _socket_print , "%X\r\n" , len );
340
+ _send_raw ((socketpool_socket_obj_t * )env , (const uint8_t * )str , len );
341
+ _send_raw ((socketpool_socket_obj_t * )env , (const uint8_t * )"\r\n" , 2 );
342
+ }
343
+
335
344
// A bit of a misnomer because it sends all arguments as one chunk.
336
345
// The last argument must be NULL! Otherwise, it won't stop.
337
346
static void _send_chunks (socketpool_socket_obj_t * socket , ...) {
@@ -349,9 +358,9 @@ static void _send_chunks(socketpool_socket_obj_t *socket, ...) {
349
358
}
350
359
va_end (strs_to_count );
351
360
352
- char encoded_len [ sizeof ( size_t ) * 2 + 1 ];
353
- snprintf ( encoded_len , sizeof ( encoded_len ), "%X" , chunk_len ) ;
354
- _send_strs ( socket , encoded_len , " \r\n" , NULL );
361
+
362
+ mp_print_t _socket_print = { socket , _print_raw } ;
363
+ mp_printf ( & _socket_print , "%X \r\n" , chunk_len );
355
364
356
365
str = va_arg (strs_to_send , const char * );
357
366
while (str != NULL ) {
@@ -556,9 +565,8 @@ static void _reply_redirect(socketpool_socket_obj_t *socket, _request *request,
556
565
557
566
_send_strs (socket , "://" , hostname , ".local" , NULL );
558
567
if (web_api_port != 80 ) {
559
- char encoded_port [6 ];
560
- snprintf (encoded_port , sizeof (encoded_port ), "%d" , web_api_port );
561
- _send_strs (socket , ":" , encoded_port , NULL );
568
+ mp_print_t _socket_print = {socket , _print_raw };
569
+ mp_printf (& _socket_print , ":%d" , web_api_port );
562
570
}
563
571
_send_strs (socket , path , "\r\n" , NULL );
564
572
_cors_header (socket , request );
@@ -569,6 +577,7 @@ static void _reply_directory_json(socketpool_socket_obj_t *socket, _request *req
569
577
socketpool_socket_send (socket , (const uint8_t * )OK_JSON , strlen (OK_JSON ));
570
578
_cors_header (socket , request );
571
579
_send_str (socket , "\r\n" );
580
+ mp_print_t _socket_print = {socket , _print_chunk };
572
581
_send_chunk (socket , "[" );
573
582
bool first = true;
574
583
@@ -589,7 +598,7 @@ static void _reply_directory_json(socketpool_socket_obj_t *socket, _request *req
589
598
}
590
599
// We use nanoseconds past Jan 1, 1970 for consistency with BLE API and
591
600
// LittleFS.
592
- _send_chunk (socket , ", \"modified_ns\": " );
601
+ _send_chunk (socket , ", " );
593
602
594
603
uint64_t truncated_time = timeutils_mktime (1980 + (file_info .fdate >> 9 ),
595
604
(file_info .fdate >> 5 ) & 0xf ,
@@ -598,15 +607,13 @@ static void _reply_directory_json(socketpool_socket_obj_t *socket, _request *req
598
607
(file_info .ftime >> 5 ) & 0x1f ,
599
608
(file_info .ftime & 0x1f ) * 2 ) * 1000000000ULL ;
600
609
601
- char encoded_number [32 ];
602
- snprintf (encoded_number , sizeof (encoded_number ), "%lld" , truncated_time );
603
- _send_chunks (socket , encoded_number , ", \"file_size\": " , NULL );
610
+ mp_printf (& _socket_print , "\"modified_ns\": %lld, " , truncated_time );
604
611
size_t file_size = 0 ;
605
612
if ((file_info .fattrib & AM_DIR ) == 0 ) {
606
613
file_size = file_info .fsize ;
607
614
}
608
- snprintf ( encoded_number , sizeof ( encoded_number ), "%d " , file_size );
609
- _send_chunks ( socket , encoded_number , "}" , NULL );
615
+ mp_printf ( & _socket_print , "\"file_size\": %d } " , file_size );
616
+
610
617
first = false;
611
618
res = f_readdir (dir , & file_info );
612
619
}
@@ -619,9 +626,9 @@ static void _reply_with_file(socketpool_socket_obj_t *socket, _request *request,
619
626
char encoded_len [10 ];
620
627
snprintf (encoded_len , sizeof (encoded_len ), "%d" , total_length );
621
628
622
- _send_strs (socket ,
623
- "HTTP/1.1 200 OK\r\n" ,
624
- "Content-Length: " , encoded_len , " \r\n" , NULL );
629
+ _send_str (socket , "HTTP/1.1 200 OK\r\n" );
630
+ mp_print_t _socket_print = { socket , _print_raw };
631
+ mp_printf ( & _socket_print , "Content-Length: %d \r\n" , total_length );
625
632
// TODO: Make this a table to save space.
626
633
if (_endswith (filename , ".txt" ) || _endswith (filename , ".py" )) {
627
634
_send_str (socket , "Content-Type: text/plain\r\n" );
@@ -669,27 +676,23 @@ static void _reply_with_devices_json(socketpool_socket_obj_t *socket, _request *
669
676
socketpool_socket_send (socket , (const uint8_t * )OK_JSON , strlen (OK_JSON ));
670
677
_cors_header (socket , request );
671
678
_send_str (socket , "\r\n" );
672
- char total_encoded [ 4 ] ;
673
- snprintf ( total_encoded , sizeof ( total_encoded ), "%d" , total_results );
674
- _send_chunks ( socket , "{\"total\": " , total_encoded , ", \"devices\": [" , NULL );
679
+ mp_print_t _socket_print = { socket , _print_chunk } ;
680
+
681
+ mp_printf ( & _socket_print , "{\"total\": %d, \"devices\": [" , total_results );
675
682
for (size_t i = 0 ; i < count ; i ++ ) {
676
683
if (i > 0 ) {
677
684
_send_chunk (socket , "," );
678
685
}
679
686
const char * hostname = common_hal_mdns_remoteservice_get_hostname (& found_devices [i ]);
680
687
const char * instance_name = common_hal_mdns_remoteservice_get_instance_name (& found_devices [i ]);
681
- char port_encoded [6 ];
682
688
int port = common_hal_mdns_remoteservice_get_port (& found_devices [i ]);
683
- snprintf (port_encoded , sizeof (port_encoded ), "%d" , port );
684
- char ip_encoded [4 * 4 ];
685
689
uint32_t ipv4_address = mdns_remoteservice_get_ipv4_address (& found_devices [i ]);
686
690
uint8_t * octets = (uint8_t * )& ipv4_address ;
687
- snprintf (ip_encoded , sizeof (ip_encoded ), "%d.%d.%d.%d" , octets [0 ], octets [1 ], octets [2 ], octets [3 ]);
688
- _send_chunks (socket ,
689
- "{\"hostname\": \"" , hostname , "\", " ,
690
- "\"instance_name\": \"" , instance_name , "\", " ,
691
- "\"port\": " , port_encoded , ", " ,
692
- "\"ip\": \"" , ip_encoded , "\"}" , NULL );
691
+ mp_printf (& _socket_print ,
692
+ "{\"hostname\": \"%s\", "
693
+ "\"instance_name\": \"%s\", "
694
+ "\"port\": %d, "
695
+ "\"ip\": \"%d.%d.%d.%d\"}" , hostname , instance_name , port , octets [0 ], octets [1 ], octets [2 ], octets [3 ]);
693
696
common_hal_mdns_remoteservice_deinit (& found_devices [i ]);
694
697
}
695
698
_send_chunk (socket , "]}" );
@@ -701,26 +704,22 @@ static void _reply_with_version_json(socketpool_socket_obj_t *socket, _request *
701
704
_send_str (socket , OK_JSON );
702
705
_cors_header (socket , request );
703
706
_send_str (socket , "\r\n" );
704
- char encoded_creator_id [11 ]; // 2 ** 32 is 10 decimal digits plus one for \0
705
- snprintf (encoded_creator_id , sizeof (encoded_creator_id ), "%u" , CIRCUITPY_CREATOR_ID );
706
- char encoded_creation_id [11 ]; // 2 ** 32 is 10 decimal digits plus one for \0
707
- snprintf (encoded_creation_id , sizeof (encoded_creation_id ), "%u" , CIRCUITPY_CREATION_ID );
707
+ mp_print_t _socket_print = {socket , _print_chunk };
708
+
708
709
const char * hostname = common_hal_mdns_server_get_hostname (& mdns );
709
- char encoded_port [6 ];
710
- snprintf (encoded_port , sizeof (encoded_port ), "%d" , web_api_port );
711
- _send_chunks (socket ,
712
- "{\"web_api_version\": 1, " ,
713
- "\"version\": \"" , MICROPY_GIT_TAG , "\", " ,
714
- "\"build_date\": \"" , MICROPY_BUILD_DATE , "\", " ,
715
- "\"board_name\": \"" , MICROPY_HW_BOARD_NAME , "\", " ,
716
- "\"mcu_name\": \"" , MICROPY_HW_MCU_NAME , "\", " ,
717
- "\"board_id\": \"" , CIRCUITPY_BOARD_ID , "\", " ,
718
- "\"creator_id\": " , encoded_creator_id , ", " ,
719
- "\"creation_id\": " , encoded_creation_id , ", " ,
720
- "\"hostname\": \"" , hostname , "\", " ,
721
- "\"port\": " , encoded_port , ", " ,
722
- "\"ip\": \"" , _our_ip_encoded ,
723
- "\"}" , NULL );
710
+ // Note: this leverages the fact that C concats consecutive string literals together.
711
+ mp_printf (& _socket_print ,
712
+ "{\"web_api_version\": 1, "
713
+ "\"version\": \"" MICROPY_GIT_TAG "\", "
714
+ "\"build_date\": \"" MICROPY_BUILD_DATE "\", "
715
+ "\"board_name\": \"" MICROPY_HW_BOARD_NAME "\", "
716
+ "\"mcu_name\": \"" MICROPY_HW_MCU_NAME "\", "
717
+ "\"board_id\": \"" CIRCUITPY_BOARD_ID "\", "
718
+ "\"creator_id\": %u, "
719
+ "\"creation_id\": %u, "
720
+ "\"hostname\": \"%s\", "
721
+ "\"port\": %d, "
722
+ "\"ip\": \"%s\"}" , CIRCUITPY_CREATOR_ID , CIRCUITPY_CREATION_ID , hostname , web_api_port , _our_ip_encoded );
724
723
// Empty chunk signals the end of the response.
725
724
_send_chunk (socket , "" );
726
725
}
0 commit comments