Ejemplo n.º 1
0
//!! 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();
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}