void readInt(char rks) { WORD readedLength, lengthFromFile; uint8_t tmp; uint8_t* wptr; while(readLength) { // Расчет длины блока (выравниваем чтение на сектор) if(fs_tell()) return; readedLength = 512 - (fs_tmp % 512); if(readedLength > readLength) readedLength = readLength; // Уменьшаем счетчик readLength -= readedLength; // Читаем блок if(fs_read0(buf, readedLength)) return; // Заголовок RKS файла wptr = buf; if(rks) { // Если rks=1, перед вызовом надо проверить, что бы readLength>4 и fs_file.ptr=0, иначе может быть злостный сбой rks = 0; // У апогея числа перепутаны tmp=buf[0], buf[0]=buf[1]; buf[1]=tmp; tmp=buf[2], buf[2]=buf[3]; buf[3]=tmp; // Посылаем адрес загрузки send(ERR_OK_RKS); sendBin(buf, 2); send(ERR_WAIT); // Корректируем указатели wptr += 4; readedLength -= 4; // Длина из файла lengthFromFile = *(WORD*)(buf+2) - *(WORD*)(buf) + 1; // Корректируем длину if(readedLength > lengthFromFile) { readedLength = lengthFromFile; } else { lengthFromFile -= readedLength; if(readLength > lengthFromFile) lengthFromFile = readedLength; } } // Отправляем блок send(ERR_READ_BLOCK); sendBin((uint8_t*)&readedLength, 2); sendBin(wptr, readedLength); send(ERR_WAIT); } // Если все ОК if(!lastError) lastError = ERR_OK_READ; }
/** * Periodically send the next chunk of the file * @param app pointer to a Files application */ static void send_task(void * param) { lv_app_inst_t * app = param; my_app_data_t * app_data = app->app_data; if(app_data->send_in_prog == 0) return; /*Read a chunk*/ uint32_t rn; char rd_buf[LV_APP_FILES_CHUNK_MAX_SIZE]; fs_res_t res = fs_read(&app_data->file, rd_buf, app_data->chunk_size, &rn); if(res == FS_RES_OK) { app_data->send_in_prog = 1; lv_app_com_send(app, LV_APP_COM_TYPE_CHAR, rd_buf, rn); } /*If the read failed close the file and show an error*/ if(res != FS_RES_OK) { fs_close(&app_data->file); app_data->send_in_prog = 0; lv_app_notice_add("Can not send\nthe file in Files"); } /*If the read was successful*/ else { my_sc_data_t * sc_data = app->sc_data; /*If the file is read close it a show a notification*/ if(rn < app_data->chunk_size) { lv_app_notice_add("File sent"); fs_close(&app_data->file); app_data->send_in_prog = 0; /*Refresh the shortut*/ if(sc_data != NULL) { lv_label_set_text(sc_data->label, fs_get_last(app_data->path)); lv_obj_align(sc_data->label, NULL, LV_ALIGN_CENTER, 0, 0); } } /*If the file is not sent yet refresh the shortcut with percentage of sending*/ else { if(sc_data != NULL) { uint32_t size; fs_size(&app_data->file, &size); uint32_t pos; fs_tell(&app_data->file, &pos); uint8_t pct = (uint32_t) (pos * 100) / size; char buf[256]; sprintf(buf, "Sending\n%d%%", pct); lv_label_set_text(sc_data->label, buf); lv_obj_align(sc_data->label, NULL, LV_ALIGN_CENTER, 0, 0); } } } }
static int f_seek (lua_State *L) { static const int mode[] = {FS_SEEK_SET, FS_SEEK_CUR, FS_SEEK_END}; static const char *const modenames[] = {"set", "cur", "end", NULL}; int f = tofile(L); int op = luaL_checkoption(L, 2, "cur", modenames); long offset = luaL_optlong(L, 3, 0); op = fs_seek(f, offset, mode[op]); if (op) return pushresult(L, 0, NULL); /* error */ else { lua_pushinteger(L, fs_tell(f)); return 1; } }
/* ================= eflac_decoder_tell ================= */ static FLAC__StreamDecoderTellStatus eflac_decoder_tell (GNUC_UNUSED const FLAC__StreamDecoder *decoder, FLAC__uint64 *abs_offset, void *client_data) { snd_stream_t *s = client_data; int offset; if (0 >= (offset = fs_tell(s->file))) { *abs_offset = offset; return FLAC__STREAM_DECODER_TELL_STATUS_OK; } return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; }
static int file_seek (lua_State *L) { static const int mode[] = {FS_SEEK_SET, FS_SEEK_CUR, FS_SEEK_END}; static const char *const modenames[] = {"set", "cur", "end", NULL}; if((FS_OPEN_OK - 1)==file_fd) return luaL_error(L, "open a file first"); int op = luaL_checkoption(L, 1, "cur", modenames); long offset = luaL_optlong(L, 2, 0); op = fs_seek(file_fd, offset, mode[op]); if (op) lua_pushnil(L); /* error */ else lua_pushinteger(L, fs_tell(file_fd)); return 1; }
void cmd_read(void) { DWORD s; // Длина recvBin((uint8_t*)&readLength, 2); // Режим передачи и подтверждение sendStart(ERR_WAIT); // Ограничиваем длину длиной файла if(fs_getfilesize()) return; s = fs_tmp; if(fs_tell()) return; s -= fs_tmp; if(readLength > s) readLength = (WORD)s; // Отправляем все блоки файла readInt(/*rks*/0); }
/** * Start the sending of a file * @param app pointer to a Files application * @param path path of the file to send */ static void start_send(lv_app_inst_t * app, const char * path) { my_app_data_t * app_data = app->app_data; /*Open the file*/ fs_res_t res = fs_open(&app_data->file, path, FS_MODE_RD); if(res == FS_RES_OK) { app_data->send_in_prog = 1; /*Send the header*/ if(app_data->send_fn != 0) { lv_app_com_send(app, LV_APP_COM_TYPE_CHAR, app_data->path, strlen(app_data->path)); lv_app_com_send(app, LV_APP_COM_TYPE_CHAR, "/", 1); lv_app_com_send(app, LV_APP_COM_TYPE_CHAR, app_data->fn, strlen(app_data->fn)); lv_app_com_send(app, LV_APP_COM_TYPE_CHAR, "\n", 1); } if(app_data->send_size != 0) { char buf[64]; uint32_t size; fs_size(&app_data->file, &size); sprintf(buf,"%d", (int) size); lv_app_com_send(app, LV_APP_COM_TYPE_CHAR, buf, strlen(buf)); lv_app_com_send(app, LV_APP_COM_TYPE_CHAR, "\n", 1); } if(app_data->send_crc != 0) { lv_app_com_send(app, LV_APP_COM_TYPE_CHAR, "0x0000", 6); lv_app_com_send(app, LV_APP_COM_TYPE_CHAR, "\n", 1); } /*Add an extra \n to separate the header from the file data*/ if(app_data->send_fn != 0 || app_data->send_size != 0 || app_data->send_crc != 0) { lv_app_com_send(app, LV_APP_COM_TYPE_CHAR, "\n", 1); } } /*If an error occurred close the file*/ if(res != FS_RES_OK) { fs_close(&app_data->file); ptask_set_prio(app_data->send_task, PTASK_PRIO_OFF); app_data->send_in_prog = 0; lv_app_notice_add("Can not send\nthe file in Files"); } /*If no error show notification, start the sender task and refresh the shortcut*/ else { /*Start the sender task*/ ptask_set_period(app_data->send_task, app_data->chunk_delay); ptask_reset(app_data->send_task); ptask_set_prio(app_data->send_task, PTASK_PRIO_HIGH); lv_app_notice_add("Sending\n%s", fs_get_last(path)); /*Refresh the shortcut with the percentage of the sending*/ if(app->sc_data != NULL) { my_sc_data_t * sc_data = app->sc_data; uint32_t size; fs_size(&app_data->file, &size); uint32_t pos; fs_tell(&app_data->file, &pos); int pct = (uint32_t) (pos * 100) / size; char buf[256]; sprintf(buf, "Sending\n%d%%", pct); lv_label_set_text(sc_data->label, buf); lv_obj_align(sc_data->label, NULL, LV_ALIGN_CENTER, 0, 0); } } }
static bool fs_zip_read (fs_file_t *file, void *buffer, size_t size, size_t *result) { fs_zip_file_t *f = (fs_zip_file_t *)file; const size_t need = size; if (!f->zipfile->compressed) { // file is not compressed one, just read to buffer size_t to_read = MIN(size, f->zipfile->size_zipped - f->position_zipped); if (to_read) { size_t got = to_read; if (seek_file_zip(f) && fs_read(f->zip->f, buffer, to_read, result ? &got : NULL, "read failed")) { size -= got; f->position_zipped += got; f->zip->position += got; } } } else { if (unlikely(!seek_file_zip(f))) { g_critical("failed to seek"); } else { for (size_t got = 0; size; buffer += got, f->position += got, size -= got) { if (f->position >= f->zipfile->size_real) { break; } if (f->input_position == f->input_size) { size_t to_read = MIN(fs_zip_file_buffer_size, f->zipfile->size_zipped - f->position_zipped); if (unlikely(!seek_file_zip(f) || !fs_read(f->zip->f, f->input, to_read, &got, "read failed") || !got)) { g_critical("failed to read zip file"); break; } f->input_position = 0; f->input_size = got; f->position_zipped += got; f->zip->position += got; size_t off; fs_tell(f->zip->f, &off); } f->stream.next_in = &f->input[f->input_position]; f->stream.avail_in = f->input_size - f->input_position; f->stream.next_out = buffer; f->stream.avail_out = size; int res = inflate(&f->stream, Z_SYNC_FLUSH); if (unlikely(Z_STREAM_END != res && Z_OK != res)) { g_critical("failed to decompress (error code: %i)", res); break; } f->input_position = f->input_size - f->stream.avail_in; got = size - f->stream.avail_out; } } } // how much we have size = need - size; if (!result) { return (need == size); } *result = size; return true; }