//!! promise 不要让我等得太久, 对应future int main() { std::istringstream iss_numbers{"3 4 1 42 23 -23 93 2 -289 93"}; std::istringstream iss_letters{" a 23 b,e a2 k k?a;si,ksa c"}; std::vector<int> numbers; //!! 对应的future也是void std::vector<char> letters; std::promise<void> numbers_promise, letters_promise; auto numbers_ready = numbers_promise.get_future(); auto letter_ready = letters_promise.get_future(); std::thread value_reader([&] { // run in seperate thread // I/O operations. std::copy(std::istream_iterator<int>{iss_numbers}, std::istream_iterator<int>{}, std::back_inserter(numbers)); //Notify for numbers. numbers_promise.set_value(); //!! 此例中,promise-future 像条件变量,等待条件设置 std::copy_if(std::istreambuf_iterator<char>{iss_letters}, std::istreambuf_iterator<char>{}, std::back_inserter(letters), ::isalpha); //Notify for letters. letters_promise.set_value(); }); // in main thread numbers_ready.wait(); // future std::sort(numbers.begin(), numbers.end()); if (letter_ready.wait_for(std::chrono::seconds(1)) == std::future_status::timeout) { //output the numbers while letters are being obtained. for (int num : numbers) std::cout << num << ' '; numbers.clear(); //Numbers were already printed. } letter_ready.wait(); std::sort(letters.begin(), letters.end()); //If numbers were already printed, it does nothing. for (int num : numbers) std::cout << num << ' '; std::cout << '\n'; for (char let : letters) std::cout << let << ' '; std::cout << '\n'; value_reader.join(); }
bool NDS2SF::exe2sf(const std::string& nds2sf_path, uint8_t *exe, size_t exe_size, std::map<std::string, std::string>& tags) { FILE *nds2sf_file = NULL; z_stream z; uint8_t zbuf[CHUNK]; uLong zcrc; uLong zlen; int zflush; int zret; // check exe size if (exe_size > MAX_NDS2SF_EXE_SIZE) { return false; } // open output file nds2sf_file = fopen(nds2sf_path.c_str(), "wb"); if (nds2sf_file == NULL) { return false; } // write PSF header // (EXE length and CRC will be set later) fwrite(PSF_SIGNATURE, strlen(PSF_SIGNATURE), 1, nds2sf_file); fputc(NDS2SF_PSF_VERSION, nds2sf_file); fput4l(0, nds2sf_file); fput4l(0, nds2sf_file); fput4l(0, nds2sf_file); // init compression z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; if (deflateInit(&z, Z_BEST_COMPRESSION) != Z_OK) { return false; } // compress exe z.next_in = exe; z.avail_in = (uInt) exe_size; z.next_out = zbuf; z.avail_out = CHUNK; zcrc = crc32(0L, Z_NULL, 0); do { if (z.avail_in == 0) { zflush = Z_FINISH; } else { zflush = Z_NO_FLUSH; } // compress zret = deflate(&z, zflush); if (zret != Z_STREAM_END && zret != Z_OK) { deflateEnd(&z); fclose(nds2sf_file); return false; } // write compressed data zlen = CHUNK - z.avail_out; if (zlen != 0) { if (fwrite(zbuf, zlen, 1, nds2sf_file) != 1) { deflateEnd(&z); fclose(nds2sf_file); return false; } zcrc = crc32(zcrc, zbuf, zlen); } // give space for next chunk z.next_out = zbuf; z.avail_out = CHUNK; } while (zret != Z_STREAM_END); // set EXE info to PSF header fseek(nds2sf_file, 8, SEEK_SET); fput4l(z.total_out, nds2sf_file); fput4l(zcrc, nds2sf_file); fseek(nds2sf_file, 0, SEEK_END); // end compression deflateEnd(&z); // write tags if (!tags.empty()) { fwrite(PSF_TAG_SIGNATURE, strlen(PSF_TAG_SIGNATURE), 1, nds2sf_file); for (std::map<std::string, std::string>::iterator it = tags.begin(); it != tags.end(); ++it) { const std::string& key = it->first; const std::string& value = it->second; std::istringstream value_reader(value); std::string line; // process for each lines while (std::getline(value_reader, line)) { if (fprintf(nds2sf_file, "%s=%s\n", key.c_str(), line.c_str()) < 0) { fclose(nds2sf_file); return false; } } } } fclose(nds2sf_file); return true; }
bool mvt_tile::decode(std::string &message) { layers.clear(); std::string src; if (is_compressed(message)) { std::string uncompressed; decompress(message, uncompressed); src = uncompressed; } else { src = message; } protozero::pbf_reader reader(src); while (reader.next()) { switch (reader.tag()) { case 3: /* layer */ { protozero::pbf_reader layer_reader(reader.get_message()); mvt_layer layer; while (layer_reader.next()) { switch (layer_reader.tag()) { case 1: /* name */ layer.name = layer_reader.get_string(); break; case 3: /* key */ layer.keys.push_back(layer_reader.get_string()); break; case 4: /* value */ { protozero::pbf_reader value_reader(layer_reader.get_message()); mvt_value value; while (value_reader.next()) { switch (value_reader.tag()) { case 1: /* string */ value.type = mvt_string; value.string_value = value_reader.get_string(); break; case 2: /* float */ value.type = mvt_float; value.numeric_value.float_value = value_reader.get_float(); break; case 3: /* double */ value.type = mvt_double; value.numeric_value.double_value = value_reader.get_double(); break; case 4: /* int */ value.type = mvt_int; value.numeric_value.int_value = value_reader.get_int64(); break; case 5: /* uint */ value.type = mvt_uint; value.numeric_value.uint_value = value_reader.get_uint64(); break; case 6: /* sint */ value.type = mvt_sint; value.numeric_value.sint_value = value_reader.get_sint64(); break; case 7: /* bool */ value.type = mvt_bool; value.numeric_value.bool_value = value_reader.get_bool(); break; default: value_reader.skip(); break; } } layer.values.push_back(value); break; } case 5: /* extent */ layer.extent = layer_reader.get_uint32(); break; case 2: /* feature */ { protozero::pbf_reader feature_reader(layer_reader.get_message()); mvt_feature feature; std::vector<uint32_t> geoms; while (feature_reader.next()) { switch (feature_reader.tag()) { case 2: /* tag */ { auto pi = feature_reader.get_packed_uint32(); for (auto it = pi.first; it != pi.second; ++it) { feature.tags.push_back(*it); } break; } case 3: /* feature type */ feature.type = feature_reader.get_enum(); break; case 4: /* geometry */ { auto pi = feature_reader.get_packed_uint32(); for (auto it = pi.first; it != pi.second; ++it) { geoms.push_back(*it); } break; } default: feature_reader.skip(); break; } } long long px = 0, py = 0; for (size_t g = 0; g < geoms.size(); g++) { uint32_t geom = geoms[g]; uint32_t op = geom & 7; uint32_t count = geom >> 3; if (op == mvt_moveto || op == mvt_lineto) { for (size_t k = 0; k < count && g + 2 < geoms.size(); k++) { px += protozero::decode_zigzag32(geoms[g + 1]); py += protozero::decode_zigzag32(geoms[g + 2]); g += 2; feature.geometry.push_back(mvt_geometry(op, px, py)); } } else { feature.geometry.push_back(mvt_geometry(op, 0, 0)); } } layer.features.push_back(feature); break; } default: layer_reader.skip(); break; } } for (size_t i = 0; i < layer.keys.size(); i++) { layer.key_map.insert(std::pair<std::string, size_t>(layer.keys[i], i)); } for (size_t i = 0; i < layer.values.size(); i++) { layer.value_map.insert(std::pair<mvt_value, size_t>(layer.values[i], i)); } layers.push_back(layer); break; } default: reader.skip(); break; } } return true; }