static int sendFile(const char* path, const MABtAddr* address, int port, int maxPacketSize) { FILE* file = fopen(path, "rb"); if(!file) { printf("Couldn't open file \"%s\"!\n", path); return -__COUNTER__; } const char* filename = MAX(MAX(path, strrchr(path, '\\')), strrchr(path, '/')); Array<u16> unicode_buf(strlen(filename)); //Big Endian Unicode for(uint i=0; i<unicode_buf.size(); i++) { unicode_buf[i] = filename[i] << 8; } if(fseek(file, 0, SEEK_END)) { printf("Couldn't scan file \"%s\"!\n", filename); return -__COUNTER__; } int file_len = ftell(file); if(fseek(file, 0, SEEK_SET)) { printf("Couldn't scan file \"%s\"!\n", filename); return -__COUNTER__; } Array<char> file_buf(file_len); int res = fread(file_buf, 1, file_len, file); if(res != file_len) { DUMPINT(res); printf("Couldn't read file \"%s\"!\n", filename); return -__COUNTER__; } return sendObject(*address, file_buf, unicode_buf, port, maxPacketSize); }
static int sendFile(const char* path, const MABtAddr* address, int port, int maxPacketSize) { FILE* file = fopen(path, "rb"); if(!file) { printf("Couldn't open file \"%s\"!\n", path); return -__COUNTER__; } const char* filename = MAX(MAX(path, strrchr(path, '\\')), strrchr(path, '/')); Array<u16> unicode_buf(strlen(filename)); //Big Endian Unicode for(uint i=0; i<unicode_buf.size(); i++) { unicode_buf[i] = filename[i] << 8; } if(fseek(file, 0, SEEK_END)) { printf("Couldn't scan file \"%s\"!\n", filename); return -__COUNTER__; } int file_len = ftell(file); if(fseek(file, 0, SEEK_SET)) { printf("Couldn't scan file \"%s\"!\n", filename); return -__COUNTER__; } Array<char> file_buf(file_len); int res = fread(file_buf, 1, file_len, file); if(res != file_len) { DUMPINT(res); printf("Couldn't read file \"%s\"!\n", filename); return -__COUNTER__; } if(port < 0) { printf("OBEX Object Push port not specified, querying remote device...\n"); port = findObexPort(address); if(port < 0) { printf("Query failed (%i). File not sent.\n", port); return port; } else { printf("Port found: %i\n", port); } } return sendObject(*address, file_buf, unicode_buf, port, maxPacketSize); }
Block MergeSortingBlockInputStream::readImpl() { /** Algorithm: * - read to memory blocks from source stream; * - if too much of them and if external sorting is enabled, * - merge all blocks to sorted stream and write it to temporary file; * - at the end, merge all sorted streams from temporary files and also from rest of blocks in memory. */ /// If has not read source blocks. if (!impl) { while (Block block = children.back()->read()) { if (!sample_block) { sample_block = block.cloneEmpty(); removeConstantsFromSortDescription(sample_block, description); } /// If there were only const columns in sort description, then there is no need to sort. /// Return the blocks as is. if (description.empty()) return block; removeConstantsFromBlock(block); blocks.push_back(block); sum_bytes_in_blocks += block.bytes(); /** If too much of them and if external sorting is enabled, * will merge blocks that we have in memory at this moment and write merged stream to temporary (compressed) file. * NOTE. It's possible to check free space in filesystem. */ if (max_bytes_before_external_sort && sum_bytes_in_blocks > max_bytes_before_external_sort) { temporary_files.emplace_back(new Poco::TemporaryFile(tmp_path)); const std::string & path = temporary_files.back()->path(); WriteBufferFromFile file_buf(path); CompressedWriteBuffer compressed_buf(file_buf); NativeBlockOutputStream block_out(compressed_buf); MergeSortingBlocksBlockInputStream block_in(blocks, description, max_merged_block_size, limit); LOG_INFO(log, "Sorting and writing part of data into temporary file " + path); ProfileEvents::increment(ProfileEvents::ExternalSortWritePart); copyData(block_in, block_out, &is_cancelled); /// NOTE. Possibly limit disk usage. LOG_INFO(log, "Done writing part of data into temporary file " + path); blocks.clear(); sum_bytes_in_blocks = 0; } } if ((blocks.empty() && temporary_files.empty()) || isCancelled()) return Block(); if (temporary_files.empty()) { impl = std::make_unique<MergeSortingBlocksBlockInputStream>(blocks, description, max_merged_block_size, limit); } else { /// If there was temporary files. ProfileEvents::increment(ProfileEvents::ExternalSortMerge); LOG_INFO(log, "There are " << temporary_files.size() << " temporary sorted parts to merge."); /// Create sorted streams to merge. for (const auto & file : temporary_files) { temporary_inputs.emplace_back(std::make_unique<TemporaryFileStream>(file->path())); inputs_to_merge.emplace_back(temporary_inputs.back()->block_in); } /// Rest of blocks in memory. if (!blocks.empty()) inputs_to_merge.emplace_back(std::make_shared<MergeSortingBlocksBlockInputStream>(blocks, description, max_merged_block_size, limit)); /// Will merge that sorted streams. impl = std::make_unique<MergingSortedBlockInputStream>(inputs_to_merge, description, max_merged_block_size, limit); } } Block res = impl->read(); if (res) enrichBlockWithConstants(res, sample_block); return res; }