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;
   }
}
Пример #2
0
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");
   }
}
Пример #4
0
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;
}
Пример #10
0
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;
   }
}