void OsmAnd::ObfReaderUtilities::skipUnknownField( gpb::io::CodedInputStream* cis, int tag )
{
    auto wireType = gpb::internal::WireFormatLite::GetTagWireType(tag);
    if(wireType == gpb::internal::WireFormatLite::WIRETYPE_FIXED32_LENGTH_DELIMITED)
    {
        auto length = readBigEndianInt(cis);
        cis->Skip(length);
    }
    else
        gpb::internal::WireFormatLite::SkipField(cis, tag);
}
std::ostream & operator<<(std::ostream & lhs_sout, const DataSet & rhs_obj) {
	std::string dataSetName(rhs_obj._name.cbegin(), rhs_obj._name.cend());
	unsigned int numColumns = (unsigned int)rhs_obj._columnMeta.size();
	unsigned int numRows = rhs_obj.getRowCount();
	lhs_sout << '"' << dataSetName << '(' << numColumns << 'x' << numRows << ')' << '[';

	std::vector<ColumnMetadata>::const_iterator oneColumnMeta;
	std::vector<ColumnMetadata>::const_iterator allMetadataEnd;
	oneColumnMeta = rhs_obj._columnMeta.cbegin();
	allMetadataEnd = rhs_obj._columnMeta.cend();

	std::wstring dummyWideColumnName;
	for (; oneColumnMeta < allMetadataEnd; oneColumnMeta++) {
		dummyWideColumnName = oneColumnMeta->getColumnName();
		std::string columnName(dummyWideColumnName.cbegin(), dummyWideColumnName.cend());
		lhs_sout << '(';
		lhs_sout << columnName << ',';
		lhs_sout << oneColumnMeta->getColumnTypeAsStr() << ',';
		lhs_sout << oneColumnMeta->getColumnSize();
		lhs_sout << ')';
	}

	lhs_sout << "]\"\n";

	if (numRows > 0) {
		int strLen;
		unsigned char oneElementBuff[4];
		std::string oneCELString;
		std::wstring oneCELWstring;
		std::vector<unsigned char>::const_iterator dataCursor, rawDataEnd;
		dataCursor = rhs_obj._data.cbegin();
		rawDataEnd = rhs_obj._data.cend();

		for (unsigned int i = 1; i < numRows+1; i++) {

			oneColumnMeta = rhs_obj._columnMeta.cbegin();
			for (; oneColumnMeta < allMetadataEnd; oneColumnMeta++) {

				switch (oneColumnMeta->getColumnType()) {
				case BYTE_COL:
					oneElementBuff[0] = *(dataCursor++);
					lhs_sout << *((char *)oneElementBuff);
					break;
				case UBYTE_COL:
					oneElementBuff[0] = *(dataCursor++);
					lhs_sout << *((unsigned char *)oneElementBuff);
					break;
				case SHORT_COL:
					oneElementBuff[1] = *(dataCursor++);
					oneElementBuff[0] = *(dataCursor++);
					lhs_sout << *((short *)oneElementBuff);
					break;
				case USHORT_COL:
					oneElementBuff[1] = *(dataCursor++);
					oneElementBuff[0] = *(dataCursor++);
					lhs_sout << *((unsigned short *)oneElementBuff);
					break;
				case INT_COL:
					oneElementBuff[3] = *(dataCursor++);
					oneElementBuff[2] = *(dataCursor++);
					oneElementBuff[1] = *(dataCursor++);
					oneElementBuff[0] = *(dataCursor++);
					lhs_sout << *((int *)oneElementBuff);
					break;
				case UINT_COL:
					oneElementBuff[3] = *(dataCursor++);
					oneElementBuff[2] = *(dataCursor++);
					oneElementBuff[1] = *(dataCursor++);
					oneElementBuff[0] = *(dataCursor++);
					lhs_sout << *((unsigned int *)oneElementBuff);
					break;
				case FLOAT_COL:
					oneElementBuff[3] = *(dataCursor++);
					oneElementBuff[2] = *(dataCursor++);
					oneElementBuff[1] = *(dataCursor++);
					oneElementBuff[0] = *(dataCursor++);
					lhs_sout << *((float*)oneElementBuff);
					break;
				case STRING_COL:
					strLen = readBigEndianInt(dataCursor);
					lhs_sout << '"' << readString(dataCursor, strLen) << '"';
					break;
				case WSTRING_COL:
					strLen = readBigEndianInt(dataCursor);
					oneCELWstring = readWstring(dataCursor, strLen);
					oneCELString.clear();
					oneCELString.assign(oneCELWstring.cbegin(), oneCELWstring.cend());
					lhs_sout << '"' << oneCELString << '"';
					break;
				} // end switch (oneColumnMeta->getColumnType())
				lhs_sout << ',';
			} // end for (; oneColumnMeta < allMetadataEnd; oneColumnMeta++)
			lhs_sout << '\n';
		} // end for upper-bounded by numRows
	}

	return lhs_sout;
}