replaced contigouos output data with collection of small'ish sub blocks. saves (re-)allocations. also removed a remaining stringstream

This commit is contained in:
Dennis Luxen 2013-11-14 17:16:26 -05:00
parent 8b6fe691ed
commit cabaad4b17
17 changed files with 391 additions and 305 deletions

View File

@ -29,7 +29,7 @@ add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/UUID.cpp UUID.cpp.alwaysbuild
add_custom_target(UUIDConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/UUID.cpp )
set(BOOST_COMPONENTS filesystem program_options regex system thread)
set(BOOST_COMPONENTS filesystem iostreams program_options regex system thread)
configure_file(Util/GitDescription.cpp.in ${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp)
file(GLOB ExtractorGlob Extractor/*.cpp)

View File

@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/HashTable.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../Server/Http/Reply.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"

View File

@ -95,21 +95,31 @@ void DescriptionFactory::AppendSegment(
void DescriptionFactory::AppendEncodedPolylineString(
const bool return_encoded,
std::string & output
std::vector<std::string> & output
) {
std::string temp;
if(return_encoded) {
polyline_compressor.printEncodedString(pathDescription, output);
polyline_compressor.printEncodedString(pathDescription, temp);
} else {
polyline_compressor.printUnencodedString(pathDescription, output);
polyline_compressor.printUnencodedString(pathDescription, temp);
}
output.push_back(temp);
}
void DescriptionFactory::AppendEncodedPolylineString(std::string &output) const {
polyline_compressor.printEncodedString(pathDescription, output);
void DescriptionFactory::AppendEncodedPolylineString(
std::vector<std::string> &output
) const {
std::string temp;
polyline_compressor.printEncodedString(pathDescription, temp);
output.push_back(temp);
}
void DescriptionFactory::AppendUnencodedPolylineString(std::string &output) const {
polyline_compressor.printUnencodedString(pathDescription, output);
void DescriptionFactory::AppendUnencodedPolylineString(
std::vector<std::string>& output
) const {
std::string temp;
polyline_compressor.printUnencodedString(pathDescription, temp);
output.push_back(temp);
}
// void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLevel) {

View File

@ -82,15 +82,15 @@ public:
DescriptionFactory();
virtual ~DescriptionFactory();
double GetBearing(const FixedPointCoordinate& C, const FixedPointCoordinate& B) const;
void AppendEncodedPolylineString(std::string &output) const;
void AppendUnencodedPolylineString(std::string &output) const;
void AppendEncodedPolylineString(std::vector<std::string> &output) const;
void AppendUnencodedPolylineString(std::vector<std::string> &output) const;
void AppendSegment(const FixedPointCoordinate & coordinate, const _PathData & data);
void BuildRouteSummary(const double distance, const unsigned time);
void SetStartSegment(const PhantomNode & start_phantom);
void SetEndSegment(const PhantomNode & start_phantom);
void AppendEncodedPolylineString(
const bool return_encoded,
std::string & output
std::vector<std::string> & output
);
template<class DataFacadeT>

View File

@ -49,18 +49,18 @@ public:
PhantomNodes &phantomNodes,
const DataFacadeT * facade
) {
reply.content += ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
reply.content +=
reply.content.push_back("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
reply.content.push_back(
"<gpx creator=\"OSRM Routing Engine\" version=\"1.1\" "
"xmlns=\"http://www.topografix.com/GPX/1/1\" "
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 gpx.xsd"
"\">";
reply.content +=
"\">");
reply.content.push_back(
"<metadata><copyright author=\"Project OSRM\"><license>Data (c)"
" OpenStreetMap contributors (ODbL)</license></copyright>"
"</metadata>";
reply.content += "<rte>";
"</metadata>");
reply.content.push_back("<rte>");
bool found_route = (rawRoute.lengthOfShortestPath != INT_MAX) &&
(rawRoute.computedShortestPath.size() );
if( found_route ) {
@ -68,12 +68,12 @@ public:
phantomNodes.startPhantom.location.lat,
tmp
);
reply.content += "<rtept lat=\"" + tmp + "\" ";
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
convertInternalLatLonToString(
phantomNodes.startPhantom.location.lon,
tmp
);
reply.content += "lon=\"" + tmp + "\"></rtept>";
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
BOOST_FOREACH(
const _PathData & pathData,
@ -82,22 +82,22 @@ public:
current = facade->GetCoordinateOfNode(pathData.node);
convertInternalLatLonToString(current.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
convertInternalLatLonToString(current.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
}
convertInternalLatLonToString(
phantomNodes.targetPhantom.location.lat,
tmp
);
reply.content += "<rtept lat=\"" + tmp + "\" ";
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
convertInternalLatLonToString(
phantomNodes.targetPhantom.location.lon,
tmp
);
reply.content += "lon=\"" + tmp + "\"></rtept>";
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
}
reply.content += "</rte></gpx>";
reply.content.push_back("</rte></gpx>");
}
};
#endif // GPX_DESCRIPTOR_H_

View File

@ -92,8 +92,8 @@ public:
if(raw_route_information.lengthOfShortestPath != INT_MAX) {
description_factory.SetStartSegment(phantom_nodes.startPhantom);
reply.content += "0,"
"\"status_message\": \"Found route between points\",";
reply.content.push_back("0,"
"\"status_message\": \"Found route between points\",");
//Get all the coordinates for the computed route
BOOST_FOREACH(const _PathData & path_data, raw_route_information.computedShortestPath) {
@ -103,23 +103,23 @@ public:
description_factory.SetEndSegment(phantom_nodes.targetPhantom);
} else {
//We do not need to do much, if there is no route ;-)
reply.content += "207,"
"\"status_message\": \"Cannot find route between points\",";
reply.content.push_back("207,"
"\"status_message\": \"Cannot find route between points\",");
}
description_factory.Run(facade, config.zoom_level);
reply.content += "\"route_geometry\": ";
reply.content.push_back("\"route_geometry\": ");
if(config.geometry) {
description_factory.AppendEncodedPolylineString(
config.encode_geometry,
reply.content
);
} else {
reply.content += "[]";
reply.content.push_back("[]");
}
reply.content += ","
"\"route_instructions\": [";
reply.content.push_back(","
"\"route_instructions\": [");
entered_restricted_area_count = 0;
if(config.instructions) {
BuildTextualDescription(
@ -138,32 +138,32 @@ public:
entered_restricted_area_count += (current_instruction != segment.turnInstruction);
}
}
reply.content += "],";
reply.content.push_back("],");
description_factory.BuildRouteSummary(
description_factory.entireLength,
raw_route_information.lengthOfShortestPath - ( entered_restricted_area_count*TurnInstructions.AccessRestrictionPenalty)
);
reply.content += "\"route_summary\":";
reply.content += "{";
reply.content += "\"total_distance\":";
reply.content += description_factory.summary.lengthString;
reply.content += ","
"\"total_time\":";
reply.content += description_factory.summary.durationString;
reply.content += ","
"\"start_point\":\"";
reply.content += facade->GetEscapedNameForNameID(
description_factory.summary.startName
reply.content.push_back("\"route_summary\":");
reply.content.push_back("{");
reply.content.push_back("\"total_distance\":");
reply.content.push_back(description_factory.summary.lengthString);
reply.content.push_back(","
"\"total_time\":");
reply.content.push_back(description_factory.summary.durationString);
reply.content.push_back(","
"\"start_point\":\"");
reply.content.push_back(
facade->GetEscapedNameForNameID(description_factory.summary.startName)
);
reply.content += "\","
"\"end_point\":\"";
reply.content += facade->GetEscapedNameForNameID(
description_factory.summary.destName
reply.content.push_back("\","
"\"end_point\":\"");
reply.content.push_back(
facade->GetEscapedNameForNameID(description_factory.summary.destName)
);
reply.content += "\"";
reply.content += "}";
reply.content +=",";
reply.content.push_back("\"");
reply.content.push_back("}");
reply.content.push_back(",");
//only one alternative route is computed at this time, so this is hardcoded
@ -179,7 +179,7 @@ public:
alternateDescriptionFactory.Run(facade, config.zoom_level);
//give an array of alternative routes
reply.content += "\"alternative_geometries\": [";
reply.content.push_back("\"alternative_geometries\": [");
if(config.geometry && INT_MAX != raw_route_information.lengthOfAlternativePath) {
//Generate the linestrings for each alternative
alternateDescriptionFactory.AppendEncodedPolylineString(
@ -187,11 +187,11 @@ public:
reply.content
);
}
reply.content += "],";
reply.content += "\"alternative_instructions\":[";
reply.content.push_back("],");
reply.content.push_back("\"alternative_instructions\":[");
entered_restricted_area_count = 0;
if(INT_MAX != raw_route_information.lengthOfAlternativePath) {
reply.content += "[";
reply.content.push_back("[");
//Generate instructions for each alternative
if(config.instructions) {
BuildTextualDescription(
@ -207,89 +207,89 @@ public:
entered_restricted_area_count += (current_instruction != segment.turnInstruction);
}
}
reply.content += "]";
reply.content.push_back("]");
}
reply.content += "],";
reply.content += "\"alternative_summaries\":[";
reply.content.push_back("],");
reply.content.push_back("\"alternative_summaries\":[");
if(INT_MAX != raw_route_information.lengthOfAlternativePath) {
//Generate route summary (length, duration) for each alternative
alternateDescriptionFactory.BuildRouteSummary(alternateDescriptionFactory.entireLength, raw_route_information.lengthOfAlternativePath - ( entered_restricted_area_count*TurnInstructions.AccessRestrictionPenalty));
reply.content += "{";
reply.content += "\"total_distance\":";
reply.content += alternateDescriptionFactory.summary.lengthString;
reply.content += ","
"\"total_time\":";
reply.content += alternateDescriptionFactory.summary.durationString;
reply.content += ","
"\"start_point\":\"";
reply.content += facade->GetEscapedNameForNameID(description_factory.summary.startName);
reply.content += "\","
"\"end_point\":\"";
reply.content += facade->GetEscapedNameForNameID(description_factory.summary.destName);
reply.content += "\"";
reply.content += "}";
reply.content.push_back("{");
reply.content.push_back("\"total_distance\":");
reply.content.push_back(alternateDescriptionFactory.summary.lengthString);
reply.content.push_back(","
"\"total_time\":");
reply.content.push_back(alternateDescriptionFactory.summary.durationString);
reply.content.push_back(","
"\"start_point\":\"");
reply.content.push_back(facade->GetEscapedNameForNameID(description_factory.summary.startName));
reply.content.push_back("\","
"\"end_point\":\"");
reply.content.push_back(facade->GetEscapedNameForNameID(description_factory.summary.destName));
reply.content.push_back("\"");
reply.content.push_back("}");
}
reply.content += "],";
reply.content.push_back("],");
//Get Names for both routes
RouteNames routeNames;
GetRouteNames(shortest_path_segments, alternative_path_segments, facade, routeNames);
reply.content += "\"route_name\":[\"";
reply.content += routeNames.shortestPathName1;
reply.content += "\",\"";
reply.content += routeNames.shortestPathName2;
reply.content += "\"],"
"\"alternative_names\":[";
reply.content += "[\"";
reply.content += routeNames.alternativePathName1;
reply.content += "\",\"";
reply.content += routeNames.alternativePathName2;
reply.content += "\"]";
reply.content += "],";
reply.content.push_back("\"route_name\":[\"");
reply.content.push_back(routeNames.shortestPathName1);
reply.content.push_back("\",\"");
reply.content.push_back(routeNames.shortestPathName2);
reply.content.push_back("\"],"
"\"alternative_names\":[");
reply.content.push_back("[\"");
reply.content.push_back(routeNames.alternativePathName1);
reply.content.push_back("\",\"");
reply.content.push_back(routeNames.alternativePathName2);
reply.content.push_back("\"]");
reply.content.push_back("],");
//list all viapoints so that the client may display it
reply.content += "\"via_points\":[";
reply.content.push_back("\"via_points\":[");
std::string tmp;
if(config.geometry && INT_MAX != raw_route_information.lengthOfShortestPath) {
for(unsigned i = 0; i < raw_route_information.segmentEndCoordinates.size(); ++i) {
reply.content += "[";
reply.content.push_back("[");
if(raw_route_information.segmentEndCoordinates[i].startPhantom.location.isSet())
convertInternalReversedCoordinateToString(raw_route_information.segmentEndCoordinates[i].startPhantom.location, tmp);
else
convertInternalReversedCoordinateToString(raw_route_information.rawViaNodeCoordinates[i], tmp);
reply.content += tmp;
reply.content += "],";
reply.content.push_back(tmp);
reply.content.push_back("],");
}
reply.content += "[";
reply.content.push_back("[");
if(raw_route_information.segmentEndCoordinates.back().startPhantom.location.isSet())
convertInternalReversedCoordinateToString(raw_route_information.segmentEndCoordinates.back().targetPhantom.location, tmp);
else
convertInternalReversedCoordinateToString(raw_route_information.rawViaNodeCoordinates.back(), tmp);
reply.content += tmp;
reply.content += "]";
reply.content.push_back(tmp);
reply.content.push_back("]");
}
reply.content += "],";
reply.content += "\"hint_data\": {";
reply.content += "\"checksum\":";
reply.content.push_back("],");
reply.content.push_back("\"hint_data\": {");
reply.content.push_back("\"checksum\":");
intToString(raw_route_information.checkSum, tmp);
reply.content += tmp;
reply.content += ", \"locations\": [";
reply.content.push_back(tmp);
reply.content.push_back(", \"locations\": [");
std::string hint;
for(unsigned i = 0; i < raw_route_information.segmentEndCoordinates.size(); ++i) {
reply.content += "\"";
reply.content.push_back("\"");
EncodeObjectToBase64(raw_route_information.segmentEndCoordinates[i].startPhantom, hint);
reply.content += hint;
reply.content += "\", ";
reply.content.push_back(hint);
reply.content.push_back("\", ");
}
EncodeObjectToBase64(raw_route_information.segmentEndCoordinates.back().targetPhantom, hint);
reply.content += "\"";
reply.content += hint;
reply.content += "\"]";
reply.content += "},";
reply.content += "\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\"";
reply.content += "}";
reply.content.push_back("\"");
reply.content.push_back(hint);
reply.content.push_back("\"]");
reply.content.push_back("},");
reply.content.push_back("\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\"");
reply.content.push_back("}");
}
// construct routes names
@ -357,10 +357,12 @@ public:
}
}
inline void WriteHeaderToOutput(std::string & output) {
output += "{"
inline void WriteHeaderToOutput(std::vector<std::string> & output) {
output.push_back(
"{"
"\"version\": 0.3,"
"\"status\":";
"\"status\":"
);
}
//TODO: reorder parameters
@ -389,41 +391,41 @@ public:
roundAbout.start_index = prefixSumOfNecessarySegments;
} else {
if(0 != prefixSumOfNecessarySegments){
reply.content += ",";
reply.content.push_back(",");
}
reply.content += "[\"";
reply.content.push_back("[\"");
if(TurnInstructions.LeaveRoundAbout == current_instruction) {
intToString(TurnInstructions.EnterRoundAbout, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "-";
reply.content.push_back(tmpInstruction);
reply.content.push_back("-");
intToString(roundAbout.leave_at_exit+1, tmpInstruction);
reply.content += tmpInstruction;
reply.content.push_back(tmpInstruction);
roundAbout.leave_at_exit = 0;
} else {
intToString(current_instruction, tmpInstruction);
reply.content += tmpInstruction;
reply.content.push_back(tmpInstruction);
}
reply.content += "\",\"";
reply.content += facade->GetEscapedNameForNameID(segment.nameID);
reply.content += "\",";
reply.content.push_back("\",\"");
reply.content.push_back(facade->GetEscapedNameForNameID(segment.nameID));
reply.content.push_back("\",");
intToString(segment.length, tmpDist);
reply.content += tmpDist;
reply.content += ",";
reply.content.push_back(tmpDist);
reply.content.push_back(",");
intToString(prefixSumOfNecessarySegments, tmpLength);
reply.content += tmpLength;
reply.content += ",";
reply.content.push_back(tmpLength);
reply.content.push_back(",");
intToString(segment.duration/10, tmpDuration);
reply.content += tmpDuration;
reply.content += ",\"";
reply.content.push_back(tmpDuration);
reply.content.push_back(",\"");
intToString(segment.length, tmpLength);
reply.content += tmpLength;
reply.content += "m\",\"";
reply.content += Azimuth::Get(segment.bearing);
reply.content += "\",";
reply.content.push_back(tmpLength);
reply.content.push_back("m\",\"");
reply.content.push_back(Azimuth::Get(segment.bearing));
reply.content.push_back("\",");
intToString(round(segment.bearing), tmpBearing);
reply.content += tmpBearing;
reply.content += "]";
reply.content.push_back(tmpBearing);
reply.content.push_back("]");
route_segments_list.push_back(
Segment(
@ -440,23 +442,23 @@ public:
++prefixSumOfNecessarySegments;
}
if(INT_MAX != route_length) {
reply.content += ",[\"";
reply.content.push_back(",[\"");
intToString(TurnInstructions.ReachedYourDestination, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "\",\"";
reply.content += "\",";
reply.content += "0";
reply.content += ",";
reply.content.push_back(tmpInstruction);
reply.content.push_back("\",\"");
reply.content.push_back("\",");
reply.content.push_back("0");
reply.content.push_back(",");
intToString(prefixSumOfNecessarySegments-1, tmpLength);
reply.content += tmpLength;
reply.content += ",";
reply.content += "0";
reply.content += ",\"";
reply.content += "\",\"";
reply.content += Azimuth::Get(0.0);
reply.content += "\",";
reply.content += "0.0";
reply.content += "]";
reply.content.push_back(tmpLength);
reply.content.push_back(",");
reply.content.push_back("0");
reply.content.push_back(",\"");
reply.content.push_back("\",\"");
reply.content.push_back(Azimuth::Get(0.0));
reply.content.push_back("\",");
reply.content.push_back("0.0");
reply.content.push_back("]");
}
}

View File

@ -29,10 +29,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define HELLOWORLDPLUGIN_H_
#include "BasePlugin.h"
#include "../Util/StringUtil.h"
#include <sstream>
#include <string>
class HelloWorldPlugin : public BasePlugin {
private:
std::string temp_string;
public:
HelloWorldPlugin() : descriptor_string("hello"){}
virtual ~HelloWorldPlugin() { }
@ -40,28 +43,56 @@ public:
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
reply.status = http::Reply::ok;
reply.content.append("<html><head><title>Hello World Demonstration Document</title></head><body><h1>Hello, World!</h1>");
std::stringstream content;
content << "<pre>";
content << "zoom level: " << routeParameters.zoomLevel << "\n";
content << "checksum: " << routeParameters.checkSum << "\n";
content << "instructions: " << (routeParameters.printInstructions ? "yes" : "no") << "\n";
content << "geometry: " << (routeParameters.geometry ? "yes" : "no") << "\n";
content << "compression: " << (routeParameters.compression ? "yes" : "no") << "\n";
content << "output format: " << routeParameters.outputFormat << "\n";
content << "json parameter: " << routeParameters.jsonpParameter << "\n";
content << "language: " << routeParameters.language << "<br>";
content << "Number of locations: " << routeParameters.coordinates.size() << "\n";
reply.content.push_back("<html><head><title>Hello World Demonstration Document</title></head><body><h1>Hello, World!</h1>");
reply.content.push_back("<pre>");
reply.content.push_back("zoom level: ");
intToString(routeParameters.zoomLevel, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\nchecksum: ");
intToString(routeParameters.checkSum, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\ninstructions: ");
reply.content.push_back((routeParameters.printInstructions ? "yes" : "no"));
reply.content.push_back(temp_string);
reply.content.push_back("\ngeometry: ");
reply.content.push_back((routeParameters.geometry ? "yes" : "no"));
reply.content.push_back("\ncompression: ");
reply.content.push_back((routeParameters.compression ? "yes" : "no"));
reply.content.push_back("\noutput format: ");
reply.content.push_back(routeParameters.outputFormat);
reply.content.push_back("\njson parameter: ");
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("\nlanguage: ");
reply.content.push_back(routeParameters.language);
reply.content.push_back("\nNumber of locations: ");
intToString(routeParameters.coordinates.size(), temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\n");
for(unsigned i = 0; i < routeParameters.coordinates.size(); ++i) {
content << " [" << i << "] " << routeParameters.coordinates[i].lat/COORDINATE_PRECISION << "," << routeParameters.coordinates[i].lon/COORDINATE_PRECISION << "\n";
reply.content.push_back( " [");
intToString(i, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("] ");
doubleToString(routeParameters.coordinates[i].lat/COORDINATE_PRECISION, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back(",");
doubleToString(routeParameters.coordinates[i].lon/COORDINATE_PRECISION, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\n");
}
content << "Number of hints: " << routeParameters.hints.size() << "\n";
reply.content.push_back( "Number of hints: ");
intToString(routeParameters.hints.size(), temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\n");
for(unsigned i = 0; i < routeParameters.hints.size(); ++i) {
content << " [" << i << "] " << routeParameters.hints[i] << "\n";
reply.content.push_back( " [");
intToString(i, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("] ");
reply.content.push_back(routeParameters.hints[i]);
reply.content.push_back("\n");
}
content << "</pre>";
reply.content.append(content.str());
reply.content.append("</body></html>");
reply.content.push_back( "</pre></body></html>");
}
private:
std::string descriptor_string;

View File

@ -63,38 +63,38 @@ public:
//json
if(!routeParameters.jsonpParameter.empty()) {
reply.content += routeParameters.jsonpParameter;
reply.content += "(";
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("(");
}
reply.status = http::Reply::ok;
reply.content += ("{");
reply.content += ("\"version\":0.3,");
reply.content.push_back ("{");
reply.content.push_back ("\"version\":0.3,");
if(
!facade->LocateClosestEndPointForCoordinate(
routeParameters.coordinates[0],
result
)
) {
reply.content += ("\"status\":207,");
reply.content += ("\"mapped_coordinate\":[]");
reply.content.push_back ("\"status\":207,");
reply.content.push_back ("\"mapped_coordinate\":[]");
} else {
//Write coordinate to stream
reply.status = http::Reply::ok;
reply.content += ("\"status\":0,");
reply.content += ("\"mapped_coordinate\":");
reply.content.push_back ("\"status\":0,");
reply.content.push_back ("\"mapped_coordinate\":");
convertInternalLatLonToString(result.lat, tmp);
reply.content += "[";
reply.content += tmp;
reply.content.push_back("[");
reply.content.push_back(tmp);
convertInternalLatLonToString(result.lon, tmp);
reply.content += ",";
reply.content += tmp;
reply.content += "]";
reply.content.push_back(",");
reply.content.push_back(tmp);
reply.content.push_back("]");
}
reply.content += ",\"transactionId\": \"OSRM Routing Engine JSON Locate (v0.3)\"";
reply.content += ("}");
reply.content.push_back(",\"transactionId\": \"OSRM Routing Engine JSON Locate (v0.3)\"");
reply.content.push_back("}");
reply.headers.resize(3);
if(!routeParameters.jsonpParameter.empty()) {
reply.content += ")";
reply.content.push_back( ")");
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";

View File

@ -70,40 +70,40 @@ public:
//json
if("" != routeParameters.jsonpParameter) {
reply.content += routeParameters.jsonpParameter;
reply.content += "(";
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("(");
}
reply.status = http::Reply::ok;
reply.content += ("{");
reply.content += ("\"version\":0.3,");
reply.content += ("\"status\":");
reply.content.push_back("{");
reply.content.push_back("\"version\":0.3,");
reply.content.push_back("\"status\":");
if(UINT_MAX != result.edgeBasedNode) {
reply.content += "0,";
reply.content.push_back("0,");
} else {
reply.content += "207,";
reply.content.push_back("207,");
}
reply.content += ("\"mapped_coordinate\":");
reply.content += "[";
reply.content.push_back("\"mapped_coordinate\":");
reply.content.push_back("[");
if(UINT_MAX != result.edgeBasedNode) {
convertInternalLatLonToString(result.location.lat, temp_string);
reply.content += temp_string;
reply.content.push_back(temp_string);
convertInternalLatLonToString(result.location.lon, temp_string);
reply.content += ",";
reply.content += temp_string;
reply.content.push_back(",");
reply.content.push_back(temp_string);
}
reply.content += "],";
reply.content += "\"name\":\"";
reply.content.push_back("],");
reply.content.push_back("\"name\":\"");
if(UINT_MAX != result.edgeBasedNode) {
facade->GetName(result.nodeBasedEdgeNameID, temp_string);
reply.content += temp_string;
reply.content.push_back(temp_string);
}
reply.content += "\"";
reply.content += ",\"transactionId\":\"OSRM Routing Engine JSON Nearest (v0.3)\"";
reply.content += ("}");
reply.content.push_back("\"");
reply.content.push_back(",\"transactionId\":\"OSRM Routing Engine JSON Nearest (v0.3)\"");
reply.content.push_back("}");
reply.headers.resize(3);
if( !routeParameters.jsonpParameter.empty() ) {
reply.content += ")";
reply.content.push_back(")");
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";

View File

@ -42,23 +42,23 @@ public:
//json
if("" != routeParameters.jsonpParameter) {
reply.content += routeParameters.jsonpParameter;
reply.content += "(";
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("(");
}
reply.status = http::Reply::ok;
reply.content += ("{");
reply.content += ("\"version\":0.3,");
reply.content += ("\"status\":");
reply.content += "0,";
reply.content += ("\"timestamp\":\"");
reply.content += facade->GetTimestamp();
reply.content += "\"";
reply.content += ",\"transactionId\":\"OSRM Routing Engine JSON timestamp (v0.3)\"";
reply.content += ("}");
reply.content.push_back("{");
reply.content.push_back("\"version\":0.3,");
reply.content.push_back("\"status\":");
reply.content.push_back("0,");
reply.content.push_back("\"timestamp\":\"");
reply.content.push_back(facade->GetTimestamp());
reply.content.push_back("\"");
reply.content.push_back(",\"transactionId\":\"OSRM Routing Engine JSON timestamp (v0.3)\"");
reply.content.push_back("}");
reply.headers.resize(3);
if("" != routeParameters.jsonpParameter) {
reply.content += ")";
reply.content.push_back(")");
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";

View File

@ -140,8 +140,8 @@ public:
//TODO: Move to member as smart pointer
BaseDescriptor<DataFacadeT> * desc;
if("" != routeParameters.jsonpParameter) {
reply.content += routeParameters.jsonpParameter;
reply.content += "(";
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("(");
}
DescriptorConfig descriptorConfig;
@ -172,15 +172,12 @@ public:
PhantomNodes phantomNodes;
phantomNodes.startPhantom = rawRoute.segmentEndCoordinates[0].startPhantom;
// SimpleLogger().Write() << "Start location: " << phantomNodes.startPhantom.location;
phantomNodes.targetPhantom = rawRoute.segmentEndCoordinates[rawRoute.segmentEndCoordinates.size()-1].targetPhantom;
// SimpleLogger().Write() << "TargetLocation: " << phantomNodes.targetPhantom.location;
// SimpleLogger().Write() << "Number of segments: " << rawRoute.segmentEndCoordinates.size();
desc->SetConfig(descriptorConfig);
desc->Run(reply, rawRoute, phantomNodes, facade);
if("" != routeParameters.jsonpParameter) {
reply.content += ")\n";
reply.content.push_back(")\n");
}
reply.headers.resize(3);
reply.headers[0].name = "Content-Length";

View File

@ -37,11 +37,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/assert.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <zlib.h>
// #include <zlib.h>
#include <string>
#include <vector>
namespace http {
@ -92,7 +96,7 @@ private:
request_handler.handle_request(request, reply);
Header compression_header;
std::vector<unsigned char> compressed_output;
std::vector<char> compressed_output;
std::vector<boost::asio::const_buffer> output_buffer;
switch(compression_type) {
case deflateRFC1951:
@ -102,11 +106,10 @@ private:
reply.headers.begin(),
compression_header
);
compressCharArray(
reply.content.c_str(),
reply.content.length(),
compressed_output,
compression_type
compressBufferCollection(
reply.content,
compression_type,
compressed_output
);
reply.setSize(compressed_output.size());
output_buffer = reply.HeaderstoBuffers();
@ -132,11 +135,10 @@ private:
reply.headers.begin(),
compression_header
);
compressCharArray(
reply.content.c_str(),
reply.content.length(),
compressed_output,
compression_type
compressBufferCollection(
reply.content,
compression_type,
compressed_output
);
reply.setSize(compressed_output.size());
output_buffer = reply.HeaderstoBuffers();
@ -210,71 +212,100 @@ private:
}
}
void compressBufferCollection(
std::vector<std::string> uncompressed_data,
CompressionType compression_type,
std::vector<char> & compressed_data
) {
boost::iostreams::gzip_params compression_parameters;
compression_parameters.level = boost::iostreams::zlib::best_speed;
if ( deflateRFC1951 == compression_type ) {
compression_parameters.noheader = true;
}
BOOST_ASSERT( compressed_data.empty() );
boost::iostreams::filtering_ostream compressing_stream;
compressing_stream.push(
boost::iostreams::gzip_compressor(compression_parameters)
);
compressing_stream.push(
boost::iostreams::back_inserter(compressed_data)
);
BOOST_FOREACH( const std::string & line, uncompressed_data) {
compressing_stream << line;
}
compressing_stream.reset();
}
// Big thanks to deusty who explains how to use gzip compression by
// the right call to deflateInit2():
// http://deusty.blogspot.com/2007/07/gzip-compressiondecompression.html
void compressCharArray(
const char * in_data,
size_t in_data_size,
std::vector<unsigned char> & buffer,
CompressionType type
) {
const size_t BUFSIZE = 128 * 1024;
unsigned char temp_buffer[BUFSIZE];
// void compressCharArray(
// const char * in_data,
// size_t in_data_size,
// std::vector<unsigned char> & buffer,
// CompressionType type
// ) {
// const size_t BUFSIZE = 128 * 1024;
// unsigned char temp_buffer[BUFSIZE];
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_out = 0;
strm.next_in = (unsigned char *)(in_data);
strm.avail_in = in_data_size;
strm.next_out = temp_buffer;
strm.avail_out = BUFSIZE;
strm.data_type = Z_ASCII;
// z_stream strm;
// strm.zalloc = Z_NULL;
// strm.zfree = Z_NULL;
// strm.opaque = Z_NULL;
// strm.total_out = 0;
// strm.next_in = (unsigned char *)(in_data);
// strm.avail_in = in_data_size;
// strm.next_out = temp_buffer;
// strm.avail_out = BUFSIZE;
// strm.data_type = Z_ASCII;
switch(type){
case deflateRFC1951:
deflateInit(&strm, Z_BEST_SPEED);
break;
case gzipRFC1952:
deflateInit2(
&strm,
Z_DEFAULT_COMPRESSION,
Z_DEFLATED,
(15+16),
9,
Z_DEFAULT_STRATEGY
);
break;
default:
BOOST_ASSERT_MSG(false, "should not happen");
break;
}
// switch(type){
// case deflateRFC1951:
// deflateInit(&strm, Z_BEST_SPEED);
// break;
// case gzipRFC1952:
// deflateInit2(
// &strm,
// Z_DEFAULT_COMPRESSION,
// Z_DEFLATED,
// (15+16),
// 9,
// Z_DEFAULT_STRATEGY
// );
// break;
// default:
// BOOST_ASSERT_MSG(false, "should not happen");
// break;
// }
int deflate_res = Z_OK;
do {
if ( 0 == strm.avail_out ) {
buffer.insert(buffer.end(), temp_buffer, temp_buffer + BUFSIZE);
strm.next_out = temp_buffer;
strm.avail_out = BUFSIZE;
}
deflate_res = deflate(&strm, Z_FINISH);
// int deflate_res = Z_OK;
// do {
// if ( 0 == strm.avail_out ) {
// buffer.insert(buffer.end(), temp_buffer, temp_buffer + BUFSIZE);
// strm.next_out = temp_buffer;
// strm.avail_out = BUFSIZE;
// }
// deflate_res = deflate(&strm, Z_FINISH);
} while (deflate_res == Z_OK);
// } while (deflate_res == Z_OK);
BOOST_ASSERT_MSG(
deflate_res == Z_STREAM_END,
"compression not properly finished"
);
// BOOST_ASSERT_MSG(
// deflate_res == Z_STREAM_END,
// "compression not properly finished"
// );
buffer.insert(
buffer.end(),
temp_buffer,
temp_buffer + BUFSIZE - strm.avail_out
);
deflateEnd(&strm);
}
// buffer.insert(
// buffer.end(),
// temp_buffer,
// temp_buffer + BUFSIZE - strm.avail_out
// );
// deflateEnd(&strm);
// }
boost::asio::io_service::strand strand;
boost::asio::ip::tcp::socket TCP_socket;

View File

@ -41,15 +41,16 @@ void Reply::setSize(const unsigned size) {
std::vector<boost::asio::const_buffer> Reply::toBuffers(){
std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(ToBuffer(status));
for (std::size_t i = 0; i < headers.size(); ++i) {
Header& h = headers[i];
BOOST_FOREACH(const Header & h, headers) {
buffers.push_back(boost::asio::buffer(h.name));
buffers.push_back(boost::asio::buffer(seperators));
buffers.push_back(boost::asio::buffer(h.value));
buffers.push_back(boost::asio::buffer(crlf));
}
buffers.push_back(boost::asio::buffer(crlf));
buffers.push_back(boost::asio::buffer(content));
BOOST_FOREACH(const std::string & line, content) {
buffers.push_back(boost::asio::buffer(line));
}
return buffers;
}
@ -70,7 +71,8 @@ std::vector<boost::asio::const_buffer> Reply::HeaderstoBuffers(){
Reply Reply::StockReply(Reply::status_type status) {
Reply rep;
rep.status = status;
rep.content = ToString(status);
rep.content.clear();
rep.content.push_back( ToString(status) );
rep.headers.resize(3);
rep.headers[0].name = "Access-Control-Allow-Origin";
rep.headers[0].value = "*";
@ -85,7 +87,6 @@ Reply Reply::StockReply(Reply::status_type status) {
return rep;
}
std::string Reply::ToString(Reply::status_type status) {
switch (status) {
case Reply::ok:
@ -110,7 +111,7 @@ boost::asio::const_buffer Reply::ToBuffer(Reply::status_type status) {
Reply::Reply() : status(ok) {
content.reserve(2 << 20);
}
}

View File

@ -59,7 +59,7 @@ const std::string internalServerErrorString = "HTTP/1.0 500 Internal Server Erro
std::vector<Header> headers;
std::vector<boost::asio::const_buffer> toBuffers();
std::vector<boost::asio::const_buffer> HeaderstoBuffers();
std::string content;
std::vector<std::string> content;
static Reply StockReply(status_type status);
void setSize(const unsigned size);
Reply();

View File

@ -85,16 +85,18 @@ public:
const int position = std::distance(request.begin(), it);
std::string tmp_position_string;
intToString(position, tmp_position_string);
rep.content += "Input seems to be malformed close to position ";
rep.content += "<br><pre>";
rep.content += request;
rep.content += tmp_position_string;
rep.content += "<br>";
rep.content.push_back(
"Input seems to be malformed close to position "
"<br><pre>"
);
rep.content.push_back( request );
rep.content.push_back(tmp_position_string);
rep.content.push_back("<br>");
const unsigned end = std::distance(request.begin(), it);
for(unsigned i = 0; i < end; ++i) {
rep.content += "&nbsp;";
rep.content.push_back("&nbsp;");
}
rep.content += "^<br></pre>";
rep.content.push_back("^<br></pre>");
} else {
//parsing done, lets call the right plugin to handle the request
BOOST_ASSERT_MSG(

View File

@ -42,10 +42,19 @@ public:
RequestParser();
void Reset();
boost::tuple<boost::tribool, char*> Parse(Request& req, char* begin, char* end, CompressionType * compressionType);
boost::tuple<boost::tribool, char*> Parse(
Request& req,
char* begin,
char* end,
CompressionType * compressionType
);
private:
boost::tribool consume(Request& req, char input, CompressionType * compressionType);
boost::tribool consume(
Request& req,
char input,
CompressionType * compressionType
);
inline bool isChar(int c);

View File

@ -98,12 +98,14 @@ int main (int argc, const char * argv[]) {
routing_machine.RunQuery(route_parameters, osrm_reply);
std::cout << osrm_reply.content << std::endl;
//attention: super-inefficient hack below:
std::stringstream ss;
ss << osrm_reply.content;
BOOST_FOREACH(const std::string & line, osrm_reply.content) {
std::cout << line;
ss << line;
}
std::cout << std::endl;
boost::property_tree::ptree pt;
boost::property_tree::read_json(ss, pt);