DataBuffer* GfxFeatureMapReplyPacket::getGfxFeatureMapData() { bool zipped = false; DataBuffer* maybeZippedBuf = getGfxFeatureMapData( zipped ); if ( zipped ) { // Zipped, means that we should unzip it. // Check unzipped length. int unzippedLength = GunzipUtil::origLength( maybeZippedBuf->getBufferAddress(), maybeZippedBuf->getBufferSize() ); // Unzip. DataBuffer* unzippedBuf = new DataBuffer( unzippedLength ); int retVal = GunzipUtil::gunzip( unzippedBuf->getBufferAddress(), unzippedBuf->getBufferSize(), maybeZippedBuf->getBufferAddress(), maybeZippedBuf->getBufferSize() ); delete maybeZippedBuf; if ( retVal < 0 ) { delete unzippedBuf; return NULL; } // Better read past the bytes just to make sure.. unzippedBuf->readPastBytes( unzippedLength ); return unzippedBuf; } else { // Was already unzipped. return maybeZippedBuf; } }
DataBuffer* ByteBuffer::copyToDataBuffer() const { DataBuffer* retBuf = new DataBuffer(getNbrBytes()); peek(retBuf->getBufferAddress(), getNbrBytes()); retBuf->readPastBytes(getNbrBytes()); return retBuf; }
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 POIInfo::load( const MC2String& filename, uint32 offset ) { DataBuffer fileBuff; fileBuff.memMapFile( filename.c_str() ); DataBuffer offsetBuff( fileBuff.getBufferAddress() + offset, fileBuff.getBufferSize() - offset ); load( offsetBuff ); return true; }
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; }
std::auto_ptr< BitBuffer> convertToBitBuffer( DataBuffer& buffer ) { std::auto_ptr< BitBuffer > retBuffer; // Copy the buffer if it is mmaped, which hopefully will not happen // to often. if ( buffer.isMMaped() ) { uint8* data = new uint8[ buffer.getBufferSize() ]; memcpy( data, buffer.getBufferAddress(), buffer.getBufferSize() ); retBuffer = std::auto_ptr< BitBuffer > ( new BitBuffer( data, buffer.getBufferSize() ) ); } else { // take ownership of the memory uint32 size = buffer.getBufferSize(); retBuffer = std::auto_ptr< BitBuffer > ( new BitBuffer( buffer.release(), size ) ); retBuffer->setSelfAlloc( true ); } return retBuffer; }
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 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); }
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; }
bool ModuleMap::saveCachedMap(DataBuffer& mapBuffer, const GenericMap* theMap, uint32 loadMapRequestType, uint32 mapVersion, uint32 generatorVersion, bool update, byte zoomlevel) { uint32 mapID = theMap->getMapID(); MC2String finalFileName( ModuleMap::getCacheFilename(mapID, loadMapRequestType, zoomlevel) ); if ( update && cacheIsUpToDate(theMap->getMapID(), theMap->getFilename(), loadMapRequestType, zoomlevel) ){ return true; } const char* fileName = finalFileName.c_str(); MC2String tmpDir = ModuleMap::getCachePath(); if ( tmpDir[0] == '\0' ) { mc2log << info << "[ModuleMap]: No cachepath set - will not save " << "map 0x" << hex << mapID << dec << endl; return false; } else { mc2log << info << "[ModuleMap]: Will try to save " << MC2CITE(fileName) << endl; } char tempTemplate[1024]; sprintf(tempTemplate, "%scachingXXXXXX", tmpDir.c_str()); int tmpDesc = mkstemp(tempTemplate); MC2String tempName = MC2String(tempTemplate); // Remove the old file if there is one ( to make space for new map ) mc2dbg << "[ModuleMap]: Removing " << MC2CITE(fileName) << " if it exists" << endl; unlink(fileName); int headerSize; byte* header = makeHeader( headerSize, mapID, mapVersion, generatorVersion); FILE* writeFile = NULL; if ( tmpDesc < 0 ) { mc2dbg << "[ModuleMap]: Could not make tempfile" << endl; writeFile = NULL; return false; } else { writeFile = fdopen(tmpDesc, "w"); if ( header ) { if ( fwrite(header, headerSize, 1, writeFile) != 1 ) { mc2dbg << "[ModuleMap]: Could not write header: " << strerror(errno) << endl; fclose(writeFile); unlink(tempName.c_str()); writeFile = NULL; return false; } } else { mc2log << "[ModuleMap]: Header is NULL" << endl; return false; } } delete [] header; MC2_ASSERT( writeFile != NULL ); // Now the header should be written. if ( fwrite(mapBuffer.getBufferAddress(), mapBuffer.getBufferSize(), 1, writeFile) != 1 ) { fclose(writeFile); unlink(tempName.c_str()); writeFile = NULL; mc2dbg << "[ModuleMap]: Could not write map data" << endl; return false; } else { rename(tempName.c_str(), fileName); chmod (fileName, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) ); fclose(writeFile); mc2log << info << "[ModuleMap]: Map 0x" << hex << mapID << dec << " saved." << endl; return true; } }