void saveBuffer( const DataBuffer& buff, int fd ) throw (MC2String) { int retVal = write( fd, buff.getBufferAddress(), buff.getCurrentOffset() ); if ( retVal == -1 ) { throw MC2String("[DBU]: Could not write: ") + strerror(errno); } else if ( uint32(retVal) != buff.getCurrentOffset() ) { throw MC2String("[DBU]: Could not write buffer. Short byte count"); } }
bool NavMapHandler::handleVectorMap( UserItem* userItem, NavRequestPacket* req, NavReplyPacket* reply ) { bool ok = true; // The params const NParamBlock& params = req->getParamBlock(); NParamBlock& rparams = reply->getParamBlock(); uint32 startTime = TimeUtility::getCurrentTime(); MC2String reqStr; // Start parameter printing mc2log << info << "handleVectorMap:"; if ( params.getParam( 2400 ) ) { reqStr = params.getParam( 2400 )->getString( m_thread->clientUsesLatin1()); mc2log << " " << reqStr; } mc2log << endl; rparams.addParam( NParam( 2500, reqStr, m_thread->clientUsesLatin1() ) ); DataBuffer* data = m_thread->getTileMap( reqStr.c_str() ); if ( data != NULL ) { NParam& pdata = rparams.addParam( NParam( 2501 ) ); pdata.addByteArray( data->getBufferAddress(), data->getCurrentOffset() ); mc2log << info << "handleVectorMap: Reply " << data->getCurrentOffset() << " bytes" << endl; } else { // Error mc2log << warn << "handleVectorMap: NULL TileMap answer: "; if ( TimeUtility::getCurrentTime() - startTime > 3000 ) { reply->setStatusCode( NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT ); mc2log << "Timeout"; } else { reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK ); mc2log << "Error"; } mc2log << endl; } delete data; return ok; }
bool NavMapHandler::handleMultiVectorMap( UserItem* userItem, NavRequestPacket* req, NavReplyPacket* reply ) { bool ok = true; // The params const NParamBlock& params = req->getParamBlock(); NParamBlock& rparams = reply->getParamBlock(); uint32 startTime = TimeUtility::getCurrentTime(); vector<MC2SimpleString> tmapParams; uint32 inReqSize = 0; uint32 startOffset = 0; uint32 maxSize = 2048; // Start parameter printing mc2log << info << "handleMultiVectorMap:"; if ( params.getParam( 4600 ) ) { startOffset = params.getParam( 4600 )->getUint32(); mc2log << " startOffset " << startOffset; } if ( params.getParam( 4601 ) ) { maxSize = params.getParam( 4601 )->getUint32(); mc2log << " maxSize " << maxSize; } if ( params.getParam( 4602 ) ) { uint32 pos = 0; while ( pos < params.getParam( 4602 )->getLength() ) { MC2String reqStr = params.getParam( 4602 )->incGetString( m_thread->clientUsesLatin1(), pos); mc2log << " " << reqStr; tmapParams.push_back( reqStr.c_str() ); } inReqSize = pos; } mc2log << endl; DataBuffer* data = m_thread->getTileMaps( tmapParams, startOffset, maxSize ); if ( data != NULL ) { for ( uint32 pos = 0; pos < data->getCurrentOffset() ; pos += MAX_UINT16 ) { NParam& pdata = rparams.addParam( NParam( 4700 ) ); uint32 size = MIN( data->getCurrentOffset() - pos, MAX_UINT16 ); pdata.addByteArray( data->getBufferAddress() + pos, size ); } mc2log << info << "handleMultiVectorMap: Reply " << data->getCurrentOffset() << " bytes Request " << inReqSize << " bytes" << endl; } else { // Error mc2log << warn << "handleMultiVectorMap: NULL TileMap answer: "; if ( TimeUtility::getCurrentTime() - startTime > 3000 ) { reply->setStatusCode( NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT ); mc2log << "Timeout"; } else { reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK ); mc2log << "Error"; } mc2log << endl; } delete data; return ok; }
bool GenericMapHeader::internalLoad(DataBuffer& dataBuffer) { CLOCK_MAPLOAD(DebugClock loadClock); mc2dbg4 << "GenericMapHeader::internalLoad" << endl; // *************************************************************** // Read the general map information // *************************************************************** uint32 currentMapID = dataBuffer.readNextLong(); // do check without map set bits if (currentMapID != MapBits::getMapIDWithoutMapSet( m_mapID )) { mc2log << fatal << "GenericMapHeader::createFromDataBuffer, currentMapID: " << prettyMapIDFill(currentMapID) << " does not match filename, mapID: " << prettyMapIDFill(m_mapID) << ". EXITING!" << endl; exit(1); } m_totalMapSize = dataBuffer.readNextLong(); // WARNING: Not set in file!!! mc2dbg << "[GMH]: Total map size variable = " << m_totalMapSize << " and size of DataBuffer = " << dataBuffer.getBufferSize() << endl; // Read the creationtime of this map m_creationTime = dataBuffer.readNextLong(); // Read some data about all the items in this map m_country = StringTable::countryCode(dataBuffer.readNextLong()); byte flagByte = dataBuffer.readNextByte(); byte nbrNativeLanguages = dataBuffer.readNextByte(); byte nbrCurrencies = dataBuffer.readNextByte(); m_loadedVersion= dataBuffer.readNextByte(); if ( m_loadedVersion < 3 ) { m_driveOnRightSide = (flagByte != 0); } else { m_driveOnRightSide = BitUtility::getBit( flagByte, 0 ); m_groupsInLocationNameOrder = BitUtility::getBit( flagByte, 1 ); } m_nbrAllocators = dataBuffer.readNextLong(); mc2dbg << "Nbr allocators: " << m_nbrAllocators << endl; // The languages m_nativeLanguages.resize( nbrNativeLanguages ); for (NativeLanguageIndexes::size_type i=0; i<nbrNativeLanguages; i++) { m_nativeLanguages[ i ] = static_cast<NativeLanguageIndexes::value_type> ( dataBuffer.readNextLong() ); } // The currencies m_currency = new Vector(nbrCurrencies); for (uint32 i=0; i<nbrCurrencies; i++) { m_currency->addLast(dataBuffer.readNextLong()); } // Variable header: delete [] m_name; delete [] m_origin; delete [] m_mapCountryDir; switch ( m_loadedVersion ) { case ( 0 ) : m_name = StringUtility::newStrDup( "" ); m_origin = StringUtility::newStrDup( "" ); m_trueCreationTime = MAX_UINT32; m_waspTime = MAX_UINT32; m_dynamicExtradataTime = MAX_UINT32; m_utf8Strings = false; m_mapFiltered = false; m_mapGfxDataFiltered = false; m_mapCountryDir = StringUtility::newStrDup(""); break; case ( 1 ) : { uint32 offset = dataBuffer.getCurrentOffset(); uint32 variableHeaderSize = dataBuffer.readNextLong(); m_name = StringUtility::newStrDup( dataBuffer.readNextString() ); m_origin = StringUtility::newStrDup( "" ); m_trueCreationTime = MAX_UINT32; m_waspTime = MAX_UINT32; m_dynamicExtradataTime = MAX_UINT32; m_utf8Strings = false; m_mapFiltered = false; m_mapGfxDataFiltered = false; m_mapCountryDir = StringUtility::newStrDup(""); dataBuffer.readPastBytes( variableHeaderSize - ( dataBuffer.getCurrentOffset() - offset ) ); } break; case ( 2 ) : case ( 3 ) : { uint32 offset = dataBuffer.getCurrentOffset(); uint32 variableHeaderSize = dataBuffer.readNextLong(); m_name = StringUtility::newStrDup( dataBuffer.readNextString() ); m_origin = StringUtility::newStrDup( dataBuffer.readNextString() ); m_trueCreationTime = MAX_UINT32; m_waspTime = MAX_UINT32; m_dynamicExtradataTime = MAX_UINT32; m_utf8Strings = false; m_mapFiltered = false; m_mapGfxDataFiltered = false; m_mapCountryDir = StringUtility::newStrDup(""); dataBuffer.readPastBytes( variableHeaderSize - ( dataBuffer.getCurrentOffset() - offset ) ); } break; case ( 4 ) : { uint32 offset = dataBuffer.getCurrentOffset(); uint32 variableHeaderSize = dataBuffer.readNextLong(); m_name = StringUtility::newStrDup( dataBuffer.readNextString() ); m_origin = StringUtility::newStrDup( dataBuffer.readNextString() ); m_trueCreationTime = dataBuffer.readNextLong(); m_waspTime = dataBuffer.readNextLong(); m_dynamicExtradataTime = dataBuffer.readNextLong(); m_utf8Strings = false; m_mapFiltered = false; m_mapGfxDataFiltered = false; m_mapCountryDir = StringUtility::newStrDup(""); dataBuffer.readPastBytes( variableHeaderSize - ( dataBuffer.getCurrentOffset() - offset ) ); } break; case (5) : case (6) : // GenericMap::m_userRightsTable case (7) : // GenericMap::m_adminAreaCentres default : { uint32 offset = dataBuffer.getCurrentOffset(); uint32 variableHeaderSize = dataBuffer.readNextLong(); m_name = StringUtility::newStrDup( dataBuffer.readNextString() ); m_origin = StringUtility::newStrDup( dataBuffer.readNextString() ); m_trueCreationTime = dataBuffer.readNextLong(); m_waspTime = dataBuffer.readNextLong(); m_dynamicExtradataTime = dataBuffer.readNextLong(); m_utf8Strings = dataBuffer.readNextBool(); m_mapFiltered = dataBuffer.readNextBool(); m_mapGfxDataFiltered = dataBuffer.readNextBool(); m_mapCountryDir = StringUtility::newStrDup( dataBuffer.readNextString() ); dataBuffer.readPastBytes( variableHeaderSize - ( dataBuffer.getCurrentOffset() - offset ) ); } break; } // Read string with copyright-information for images of this map m_copyrightString = StringUtility::newStrDup(dataBuffer.readNextString()); CLOCK_MAPLOAD(mc2log << "[" << m_mapID << "] Header loaded in " << loadClock << ", m_loadedVersion=" << int(m_loadedVersion) << endl ); return true; }
bool OldCountryOverviewMap::internalSave(int outfile) { // Save the general map data bool retVal = OldGenericMap::internalSave(outfile); mc2dbg1 << "SAVING COUNTRYMAP" << endl; if (retVal) { // Save the ID of the maps in this country DataBuffer dataBuffer((m_mapsInCountry.size()+1)*24); dataBuffer.writeNextLong(m_mapsInCountry.size()); mc2dbg1 << "Nbr maps = " << m_mapsInCountry.size() << endl; for (uint32 i=0; i<m_mapsInCountry.size(); i++) { mc2dbg4 << "Saving map with ID=" << m_mapsInCountry[i].mapID << endl; dataBuffer.writeNextLong(m_mapsInCountry[i].mapID); dataBuffer.writeNextLong(m_mapsInCountry[i].creationTime); mc2dbg4 << "creationTime = " << m_mapsInCountry[i].creationTime << endl; dataBuffer.writeNextLong(m_mapsInCountry[i].maxLat); dataBuffer.writeNextLong(m_mapsInCountry[i].minLon); dataBuffer.writeNextLong(m_mapsInCountry[i].minLat); dataBuffer.writeNextLong(m_mapsInCountry[i].maxLon); } // Save to file write(outfile, dataBuffer.getBufferAddress(), dataBuffer.getCurrentOffset()); // Save the original ID of the items in this map uint32 nbrOriginalIDs = m_originalIDs.size(); mc2dbg1 << "To save " << nbrOriginalIDs << " original ID:s" << endl; DataBuffer origIDs(4 + nbrOriginalIDs*12); origIDs.writeNextLong(nbrOriginalIDs); map<uint32, struct originalIDs_t>::iterator p = m_originalIDs.begin(); while (p != m_originalIDs.end()) { origIDs.writeNextLong(p->first); origIDs.writeNextLong(p->second.origMapID); origIDs.writeNextLong(p->second.origItemID); mc2dbg4 << "Saving itemID " << p->first << " orig(" << p->second.origMapID << "." << p->second.origItemID << ")" << endl; p++; } // Write the original IDs to file write(outfile, origIDs.getBufferAddress(), origIDs.getCurrentOffset()); // Write the array of filter stacks. if (m_simplifiedGfxStack != NULL) { int numElements = m_nbrGfxPolygons * NBR_SIMPLIFIED_COUNTRY_GFX; // 10MB should be enough. for (byte i = 0; i < NBR_SIMPLIFIED_COUNTRY_GFX; i++) { // And each stack for that level for (uint32 j = 0; j < m_nbrGfxPolygons; j++) { // The number of elements of this stack. numElements += m_simplifiedGfxStack[i][j]->getStackSize(); } } mc2dbg4 << "required stack size="<<4*numElements+12<<endl; DataBuffer* stackBuf = new DataBuffer(4*numElements + 12); // Write the number of bytes to follow (filled in later) stackBuf->writeNextLong(0); // Nbr levels of stack. stackBuf->writeNextLong(NBR_SIMPLIFIED_COUNTRY_GFX); // Nbr of polygons per level. stackBuf->writeNextLong(m_nbrGfxPolygons); // For each level. for (byte i = 0; i < NBR_SIMPLIFIED_COUNTRY_GFX; i++) { // And each stack for that level for (uint32 j = 0; j < m_nbrGfxPolygons; j++) { // The number of elements of this stack. Stack* curStack = m_simplifiedGfxStack[i][j]; stackBuf->writeNextLong(curStack->getStackSize()); // And write all elements for (uint32 k = 0; k < curStack->getStackSize(); k++) { stackBuf->writeNextLong(curStack->getElementAt(k)); } } } // Fill in size stackBuf->writeLong( stackBuf->getCurrentOffset() - 4, 0); write(outfile, stackBuf->getBufferAddress(), stackBuf->getCurrentOffset()); delete stackBuf; } } else { mc2log << error << here << " Failed to save country overview map" << endl; } return (retVal); }
bool OldCountryOverviewMap::internalLoad(DataBuffer& dataBuffer) { // Load the general map data bool retVal = OldGenericMap::internalLoad(dataBuffer); if (retVal) { // Read the number of countries uint32 nbrCountries = dataBuffer.readNextLong(); if (nbrCountries > 0) { CLOCK_MAPLOAD(uint32 startTime = TimeUtility::getCurrentMicroTime()); // Insert the mapID's into the m_mapsInCountry-array for (uint32 i=0; i<nbrCountries; i++) { struct mapnotice_t notice; notice.mapID = dataBuffer.readNextLong(); notice.creationTime = dataBuffer.readNextLong(); notice.maxLat = dataBuffer.readNextLong(); notice.minLon = dataBuffer.readNextLong(); notice.minLat = dataBuffer.readNextLong(); notice.maxLon = dataBuffer.readNextLong(); mc2dbg2 << "[COMap] Creation time(0x" << hex << notice.mapID << dec << "):" << notice.creationTime << endl; m_mapsInCountry.push_back(notice); mc2dbg2 << " Added map with ID=" << notice.mapID << endl; } CLOCK_MAPLOAD(mc2log << "[" << m_mapID << "] Countries read in " << (TimeUtility::getCurrentMicroTime()-startTime)/1000.0 << " ms" << endl; startTime = TimeUtility::getCurrentMicroTime()); // Read the number of original IDs uint32 nbrOrigIDs = dataBuffer.readNextLong(); // Read the original IDs of the items in this map mc2dbg2 << "To insert " << nbrOrigIDs << " original IDs" << endl; for (uint32 i=0; i<nbrOrigIDs; i++) { uint32 newID = dataBuffer.readNextLong(); struct originalIDs_t origIDs; origIDs.origMapID = dataBuffer.readNextLong(); origIDs.origItemID = dataBuffer.readNextLong(); mc2dbg4 << " ID: " << newID << " <==> " << origIDs.origMapID << "." << origIDs.origItemID << endl; m_originalIDs.insert(make_pair(newID, origIDs)); } CLOCK_MAPLOAD(mc2log << "[" << m_mapID << "] Orig IDs read in " << (TimeUtility::getCurrentMicroTime()-startTime)/1000.0 << " ms" << endl; startTime = TimeUtility::getCurrentMicroTime()); // Create the simplified representation of the country gfxdata. // If it exists on disk, then read from there, otherwise filter. if ( (dataBuffer.getBufferSize() - dataBuffer.getCurrentOffset()) > 0) { // Read the size.(not used now) dataBuffer.readNextLong(); // Ok, read from disk. // Nbr levels of stack. uint32 levelsOfStack = dataBuffer.readNextLong(); // Nbr polygons per level. m_nbrGfxPolygons = dataBuffer.readNextLong(); // Allocate stack matrix. m_simplifiedGfxStack = new Stack**[levelsOfStack]; // For each level. for (byte i = 0; i < levelsOfStack; i++) { // And each stack for that level m_simplifiedGfxStack[i] = new Stack*[m_nbrGfxPolygons]; for (uint32 j = 0; j < m_nbrGfxPolygons; j++) { Stack* curStack = new Stack; // The number of elements of this stack. uint32 nbrElems = dataBuffer.readNextLong(); // And read all elements for (uint32 k = 0; k < nbrElems; k++) { curStack->push(dataBuffer.readNextLong()); } m_simplifiedGfxStack[i][j] = curStack; } } } else { // Could not read from disk, filter now instead. mc2log << info << "OldCountryOverviewMap::internalLoad(), " << "Error reading simplified representation of " << "country gfxdata. Exits." << endl; //makeSimplifiedCountryGfx(); exit(1); } CLOCK_MAPLOAD(mc2log << "[" << m_mapID << "] Country GfxData " << "created/read in " << (TimeUtility::getCurrentMicroTime()-startTime)/1000.0 << " ms" << endl; startTime = TimeUtility::getCurrentMicroTime()); } else {
bool MapModuleNoticeContainer::load( DataBuffer& dataBuf, uint32 mapSet ) { dataBuf.readNextLong(); // old totalLength dataBuf.readNextLong(); // nbrMaps mc2dbg << "[MMNC]: Using new kind of index.db" << endl; // Format on disk begins with two 32-bit words with zeroes. // They should already have been read by load. // We should really implement version 0 here as well so that // we can remove the MapModuleObjVector. // Then comes length and version uint32 totalLength = dataBuf.readNextLong(); // length uint32 version = dataBuf.readNextLong(); uint32 nbrItems = dataBuf.readNextLong(); if (dataBuf.getNbrBytesLeft() == 0) { // we must have some bytes left // TODO: check if nbr bytes left is at least // = length * something... return false; } // Reset the internal structs. deleteAllObjs(); // Version should only be 1 now. for ( uint32 i = 0; i < nbrItems; ++i ) { MapModuleNotice* notice = new MapModuleNotice( &dataBuf, version, mapSet ); // Add the notice to the appropriate vectors and maps. addNotice( notice ); mc2dbg << "[MMNC]: Added MapModuleNotice for " << notice->getMapName() << endl; } // Read the map hierarchy m_mapTree.load( &dataBuf, mapSet ); // Read the regions int nbrRegions = dataBuf.readNextLong(); m_regions.clear(); mc2dbg << "[MMNC]: Number of top regions:" << nbrRegions << endl; for ( int i = 0; i < nbrRegions; ++i ) { MapTopRegion* region = new MapTopRegion(); region->load( &dataBuf, mapSet ); m_regions[ region->getID() ] = region; const char* name = region->getName( LangTypes::english ); if ( name == NULL ) { name = "NULL"; } mc2dbg << "[MMNC]: Added Top Region ID:" << region->getID() << " name: " << name << endl; } // Read the region hierarchy m_regionTree.load( &dataBuf ); // Read map supplier coverage data. mc2dbg8 << "Curr offset: " << dataBuf.getCurrentOffset() << " total length " << totalLength << endl; if (dataBuf.getCurrentOffset() < totalLength+12 ){ mc2dbg << "[MMNC]: Loading map supplier coverage." << endl; loadMapSupCoverage( &dataBuf ); mc2dbg << "[MMNC]: Done loading map supplier coverage." << endl; } else { mc2dbg << "[MMNC]: Not loading map supplier coverage." << endl; } #ifdef DEBUG_LEVEL_1 // // debug // for(uint32 i = 0; i < m_allNotices.size(); ++i ) { mc2dbg << "Overview maps for " << m_allNotices[i]->getMapID() << endl; vector<uint32> overviewIDs; m_mapTree.getOverviewMapsFor(m_allNotices[i]->getMapID(), overviewIDs); for(uint32 j = 0; j < overviewIDs.size(); ++j ) { mc2dbg << " " << j << "=" << overviewIDs[j] << endl; } } { // Print stuff mc2dbg << "MAP_HIERARCHY" << endl; set<uint32> mapIDs; m_mapTree.getTopLevelMapIDs(mapIDs); for(set<uint32>::const_iterator it = mapIDs.begin(); it != mapIDs.end(); ++it) { mc2dbg << "TopLevelMap :" << hex << *it << dec << " contains " << endl; set<IDPair_t> items; m_mapTree.getContents(*it, items); for( set<IDPair_t>::iterator it = items.begin(); it != items.end(); ++it ) { mc2dbg << " " << it->getMapID() << ":" << hex << it->getItemID() << dec << endl; } } } // Print stuff mc2dbg << "REGION_HIERARCHY" << endl; set<uint32> mapIDs; m_regionTree.getTopLevelRegionIDs(mapIDs); for(set<uint32>::const_iterator it = mapIDs.begin(); it != mapIDs.end(); ++it) { mc2dbg << "TopLevelRegion : " << getRegion( *it )->getNames() ->getBestName( LangTypes::swedish )->getName() << " " << *it << endl; const ItemIDTree& idTree = getRegion( *it )->getItemIDTree(); set<uint32> mapIDs; mc2dbg << " consists of the following items:" << endl; idTree.getTopLevelMapIDs( mapIDs ); for ( set<uint32>::const_iterator jt = mapIDs.begin(); jt != mapIDs.end(); ++jt ) { mc2dbg << " map id = " << *jt << endl; set<IDPair_t> items; idTree.getContents( *jt, items ); for ( set<IDPair_t>::const_iterator kt = items.begin(); kt != items.end(); ++kt ) { mc2dbg << " [" << kt->first << ", " << kt->second << "]" << endl; } } mc2dbg << " contains the following other regions: " << endl; set<uint32> items; m_regionTree.getContents(*it, items); for( set<uint32>::iterator jt = items.begin(); jt != items.end(); ++jt ) { mc2dbg << " " << *jt << endl; } } // // end debug // #endif // DEBUG_LEVEL_1 return true; }
void IDTranslationTable::loadOld(DataBuffer& dataBuffer, uint32 mapSet) { // Nbr elements in the table or tables uint32 size = dataBuffer.readNextLong(); mc2dbg << "Loading old id translation table size = " << size << endl; m_lookupTable.clear(); m_lookupTable.reserve( size ); uint32 version = MAX_UINT32 - dataBuffer.readLong(dataBuffer.getCurrentOffset()); // if we have version above 100....this should be enough to indicate // that the buffer value is MapID if ( version < MAX_UINT32 - 100 ) version++; else version = 0; mc2dbg << "Loading old id table version = " << version << endl; // Chck if we have one or several tables in the databuffer if ( version == 1 ) { // TWO tables mc2dbg << "[IDT] To create IDTranslationTable from " << "databuffer with TWO tables, size: " << size << endl; dataBuffer.readNextLong(); // Skip flag // Read and ignore elements for reverseTable for (uint32 i=0; i < size; i++) { dataBuffer.readNextLong(); // mapID dataBuffer.readNextLong(); // itemID dataBuffer.readNextLong(); // overviewItemID } // Read and insert the elements into the lookup table for (uint32 i=0; i < size; i++) { uint32 tmpMapID = dataBuffer.readNextLong(); if (mapSet != MAX_UINT32) tmpMapID = MapBits::getMapIDWithMapSet(tmpMapID, mapSet); const uint32 tmpItemID = dataBuffer.readNextLong(); const uint32 tmpOverviewItemID = dataBuffer.readNextLong(); m_lookupTable.push_back( lookupElement_t(tmpOverviewItemID, IDPair_t(tmpMapID, tmpItemID) ) ); } // setup and sort reverse table sortReverseTable(); } else if ( version == 2 ) { dataBuffer.readNextLong(); // Skip flag m_reverseLookupTable.resize( size ); // Read and insert the elements into the lookup tables for ( uint32 i = 0; i < size; ++i ) { uint32 tmpMapID = dataBuffer.readNextLong(); const uint32 tmpItemID = dataBuffer.readNextLong(); const uint32 tmpOverviewItemID = dataBuffer.readNextLong(); m_reverseLookupTable[ i ] = dataBuffer.readNextLong(); if ( mapSet != MAX_UINT32 ) tmpMapID = MapBits::getMapIDWithMapSet(tmpMapID, mapSet); addElement(tmpOverviewItemID, tmpMapID, tmpItemID); } } else if ( version == 0 ) { // "Normal", one table.. mc2log << "[IDTranslationTable]: Reading ONE table, size = " << size << endl; // Read and insert the elements into the lookup tables // Must be sorted as in m_reverseLookupTable for (uint32 i=0; i < size; ++i) { uint32 tmpMapID = dataBuffer.readNextLong(); if (mapSet != MAX_UINT32) tmpMapID = MapBits::getMapIDWithMapSet(tmpMapID, mapSet); const uint32 tmpItemID = dataBuffer.readNextLong(); const uint32 tmpOverviewItemID = dataBuffer.readNextLong(); addElement(tmpOverviewItemID, tmpMapID, tmpItemID); } // setup and sort reverse table sortReverseTable(); } }
int ParserCWHandler::getURL( const MC2String& urlStr, const MC2String& postData, uint32 peerIP, uint32 fromByte, uint32 toByte, LangTypes::language_t clientLang, const HttpHeader* inHeaders, HttpHeader& outHeaders, MC2String& reply, uint32& startByte, uint32& endByte ) { uint32 startTime = TimeUtility::getCurrentTime(); // Work with url MC2String serverURLStr( urlStr ); mc2dbg2 << "serverURLStr " << serverURLStr << endl; updateRequest( serverURLStr, clientLang ); bool fetchedThruProxy = false; if ( serverURLStr.find( "://sendThruProxyServer" ) != MC2String::npos ) { // This url should be fetched thru the proxy server // Remove 'sendThruProxyServer' from URL STLStringUtility::replaceString( serverURLStr, "://sendThruProxyServer/", "://" ); URL url(serverURLStr); HttpBody outBody; HttpVariableContainer myVar; myVar.https = ( serverURLStr.find( "https://" ) != MC2String::npos ); // Fetch the url thru proxy server. If proxy fails it will be fetched without // proxy below. fetchedThruProxy = HttpProxyFunctions::fetchThruProxy( url, &outHeaders, &outBody, m_thread, &myVar ); if ( fetchedThruProxy ) { // Successfully fetched thru proxy reply.append( outBody.getBody(), outBody.getBodyLength() ); } } // Work with url mc2dbg2 << "serverURLStr " << serverURLStr << endl; updateRequest( serverURLStr, clientLang ); URL url2( serverURLStr ); int ures = 0; uint32 timeout = Properties::getUint32Property( "CW_TIMEOUT", 5000 ); if ( ! fetchedThruProxy ) { if ( serverURLStr.find( "internalInThisProcess" ) != MC2String::npos ) { // Handle internally reply.clear(); if ( serverURLStr.find("/TMap/") != MC2String::npos ) { MC2String urlParam = STLStringUtility::basename( url2.getFile() ); if ( !urlParam.empty() ) { DataBuffer* d = m_thread->getTileMap( urlParam.c_str() ); if ( d != NULL ) { ures = 200; reply.append( reinterpret_cast<char*>( d->getBufferAddress() ), d->getCurrentOffset() ); outHeaders.setStartLine( 200 ); } else { outHeaders.setStartLine( 503 ); } delete d; } } } else { // Send request using the parserthreads urlfetcher URLFetcher* f = m_thread->getURLFetcher(); HttpHeader sendHeaders; // Extra headers to send // TODO: Add byterange using fromByte and toByte if not 0,MAX_UINT32 // so we don't download whole file all the time. MC2String peerIPstr = NetUtility::ip2str( peerIP ); sendHeaders.addHeaderLine( "X-Forwarded-For", peerIPstr ); static const MC2String notForwardHeadersStr[] = { "X-WAYF-CT", HttpHeaderLines::CONTENT_TYPE, HttpHeaderLines::CONTENT_LENGTH, HttpHeaderLines::CONNECTION, HttpHeaderLines::TRANSFER_ENCODING, HttpHeaderLines::X_FORWARDED_FOR, HttpHeaderLines::PROXY_CONNECTION, HttpHeaderLines::HOST, HttpHeaderLines::TE, HttpHeaderLines::TRAILER, HttpHeaderLines::KEEP_ALIVE, HttpHeaderLines::PROXY_AUTHENTICATE, HttpHeaderLines::PROXY_AUTHORIZATION, HttpHeaderLines::UPGRADE, }; // TODO: Also remove all headers in Connection: header. Like // "Connection: Keep-Alive, Trailer" should delete those two. static const set< MC2String, strNoCaseCompareLess > notForwardHeaders( BEGIN_ARRAY( notForwardHeadersStr ), END_ARRAY( notForwardHeadersStr ) ); if ( inHeaders != NULL ) { const HttpHeader::HeaderMap& headers = inHeaders->getHeaderMap(); for ( HttpHeader::HeaderMap::const_iterator it = headers.begin() ; it != headers.end() ; ++it ) { if ( notForwardHeaders.find( it->first ) == notForwardHeaders.end() ) { sendHeaders.addHeaderLine( it->first, *it->second ); } } } if ( postData.empty() ) { ures = f->get( reply, outHeaders, url2, timeout, &sendHeaders ); } else { if ( inHeaders->getHeaderValue( "X-WAYF-CT" ) != NULL ) { sendHeaders.addHeaderLine( HttpHeaderLines::CONTENT_TYPE, *inHeaders->getHeaderValue( "X-WAYF-CT" ) ); } else { sendHeaders.addHeaderLine( HttpHeaderLines::CONTENT_TYPE, "application/x-www-form-urlencoded" ); } ures = f->post( reply, outHeaders, url2, postData, timeout, &sendHeaders ); } // Reset user agent //f->setDefaultUserAgent(); } } // if (! fetchedThruProxy ) // Remove chunked-encoding from reply (if present) const MC2String teh( "Transfer-Encoding" ); const MC2String* te = outHeaders.getHeaderValue( &teh ); if ( te != NULL && ( te->find( "chunked") != MC2String::npos ) ) { outHeaders.deleteHeaderLine( &teh ); } // Check if web updated user const MC2String wfidh( "X-WFID-UPDATE" ); const MC2String* wfid = outHeaders.getHeaderValue( &wfidh ); if ( wfid != NULL ) { // Remove the uin from user cache uint32 uin = STLStringUtility::strtoul( *wfid ); m_group->removeUserFromCache( uin ); // And remove the header outHeaders.deleteHeaderLine( &wfidh ); } // Make reply const MC2String eol( "\r\n" ); if ( fromByte > toByte ) { toByte = fromByte; } const uint32 maxBytes = toByte - fromByte; uint32 lastByte = uint32( MAX( int32(reply.size()) - 1, 0 ) ); startByte = MIN( fromByte, lastByte ); endByte = startByte + MIN( lastByte - startByte, maxBytes ); if ( ures > 0 && reply.size() > 0 && (endByte != lastByte || startByte != 0) ) { // Set byte range in reply MC2String rangeStr( "bytes " ); STLStringUtility::uint2str( startByte, rangeStr ); rangeStr.append( "-" ); STLStringUtility::uint2str( endByte, rangeStr ); rangeStr.append( "/" ); STLStringUtility::uint2str( reply.size(), rangeStr ); // Real size outHeaders.addHeaderLine( "Content-Range", rangeStr ); rangeStr = ""; STLStringUtility::uint2str( endByte - startByte + 1, rangeStr ); // Set right content length outHeaders.addHeaderLine( "Content-Length", rangeStr ); // Set startline with 206 Partial Content MC2String responce( outHeaders.getStartLine()->substr( 0, 9 ) ); responce.append( "206 Partial Content" ); responce.append( eol ); outHeaders.setStartLine( new MC2String( responce ) ); } else if ( ures < 0 || outHeaders.getStartLine() == NULL ) { if ( TimeUtility::getCurrentTime() - startTime >= timeout ) { outHeaders.setStartLine( 503 ); } else { outHeaders.setStartLine( 500 ); } } else { // Set startline with eol outHeaders.setStartLine( new MC2String( StringUtility::trimStartEnd( *outHeaders.getStartLine() ) + eol ) ); } return ures; }