summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--benchmark/api/query.benchmark.cpp4
-rw-r--r--benchmark/api/render.benchmark.cpp8
-rw-r--r--benchmark/parse/vector_tile.benchmark.cpp2
-rw-r--r--bin/render.cpp2
-rw-r--r--cmake/core-files.cmake2
-rw-r--r--include/mbgl/storage/resource.hpp16
-rw-r--r--include/mbgl/storage/response.hpp3
-rw-r--r--include/mbgl/style/style.hpp5
-rw-r--r--include/mbgl/util/blob.hpp34
-rw-r--r--include/mbgl/util/compression.hpp7
-rw-r--r--include/mbgl/util/image.hpp6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/UnknownContentEncodingException.java12
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java19
-rw-r--r--platform/android/src/asset_manager_file_source.cpp5
-rw-r--r--platform/android/src/http_file_source.cpp14
-rw-r--r--platform/android/src/image.cpp12
-rwxr-xr-xplatform/android/src/native_map_view.cpp4
-rw-r--r--platform/darwin/src/http_file_source.mm5
-rw-r--r--platform/darwin/src/image.mm5
-rw-r--r--platform/darwin/test/MGLOfflineStorageTests.mm4
-rw-r--r--platform/default/asset_file_source.cpp8
-rw-r--r--platform/default/default_file_source.cpp15
-rw-r--r--platform/default/http_file_source.cpp4
-rw-r--r--platform/default/image.cpp7
-rw-r--r--platform/default/local_file_source.cpp8
-rw-r--r--platform/default/mbgl/storage/offline_database.cpp73
-rw-r--r--platform/default/mbgl/storage/offline_database.hpp2
-rw-r--r--platform/default/mbgl/storage/offline_download.cpp18
-rw-r--r--platform/default/online_file_source.cpp10
-rw-r--r--platform/default/png_writer.cpp4
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj4
-rw-r--r--platform/macos/macos.xcodeproj/project.pbxproj2
-rw-r--r--platform/node/src/node_map.cpp4
-rw-r--r--platform/node/src/node_request.cpp6
-rw-r--r--platform/qt/src/http_request.cpp4
-rw-r--r--platform/qt/src/qmapboxgl.cpp4
-rw-r--r--platform/qt/src/qt_image.cpp11
-rw-r--r--platform/qt/test/qmapboxgl.test.cpp2
-rw-r--r--src/mbgl/gl/program.hpp4
-rw-r--r--src/mbgl/programs/binary_program.cpp9
-rw-r--r--src/mbgl/programs/binary_program.hpp5
-rw-r--r--src/mbgl/sprite/sprite_loader.cpp8
-rw-r--r--src/mbgl/sprite/sprite_loader_worker.cpp5
-rw-r--r--src/mbgl/sprite/sprite_loader_worker.hpp3
-rw-r--r--src/mbgl/sprite/sprite_parser.cpp7
-rw-r--r--src/mbgl/sprite/sprite_parser.hpp2
-rw-r--r--src/mbgl/storage/resource.cpp18
-rw-r--r--src/mbgl/style/sources/geojson_source.cpp3
-rw-r--r--src/mbgl/style/sources/image_source.cpp2
-rw-r--r--src/mbgl/style/sources/raster_source.cpp2
-rw-r--r--src/mbgl/style/sources/vector_source.cpp3
-rw-r--r--src/mbgl/style/style.cpp4
-rw-r--r--src/mbgl/style/style_impl.cpp12
-rw-r--r--src/mbgl/style/style_impl.hpp8
-rw-r--r--src/mbgl/text/glyph_manager.cpp2
-rw-r--r--src/mbgl/text/glyph_pbf.cpp5
-rw-r--r--src/mbgl/text/glyph_pbf.hpp2
-rw-r--r--src/mbgl/tile/raster_dem_tile.cpp2
-rw-r--r--src/mbgl/tile/raster_dem_tile.hpp2
-rw-r--r--src/mbgl/tile/raster_dem_tile_worker.cpp4
-rw-r--r--src/mbgl/tile/raster_dem_tile_worker.hpp3
-rw-r--r--src/mbgl/tile/raster_tile.cpp2
-rw-r--r--src/mbgl/tile/raster_tile.hpp2
-rw-r--r--src/mbgl/tile/raster_tile_worker.cpp4
-rw-r--r--src/mbgl/tile/raster_tile_worker.hpp3
-rw-r--r--src/mbgl/tile/tile_loader_impl.hpp2
-rw-r--r--src/mbgl/tile/vector_tile.cpp4
-rw-r--r--src/mbgl/tile/vector_tile.hpp2
-rw-r--r--src/mbgl/tile/vector_tile_data.cpp15
-rw-r--r--src/mbgl/tile/vector_tile_data.hpp9
-rw-r--r--src/mbgl/util/blob.cpp46
-rw-r--r--src/mbgl/util/compression.cpp37
-rw-r--r--src/mbgl/util/io.cpp34
-rw-r--r--src/mbgl/util/io.hpp7
-rw-r--r--test/api/annotations.test.cpp54
-rw-r--r--test/api/custom_geometry_source.test.cpp2
-rw-r--r--test/api/custom_layer.test.cpp2
-rw-r--r--test/api/query.test.cpp4
-rw-r--r--test/api/recycle_map.cpp4
-rw-r--r--test/api/zoom_history.cpp2
-rw-r--r--test/gl/context.test.cpp2
-rw-r--r--test/map/map.test.cpp54
-rw-r--r--test/map/prefetch.test.cpp10
-rw-r--r--test/programs/binary_program.test.cpp2
-rw-r--r--test/renderer/image_manager.test.cpp4
-rw-r--r--test/sprite/sprite_loader.test.cpp6
-rw-r--r--test/sprite/sprite_parser.test.cpp38
-rw-r--r--test/src/mbgl/test/util.cpp12
-rw-r--r--test/storage/asset_file_source.test.cpp22
-rw-r--r--test/storage/default_file_source.test.cpp100
-rw-r--r--test/storage/http_file_source.test.cpp27
-rw-r--r--test/storage/local_file_source.test.cpp20
-rw-r--r--test/storage/offline_database.test.cpp62
-rw-r--r--test/storage/offline_download.test.cpp10
-rw-r--r--test/storage/online_file_source.test.cpp28
-rw-r--r--test/style/expression/expression.test.cpp6
-rw-r--r--test/style/source.test.cpp26
-rw-r--r--test/style/style.test.cpp16
-rw-r--r--test/style/style_layer.test.cpp2
-rw-r--r--test/style/style_parser.test.cpp8
-rw-r--r--test/text/glyph_manager.test.cpp8
-rw-r--r--test/text/glyph_pbf.test.cpp2
-rw-r--r--test/text/local_glyph_rasterizer.test.cpp8
-rw-r--r--test/util/image.test.cpp14
-rw-r--r--test/util/memory.test.cpp6
105 files changed, 723 insertions, 475 deletions
diff --git a/benchmark/api/query.benchmark.cpp b/benchmark/api/query.benchmark.cpp
index 7694585526..f9cbbff32b 100644
--- a/benchmark/api/query.benchmark.cpp
+++ b/benchmark/api/query.benchmark.cpp
@@ -22,10 +22,10 @@ public:
NetworkStatus::Set(NetworkStatus::Status::Offline);
fileSource.setAccessToken("foobar");
- map.getStyle().loadJSON(util::read_file("benchmark/fixtures/api/style.json"));
+ map.getStyle().loadJSON(util::readFile("benchmark/fixtures/api/style.json"));
map.setLatLngZoom({ 40.726989, -73.992857 }, 15); // Manhattan
map.getStyle().addImage(std::make_unique<style::Image>("test-icon",
- decodeImage(util::read_file("benchmark/fixtures/api/default_marker.png")), 1.0));
+ decodeImage(util::readFile("benchmark/fixtures/api/default_marker.png")), 1.0));
frontend.render(map);
}
diff --git a/benchmark/api/render.benchmark.cpp b/benchmark/api/render.benchmark.cpp
index a1b557777f..8c783c6a0e 100644
--- a/benchmark/api/render.benchmark.cpp
+++ b/benchmark/api/render.benchmark.cpp
@@ -29,11 +29,11 @@ public:
ThreadPool threadPool { 4 };
};
-static void prepare(Map& map, optional<std::string> json = {}) {
- map.getStyle().loadJSON(json ? *json : util::read_file("benchmark/fixtures/api/style.json"));
+static void prepare(Map& map, Blob json = {}) {
+ map.getStyle().loadJSON(json ? json : util::readFile("benchmark/fixtures/api/style.json"));
map.setLatLngZoom({ 40.726989, -73.992857 }, 15); // Manhattan
map.getStyle().addImage(std::make_unique<style::Image>("test-icon",
- decodeImage(util::read_file("benchmark/fixtures/api/default_marker.png")), 1.0));
+ decodeImage(util::readFile("benchmark/fixtures/api/default_marker.png")), 1.0));
}
} // end namespace
@@ -55,7 +55,7 @@ static void API_renderStill_reuse_map_switch_styles(::benchmark::State& state) {
Map map { frontend, MapObserver::nullObserver(), frontend.getSize(), 1, bench.fileSource, bench.threadPool, MapMode::Static};
while (state.KeepRunning()) {
- prepare(map, { "{}" });
+ prepare(map, { "{}", false });
frontend.render(map);
prepare(map);
frontend.render(map);
diff --git a/benchmark/parse/vector_tile.benchmark.cpp b/benchmark/parse/vector_tile.benchmark.cpp
index 24623dbda7..fab22ae380 100644
--- a/benchmark/parse/vector_tile.benchmark.cpp
+++ b/benchmark/parse/vector_tile.benchmark.cpp
@@ -6,7 +6,7 @@
using namespace mbgl;
static void Parse_VectorTile(benchmark::State& state) {
- auto data = std::make_shared<std::string>(util::read_file("test/fixtures/api/assets/streets/10-163-395.vector.pbf"));
+ auto data = util::readFile("test/fixtures/api/assets/streets/10-163-395.vector.pbf");
while (state.KeepRunning()) {
std::size_t length = 0;
diff --git a/bin/render.cpp b/bin/render.cpp
index 6ceb32eb00..4b15ced9a9 100644
--- a/bin/render.cpp
+++ b/bin/render.cpp
@@ -101,7 +101,7 @@ int main(int argc, char *argv[]) {
try {
std::ofstream out(output, std::ios::binary);
- out << encodePNG(frontend.render(map));
+ out << *encodePNG(frontend.render(map)).uncompressedData();
out.close();
} catch(std::exception& e) {
std::cout << "Error: " << e.what() << std::endl;
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index f24482e301..a0523a6f42 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -656,6 +656,7 @@ set(MBGL_CORE_FILES
# util
include/mbgl/util/async_request.hpp
include/mbgl/util/async_task.hpp
+ include/mbgl/util/blob.hpp
include/mbgl/util/char_array_buffer.hpp
include/mbgl/util/chrono.hpp
include/mbgl/util/color.hpp
@@ -698,6 +699,7 @@ set(MBGL_CORE_FILES
include/mbgl/util/work_request.hpp
include/mbgl/util/work_task.hpp
include/mbgl/util/work_task_impl.hpp
+ src/mbgl/util/blob.cpp
src/mbgl/util/chrono.cpp
src/mbgl/util/clip_id.cpp
src/mbgl/util/clip_id.hpp
diff --git a/include/mbgl/storage/resource.hpp b/include/mbgl/storage/resource.hpp
index 318fa389f4..d9da494e4d 100644
--- a/include/mbgl/storage/resource.hpp
+++ b/include/mbgl/storage/resource.hpp
@@ -42,12 +42,23 @@ public:
All = Cache | Network,
};
+ enum class Compression : bool {
+ // The data will be an uncompressed blob, even if it was obtained in compressed form.
+ Uncompressed = false,
+
+ // The data will be returned compressed if it was already obtained in compressed form,
+ // and uncompressed otherwise.
+ PreferCompressed = true,
+ };
+
Resource(Kind kind_,
std::string url_,
optional<TileData> tileData_ = {},
- LoadingMethod loadingMethod_ = LoadingMethod::All)
+ LoadingMethod loadingMethod_ = LoadingMethod::All,
+ Compression compression_ = Compression::PreferCompressed)
: kind(kind_),
loadingMethod(loadingMethod_),
+ compression(compression_),
url(std::move(url_)),
tileData(std::move(tileData_)) {
}
@@ -72,6 +83,7 @@ public:
Kind kind;
LoadingMethod loadingMethod;
+ Compression compression;
std::string url;
// Includes auxiliary data if this is a tile request.
@@ -80,7 +92,7 @@ public:
optional<Timestamp> priorModified = {};
optional<Timestamp> priorExpires = {};
optional<std::string> priorEtag = {};
- std::shared_ptr<const std::string> priorData;
+ Blob priorData;
};
diff --git a/include/mbgl/storage/response.hpp b/include/mbgl/storage/response.hpp
index 508400141b..81a84effb7 100644
--- a/include/mbgl/storage/response.hpp
+++ b/include/mbgl/storage/response.hpp
@@ -2,6 +2,7 @@
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/optional.hpp>
+#include <mbgl/util/blob.hpp>
#include <string>
#include <memory>
@@ -31,7 +32,7 @@ public:
bool mustRevalidate = false;
// The actual data of the response. Present only for non-error, non-notModified responses.
- std::shared_ptr<const std::string> data;
+ Blob data;
optional<Timestamp> modified;
optional<Timestamp> expires;
diff --git a/include/mbgl/style/style.hpp b/include/mbgl/style/style.hpp
index d6fdbd8f2c..dffdbf99ec 100644
--- a/include/mbgl/style/style.hpp
+++ b/include/mbgl/style/style.hpp
@@ -3,6 +3,7 @@
#include <mbgl/style/transition_options.hpp>
#include <mbgl/map/camera.hpp>
#include <mbgl/util/geo.hpp>
+#include <mbgl/util/blob.hpp>
#include <string>
#include <vector>
@@ -25,10 +26,10 @@ public:
Style(Scheduler&, FileSource&, float pixelRatio);
~Style();
- void loadJSON(const std::string&);
+ void loadJSON(Blob);
void loadURL(const std::string&);
- std::string getJSON() const;
+ Blob getJSON() const;
std::string getURL() const;
// Defaults
diff --git a/include/mbgl/util/blob.hpp b/include/mbgl/util/blob.hpp
new file mode 100644
index 0000000000..df8fddc773
--- /dev/null
+++ b/include/mbgl/util/blob.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <memory>
+#include <string>
+
+namespace mbgl {
+
+class Blob {
+public:
+ Blob();
+ Blob(std::shared_ptr<const std::string> bytes, bool gzip);
+ Blob(std::string&& bytes, bool compressed);
+
+ // Return uncompressed/compressed data.
+ std::shared_ptr<const std::string> uncompressedData() const;
+ std::shared_ptr<const std::string> compressedData() const;
+
+ // Transform the blob to being uncompressed.
+ void uncompress();
+
+ bool isCompressed() const {
+ return compressed;
+ }
+
+ explicit operator bool() const {
+ return (bool)bytes;
+ }
+
+private:
+ std::shared_ptr<const std::string> bytes;
+ bool compressed;
+};
+
+} // namespace mbgl
diff --git a/include/mbgl/util/compression.hpp b/include/mbgl/util/compression.hpp
index 93a3ddb8bc..cbce764683 100644
--- a/include/mbgl/util/compression.hpp
+++ b/include/mbgl/util/compression.hpp
@@ -5,8 +5,15 @@
namespace mbgl {
namespace util {
+// Compresses data with the deflate algorithm.
std::string compress(const std::string& raw);
+
+// Decompresses data that is in deflate format, optionally wrapped in a gzip container.
std::string decompress(const std::string& raw);
+// Returns true when there's a good chance that the string can be compressed.
+// In particular, it returns false when the data is an already compressed image format.
+bool isCompressible(const std::string& raw);
+
} // namespace util
} // namespace mbgl
diff --git a/include/mbgl/util/image.hpp b/include/mbgl/util/image.hpp
index 4887058f79..1cb3cca8c9 100644
--- a/include/mbgl/util/image.hpp
+++ b/include/mbgl/util/image.hpp
@@ -2,6 +2,7 @@
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/geometry.hpp>
+#include <mbgl/util/blob.hpp>
#include <mbgl/util/size.hpp>
#include <string>
@@ -170,8 +171,7 @@ using UnassociatedImage = Image<ImageAlphaMode::Unassociated>;
using PremultipliedImage = Image<ImageAlphaMode::Premultiplied>;
using AlphaImage = Image<ImageAlphaMode::Exclusive>;
-// TODO: don't use std::string for binary data.
-PremultipliedImage decodeImage(const std::string&);
-std::string encodePNG(const PremultipliedImage&);
+PremultipliedImage decodeImage(Blob);
+Blob encodePNG(const PremultipliedImage&);
} // namespace mbgl
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/UnknownContentEncodingException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/UnknownContentEncodingException.java
new file mode 100644
index 0000000000..4debc33ee4
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/UnknownContentEncodingException.java
@@ -0,0 +1,12 @@
+package com.mapbox.mapboxsdk.exceptions;
+
+/**
+ * An UnknownContentEncodingException is thrown by HTTPRequest
+ * when there aren't enough LatLng to create a bounds.
+ */
+public class UnknownContentEncodingException extends RuntimeException {
+
+ public UnknownContentEncodingException(String encoding) {
+ super("Unknown content encoding '" + encoding + "'");
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
index caee493e6f..942b88f1fb 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
@@ -9,6 +9,7 @@ import android.text.TextUtils;
import com.mapbox.mapboxsdk.BuildConfig;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import com.mapbox.mapboxsdk.exceptions.UnknownContentEncodingException;
import java.io.IOException;
import java.io.InterruptedIOException;
@@ -66,7 +67,7 @@ class HTTPRequest implements Callback {
private native void nativeOnFailure(int type, String message);
private native void nativeOnResponse(int code, String etag, String modified, String cacheControl, String expires,
- String retryAfter, String xRateLimitReset, byte[] body);
+ String retryAfter, String xRateLimitReset, byte[] body, boolean gzip);
private HTTPRequest(long nativePtr, String resourceUrl, String etag, String modified) {
mNativePtr = nativePtr;
@@ -93,6 +94,7 @@ class HTTPRequest implements Callback {
Request.Builder builder = new Request.Builder()
.url(resourceUrl)
.tag(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE))
+ .addHeader("Accept-Encoding", "gzip, deflate")
.addHeader("User-Agent", getUserAgent());
if (etag.length() > 0) {
builder = builder.addHeader("If-None-Match", etag);
@@ -149,6 +151,18 @@ class HTTPRequest implements Callback {
mLock.lock();
if (mNativePtr != 0) {
+ String encoding = response.header("Content-Encoding");
+ boolean compressed = false;
+ if (encoding != null) {
+ if (encoding.equals("gzip") || encoding.equals("deflate")) {
+ compressed = true;
+ } else if (!encoding.equals("identity")) {
+ mLock.unlock();
+ handleFailure(call, new UnknownContentEncodingException(encoding));
+ return;
+ }
+ }
+
nativeOnResponse(response.code(),
response.header("ETag"),
response.header("Last-Modified"),
@@ -156,7 +170,8 @@ class HTTPRequest implements Callback {
response.header("Expires"),
response.header("Retry-After"),
response.header("x-rate-limit-reset"),
- body);
+ body,
+ compressed);
}
mLock.unlock();
}
diff --git a/platform/android/src/asset_manager_file_source.cpp b/platform/android/src/asset_manager_file_source.cpp
index aa65e3ff48..404177ba95 100644
--- a/platform/android/src/asset_manager_file_source.cpp
+++ b/platform/android/src/asset_manager_file_source.cpp
@@ -23,8 +23,9 @@ public:
Response response;
if (AAsset* asset = AAssetManager_open(assetManager, path.c_str(), AASSET_MODE_BUFFER)) {
- response.data = std::make_shared<std::string>(
- reinterpret_cast<const char*>(AAsset_getBuffer(asset)), AAsset_getLength64(asset));
+ response.data = { { reinterpret_cast<const char*>(AAsset_getBuffer(asset)),
+ static_cast<size_t>(AAsset_getLength64(asset)) },
+ false };
AAsset_close(asset);
} else {
response.error = std::make_unique<Response::Error>(Response::Error::Reason::NotFound,
diff --git a/platform/android/src/http_file_source.cpp b/platform/android/src/http_file_source.cpp
index 8eb9416e9d..7602c1914e 100644
--- a/platform/android/src/http_file_source.cpp
+++ b/platform/android/src/http_file_source.cpp
@@ -30,7 +30,8 @@ public:
jni::String etag, jni::String modified,
jni::String cacheControl, jni::String expires,
jni::String retryAfter, jni::String xRateLimitReset,
- jni::Array<jni::jbyte> body);
+ jni::Array<jni::jbyte> body,
+ jni::jboolean compressed);
static jni::Class<HTTPRequest> javaClass;
jni::UniqueObject<HTTPRequest> javaRequest;
@@ -104,7 +105,8 @@ void HTTPRequest::onResponse(jni::JNIEnv& env, int code,
jni::String etag, jni::String modified,
jni::String cacheControl, jni::String expires,
jni::String jRetryAfter, jni::String jXRateLimitReset,
- jni::Array<jni::jbyte> body) {
+ jni::Array<jni::jbyte> body,
+ jni::jboolean compressed) {
using Error = Response::Error;
@@ -128,11 +130,11 @@ void HTTPRequest::onResponse(jni::JNIEnv& env, int code,
if (code == 200) {
if (body) {
- auto data = std::make_shared<std::string>(body.Length(env), char());
- jni::GetArrayRegion(env, *body, 0, data->size(), reinterpret_cast<jbyte*>(&(*data)[0]));
- response.data = data;
+ std::string data(static_cast<size_t>(body.Length(env)), char());
+ jni::GetArrayRegion(env, *body, 0, data.size(), reinterpret_cast<jbyte*>(&data[0]));
+ response.data = Blob{ std::move(data), static_cast<bool>(compressed) };
} else {
- response.data = std::make_shared<std::string>();
+ response.data = {};
}
} else if (code == 204 || (code == 404 && resource.kind == Resource::Kind::Tile)) {
response.noContent = true;
diff --git a/platform/android/src/image.cpp b/platform/android/src/image.cpp
index 2a33944b18..dd98a3a6c8 100644
--- a/platform/android/src/image.cpp
+++ b/platform/android/src/image.cpp
@@ -8,14 +8,16 @@
namespace mbgl {
-PremultipliedImage decodeImage(const std::string& string) {
+PremultipliedImage decodeImage(Blob blob) {
auto env{ android::AttachEnv() };
- auto array = jni::Array<jni::jbyte>::New(*env, string.size());
- jni::SetArrayRegion(*env, *array, 0, string.size(),
- reinterpret_cast<const signed char*>(string.data()));
+ const auto string = blob.uncompressedData();
- auto bitmap = android::BitmapFactory::DecodeByteArray(*env, array, 0, string.size());
+ auto array = jni::Array<jni::jbyte>::New(*env, string->size());
+ jni::SetArrayRegion(*env, *array, 0, string->size(),
+ reinterpret_cast<const signed char*>(string->data()));
+
+ auto bitmap = android::BitmapFactory::DecodeByteArray(*env, array, 0, string->size());
return android::Bitmap::GetImage(*env, bitmap);
}
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp
index 67fc132204..c52aad6405 100755
--- a/platform/android/src/native_map_view.cpp
+++ b/platform/android/src/native_map_view.cpp
@@ -188,11 +188,11 @@ void NativeMapView::setStyleUrl(jni::JNIEnv& env, jni::String url) {
}
jni::String NativeMapView::getStyleJson(jni::JNIEnv& env) {
- return jni::Make<jni::String>(env, map->getStyle().getJSON());
+ return jni::Make<jni::String>(env, *map->getStyle().getJSON().uncompressedData());
}
void NativeMapView::setStyleJson(jni::JNIEnv& env, jni::String json) {
- map->getStyle().loadJSON(jni::Make<std::string>(env, json));
+ map->getStyle().loadJSON(Blob{ jni::Make<std::string>(env, json), false });
}
void NativeMapView::setLatLngBounds(jni::JNIEnv& env, jni::Object<mbgl::android::LatLngBounds> jBounds) {
diff --git a/platform/darwin/src/http_file_source.mm b/platform/darwin/src/http_file_source.mm
index 4a16ad82fb..6840740c44 100644
--- a/platform/darwin/src/http_file_source.mm
+++ b/platform/darwin/src/http_file_source.mm
@@ -232,8 +232,7 @@ std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource,
if (error) {
if (data) {
- response.data =
- std::make_shared<std::string>((const char*)[data bytes], [data length]);
+ response.data = Blob{ { (const char*)[data bytes], [data length] }, false };
}
switch ([error code]) {
@@ -287,7 +286,7 @@ std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource,
}
if (responseCode == 200) {
- response.data = std::make_shared<std::string>((const char *)[data bytes], [data length]);
+ response.data = { { (const char *)[data bytes], [data length] }, false };
} else if (responseCode == 204 || (responseCode == 404 && resource.kind == Resource::Kind::Tile)) {
response.noContent = true;
} else if (responseCode == 304) {
diff --git a/platform/darwin/src/image.mm b/platform/darwin/src/image.mm
index 3a5adcca0a..f08fb9a25f 100644
--- a/platform/darwin/src/image.mm
+++ b/platform/darwin/src/image.mm
@@ -71,9 +71,10 @@ mbgl::PremultipliedImage MGLPremultipliedImageFromCGImage(CGImageRef src) {
namespace mbgl {
-PremultipliedImage decodeImage(const std::string& source) {
+PremultipliedImage decodeImage(Blob blob) {
+ const auto source = blob.uncompressedData();
CFDataHandle data(CFDataCreateWithBytesNoCopy(
- kCFAllocatorDefault, reinterpret_cast<const unsigned char*>(source.data()), source.size(),
+ kCFAllocatorDefault, reinterpret_cast<const unsigned char*>(source->data()), source->size(),
kCFAllocatorNull));
if (!data) {
throw std::runtime_error("CFDataCreateWithBytesNoCopy failed");
diff --git a/platform/darwin/test/MGLOfflineStorageTests.mm b/platform/darwin/test/MGLOfflineStorageTests.mm
index 28c6633028..f0d54f81b4 100644
--- a/platform/darwin/test/MGLOfflineStorageTests.mm
+++ b/platform/darwin/test/MGLOfflineStorageTests.mm
@@ -182,8 +182,8 @@
req = fs->request(resource, [&](mbgl::Response res) {
req.reset();
XCTAssertFalse(res.error.get(), @"Request should not return an error");
- XCTAssertTrue(res.data.get(), @"Request should return data");
- XCTAssertEqual("{\"api\":\"mapbox\"}", *res.data, @"Request did not return expected data");
+ XCTAssertTrue(res.data, @"Request should return data");
+ XCTAssertEqual("{\"api\":\"mapbox\"}", *res.data.uncompressedData(), @"Request did not return expected data");
CFRunLoopStop(CFRunLoopGetCurrent());
});
diff --git a/platform/default/asset_file_source.cpp b/platform/default/asset_file_source.cpp
index 3063bf88a0..0b57a6dcef 100644
--- a/platform/default/asset_file_source.cpp
+++ b/platform/default/asset_file_source.cpp
@@ -44,12 +44,10 @@ public:
} else if (result == -1 && errno == ENOENT) {
response.error = std::make_unique<Response::Error>(Response::Error::Reason::NotFound);
} else {
- try {
- response.data = std::make_shared<std::string>(util::read_file(path));
- } catch (...) {
+ response.data = util::readFile(path);
+ if (!response.data) {
response.error = std::make_unique<Response::Error>(
- Response::Error::Reason::Other,
- util::toString(std::current_exception()));
+ Response::Error::Reason::Other, "Cannot read file " + path);
}
}
diff --git a/platform/default/default_file_source.cpp b/platform/default/default_file_source.cpp
index cb602995a4..5dcd28facd 100644
--- a/platform/default/default_file_source.cpp
+++ b/platform/default/default_file_source.cpp
@@ -151,8 +151,23 @@ public:
// Get from the online file source
if (resource.hasLoadingMethod(Resource::LoadingMethod::Network)) {
+ // Always solicit a compressed response so that we can insert it into the database
+ // while still compressed to save on CPU time.
+ const auto compression = resource.compression;
+ resource.compression = Resource::Compression::PreferCompressed;
tasks[req] = onlineFileSource.request(resource, [=] (Response onlineResponse) mutable {
this->offlineDatabase->put(resource, onlineResponse);
+ // If the original request expects an uncompressed response, uncompress before
+ // handing it back.
+ if (onlineResponse.data && onlineResponse.data.isCompressed() &&
+ compression == Resource::Compression::Uncompressed) {
+ try {
+ onlineResponse.data.uncompress();
+ } catch (std::exception& ex) {
+ onlineResponse.error = std::make_unique<Response::Error>(
+ Response::Error::Reason::Other, ex.what());
+ }
+ }
callback(onlineResponse);
});
}
diff --git a/platform/default/http_file_source.cpp b/platform/default/http_file_source.cpp
index a9c442c2de..1a0ae577b8 100644
--- a/platform/default/http_file_source.cpp
+++ b/platform/default/http_file_source.cpp
@@ -371,9 +371,9 @@ void HTTPRequest::handleResult(CURLcode code) {
if (responseCode == 200) {
if (data) {
- response->data = std::move(data);
+ response->data = Blob{ std::move(data), false };
} else {
- response->data = std::make_shared<std::string>();
+ response->data = Blob{ "", false };
}
} else if (responseCode == 204 || (responseCode == 404 && resource.kind == Resource::Kind::Tile)) {
response->noContent = true;
diff --git a/platform/default/image.cpp b/platform/default/image.cpp
index 447c6bcd66..4fde1898c6 100644
--- a/platform/default/image.cpp
+++ b/platform/default/image.cpp
@@ -11,9 +11,10 @@ PremultipliedImage decodeWebP(const uint8_t*, size_t);
PremultipliedImage decodePNG(const uint8_t*, size_t);
PremultipliedImage decodeJPEG(const uint8_t*, size_t);
-PremultipliedImage decodeImage(const std::string& string) {
- const auto* data = reinterpret_cast<const uint8_t*>(string.data());
- const size_t size = string.size();
+PremultipliedImage decodeImage(Blob blob) {
+ const auto uncompressed = blob.uncompressedData();
+ const auto* data = reinterpret_cast<const uint8_t*>(uncompressed->data());
+ const size_t size = uncompressed->size();
#if !defined(__ANDROID__) && !defined(__APPLE__)
if (size >= 12) {
diff --git a/platform/default/local_file_source.cpp b/platform/default/local_file_source.cpp
index 0635e86d80..9a8f5ae51b 100644
--- a/platform/default/local_file_source.cpp
+++ b/platform/default/local_file_source.cpp
@@ -46,12 +46,10 @@ public:
} else if (result == -1 && errno == ENOENT) {
response.error = std::make_unique<Response::Error>(Response::Error::Reason::NotFound);
} else {
- try {
- response.data = std::make_shared<std::string>(util::read_file(path));
- } catch (...) {
+ response.data = util::readFile(path);
+ if (!response.data) {
response.error = std::make_unique<Response::Error>(
- Response::Error::Reason::Other,
- util::toString(std::current_exception()));
+ Response::Error::Reason::Other, "Cannot read file " + path);
}
}
diff --git a/platform/default/mbgl/storage/offline_database.cpp b/platform/default/mbgl/storage/offline_database.cpp
index 65c2097182..d7022f1c80 100644
--- a/platform/default/mbgl/storage/offline_database.cpp
+++ b/platform/default/mbgl/storage/offline_database.cpp
@@ -1,10 +1,10 @@
#include <mbgl/storage/offline_database.hpp>
#include <mbgl/storage/response.hpp>
-#include <mbgl/util/compression.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/logging.hpp>
+#include <mbgl/util/compression.hpp>
#include "sqlite3.hpp"
@@ -153,7 +153,7 @@ optional<Response> OfflineDatabase::get(const Resource& resource) {
optional<std::pair<Response, uint64_t>> OfflineDatabase::getInternal(const Resource& resource) {
if (resource.kind == Resource::Kind::Tile) {
assert(resource.tileData);
- return getTile(*resource.tileData);
+ return getTile(resource);
} else {
return getResource(resource);
}
@@ -177,14 +177,31 @@ std::pair<bool, uint64_t> OfflineDatabase::putInternal(const Resource& resource,
return { false, 0 };
}
- std::string compressedData;
+ std::shared_ptr<const std::string> data;
bool compressed = false;
uint64_t size = 0;
if (response.data) {
- compressedData = util::compress(*response.data);
- compressed = compressedData.size() < response.data->size();
- size = compressed ? compressedData.size() : response.data->size();
+ if (response.data.isCompressed()) {
+ // The response is already compressed; don't try to compare it against the uncompressed size.
+ compressed = true;
+ data = response.data.compressedData();
+ } else {
+ data = response.data.uncompressedData();
+
+ // Only try to compress the data when we have a good chance that the data can actually
+ // be considerably compressed.
+ if (util::isCompressible(*data)) {
+ const auto compressedData = response.data.compressedData();
+ if (compressedData->size() < data->size()) {
+ compressed = true;
+ data = compressedData;
+ }
+ }
+ }
+ size = data->size();
+ } else {
+ data = std::make_shared<const std::string>();
}
if (evict_ && !evict(size)) {
@@ -196,13 +213,9 @@ std::pair<bool, uint64_t> OfflineDatabase::putInternal(const Resource& resource,
if (resource.kind == Resource::Kind::Tile) {
assert(resource.tileData);
- inserted = putTile(*resource.tileData, response,
- compressed ? compressedData : response.data ? *response.data : "",
- compressed);
+ inserted = putTile(*resource.tileData, response, *data, compressed);
} else {
- inserted = putResource(resource, response,
- compressed ? compressedData : response.data ? *response.data : "",
- compressed);
+ inserted = putResource(resource, response, *data, compressed);
}
return { inserted, size };
@@ -243,12 +256,20 @@ optional<std::pair<Response, uint64_t>> OfflineDatabase::getResource(const Resou
optional<std::string> data = stmt->get<optional<std::string>>(4);
if (!data) {
response.noContent = true;
- } else if (stmt->get<bool>(5)) {
- response.data = std::make_shared<std::string>(util::decompress(*data));
- size = data->length();
} else {
- response.data = std::make_shared<std::string>(*data);
+ response.data = { std::move(*data), stmt->get<bool>(5) };
size = data->length();
+
+ // Make sure the data is decompressed when the user explicitly requested uncompressed data.
+ if (response.data.isCompressed() &&
+ resource.compression == Resource::Compression::Uncompressed) {
+ try {
+ response.data.uncompress();
+ } catch (std::exception& ex) {
+ response.error =
+ std::make_unique<Response::Error>(Response::Error::Reason::Other, ex.what());
+ }
+ }
}
return std::make_pair(response, size);
@@ -359,7 +380,9 @@ bool OfflineDatabase::putResource(const Resource& resource,
return true;
}
-optional<std::pair<Response, uint64_t>> OfflineDatabase::getTile(const Resource::TileData& tile) {
+optional<std::pair<Response, uint64_t>> OfflineDatabase::getTile(const Resource& resource) {
+ const auto& tile = *resource.tileData;
+
// clang-format off
Statement accessedStmt = getStatement(
"UPDATE tiles "
@@ -412,12 +435,20 @@ optional<std::pair<Response, uint64_t>> OfflineDatabase::getTile(const Resource:
optional<std::string> data = stmt->get<optional<std::string>>(4);
if (!data) {
response.noContent = true;
- } else if (stmt->get<bool>(5)) {
- response.data = std::make_shared<std::string>(util::decompress(*data));
- size = data->length();
} else {
- response.data = std::make_shared<std::string>(*data);
+ response.data = { std::move(*data), stmt->get<bool>(5) };
size = data->length();
+
+ // Make sure the data is decompressed when the user explicitly requested uncompressed data.
+ if (response.data.isCompressed() &&
+ resource.compression == Resource::Compression::Uncompressed) {
+ try {
+ response.data.uncompress();
+ } catch (std::exception& ex) {
+ response.error =
+ std::make_unique<Response::Error>(Response::Error::Reason::Other, ex.what());
+ }
+ }
}
return std::make_pair(response, size);
diff --git a/platform/default/mbgl/storage/offline_database.hpp b/platform/default/mbgl/storage/offline_database.hpp
index 91b544a9e0..fba1a3c230 100644
--- a/platform/default/mbgl/storage/offline_database.hpp
+++ b/platform/default/mbgl/storage/offline_database.hpp
@@ -81,7 +81,7 @@ private:
Statement getStatement(const char *);
- optional<std::pair<Response, uint64_t>> getTile(const Resource::TileData&);
+ optional<std::pair<Response, uint64_t>> getTile(const Resource&);
optional<int64_t> hasTile(const Resource::TileData&);
bool putTile(const Resource::TileData&, const Response&,
const std::string&, bool compressed);
diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp
index ba504c1f9b..d8fe8c646b 100644
--- a/platform/default/mbgl/storage/offline_download.cpp
+++ b/platform/default/mbgl/storage/offline_download.cpp
@@ -71,7 +71,7 @@ OfflineRegionStatus OfflineDownload::getStatus() const {
}
style::Parser parser;
- parser.parse(*styleResponse->data);
+ parser.parse(*styleResponse->data.uncompressedData());
result.requiredResourceCountIsPrecise = true;
@@ -88,7 +88,8 @@ OfflineRegionStatus OfflineDownload::getStatus() const {
optional<Response> sourceResponse = offlineDatabase.get(Resource::source(url));
if (sourceResponse) {
style::conversion::Error error;
- optional<Tileset> tileset = style::conversion::convertJSON<Tileset>(*sourceResponse->data, error);
+ optional<Tileset> tileset = style::conversion::convertJSON<Tileset>(
+ *sourceResponse->data.uncompressedData(), error);
if (tileset) {
result.requiredResourceCount +=
definition.tileCount(type, tileSize, (*tileset).zoomRange);
@@ -160,7 +161,7 @@ void OfflineDownload::activateDownload() {
status.requiredResourceCountIsPrecise = true;
style::Parser parser;
- parser.parse(*styleResponse.data);
+ parser.parse(*styleResponse.data.uncompressedData());
for (const auto& source : parser.sources) {
SourceType type = source->getType();
@@ -176,7 +177,8 @@ void OfflineDownload::activateDownload() {
ensureResource(Resource::source(url), [=](Response sourceResponse) {
style::conversion::Error error;
- optional<Tileset> tileset = style::conversion::convertJSON<Tileset>(*sourceResponse.data, error);
+ optional<Tileset> tileset = style::conversion::convertJSON<Tileset>(
+ *sourceResponse.data.uncompressedData(), error);
if (tileset) {
util::mapbox::canonicalizeTileset(*tileset, url, type, tileSize);
queueTiles(type, tileSize, *tileset);
@@ -236,14 +238,18 @@ void OfflineDownload::activateDownload() {
if (!parser.glyphURL.empty()) {
for (const auto& fontStack : parser.fontStacks()) {
for (char16_t i = 0; i < GLYPH_RANGES_PER_FONT_STACK; i++) {
- queueResource(Resource::glyphs(parser.glyphURL, fontStack, getGlyphRange(i * GLYPHS_PER_GLYPH_RANGE)));
+ auto resource = Resource::glyphs(parser.glyphURL, fontStack, getGlyphRange(i * GLYPHS_PER_GLYPH_RANGE));
+ resource.compression = Resource::Compression::PreferCompressed;
+ queueResource(resource);
}
}
}
if (!parser.spriteURL.empty()) {
queueResource(Resource::spriteImage(parser.spriteURL, definition.pixelRatio));
- queueResource(Resource::spriteJSON(parser.spriteURL, definition.pixelRatio));
+ auto spriteJSON = Resource::spriteJSON(parser.spriteURL, definition.pixelRatio);
+ spriteJSON.compression = Resource::Compression::PreferCompressed;
+ queueResource(spriteJSON);
}
continueDownload();
diff --git a/platform/default/online_file_source.cpp b/platform/default/online_file_source.cpp
index d685109b95..fe77df8c02 100644
--- a/platform/default/online_file_source.cpp
+++ b/platform/default/online_file_source.cpp
@@ -374,6 +374,16 @@ void OnlineFileRequest::completed(Response response) {
failedRequestReason = Response::Error::Reason::Success;
}
+ // Make sure the data is decompressed when the user explicitly requested uncompressed data.
+ if (response.data && response.data.isCompressed() &&
+ resource.compression == Resource::Compression::Uncompressed) {
+ try {
+ response.data.uncompress();
+ } catch (std::exception& ex) {
+ response.error = std::make_unique<Response::Error>(Response::Error::Reason::Other, ex.what());
+ }
+ }
+
schedule(response.expires);
// Calling the callback may result in `this` being deleted. It needs to be done last,
diff --git a/platform/default/png_writer.cpp b/platform/default/png_writer.cpp
index 9ef9052158..d3297b8ebf 100644
--- a/platform/default/png_writer.cpp
+++ b/platform/default/png_writer.cpp
@@ -38,7 +38,7 @@ void addChunk(std::string& png, const char* type, const char* data = "", const u
namespace mbgl {
// Encode PNGs without libpng.
-std::string encodePNG(const PremultipliedImage& pre) {
+Blob encodePNG(const PremultipliedImage& pre) {
// Make copy of the image so that we can unpremultiply it.
const auto src = util::unpremultiply(pre.clone());
@@ -74,7 +74,7 @@ std::string encodePNG(const PremultipliedImage& pre) {
addChunk(png, "IHDR", ihdr, 13);
addChunk(png, "IDAT", idat.data(), static_cast<uint32_t>(idat.size()));
addChunk(png, "IEND");
- return png;
+ return { std::move(png), false };
}
} // namespace mbgl
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index 07fae5945c..c29c2ec89f 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -211,6 +211,7 @@
40F887701D7A1E58008ECB67 /* MGLShapeSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40F8876F1D7A1DB8008ECB67 /* MGLShapeSource_Private.h */; };
40F887711D7A1E59008ECB67 /* MGLShapeSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40F8876F1D7A1DB8008ECB67 /* MGLShapeSource_Private.h */; };
40FDA76B1CCAAA6800442548 /* MBXAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 40FDA76A1CCAAA6800442548 /* MBXAnnotationView.m */; };
+ 55434256203C7530002624EB /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 55434255203C7530002624EB /* libz.tbd */; };
5549A0381EF1D86B00073113 /* libmbgl-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5549A0371EF1D86B00073113 /* libmbgl-core.a */; };
5549A0391EF2877100073113 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 554180411D2E97DE00012372 /* OpenGLES.framework */; };
5549A03A1EF2877500073113 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 554180411D2E97DE00012372 /* OpenGLES.framework */; };
@@ -794,6 +795,7 @@
40FDA7691CCAAA6800442548 /* MBXAnnotationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBXAnnotationView.h; sourceTree = "<group>"; };
40FDA76A1CCAAA6800442548 /* MBXAnnotationView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBXAnnotationView.m; sourceTree = "<group>"; };
554180411D2E97DE00012372 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
+ 55434255203C7530002624EB /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
5549A0371EF1D86B00073113 /* libmbgl-core.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-core.a"; path = "../../build/ios/Debug-iphonesimulator/libmbgl-core.a"; sourceTree = "<group>"; };
556660C91E1BF3A900E2C41B /* MGLFoundation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLFoundation.h; sourceTree = "<group>"; };
556660D71E1D085500E2C41B /* MGLVersionNumber.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MGLVersionNumber.m; path = ../../darwin/test/MGLVersionNumber.m; sourceTree = "<group>"; };
@@ -1145,6 +1147,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 55434256203C7530002624EB /* libz.tbd in Frameworks */,
5549A0381EF1D86B00073113 /* libmbgl-core.a in Frameworks */,
DA2E88561CC036F400F24E7B /* Mapbox.framework in Frameworks */,
);
@@ -1477,6 +1480,7 @@
DA1DC9921CB6DF24006E619F /* Frameworks */ = {
isa = PBXGroup;
children = (
+ 55434255203C7530002624EB /* libz.tbd */,
55D120AD1F791018004B6D81 /* libmbgl-loop-darwin.a */,
55D120AB1F791015004B6D81 /* libmbgl-filesource.a */,
55D120A91F79100C004B6D81 /* libmbgl-filesource.a */,
diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj
index 4327670911..58f29ed2a3 100644
--- a/platform/macos/macos.xcodeproj/project.pbxproj
+++ b/platform/macos/macos.xcodeproj/project.pbxproj
@@ -80,6 +80,7 @@
52B5D17F1E5E26DF00BBCB48 /* libmbgl-loop-darwin.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5548BE7B1D0ACBBD005DDE81 /* libmbgl-loop-darwin.a */; };
52B5D1801E5E26DF00BBCB48 /* libmbgl-loop-darwin.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5548BE7B1D0ACBBD005DDE81 /* libmbgl-loop-darwin.a */; };
5548BE781D09E718005DDE81 /* libmbgl-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAE6C3451CC31D1200DB3429 /* libmbgl-core.a */; };
+ 555CF3EC203DA46F004C828F /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 55D9B4B01D005D3900C1CCE2 /* libz.tbd */; };
556660C61E1BEA0100E2C41B /* MGLFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 556660C51E1BEA0100E2C41B /* MGLFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
556660D61E1D07E400E2C41B /* MGLVersionNumber.m in Sources */ = {isa = PBXBuildFile; fileRef = 556660D51E1D07E400E2C41B /* MGLVersionNumber.m */; };
558DE7A61E56161C00C7916D /* MGLFoundation_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 558DE7A41E56161C00C7916D /* MGLFoundation_Private.h */; };
@@ -659,6 +660,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 555CF3EC203DA46F004C828F /* libz.tbd in Frameworks */,
DAE0DD7A1D5F015A005A6BB1 /* libmbgl-core.a in Frameworks */,
55D120A51F790A0C004B6D81 /* libmbgl-filesource.a in Frameworks */,
DAE6C3321CC30DB200DB3429 /* Mapbox.framework in Frameworks */,
diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp
index ac14df0228..a4f6f6a9de 100644
--- a/platform/node/src/node_map.cpp
+++ b/platform/node/src/node_map.cpp
@@ -214,8 +214,8 @@ void NodeMap::Load(const Nan::FunctionCallbackInfo<v8::Value>& info) {
}
try {
- nodeMap->map->getStyle().loadJSON(style);
- } catch (const std::exception &ex) {
+ nodeMap->map->getStyle().loadJSON(mbgl::Blob{ std::move(style), false });
+ } catch (const std::exception& ex) {
return Nan::ThrowError(ex.what());
}
diff --git a/platform/node/src/node_request.cpp b/platform/node/src/node_request.cpp
index de16710f78..7b2b57fd1f 100644
--- a/platform/node/src/node_request.cpp
+++ b/platform/node/src/node_request.cpp
@@ -99,10 +99,8 @@ void NodeRequest::HandleCallback(const Nan::FunctionCallbackInfo<v8::Value>& inf
if (Nan::Has(res, Nan::New("data").ToLocalChecked()).FromJust()) {
auto data = Nan::Get(res, Nan::New("data").ToLocalChecked()).ToLocalChecked();
if (node::Buffer::HasInstance(data)) {
- response.data = std::make_shared<std::string>(
- node::Buffer::Data(data),
- node::Buffer::Length(data)
- );
+ response.data = { std::string{ node::Buffer::Data(data), node::Buffer::Length(data), },
+ false };
} else {
return Nan::ThrowTypeError("Response data must be a Buffer");
}
diff --git a/platform/qt/src/http_request.cpp b/platform/qt/src/http_request.cpp
index ea3f388bd5..4e2143ba8e 100644
--- a/platform/qt/src/http_request.cpp
+++ b/platform/qt/src/http_request.cpp
@@ -99,9 +99,9 @@ void HTTPRequest::handleNetworkReply(QNetworkReply *reply, const QByteArray& dat
switch(responseCode) {
case 200: {
if (data.isEmpty()) {
- response.data = std::make_shared<std::string>();
+ response.data = Blob{ "", false };
} else {
- response.data = std::make_shared<std::string>(data.constData(), data.size());
+ response.data = Blob{ std::string{ data.constData(), static_cast<size_t>(data.size()) }, false };
}
break;
}
diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp
index 414b65255c..e054d88489 100644
--- a/platform/qt/src/qmapboxgl.cpp
+++ b/platform/qt/src/qmapboxgl.cpp
@@ -585,12 +585,12 @@ void QMapboxGL::cycleDebugOptions()
*/
QString QMapboxGL::styleJson() const
{
- return QString::fromStdString(d_ptr->mapObj->getStyle().getJSON());
+ return QString::fromStdString(*d_ptr->mapObj->getStyle().getJSON().uncompressedData());
}
void QMapboxGL::setStyleJson(const QString &style)
{
- d_ptr->mapObj->getStyle().loadJSON(style.toStdString());
+ d_ptr->mapObj->getStyle().loadJSON(mbgl::Blob{ style.toStdString(), false });
}
/*!
diff --git a/platform/qt/src/qt_image.cpp b/platform/qt/src/qt_image.cpp
index a5c92514c1..ff45b02ef1 100644
--- a/platform/qt/src/qt_image.cpp
+++ b/platform/qt/src/qt_image.cpp
@@ -6,7 +6,7 @@
namespace mbgl {
-std::string encodePNG(const PremultipliedImage& pre) {
+Blob encodePNG(const PremultipliedImage& pre) {
QImage image(pre.data.get(), pre.size.width, pre.size.height,
QImage::Format_ARGB32_Premultiplied);
@@ -16,7 +16,7 @@ std::string encodePNG(const PremultipliedImage& pre) {
buffer.open(QIODevice::WriteOnly);
image.rgbSwapped().save(&buffer, "PNG");
- return std::string(array.constData(), array.size());
+ return { std::string(array.constData(), array.size()), false };
}
#if !defined(QT_IMAGE_DECODERS)
@@ -24,9 +24,10 @@ PremultipliedImage decodeJPEG(const uint8_t*, size_t);
PremultipliedImage decodeWebP(const uint8_t*, size_t);
#endif
-PremultipliedImage decodeImage(const std::string& string) {
- const uint8_t* data = reinterpret_cast<const uint8_t*>(string.data());
- const size_t size = string.size();
+PremultipliedImage decodeImage(Blob blob) {
+ const auto uncompressed = blob.uncompressedData();
+ const uint8_t* data = reinterpret_cast<const uint8_t*>(uncompressed->data());
+ const size_t size = uncompressed->size();
#if !defined(QT_IMAGE_DECODERS)
if (size >= 12) {
diff --git a/platform/qt/test/qmapboxgl.test.cpp b/platform/qt/test/qmapboxgl.test.cpp
index 2a56b346a3..607cdd6ba9 100644
--- a/platform/qt/test/qmapboxgl.test.cpp
+++ b/platform/qt/test/qmapboxgl.test.cpp
@@ -47,7 +47,7 @@ void QMapboxGLTest::onNeedsRendering() {
TEST_F(QMapboxGLTest, TEST_DISABLED_ON_CI(styleJson)) {
QString json = QString::fromStdString(
- mbgl::util::read_file("test/fixtures/resources/style_vector.json"));
+ *mbgl::util::readFile("test/fixtures/resources/style_vector.json").uncompressedData());
map.setStyleJson(json);
ASSERT_EQ(map.styleJson(), json);
diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp
index 3b54ec194a..64e3a355d6 100644
--- a/src/mbgl/gl/program.hpp
+++ b/src/mbgl/gl/program.hpp
@@ -62,7 +62,7 @@ public:
try {
if (auto cachedBinaryProgram = util::readFile(*cachePath)) {
- const BinaryProgram binaryProgram(std::move(*cachedBinaryProgram));
+ const BinaryProgram binaryProgram(cachedBinaryProgram);
if (binaryProgram.identifier() == identifier) {
return Program { context, binaryProgram };
} else {
@@ -82,7 +82,7 @@ public:
try {
if (const auto binaryProgram =
result.template get<BinaryProgram>(context, identifier)) {
- util::write_file(*cachePath, binaryProgram->serialize());
+ util::writeFile(*cachePath, binaryProgram->serialize());
Log::Warning(Event::OpenGL, "Caching program in: %s", (*cachePath).c_str());
}
} catch (std::runtime_error& error) {
diff --git a/src/mbgl/programs/binary_program.cpp b/src/mbgl/programs/binary_program.cpp
index da629194b4..e5943bb5db 100644
--- a/src/mbgl/programs/binary_program.cpp
+++ b/src/mbgl/programs/binary_program.cpp
@@ -32,9 +32,10 @@ static std::pair<const std::string, Binding> parseBinding(protozero::pbf_reader&
namespace mbgl {
-BinaryProgram::BinaryProgram(std::string&& data) {
+BinaryProgram::BinaryProgram(Blob blob) {
+ const auto data = blob.uncompressedData();
bool hasFormat = false, hasCode = false;
- protozero::pbf_reader pbf(data);
+ protozero::pbf_reader pbf(*data);
while (pbf.next()) {
switch (pbf.tag()) {
case 1: // format
@@ -76,7 +77,7 @@ BinaryProgram::BinaryProgram(
uniforms(std::move(uniforms_)) {
}
-std::string BinaryProgram::serialize() const {
+Blob BinaryProgram::serialize() const {
std::string data;
data.reserve(32 + binaryCode.size() + uniforms.size() * 32 + attributes.size() * 32);
protozero::pbf_writer pbf(data);
@@ -95,7 +96,7 @@ std::string BinaryProgram::serialize() const {
if (!binaryIdentifier.empty()) {
pbf.add_string(5 /* identifier */, binaryIdentifier);
}
- return data;
+ return { std::move(data), false };
}
optional<gl::AttributeLocation> BinaryProgram::attributeLocation(const std::string& name) const {
diff --git a/src/mbgl/programs/binary_program.hpp b/src/mbgl/programs/binary_program.hpp
index 8690f3fd6f..2d3ea45aa6 100644
--- a/src/mbgl/programs/binary_program.hpp
+++ b/src/mbgl/programs/binary_program.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/gl/types.hpp>
+#include <mbgl/util/blob.hpp>
#include <mbgl/util/optional.hpp>
#include <string>
@@ -11,7 +12,7 @@ namespace mbgl {
class BinaryProgram {
public:
// Initialize a BinaryProgram object from a serialized represenation.
- BinaryProgram(std::string&& data);
+ BinaryProgram(Blob data);
BinaryProgram(gl::BinaryProgramFormat,
std::string&& binaryCode,
@@ -19,7 +20,7 @@ public:
std::vector<std::pair<const std::string, gl::AttributeLocation>>&&,
std::vector<std::pair<const std::string, gl::UniformLocation>>&&);
- std::string serialize() const;
+ Blob serialize() const;
gl::BinaryProgramFormat format() const {
return binaryFormat;
diff --git a/src/mbgl/sprite/sprite_loader.cpp b/src/mbgl/sprite/sprite_loader.cpp
index 93d6dfd9ae..3bc8add160 100644
--- a/src/mbgl/sprite/sprite_loader.cpp
+++ b/src/mbgl/sprite/sprite_loader.cpp
@@ -25,8 +25,8 @@ struct SpriteLoader::Loader {
worker(scheduler, ActorRef<SpriteLoader>(imageManager, mailbox)) {
}
- std::shared_ptr<const std::string> image;
- std::shared_ptr<const std::string> json;
+ Blob image;
+ Blob json;
std::unique_ptr<AsyncRequest> jsonRequest;
std::unique_ptr<AsyncRequest> spriteRequest;
std::shared_ptr<Mailbox> mailbox;
@@ -55,7 +55,7 @@ void SpriteLoader::load(const std::string& url, Scheduler& scheduler, FileSource
} else if (res.notModified) {
return;
} else if (res.noContent) {
- loader->json = std::make_shared<const std::string>();
+ loader->json = {};
emitSpriteLoadedIfComplete();
} else {
// Only trigger a sprite loaded event we got new data.
@@ -70,7 +70,7 @@ void SpriteLoader::load(const std::string& url, Scheduler& scheduler, FileSource
} else if (res.notModified) {
return;
} else if (res.noContent) {
- loader->image = std::make_shared<const std::string>();
+ loader->image = {};
emitSpriteLoadedIfComplete();
} else {
loader->image = res.data;
diff --git a/src/mbgl/sprite/sprite_loader_worker.cpp b/src/mbgl/sprite/sprite_loader_worker.cpp
index 4bded33d53..a2e3f331e9 100644
--- a/src/mbgl/sprite/sprite_loader_worker.cpp
+++ b/src/mbgl/sprite/sprite_loader_worker.cpp
@@ -8,8 +8,7 @@ SpriteLoaderWorker::SpriteLoaderWorker(ActorRef<SpriteLoaderWorker>, ActorRef<Sp
: parent(std::move(parent_)) {
}
-void SpriteLoaderWorker::parse(std::shared_ptr<const std::string> image,
- std::shared_ptr<const std::string> json) {
+void SpriteLoaderWorker::parse(Blob image, Blob json) {
try {
if (!image) {
// This shouldn't happen, since we always invoke it with a non-empty pointer.
@@ -20,7 +19,7 @@ void SpriteLoaderWorker::parse(std::shared_ptr<const std::string> image,
throw std::runtime_error("missing sprite metadata");
}
- parent.invoke(&SpriteLoader::onParsed, parseSprite(*image, *json));
+ parent.invoke(&SpriteLoader::onParsed, parseSprite(std::move(image), std::move(json)));
} catch (...) {
parent.invoke(&SpriteLoader::onError, std::current_exception());
}
diff --git a/src/mbgl/sprite/sprite_loader_worker.hpp b/src/mbgl/sprite/sprite_loader_worker.hpp
index d61e07d14f..4f2e38be29 100644
--- a/src/mbgl/sprite/sprite_loader_worker.hpp
+++ b/src/mbgl/sprite/sprite_loader_worker.hpp
@@ -2,6 +2,7 @@
#include <mbgl/actor/actor_ref.hpp>
#include <mbgl/sprite/sprite_parser.hpp>
+#include <mbgl/storage/response.hpp>
#include <memory>
#include <string>
@@ -14,7 +15,7 @@ class SpriteLoaderWorker {
public:
SpriteLoaderWorker(ActorRef<SpriteLoaderWorker>, ActorRef<SpriteLoader>);
- void parse(std::shared_ptr<const std::string> image, std::shared_ptr<const std::string> json);
+ void parse(Blob image, Blob json);
private:
ActorRef<SpriteLoader> parent;
diff --git a/src/mbgl/sprite/sprite_parser.cpp b/src/mbgl/sprite/sprite_parser.cpp
index 1a36e3e990..c93d97ba78 100644
--- a/src/mbgl/sprite/sprite_parser.cpp
+++ b/src/mbgl/sprite/sprite_parser.cpp
@@ -85,11 +85,12 @@ bool getBoolean(const JSValue& value, const char* name, const bool def = false)
} // namespace
-std::vector<std::unique_ptr<style::Image>> parseSprite(const std::string& encodedImage, const std::string& json) {
- const PremultipliedImage raster = decodeImage(encodedImage);
+std::vector<std::unique_ptr<style::Image>> parseSprite(Blob imageBlob, Blob jsonBlob) {
+ const PremultipliedImage raster = decodeImage(imageBlob);
+ const auto json = jsonBlob.uncompressedData();
JSDocument doc;
- doc.Parse<0>(json.c_str());
+ doc.Parse<0>(json->c_str());
if (doc.HasParseError()) {
std::stringstream message;
message << "Failed to parse JSON: " << rapidjson::GetParseError_En(doc.GetParseError()) << " at offset " << doc.GetErrorOffset();
diff --git a/src/mbgl/sprite/sprite_parser.hpp b/src/mbgl/sprite/sprite_parser.hpp
index f602818d3b..b17f4cc458 100644
--- a/src/mbgl/sprite/sprite_parser.hpp
+++ b/src/mbgl/sprite/sprite_parser.hpp
@@ -23,6 +23,6 @@ std::unique_ptr<style::Image> createStyleImage(const std::string& id,
bool sdf);
// Parses an image and an associated JSON file and returns the sprite objects.
-std::vector<std::unique_ptr<style::Image>> parseSprite(const std::string& image, const std::string& json);
+std::vector<std::unique_ptr<style::Image>> parseSprite(Blob image, Blob json);
} // namespace mbgl
diff --git a/src/mbgl/storage/resource.cpp b/src/mbgl/storage/resource.cpp
index 207dd2ee69..9bc8495d53 100644
--- a/src/mbgl/storage/resource.cpp
+++ b/src/mbgl/storage/resource.cpp
@@ -42,14 +42,20 @@ static std::string getTileBBox(int32_t x, int32_t y, int8_t z) {
Resource Resource::style(const std::string& url) {
return Resource {
Resource::Kind::Style,
- url
+ url,
+ {},
+ LoadingMethod::All,
+ Compression::Uncompressed
};
}
Resource Resource::source(const std::string& url) {
return Resource {
Resource::Kind::Source,
- url
+ url,
+ {},
+ LoadingMethod::All,
+ Compression::Uncompressed
};
}
@@ -87,7 +93,10 @@ Resource Resource::glyphs(const std::string& urlTemplate, const FontStack& fontS
} else {
return std::string();
}
- })
+ }),
+ {},
+ LoadingMethod::All,
+ Compression::Uncompressed
};
}
@@ -133,7 +142,8 @@ Resource Resource::tile(const std::string& urlTemplate,
y,
z
},
- loadingMethod
+ loadingMethod,
+ Compression::PreferCompressed
};
}
diff --git a/src/mbgl/style/sources/geojson_source.cpp b/src/mbgl/style/sources/geojson_source.cpp
index 4e3478322d..48308ccbc3 100644
--- a/src/mbgl/style/sources/geojson_source.cpp
+++ b/src/mbgl/style/sources/geojson_source.cpp
@@ -61,7 +61,8 @@ void GeoJSONSource::loadDescription(FileSource& fileSource) {
*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty GeoJSON")));
} else {
conversion::Error error;
- optional<GeoJSON> geoJSON = conversion::convertJSON<GeoJSON>(*res.data, error);
+ optional<GeoJSON> geoJSON =
+ conversion::convertJSON<GeoJSON>(*res.data.uncompressedData(), error);
if (!geoJSON) {
Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s",
error.message.c_str());
diff --git a/src/mbgl/style/sources/image_source.cpp b/src/mbgl/style/sources/image_source.cpp
index fa268da0ef..5be1b54410 100644
--- a/src/mbgl/style/sources/image_source.cpp
+++ b/src/mbgl/style/sources/image_source.cpp
@@ -70,7 +70,7 @@ void ImageSource::loadDescription(FileSource& fileSource) {
observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty image url")));
} else {
try {
- baseImpl = makeMutable<Impl>(impl(), decodeImage(*res.data));
+ baseImpl = makeMutable<Impl>(impl(), decodeImage(res.data));
} catch (...) {
observer->onSourceError(*this, std::current_exception());
}
diff --git a/src/mbgl/style/sources/raster_source.cpp b/src/mbgl/style/sources/raster_source.cpp
index 53f29d660b..c3c47567aa 100644
--- a/src/mbgl/style/sources/raster_source.cpp
+++ b/src/mbgl/style/sources/raster_source.cpp
@@ -57,7 +57,7 @@ void RasterSource::loadDescription(FileSource& fileSource) {
observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty TileJSON")));
} else {
conversion::Error error;
- optional<Tileset> tileset = conversion::convertJSON<Tileset>(*res.data, error);
+ optional<Tileset> tileset = conversion::convertJSON<Tileset>(*res.data.uncompressedData(), error);
if (!tileset) {
observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(error.message)));
return;
diff --git a/src/mbgl/style/sources/vector_source.cpp b/src/mbgl/style/sources/vector_source.cpp
index ccdd453c75..d88622f1b8 100644
--- a/src/mbgl/style/sources/vector_source.cpp
+++ b/src/mbgl/style/sources/vector_source.cpp
@@ -54,7 +54,8 @@ void VectorSource::loadDescription(FileSource& fileSource) {
observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty TileJSON")));
} else {
conversion::Error error;
- optional<Tileset> tileset = conversion::convertJSON<Tileset>(*res.data, error);
+ optional<Tileset> tileset =
+ conversion::convertJSON<Tileset>(*res.data.uncompressedData(), error);
if (!tileset) {
observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(error.message)));
return;
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index bd8631fc52..82f421ecdf 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -14,7 +14,7 @@ Style::Style(Scheduler& scheduler, FileSource& fileSource, float pixelRatio)
Style::~Style() = default;
-void Style::loadJSON(const std::string& json) {
+void Style::loadJSON(Blob json) {
impl->loadJSON(json);
}
@@ -22,7 +22,7 @@ void Style::loadURL(const std::string& url) {
impl->loadURL(url);
}
-std::string Style::getJSON() const {
+Blob Style::getJSON() const {
return impl->getJSON();
}
diff --git a/src/mbgl/style/style_impl.cpp b/src/mbgl/style/style_impl.cpp
index d330b3120a..a952ccb8c2 100644
--- a/src/mbgl/style/style_impl.cpp
+++ b/src/mbgl/style/style_impl.cpp
@@ -39,7 +39,7 @@ Style::Impl::Impl(Scheduler& scheduler_, FileSource& fileSource_, float pixelRat
Style::Impl::~Impl() = default;
-void Style::Impl::loadJSON(const std::string& json_) {
+void Style::Impl::loadJSON(Blob json_) {
lastError = nullptr;
observer->onStyleLoading();
@@ -73,15 +73,17 @@ void Style::Impl::loadURL(const std::string& url_) {
} else if (res.notModified || res.noContent) {
return;
} else {
- parse(*res.data);
+ parse(res.data);
}
});
}
-void Style::Impl::parse(const std::string& json_) {
+void Style::Impl::parse(Blob json_) {
Parser parser;
- if (auto error = parser.parse(json_)) {
+ const auto data = json_.uncompressedData();
+
+ if (auto error = parser.parse(*data)) {
std::string message = "Failed to parse style: " + util::toString(error);
Log::Error(Event::ParseStyle, message.c_str());
observer->onStyleError(std::make_exception_ptr(util::StyleParseException(message)));
@@ -124,7 +126,7 @@ void Style::Impl::parse(const std::string& json_) {
observer->onStyleLoaded();
}
-std::string Style::Impl::getJSON() const {
+Blob Style::Impl::getJSON() const {
return json;
}
diff --git a/src/mbgl/style/style_impl.hpp b/src/mbgl/style/style_impl.hpp
index 3dc222bfad..9dc2704391 100644
--- a/src/mbgl/style/style_impl.hpp
+++ b/src/mbgl/style/style_impl.hpp
@@ -41,10 +41,10 @@ public:
Impl(Scheduler&, FileSource&, float pixelRatio);
~Impl() override;
- void loadJSON(const std::string&);
+ void loadJSON(Blob);
void loadURL(const std::string&);
- std::string getJSON() const;
+ Blob getJSON() const;
std::string getURL() const;
void setObserver(Observer*);
@@ -96,13 +96,13 @@ public:
bool spriteLoaded = false;
private:
- void parse(const std::string&);
+ void parse(Blob);
Scheduler& scheduler;
FileSource& fileSource;
std::string url;
- std::string json;
+ Blob json;
std::unique_ptr<AsyncRequest> styleRequest;
std::unique_ptr<SpriteLoader> spriteLoader;
diff --git a/src/mbgl/text/glyph_manager.cpp b/src/mbgl/text/glyph_manager.cpp
index 3130418908..37574eff15 100644
--- a/src/mbgl/text/glyph_manager.cpp
+++ b/src/mbgl/text/glyph_manager.cpp
@@ -91,7 +91,7 @@ void GlyphManager::processResponse(const Response& res, const FontStack& fontSta
std::vector<Glyph> glyphs;
try {
- glyphs = parseGlyphPBF(range, *res.data);
+ glyphs = parseGlyphPBF(range, res.data);
} catch (...) {
observer->onGlyphsError(fontStack, range, std::current_exception());
return;
diff --git a/src/mbgl/text/glyph_pbf.cpp b/src/mbgl/text/glyph_pbf.cpp
index cfaf803f75..77ea5ec2cb 100644
--- a/src/mbgl/text/glyph_pbf.cpp
+++ b/src/mbgl/text/glyph_pbf.cpp
@@ -4,11 +4,12 @@
namespace mbgl {
-std::vector<Glyph> parseGlyphPBF(const GlyphRange& glyphRange, const std::string& data) {
+std::vector<Glyph> parseGlyphPBF(const GlyphRange& glyphRange, Blob blob) {
+ const auto data = blob.uncompressedData();
std::vector<Glyph> result;
result.reserve(256);
- protozero::pbf_reader glyphs_pbf(data);
+ protozero::pbf_reader glyphs_pbf(*data);
while (glyphs_pbf.next(1)) {
auto fontstack_pbf = glyphs_pbf.get_message();
diff --git a/src/mbgl/text/glyph_pbf.hpp b/src/mbgl/text/glyph_pbf.hpp
index 28a28b4114..0c82343ce5 100644
--- a/src/mbgl/text/glyph_pbf.hpp
+++ b/src/mbgl/text/glyph_pbf.hpp
@@ -8,6 +8,6 @@
namespace mbgl {
-std::vector<Glyph> parseGlyphPBF(const GlyphRange&, const std::string& data);
+std::vector<Glyph> parseGlyphPBF(const GlyphRange&, Blob blob);
} // namespace mbgl
diff --git a/src/mbgl/tile/raster_dem_tile.cpp b/src/mbgl/tile/raster_dem_tile.cpp
index 5db298cf4c..10f22e378b 100644
--- a/src/mbgl/tile/raster_dem_tile.cpp
+++ b/src/mbgl/tile/raster_dem_tile.cpp
@@ -45,7 +45,7 @@ void RasterDEMTile::setMetadata(optional<Timestamp> modified_, optional<Timestam
expires = expires_;
}
-void RasterDEMTile::setData(std::shared_ptr<const std::string> data) {
+void RasterDEMTile::setData(Blob data) {
pending = true;
++correlationID;
worker.invoke(&RasterDEMTileWorker::parse, data, correlationID, encoding);
diff --git a/src/mbgl/tile/raster_dem_tile.hpp b/src/mbgl/tile/raster_dem_tile.hpp
index 0c8dd75961..0c5b3e7bf2 100644
--- a/src/mbgl/tile/raster_dem_tile.hpp
+++ b/src/mbgl/tile/raster_dem_tile.hpp
@@ -70,7 +70,7 @@ public:
void setError(std::exception_ptr);
void setMetadata(optional<Timestamp> modified, optional<Timestamp> expires);
- void setData(std::shared_ptr<const std::string> data);
+ void setData(Blob data);
void upload(gl::Context&) override;
Bucket* getBucket(const style::Layer::Impl&) const override;
diff --git a/src/mbgl/tile/raster_dem_tile_worker.cpp b/src/mbgl/tile/raster_dem_tile_worker.cpp
index 7338e578c7..ec5aba380a 100644
--- a/src/mbgl/tile/raster_dem_tile_worker.cpp
+++ b/src/mbgl/tile/raster_dem_tile_worker.cpp
@@ -10,14 +10,14 @@ RasterDEMTileWorker::RasterDEMTileWorker(ActorRef<RasterDEMTileWorker>, ActorRef
: parent(std::move(parent_)) {
}
-void RasterDEMTileWorker::parse(std::shared_ptr<const std::string> data, uint64_t correlationID, Tileset::DEMEncoding encoding) {
+void RasterDEMTileWorker::parse(Blob data, uint64_t correlationID, Tileset::DEMEncoding encoding) {
if (!data) {
parent.invoke(&RasterDEMTile::onParsed, nullptr, correlationID); // No data; empty tile.
return;
}
try {
- auto bucket = std::make_unique<HillshadeBucket>(decodeImage(*data), encoding);
+ auto bucket = std::make_unique<HillshadeBucket>(decodeImage(data), encoding);
parent.invoke(&RasterDEMTile::onParsed, std::move(bucket), correlationID);
} catch (...) {
parent.invoke(&RasterDEMTile::onError, std::current_exception(), correlationID);
diff --git a/src/mbgl/tile/raster_dem_tile_worker.hpp b/src/mbgl/tile/raster_dem_tile_worker.hpp
index 5a8222bc2d..5b9bce1a19 100644
--- a/src/mbgl/tile/raster_dem_tile_worker.hpp
+++ b/src/mbgl/tile/raster_dem_tile_worker.hpp
@@ -2,6 +2,7 @@
#include <mbgl/actor/actor_ref.hpp>
#include <mbgl/util/tileset.hpp>
+#include <mbgl/util/blob.hpp>
#include <memory>
#include <string>
@@ -14,7 +15,7 @@ class RasterDEMTileWorker {
public:
RasterDEMTileWorker(ActorRef<RasterDEMTileWorker>, ActorRef<RasterDEMTile>);
- void parse(std::shared_ptr<const std::string> data, uint64_t correlationID, Tileset::DEMEncoding encoding);
+ void parse(Blob data, uint64_t correlationID, Tileset::DEMEncoding encoding);
private:
ActorRef<RasterDEMTile> parent;
diff --git a/src/mbgl/tile/raster_tile.cpp b/src/mbgl/tile/raster_tile.cpp
index ff23d4493e..4bc9830fda 100644
--- a/src/mbgl/tile/raster_tile.cpp
+++ b/src/mbgl/tile/raster_tile.cpp
@@ -34,7 +34,7 @@ void RasterTile::setMetadata(optional<Timestamp> modified_, optional<Timestamp>
expires = expires_;
}
-void RasterTile::setData(std::shared_ptr<const std::string> data) {
+void RasterTile::setData(Blob data) {
pending = true;
++correlationID;
worker.invoke(&RasterTileWorker::parse, data, correlationID);
diff --git a/src/mbgl/tile/raster_tile.hpp b/src/mbgl/tile/raster_tile.hpp
index e25329119a..c1fa6caa99 100644
--- a/src/mbgl/tile/raster_tile.hpp
+++ b/src/mbgl/tile/raster_tile.hpp
@@ -26,7 +26,7 @@ public:
void setError(std::exception_ptr);
void setMetadata(optional<Timestamp> modified, optional<Timestamp> expires);
- void setData(std::shared_ptr<const std::string> data);
+ void setData(Blob data);
void upload(gl::Context&) override;
Bucket* getBucket(const style::Layer::Impl&) const override;
diff --git a/src/mbgl/tile/raster_tile_worker.cpp b/src/mbgl/tile/raster_tile_worker.cpp
index 4afa876429..d0dd8918a2 100644
--- a/src/mbgl/tile/raster_tile_worker.cpp
+++ b/src/mbgl/tile/raster_tile_worker.cpp
@@ -10,14 +10,14 @@ RasterTileWorker::RasterTileWorker(ActorRef<RasterTileWorker>, ActorRef<RasterTi
: parent(std::move(parent_)) {
}
-void RasterTileWorker::parse(std::shared_ptr<const std::string> data, uint64_t correlationID) {
+void RasterTileWorker::parse(Blob data, uint64_t correlationID) {
if (!data) {
parent.invoke(&RasterTile::onParsed, nullptr, correlationID); // No data; empty tile.
return;
}
try {
- auto bucket = std::make_unique<RasterBucket>(decodeImage(*data));
+ auto bucket = std::make_unique<RasterBucket>(decodeImage(data));
parent.invoke(&RasterTile::onParsed, std::move(bucket), correlationID);
} catch (...) {
parent.invoke(&RasterTile::onError, std::current_exception(), correlationID);
diff --git a/src/mbgl/tile/raster_tile_worker.hpp b/src/mbgl/tile/raster_tile_worker.hpp
index 520973c3c3..c56da82d0a 100644
--- a/src/mbgl/tile/raster_tile_worker.hpp
+++ b/src/mbgl/tile/raster_tile_worker.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/actor/actor_ref.hpp>
+#include <mbgl/util/blob.hpp>
#include <memory>
#include <string>
@@ -13,7 +14,7 @@ class RasterTileWorker {
public:
RasterTileWorker(ActorRef<RasterTileWorker>, ActorRef<RasterTile>);
- void parse(std::shared_ptr<const std::string> data, uint64_t correlationID);
+ void parse(Blob data, uint64_t correlationID);
private:
ActorRef<RasterTile> parent;
diff --git a/src/mbgl/tile/tile_loader_impl.hpp b/src/mbgl/tile/tile_loader_impl.hpp
index 1b29638269..48b3b7c87b 100644
--- a/src/mbgl/tile/tile_loader_impl.hpp
+++ b/src/mbgl/tile/tile_loader_impl.hpp
@@ -106,7 +106,7 @@ void TileLoader<T>::loadedData(const Response& res) {
resource.priorExpires = res.expires;
resource.priorEtag = res.etag;
tile.setMetadata(res.modified, res.expires);
- tile.setData(res.noContent ? nullptr : res.data);
+ tile.setData(res.noContent ? Blob{} : res.data);
}
}
diff --git a/src/mbgl/tile/vector_tile.cpp b/src/mbgl/tile/vector_tile.cpp
index 0756d3e526..a815f31e41 100644
--- a/src/mbgl/tile/vector_tile.cpp
+++ b/src/mbgl/tile/vector_tile.cpp
@@ -21,8 +21,8 @@ void VectorTile::setMetadata(optional<Timestamp> modified_, optional<Timestamp>
expires = expires_;
}
-void VectorTile::setData(std::shared_ptr<const std::string> data_) {
- GeometryTile::setData(data_ ? std::make_unique<VectorTileData>(data_) : nullptr);
+void VectorTile::setData(Blob data_) {
+ GeometryTile::setData(data_ ? std::make_unique<VectorTileData>(std::move(data_)) : nullptr);
}
} // namespace mbgl
diff --git a/src/mbgl/tile/vector_tile.hpp b/src/mbgl/tile/vector_tile.hpp
index 7dae414fef..87abf2f598 100644
--- a/src/mbgl/tile/vector_tile.hpp
+++ b/src/mbgl/tile/vector_tile.hpp
@@ -17,7 +17,7 @@ public:
void setNecessity(TileNecessity) final;
void setMetadata(optional<Timestamp> modified, optional<Timestamp> expires);
- void setData(std::shared_ptr<const std::string> data);
+ void setData(Blob data);
private:
TileLoader<VectorTile> loader;
diff --git a/src/mbgl/tile/vector_tile_data.cpp b/src/mbgl/tile/vector_tile_data.cpp
index 2d4a01bda3..eaa91dc9cf 100644
--- a/src/mbgl/tile/vector_tile_data.cpp
+++ b/src/mbgl/tile/vector_tile_data.cpp
@@ -60,19 +60,24 @@ std::string VectorTileLayer::getName() const {
return layer.getName();
}
-VectorTileData::VectorTileData(std::shared_ptr<const std::string> data_) : data(std::move(data_)) {
+VectorTileData::VectorTileData(Blob blob_) : blob(std::move(blob_)) {
}
std::unique_ptr<GeometryTileData> VectorTileData::clone() const {
- return std::make_unique<VectorTileData>(data);
+ // Always pass on data that is uncompressed, if we have it.
+ return std::make_unique<VectorTileData>(data ? Blob{ data, false } : blob);
}
std::unique_ptr<GeometryTileLayer> VectorTileData::getLayer(const std::string& name) const {
- if (!parsed) {
+ if (!blob) {
+ return nullptr;
+ }
+
+ if (!data) {
// We're parsing this lazily so that we can construct VectorTileData objects on the main
- // thread without incurring the overhead of parsing immediately.
+ // thread without incurring the overhead of parsing and decompressing immediately.
+ data = blob.uncompressedData();
layers = mapbox::vector_tile::buffer(*data).getLayers();
- parsed = true;
}
auto it = layers.find(name);
diff --git a/src/mbgl/tile/vector_tile_data.hpp b/src/mbgl/tile/vector_tile_data.hpp
index 48beaf9d07..ce120e97c0 100644
--- a/src/mbgl/tile/vector_tile_data.hpp
+++ b/src/mbgl/tile/vector_tile_data.hpp
@@ -1,5 +1,7 @@
#include <mbgl/tile/geometry_tile_data.hpp>
+#include <mbgl/util/blob.hpp>
+
#include <mapbox/vector_tile.hpp>
#include <protozero/pbf_reader.hpp>
@@ -38,7 +40,8 @@ private:
class VectorTileData : public GeometryTileData {
public:
- VectorTileData(std::shared_ptr<const std::string> data);
+ VectorTileData(const VectorTileData&);
+ VectorTileData(Blob blob);
std::unique_ptr<GeometryTileData> clone() const override;
std::unique_ptr<GeometryTileLayer> getLayer(const std::string& name) const override;
@@ -46,8 +49,8 @@ public:
std::vector<std::string> layerNames() const;
private:
- std::shared_ptr<const std::string> data;
- mutable bool parsed = false;
+ Blob blob;
+ mutable std::shared_ptr<const std::string> data;
mutable std::map<std::string, const protozero::data_view> layers;
};
diff --git a/src/mbgl/util/blob.cpp b/src/mbgl/util/blob.cpp
new file mode 100644
index 0000000000..53d7644002
--- /dev/null
+++ b/src/mbgl/util/blob.cpp
@@ -0,0 +1,46 @@
+#include <mbgl/util/blob.hpp>
+#include <mbgl/util/compression.hpp>
+
+namespace mbgl {
+
+Blob::Blob() = default;
+
+Blob::Blob(std::shared_ptr<const std::string> bytes_, bool compressed_)
+ : bytes(std::move(bytes_)), compressed(compressed_) {
+}
+
+Blob::Blob(std::string&& bytes_, bool compressed_)
+ : bytes(std::make_shared<const std::string>(std::move(bytes_))), compressed(compressed_) {
+}
+
+std::shared_ptr<const std::string> Blob::uncompressedData() const {
+ if (!bytes) {
+ throw std::runtime_error("invalid blob");
+ }
+ if (compressed) {
+ return std::make_shared<const std::string>(util::decompress(*bytes));
+ } else {
+ return bytes;
+ }
+}
+
+std::shared_ptr<const std::string> Blob::compressedData() const {
+ if (!bytes) {
+ throw std::runtime_error("invalid blob");
+ }
+ if (compressed) {
+ return bytes;
+ } else {
+ return std::make_shared<const std::string>(util::compress(*bytes));
+ }
+}
+
+void Blob::uncompress() {
+ if (compressed) {
+ bytes = uncompressedData();
+ compressed = false;
+ }
+}
+
+
+} // namespace mbgl
diff --git a/src/mbgl/util/compression.cpp b/src/mbgl/util/compression.cpp
index 30e813cbb8..4d4e094f06 100644
--- a/src/mbgl/util/compression.cpp
+++ b/src/mbgl/util/compression.cpp
@@ -71,7 +71,8 @@ std::string decompress(const std::string &raw) {
memset(&inflate_stream, 0, sizeof(inflate_stream));
// TODO: reuse z_streams
- if (inflateInit(&inflate_stream) != Z_OK) {
+ // MAX_WBITS + allows decoding gzip in addition to zlib
+ if (inflateInit2(&inflate_stream, MAX_WBITS + 32) != Z_OK) {
throw std::runtime_error("failed to initialize inflate");
}
@@ -100,5 +101,39 @@ std::string decompress(const std::string &raw) {
return result;
}
+
+bool isCompressible(const std::string& raw) {
+ // WebP
+ if (raw.size() >= 12 && static_cast<uint8_t>(raw[0]) == 'R' &&
+ static_cast<uint8_t>(raw[1]) == 'I' && static_cast<uint8_t>(raw[2]) == 'F' &&
+ static_cast<uint8_t>(raw[3]) == 'F' && static_cast<uint8_t>(raw[8]) == 'W' &&
+ static_cast<uint8_t>(raw[9]) == 'E' && static_cast<uint8_t>(raw[10]) == 'B' &&
+ static_cast<uint8_t>(raw[11]) == 'P') {
+ // Note: the WebP container format allows uncompressed data as well, but we just assume that
+ // all WebP files are already compressed.
+ return false;
+ }
+
+ // PNG
+ if (raw.size() >= 8 && static_cast<uint8_t>(raw[0]) == 0x89 &&
+ static_cast<uint8_t>(raw[1]) == 'P' && static_cast<uint8_t>(raw[2]) == 'N' &&
+ static_cast<uint8_t>(raw[3]) == 'G' && static_cast<uint8_t>(raw[4]) == '\r' &&
+ static_cast<uint8_t>(raw[5]) == '\n' && static_cast<uint8_t>(raw[6]) == 0x1a &&
+ static_cast<uint8_t>(raw[7]) == '\n') {
+ // Note: this assumes the PNG file itself is compressed. However, it is possible to create
+ // PNG files with uncompressed data in it (zlib compression 0), but they are exceedingly
+ // rare, so we don't care about them.
+ return false;
+ }
+
+ // JPEG
+ if (raw.size() >= 3 && static_cast<uint8_t>(raw[0]) == 0xff &&
+ static_cast<uint8_t>(raw[1]) == 0xd8 && static_cast<uint8_t>(raw[2]) == 0xff) {
+ return false;
+ }
+
+ return true;
+}
+
} // namespace util
} // namespace mbgl
diff --git a/src/mbgl/util/io.cpp b/src/mbgl/util/io.cpp
index 6a6ed7b250..2dc6cabf0f 100644
--- a/src/mbgl/util/io.cpp
+++ b/src/mbgl/util/io.cpp
@@ -1,43 +1,29 @@
#include <mbgl/util/io.hpp>
-#include <cstdio>
#include <cerrno>
#include <iostream>
-#include <sstream>
#include <fstream>
namespace mbgl {
namespace util {
-void write_file(const std::string &filename, const std::string &data) {
- FILE *fd = fopen(filename.c_str(), "wb");
- if (fd) {
- fwrite(data.data(), sizeof(std::string::value_type), data.size(), fd);
- fclose(fd);
- } else {
- throw std::runtime_error(std::string("Failed to open file ") + filename);
- }
-}
-
-std::string read_file(const std::string &filename) {
- std::ifstream file(filename);
+void writeFile(const std::string &filename, Blob blob) {
+ std::ofstream file(filename, std::ios::binary);
if (file.good()) {
- std::stringstream data;
- data << file.rdbuf();
- return data.str();
+ file << *blob.uncompressedData();
} else {
- throw std::runtime_error(std::string("Cannot read file ") + filename);
+ throw IOException(errno, "failed to write file");
}
}
-optional<std::string> readFile(const std::string &filename) {
- std::ifstream file(filename);
+Blob readFile(const std::string &filename) {
+ std::ifstream file(filename, std::ios::binary);
if (file.good()) {
- std::stringstream data;
- data << file.rdbuf();
- return data.str();
+ return { { std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>() },
+ false };
+ } else {
+ return {};
}
- return {};
}
void deleteFile(const std::string& filename) {
diff --git a/src/mbgl/util/io.hpp b/src/mbgl/util/io.hpp
index 847271acf0..b74f89485b 100644
--- a/src/mbgl/util/io.hpp
+++ b/src/mbgl/util/io.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/util/optional.hpp>
+#include <mbgl/util/blob.hpp>
#include <string>
#include <stdexcept>
@@ -14,10 +15,8 @@ struct IOException : std::runtime_error {
const int code = 0;
};
-void write_file(const std::string &filename, const std::string &data);
-std::string read_file(const std::string &filename);
-
-optional<std::string> readFile(const std::string &filename);
+void writeFile(const std::string &filename, Blob blob);
+Blob readFile(const std::string &filename);
void deleteFile(const std::string& filename);
} // namespace util
diff --git a/test/api/annotations.test.cpp b/test/api/annotations.test.cpp
index 07257851ac..8b25fa482d 100644
--- a/test/api/annotations.test.cpp
+++ b/test/api/annotations.test.cpp
@@ -17,7 +17,7 @@ using namespace mbgl;
namespace {
PremultipliedImage namedImage(const std::string& name) {
- return decodeImage(util::read_file("test/fixtures/sprites/" + name + ".png"));
+ return decodeImage(util::readFile("test/fixtures/sprites/" + name + ".png"));
}
std::unique_ptr<style::Image> namedMarker(const std::string& name) {
@@ -45,7 +45,7 @@ public:
TEST(Annotations, SymbolAnnotation) {
AnnotationTest test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotationImage(namedMarker("default_marker"));
test.map.addAnnotation(SymbolAnnotation { Point<double>(0, 0), "default_marker" });
test.checkRendering("point_annotation");
@@ -67,7 +67,7 @@ TEST(Annotations, LineAnnotation) {
annotation.color = Color::red();
annotation.width = { 5 };
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotation(annotation);
test.checkRendering("line_annotation");
@@ -82,7 +82,7 @@ TEST(Annotations, FillAnnotation) {
FillAnnotation annotation { polygon };
annotation.color = Color::red();
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotation(annotation);
test.checkRendering("fill_annotation");
@@ -95,7 +95,7 @@ TEST(Annotations, AntimeridianAnnotationSmall) {
double antimeridian = 180;
test.map.setLatLngZoom(mbgl::LatLng(0, antimeridian), 0);
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
LineString<double> line = {{ { antimeridian, 20 }, { antimeridian, -20 } }};
LineAnnotation lineAnnotation { line };
@@ -116,7 +116,7 @@ TEST(Annotations, AntimeridianAnnotationLarge) {
double antimeridian = 180;
test.map.setLatLngZoom(mbgl::LatLng(0, antimeridian), 0);
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
LineString<double> line = {{ { antimeridian, 20 }, { antimeridian, -20 } }};
LineAnnotation lineAnnotation { line };
@@ -141,7 +141,7 @@ TEST(Annotations, OverlappingFillAnnotation) {
FillAnnotation overlaidAnnotation { polygon };
overlaidAnnotation.color = Color::red();
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotation(underlaidAnnotation);
test.map.addAnnotation(overlaidAnnotation);
test.checkRendering("overlapping_fill_annotation");
@@ -150,7 +150,7 @@ TEST(Annotations, OverlappingFillAnnotation) {
TEST(Annotations, AddMultiple) {
AnnotationTest test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotationImage(namedMarker("default_marker"));
test.map.addAnnotation(SymbolAnnotation { Point<double> { -10, 0 }, "default_marker" });
@@ -163,7 +163,7 @@ TEST(Annotations, AddMultiple) {
TEST(Annotations, NonImmediateAdd) {
AnnotationTest test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.frontend.render(test.map);
Polygon<double> polygon = { {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} };
@@ -177,7 +177,7 @@ TEST(Annotations, NonImmediateAdd) {
TEST(Annotations, UpdateSymbolAnnotationGeometry) {
AnnotationTest test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotationImage(namedMarker("default_marker"));
test.map.addAnnotationImage(namedMarker("flipped_marker"));
AnnotationID point = test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" });
@@ -191,7 +191,7 @@ TEST(Annotations, UpdateSymbolAnnotationGeometry) {
TEST(Annotations, UpdateSymbolAnnotationIcon) {
AnnotationTest test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotationImage(namedMarker("default_marker"));
test.map.addAnnotationImage(namedMarker("flipped_marker"));
AnnotationID point = test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" });
@@ -209,7 +209,7 @@ TEST(Annotations, UpdateLineAnnotationGeometry) {
annotation.color = Color::red();
annotation.width = { 5 };
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
AnnotationID line = test.map.addAnnotation(annotation);
test.frontend.render(test.map);
@@ -226,7 +226,7 @@ TEST(Annotations, UpdateLineAnnotationStyle) {
annotation.color = Color::red();
annotation.width = { 5 };
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
AnnotationID line = test.map.addAnnotation(annotation);
test.frontend.render(test.map);
@@ -243,7 +243,7 @@ TEST(Annotations, UpdateFillAnnotationGeometry) {
FillAnnotation annotation { Polygon<double> { {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} } };
annotation.color = Color::red();
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
AnnotationID fill = test.map.addAnnotation(annotation);
test.frontend.render(test.map);
@@ -260,7 +260,7 @@ TEST(Annotations, UpdateFillAnnotationStyle) {
FillAnnotation annotation { polygon };
annotation.color = Color::red();
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
AnnotationID fill = test.map.addAnnotation(annotation);
test.frontend.render(test.map);
@@ -273,7 +273,7 @@ TEST(Annotations, UpdateFillAnnotationStyle) {
TEST(Annotations, RemovePoint) {
AnnotationTest test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotationImage(namedMarker("default_marker"));
AnnotationID point = test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" });
@@ -291,7 +291,7 @@ TEST(Annotations, RemoveShape) {
annotation.color = Color::red();
annotation.width = { 5 };
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
AnnotationID shape = test.map.addAnnotation(annotation);
test.frontend.render(test.map);
@@ -304,7 +304,7 @@ TEST(Annotations, ImmediateRemoveShape) {
AnnotationTest test;
test.map.removeAnnotation(test.map.addAnnotation(LineAnnotation { LineString<double>() }));
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.frontend.render(test.map);
}
@@ -312,20 +312,20 @@ TEST(Annotations, ImmediateRemoveShape) {
TEST(Annotations, SwitchStyle) {
AnnotationTest test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotationImage(namedMarker("default_marker"));
test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" });
test.frontend.render(test.map);
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.checkRendering("switch_style");
}
TEST(Annotations, ReaddImage) {
AnnotationTest test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotationImage(namedMarker("default_marker"));
test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" });
@@ -338,7 +338,7 @@ TEST(Annotations, ReaddImage) {
TEST(Annotations, QueryRenderedFeatures) {
AnnotationTest test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotationImage(namedMarker("default_marker"));
test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" });
test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 50 }, "default_marker" });
@@ -362,7 +362,7 @@ TEST(Annotations, QueryFractionalZoomLevels) {
auto viewSize = test.frontend.getSize();
auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } };
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotationImage(namedMarker("default_marker"));
std::vector<mbgl::AnnotationID> ids;
@@ -394,7 +394,7 @@ TEST(Annotations, VisibleFeatures) {
auto viewSize = test.frontend.getSize();
auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } };
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotationImage(namedMarker("default_marker"));
test.map.setLatLngZoom({ 5, 5 }, 3);
@@ -438,7 +438,7 @@ TEST(Annotations, DebugEmpty) {
// should not render them.
AnnotationTest test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.setDebug(MapDebugOptions::TileBorders);
test.map.setZoom(1);
@@ -451,7 +451,7 @@ TEST(Annotations, DebugSparse) {
// tiles because they're all empty.
AnnotationTest test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.setDebug(MapDebugOptions::TileBorders);
test.map.setZoom(1);
test.map.addAnnotationImage(namedMarker("default_marker"));
@@ -469,7 +469,7 @@ TEST(Annotations, ChangeMaxZoom) {
annotation.width = { 5 };
test.map.setMaxZoom(6);
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.map.addAnnotation(annotation);
test.map.setMaxZoom(14);
test.map.setZoom(test.map.getMaxZoom());
diff --git a/test/api/custom_geometry_source.test.cpp b/test/api/custom_geometry_source.test.cpp
index 83d1543a0a..3397bef9ef 100644
--- a/test/api/custom_geometry_source.test.cpp
+++ b/test/api/custom_geometry_source.test.cpp
@@ -26,7 +26,7 @@ TEST(CustomGeometrySource, Grid) {
HeadlessFrontend frontend { pixelRatio, fileSource, *threadPool };
Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource,
*threadPool, MapMode::Static);
- map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json"));
+ map.getStyle().loadJSON(util::readFile("test/fixtures/api/water.json"));
map.setLatLngZoom({ 37.8, -122.5 }, 10);
CustomGeometrySource::Options options;
diff --git a/test/api/custom_layer.test.cpp b/test/api/custom_layer.test.cpp
index eb1d7e0d3a..5eaa73a37a 100644
--- a/test/api/custom_layer.test.cpp
+++ b/test/api/custom_layer.test.cpp
@@ -91,7 +91,7 @@ TEST(CustomLayer, Basic) {
HeadlessFrontend frontend { pixelRatio, fileSource, threadPool };
Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource,
threadPool, MapMode::Static);
- map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json"));
+ map.getStyle().loadJSON(util::readFile("test/fixtures/api/water.json"));
map.setLatLngZoom({ 37.8, -122.5 }, 10);
map.getStyle().addLayer(std::make_unique<CustomLayer>(
"custom",
diff --git a/test/api/query.test.cpp b/test/api/query.test.cpp
index c67ff9064c..43067dd57a 100644
--- a/test/api/query.test.cpp
+++ b/test/api/query.test.cpp
@@ -19,9 +19,9 @@ namespace {
class QueryTest {
public:
QueryTest() {
- map.getStyle().loadJSON(util::read_file("test/fixtures/api/query_style.json"));
+ map.getStyle().loadJSON(util::readFile("test/fixtures/api/query_style.json"));
map.getStyle().addImage(std::make_unique<style::Image>("test-icon",
- decodeImage(util::read_file("test/fixtures/sprites/default_marker.png")), 1.0));
+ decodeImage(util::readFile("test/fixtures/sprites/default_marker.png")), 1.0));
frontend.render(map);
}
diff --git a/test/api/recycle_map.cpp b/test/api/recycle_map.cpp
index ca6abac8c1..1055eda5a9 100644
--- a/test/api/recycle_map.cpp
+++ b/test/api/recycle_map.cpp
@@ -40,10 +40,10 @@ TEST(API, RecycleMapUpdateImages) {
auto layer = std::make_unique<SymbolLayer>("geometry", "geometry");
layer->setIconImage({ markerName });
- map->getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ map->getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
map->getStyle().addSource(std::move(source));
map->getStyle().addLayer(std::move(layer));
- map->getStyle().addImage(std::make_unique<style::Image>(markerName, decodeImage(util::read_file(markerPath)), 1.0));
+ map->getStyle().addImage(std::make_unique<style::Image>(markerName, decodeImage(util::readFile(markerPath)), 1.0));
};
// default marker
diff --git a/test/api/zoom_history.cpp b/test/api/zoom_history.cpp
index df9b6ff2a3..a16d5322d7 100644
--- a/test/api/zoom_history.cpp
+++ b/test/api/zoom_history.cpp
@@ -34,7 +34,7 @@ TEST(API, ZoomHistory) {
EXPECT_TRUE(map);
- map->getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ map->getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
auto source = std::make_unique<GeoJSONSource>("source");
source->setGeoJSON({ LineString<double> { { 45, -45 }, { -45, 45 } } });
diff --git a/test/gl/context.test.cpp b/test/gl/context.test.cpp
index 179ce5de53..157732d723 100644
--- a/test/gl/context.test.cpp
+++ b/test/gl/context.test.cpp
@@ -90,7 +90,7 @@ TEST(GLContextMode, Shared) {
HeadlessFrontend frontend { pixelRatio, fileSource, threadPool, {}, GLContextMode::Shared };
Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Static);
- map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json"));
+ map.getStyle().loadJSON(util::readFile("test/fixtures/api/water.json"));
map.setLatLngZoom({ 37.8, -122.5 }, 10);
// Set transparent background layer.
diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp
index 9b34ea89b0..bb0ff2a201 100644
--- a/test/map/map.test.cpp
+++ b/test/map/map.test.cpp
@@ -21,7 +21,6 @@
using namespace mbgl;
using namespace mbgl::style;
-using namespace std::literals::string_literals;
class StubMapObserver : public MapObserver {
public:
@@ -162,7 +161,7 @@ TEST(Map, Offline) {
auto expiredItem = [] (const std::string& path) {
Response response;
- response.data = std::make_shared<std::string>(util::read_file("test/fixtures/map/offline/"s + path));
+ response.data = util::readFile("test/fixtures/map/offline/" + path);
response.expires = Timestamp{ Seconds(0) };
return response;
};
@@ -188,13 +187,13 @@ TEST(Map, Offline) {
TEST(Map, SetStyleDefaultCamera) {
MapTest<> test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
EXPECT_DOUBLE_EQ(test.map.getZoom(), 0.0);
EXPECT_DOUBLE_EQ(test.map.getPitch(), 0.0);
EXPECT_DOUBLE_EQ(test.map.getBearing(), 0.0);
EXPECT_EQ(test.map.getLatLng(), LatLng {});
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty-zoomed.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty-zoomed.json"));
EXPECT_DOUBLE_EQ(test.map.getZoom(), 0.0);
test.map.jumpTo(test.map.getStyle().getDefaultCamera());
@@ -211,7 +210,7 @@ TEST(Map, SetStyleInvalidJSON) {
test.observer.didFailLoadingMapCallback = [&]() {
fail = true;
};
- test.map.getStyle().loadJSON("invalid");
+ test.map.getStyle().loadJSON(Blob{ "invalid", false });
}
EXPECT_TRUE(fail);
@@ -247,8 +246,8 @@ TEST(Map, SetStyleInvalidURL) {
TEST(Map, DoubleStyleLoad) {
MapTest<> test;
- test.map.getStyle().loadJSON("");
- test.map.getStyle().loadJSON("");
+ test.map.getStyle().loadJSON(Blob{ "", false });
+ test.map.getStyle().loadJSON(Blob{ "", false });
}
TEST(Map, StyleFresh) {
@@ -260,7 +259,7 @@ TEST(Map, StyleFresh) {
EXPECT_EQ(1u, test.fileSource.requests.size());
Response response;
- response.data = std::make_shared<std::string>(util::read_file("test/fixtures/api/empty.json"));
+ response.data = util::readFile("test/fixtures/api/empty.json");
response.expires = Timestamp::max();
test.fileSource.respond(Resource::Style, response);
@@ -278,7 +277,7 @@ TEST(Map, StyleExpired) {
EXPECT_EQ(1u, test.fileSource.requests.size());
Response response;
- response.data = std::make_shared<std::string>(util::read_file("test/fixtures/api/empty.json"));
+ response.data = util::readFile("test/fixtures/api/empty.json");
response.expires = util::now() - 1h;
test.fileSource.respond(Resource::Style, response);
@@ -303,7 +302,7 @@ TEST(Map, StyleExpiredWithAnnotations) {
EXPECT_EQ(1u, test.fileSource.requests.size());
Response response;
- response.data = std::make_shared<std::string>(util::read_file("test/fixtures/api/empty.json"));
+ response.data = util::readFile("test/fixtures/api/empty.json");
response.expires = util::now() - 1h;
test.fileSource.respond(Resource::Style, response);
@@ -327,7 +326,7 @@ TEST(Map, StyleExpiredWithRender) {
EXPECT_EQ(1u, test.fileSource.requests.size());
Response response;
- response.data = std::make_shared<std::string>(util::read_file("test/fixtures/api/empty.json"));
+ response.data = util::readFile("test/fixtures/api/empty.json");
response.expires = util::now() - 1h;
test.fileSource.respond(Resource::Style, response);
@@ -349,7 +348,7 @@ TEST(Map, StyleEarlyMutation) {
test.map.getStyle().addLayer(std::make_unique<style::BackgroundLayer>("bg"));
Response response;
- response.data = std::make_shared<std::string>(util::read_file("test/fixtures/api/water.json"));
+ response.data = util::readFile("test/fixtures/api/water.json");
test.fileSource.respond(Resource::Style, response);
EXPECT_EQ(0u, test.fileSource.requests.size());
@@ -363,7 +362,7 @@ TEST(Map, MapLoadingSignal) {
test.observer.onWillStartLoadingMapCallback = [&]() {
emitted = true;
};
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
EXPECT_TRUE(emitted);
}
@@ -374,7 +373,7 @@ TEST(Map, MapLoadedSignal) {
test.runLoop.stop();
};
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
test.runLoop.run();
}
@@ -386,12 +385,12 @@ TEST(Map, StyleLoadedSignal) {
test.observer.didFinishLoadingStyleCallback = [&]() {
emitted = true;
};
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
EXPECT_TRUE(emitted);
// But not when the style couldn't be parsed
emitted = false;
- test.map.getStyle().loadJSON("invalid");
+ test.map.getStyle().loadJSON(Blob{ "invalid", false });
EXPECT_FALSE(emitted);
}
@@ -437,7 +436,7 @@ TEST(Map, TEST_REQUIRES_SERVER(StyleNotFound)) {
TEST(Map, AddLayer) {
MapTest<> test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
auto layer = std::make_unique<BackgroundLayer>("background");
layer->setBackgroundColor({ { 1, 0, 0, 1 } });
@@ -452,7 +451,7 @@ TEST(Map, WithoutVAOExtension) {
BackendScope scope { *test.frontend.getBackend() };
test.frontend.getBackend()->getContext().disableVAOExtension = true;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/water.json"));
test::checkImage("test/fixtures/map/no_vao", test.frontend.render(test.map), 0.002);
}
@@ -460,7 +459,7 @@ TEST(Map, WithoutVAOExtension) {
TEST(Map, RemoveLayer) {
MapTest<> test;
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/api/empty.json"));
auto layer = std::make_unique<BackgroundLayer>("background");
layer->setBackgroundColor({{ 1, 0, 0, 1 }});
@@ -477,8 +476,7 @@ TEST(Map, DisabledSources) {
test.fileSource.response = [] (const Resource& res) -> optional<Response> {
if (res.url == "asset://tile.png") {
Response response;
- response.data = std::make_shared<std::string>(
- util::read_file("test/fixtures/map/disabled_layers/tile.png"));
+ response.data = util::readFile("test/fixtures/map/disabled_layers/tile.png");
return {std::move(response)};
}
return {};
@@ -491,7 +489,7 @@ TEST(Map, DisabledSources) {
// to an opacity of 0.5). Then, we are zooming back out to a zoom level of 0.5 and rerender.
// The "raster1" layer should not be visible anymore since it has minzoom 1, while "raster2"
// should still be there. Both layers have a distinct color through "raster-hue-rotate".
- test.map.getStyle().loadJSON(R"STYLE(
+ test.map.getStyle().loadJSON(Blob{ R"STYLE(
{
"version": 8,
"name": "Test",
@@ -523,7 +521,7 @@ TEST(Map, DisabledSources) {
}
}]
}
-)STYLE");
+)STYLE", false });
test::checkImage("test/fixtures/map/disabled_layers/first", test.frontend.render(test.map));
test.map.setZoom(0.5);
@@ -533,7 +531,7 @@ TEST(Map, DisabledSources) {
TEST(Map, DontLoadUnneededTiles) {
MapTest<> test;
- test.map.getStyle().loadJSON(R"STYLE({
+ test.map.getStyle().loadJSON(Blob{ R"STYLE({
"sources": {
"a": { "type": "vector", "tiles": [ "a/{z}/{x}/{y}" ] }
},
@@ -545,7 +543,7 @@ TEST(Map, DontLoadUnneededTiles) {
"minzoom": 0.3,
"maxzoom": 1.6
}]
-})STYLE");
+})STYLE", false });
using Tiles = std::unordered_set<std::string>;
Tiles tiles;
@@ -606,7 +604,7 @@ TEST(Map, TEST_DISABLED_ON_CI(ContinuousRendering)) {
};
Map map(frontend, observer, frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Continuous);
- map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json"));
+ map.getStyle().loadJSON(util::readFile("test/fixtures/api/water.json"));
runLoop.run();
}
@@ -624,7 +622,7 @@ TEST(Map, NoContentTiles) {
Tileset::Scheme::XYZ),
response);
- test.map.getStyle().loadJSON(R"STYLE({
+ test.map.getStyle().loadJSON(Blob{ R"STYLE({
"version": 8,
"name": "Water",
"sources": {
@@ -645,7 +643,7 @@ TEST(Map, NoContentTiles) {
"source": "mapbox",
"source-layer": "water"
}]
- })STYLE");
+ })STYLE", false });
test::checkImage("test/fixtures/map/nocontent",
test.frontend.render(test.map),
diff --git a/test/map/prefetch.test.cpp b/test/map/prefetch.test.cpp
index 4c82b2c965..7cb8ea1545 100644
--- a/test/map/prefetch.test.cpp
+++ b/test/map/prefetch.test.cpp
@@ -37,11 +37,9 @@ TEST(Map, PrefetchTiles) {
// The end rendering result should be all green because the map is only
// considered fully rendered when only ideal tiles are shown.
if (zoom == int(map.getZoom()) + 1) {
- response.data = std::make_shared<std::string>(
- util::read_file("test/fixtures/map/prefetch/tile_green.png"));
+ response.data = util::readFile("test/fixtures/map/prefetch/tile_green.png");
} else {
- response.data = std::make_shared<std::string>(
- util::read_file("test/fixtures/map/prefetch/tile_red.png"));
+ response.data = util::readFile("test/fixtures/map/prefetch/tile_red.png");
}
return { std::move(response) };
@@ -51,8 +49,8 @@ TEST(Map, PrefetchTiles) {
tiles.clear();
// Force tile reloading.
- map.getStyle().loadJSON(util::read_file("test/fixtures/map/prefetch/empty.json"));
- map.getStyle().loadJSON(util::read_file("test/fixtures/map/prefetch/style.json"));
+ map.getStyle().loadJSON(util::readFile("test/fixtures/map/prefetch/empty.json"));
+ map.getStyle().loadJSON(util::readFile("test/fixtures/map/prefetch/style.json"));
map.setLatLngZoom({ 40.726989, -73.992857 }, zoom); // Manhattan
diff --git a/test/programs/binary_program.test.cpp b/test/programs/binary_program.test.cpp
index a5cf7b6e39..7fc2acbf77 100644
--- a/test/programs/binary_program.test.cpp
+++ b/test/programs/binary_program.test.cpp
@@ -35,5 +35,5 @@ TEST(BinaryProgram, ObtainValues) {
EXPECT_EQ(3, binaryProgram2.uniformLocation("u_ratio"));
EXPECT_EQ(-1, binaryProgram2.uniformLocation("a_data"));
- EXPECT_THROW(BinaryProgram(""), std::runtime_error);
+ EXPECT_THROW(BinaryProgram(Blob{ "", false }), std::runtime_error);
}
diff --git a/test/renderer/image_manager.test.cpp b/test/renderer/image_manager.test.cpp
index ebe1bcd72f..e1d9030d4c 100644
--- a/test/renderer/image_manager.test.cpp
+++ b/test/renderer/image_manager.test.cpp
@@ -25,8 +25,8 @@ TEST(ImageManager, Basic) {
FixtureLog log;
ImageManager imageManager;
- auto images = parseSprite(util::read_file("test/fixtures/annotations/emerald.png"),
- util::read_file("test/fixtures/annotations/emerald.json"));
+ auto images = parseSprite(util::readFile("test/fixtures/annotations/emerald.png"),
+ util::readFile("test/fixtures/annotations/emerald.json"));
for (auto& image : images) {
imageManager.addImage(image->baseImpl);
}
diff --git a/test/sprite/sprite_loader.test.cpp b/test/sprite/sprite_loader.test.cpp
index 3691572265..d773afd539 100644
--- a/test/sprite/sprite_loader.test.cpp
+++ b/test/sprite/sprite_loader.test.cpp
@@ -58,14 +58,14 @@ public:
Response successfulSpriteImageResponse(const Resource& resource) {
EXPECT_EQ("test/fixtures/resources/sprite.png", resource.url);
Response response;
- response.data = std::make_unique<std::string>(util::read_file(resource.url));
+ response.data = util::readFile(resource.url);
return response;
}
Response successfulSpriteJSONResponse(const Resource& resource) {
EXPECT_EQ("test/fixtures/resources/sprite.json", resource.url);
Response response;
- response.data = std::make_unique<std::string>(util::read_file(resource.url));
+ response.data = util::readFile(resource.url);
return response;
}
@@ -79,7 +79,7 @@ Response failedSpriteResponse(const Resource&) {
Response corruptSpriteResponse(const Resource&) {
Response response;
- response.data = std::make_unique<std::string>("CORRUPT");
+ response.data = Blob{ "CORRUPT", false };
return response;
}
diff --git a/test/sprite/sprite_parser.test.cpp b/test/sprite/sprite_parser.test.cpp
index 529e4c75e8..14d5f65860 100644
--- a/test/sprite/sprite_parser.test.cpp
+++ b/test/sprite/sprite_parser.test.cpp
@@ -14,7 +14,7 @@ using namespace mbgl;
namespace {
auto readImage(const std::string& name) {
- return decodeImage(util::read_file(name));
+ return decodeImage(util::readFile(name));
}
} // namespace
@@ -22,7 +22,7 @@ auto readImage(const std::string& name) {
TEST(Sprite, SpriteImageCreationInvalid) {
FixtureLog log;
- const PremultipliedImage image_1x = decodeImage(util::read_file("test/fixtures/annotations/emerald.png"));
+ const PremultipliedImage image_1x = decodeImage(util::readFile("test/fixtures/annotations/emerald.png"));
ASSERT_EQ(200u, image_1x.size.width);
ASSERT_EQ(299u, image_1x.size.height);
@@ -135,7 +135,7 @@ TEST(Sprite, SpriteImageCreationInvalid) {
}
TEST(Sprite, SpriteImageCreation1x) {
- const PremultipliedImage image_1x = decodeImage(util::read_file("test/fixtures/annotations/emerald.png"));
+ const PremultipliedImage image_1x = decodeImage(util::readFile("test/fixtures/annotations/emerald.png"));
ASSERT_EQ(200u, image_1x.size.width);
ASSERT_EQ(299u, image_1x.size.height);
@@ -152,7 +152,7 @@ TEST(Sprite, SpriteImageCreation1x) {
}
TEST(Sprite, SpriteImageCreation2x) {
- const PremultipliedImage image_2x = decodeImage(util::read_file("test/fixtures/annotations/emerald@2x.png"));
+ const PremultipliedImage image_2x = decodeImage(util::readFile("test/fixtures/annotations/emerald@2x.png"));
// "museum_icon":{"x":354,"y":374,"width":36,"height":36,"pixelRatio":2,"sdf":false}
const auto sprite = createStyleImage("test", image_2x, 354, 374, 36, 36, 2, false);
@@ -165,7 +165,7 @@ TEST(Sprite, SpriteImageCreation2x) {
}
TEST(Sprite, SpriteImageCreation1_5x) {
- const PremultipliedImage image_2x = decodeImage(util::read_file("test/fixtures/annotations/emerald@2x.png"));
+ const PremultipliedImage image_2x = decodeImage(util::readFile("test/fixtures/annotations/emerald@2x.png"));
// "museum_icon":{"x":354,"y":374,"width":36,"height":36,"pixelRatio":2,"sdf":false}
const auto sprite = createStyleImage("test", image_2x, 354, 374, 36, 36, 1.5, false);
@@ -187,8 +187,8 @@ TEST(Sprite, SpriteImageCreation1_5x) {
}
TEST(Sprite, SpriteParsing) {
- const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
- const auto json_1x = util::read_file("test/fixtures/annotations/emerald.json");
+ const auto image_1x = util::readFile("test/fixtures/annotations/emerald.png");
+ const auto json_1x = util::readFile("test/fixtures/annotations/emerald.json");
const auto images = parseSprite(image_1x, json_1x);
@@ -281,8 +281,8 @@ TEST(Sprite, SpriteParsing) {
}
TEST(Sprite, SpriteParsingInvalidJSON) {
- const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
- const auto json_1x = R"JSON({ "image": " })JSON";
+ const auto image_1x = util::readFile("test/fixtures/annotations/emerald.png");
+ const auto json_1x = Blob{ R"JSON({ "image": " })JSON", false };
try {
parseSprite(image_1x, json_1x);
@@ -297,8 +297,8 @@ TEST(Sprite, SpriteParsingInvalidJSON) {
TEST(Sprite, SpriteParsingEmptyImage) {
FixtureLog log;
- const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
- const auto json_1x = R"JSON({ "image": {} })JSON";
+ const auto image_1x = util::readFile("test/fixtures/annotations/emerald.png");
+ const auto json_1x = Blob{ R"JSON({ "image": {} })JSON", false };
const auto images = parseSprite(image_1x, json_1x);
EXPECT_EQ(0u, images.size());
@@ -314,8 +314,8 @@ TEST(Sprite, SpriteParsingEmptyImage) {
TEST(Sprite, SpriteParsingSimpleWidthHeight) {
FixtureLog log;
- const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
- const auto json_1x = R"JSON({ "image": { "width": 32, "height": 32 } })JSON";
+ const auto image_1x = util::readFile("test/fixtures/annotations/emerald.png");
+ const auto json_1x = Blob{ R"JSON({ "image": { "width": 32, "height": 32 } })JSON", false };
const auto images = parseSprite(image_1x, json_1x);
EXPECT_EQ(1u, images.size());
@@ -324,8 +324,8 @@ TEST(Sprite, SpriteParsingSimpleWidthHeight) {
TEST(Sprite, SpriteParsingWidthTooBig) {
FixtureLog log;
- const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
- const auto json_1x = R"JSON({ "image": { "width": 65536, "height": 32 } })JSON";
+ const auto image_1x = util::readFile("test/fixtures/annotations/emerald.png");
+ const auto json_1x = Blob{ R"JSON({ "image": { "width": 65536, "height": 32 } })JSON", false };
const auto images = parseSprite(image_1x, json_1x);
EXPECT_EQ(0u, images.size());
@@ -347,8 +347,8 @@ TEST(Sprite, SpriteParsingWidthTooBig) {
TEST(Sprite, SpriteParsingNegativeWidth) {
FixtureLog log;
- const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
- const auto json_1x = R"JSON({ "image": { "width": -1, "height": 32 } })JSON";
+ const auto image_1x = util::readFile("test/fixtures/annotations/emerald.png");
+ const auto json_1x = Blob{ R"JSON({ "image": { "width": -1, "height": 32 } })JSON", false };
const auto images = parseSprite(image_1x, json_1x);
EXPECT_EQ(0u, images.size());
@@ -370,8 +370,8 @@ TEST(Sprite, SpriteParsingNegativeWidth) {
TEST(Sprite, SpriteParsingNullRatio) {
FixtureLog log;
- const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
- const auto json_1x = R"JSON({ "image": { "width": 32, "height": 32, "pixelRatio": 0 } })JSON";
+ const auto image_1x = util::readFile("test/fixtures/annotations/emerald.png");
+ const auto json_1x = Blob{ R"JSON({ "image": { "width": 32, "height": 32, "pixelRatio": 0 } })JSON", false };
const auto images = parseSprite(image_1x, json_1x);
EXPECT_EQ(0u, images.size());
diff --git a/test/src/mbgl/test/util.cpp b/test/src/mbgl/test/util.cpp
index 028a0a9d51..82d2af6cd9 100644
--- a/test/src/mbgl/test/util.cpp
+++ b/test/src/mbgl/test/util.cpp
@@ -100,26 +100,26 @@ void checkImage(const std::string& base,
double pixelThreshold) {
#if !TEST_READ_ONLY
if (getenv("UPDATE")) {
- util::write_file(base + "/expected.png", encodePNG(actual));
+ util::writeFile(base + "/expected.png", encodePNG(actual));
return;
}
#endif
- std::string expected_image;
+ Blob expectedImage;
try {
- expected_image = util::read_file(base + "/expected.png");
+ expectedImage = util::readFile(base + "/expected.png");
} catch (std::exception& ex) {
Log::Error(Event::Setup, "Failed to load expected image %s: %s",
(base + "/expected.png").c_str(), ex.what());
throw;
}
- PremultipliedImage expected = decodeImage(expected_image);
+ PremultipliedImage expected = decodeImage(expectedImage);
PremultipliedImage diff { expected.size };
#if !TEST_READ_ONLY
- util::write_file(base + "/actual.png", encodePNG(actual));
+ util::writeFile(base + "/actual.png", encodePNG(actual));
#endif
ASSERT_EQ(expected.size, actual.size);
@@ -134,7 +134,7 @@ void checkImage(const std::string& base,
EXPECT_LE(pixels / (expected.size.width * expected.size.height), imageThreshold);
#if !TEST_READ_ONLY
- util::write_file(base + "/diff.png", encodePNG(diff));
+ util::writeFile(base + "/diff.png", encodePNG(diff));
#endif
}
diff --git a/test/storage/asset_file_source.test.cpp b/test/storage/asset_file_source.test.cpp
index 978a41a306..694d56be6d 100644
--- a/test/storage/asset_file_source.test.cpp
+++ b/test/storage/asset_file_source.test.cpp
@@ -33,8 +33,8 @@ TEST(AssetFileSource, Load) {
requestCallback = [this, asset, endCallback](mbgl::Response res) {
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("content is here\n", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("content is here\n", *res.data.uncompressedData());
if (!--numRequests) {
endCallback();
@@ -86,8 +86,8 @@ TEST(AssetFileSource, EmptyFile) {
std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, "asset://empty" }, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("", *res.data.uncompressedData());
loop.stop();
});
@@ -102,8 +102,8 @@ TEST(AssetFileSource, NonEmptyFile) {
std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, "asset://nonempty" }, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("content is here\n", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("content is here\n", *res.data.uncompressedData());
loop.stop();
});
@@ -119,7 +119,7 @@ TEST(AssetFileSource, NonExistentFile) {
req.reset();
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::NotFound, res.error->reason);
- ASSERT_FALSE(res.data.get());
+ ASSERT_FALSE(res.data);
// Do not assert on platform-specific error message.
loop.stop();
});
@@ -137,7 +137,7 @@ TEST(AssetFileSource, InvalidURL) {
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::Other, res.error->reason);
EXPECT_EQ("Invalid asset URL", res.error->message);
- ASSERT_FALSE(res.data.get());
+ ASSERT_FALSE(res.data);
loop.stop();
});
@@ -153,7 +153,7 @@ TEST(AssetFileSource, ReadDirectory) {
req.reset();
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::NotFound, res.error->reason);
- ASSERT_FALSE(res.data.get());
+ ASSERT_FALSE(res.data);
// Do not assert on platform-specific error message.
loop.stop();
});
@@ -169,8 +169,8 @@ TEST(AssetFileSource, URLEncoding) {
std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, "asset://%6eonempty" }, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("content is here\n", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("content is here\n", *res.data.uncompressedData());
loop.stop();
});
diff --git a/test/storage/default_file_source.test.cpp b/test/storage/default_file_source.test.cpp
index c11d442270..f74a515d86 100644
--- a/test/storage/default_file_source.test.cpp
+++ b/test/storage/default_file_source.test.cpp
@@ -19,8 +19,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheResponse)) {
req1 = fs.request(resource, [&](Response res) {
req1.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Response 1", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Response 1", *res.data.uncompressedData());
EXPECT_TRUE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -32,8 +32,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheResponse)) {
req2 = fs.request(resource, [&](Response res2) {
req2.reset();
EXPECT_EQ(response.error, res2.error);
- ASSERT_TRUE(res2.data.get());
- EXPECT_EQ(*response.data, *res2.data);
+ ASSERT_TRUE(res2.data);
+ EXPECT_EQ(*response.data.uncompressedData(), *res2.data.uncompressedData());
EXPECT_EQ(response.expires, res2.expires);
EXPECT_EQ(response.mustRevalidate, res2.mustRevalidate);
EXPECT_EQ(response.modified, res2.modified);
@@ -61,8 +61,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateSame)) {
EXPECT_EQ(nullptr, res.error);
EXPECT_FALSE(res.notModified);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Response", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Response", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_TRUE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -81,8 +81,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateSame)) {
gotResponse = true;
EXPECT_EQ(nullptr, res2.error);
EXPECT_FALSE(res2.notModified);
- ASSERT_TRUE(res2.data.get());
- EXPECT_EQ("Response", *res2.data);
+ ASSERT_TRUE(res2.data);
+ EXPECT_EQ("Response", *res2.data.uncompressedData());
EXPECT_TRUE(bool(res2.expires));
EXPECT_TRUE(res2.mustRevalidate);
EXPECT_FALSE(bool(res2.modified));
@@ -95,7 +95,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateSame)) {
req2.reset();
EXPECT_EQ(nullptr, res2.error);
EXPECT_TRUE(res2.notModified);
- EXPECT_FALSE(res2.data.get());
+ EXPECT_FALSE(res2.data);
EXPECT_TRUE(bool(res2.expires));
EXPECT_TRUE(res2.mustRevalidate);
EXPECT_FALSE(bool(res2.modified));
@@ -124,8 +124,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateModified)) {
EXPECT_EQ(nullptr, res.error);
EXPECT_FALSE(res.notModified);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Response", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Response", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_TRUE(res.mustRevalidate);
EXPECT_EQ(Timestamp{ Seconds(1420070400) }, *res.modified);
@@ -144,8 +144,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateModified)) {
gotResponse = true;
EXPECT_EQ(nullptr, res2.error);
EXPECT_FALSE(res2.notModified);
- ASSERT_TRUE(res2.data.get());
- EXPECT_EQ("Response", *res2.data);
+ ASSERT_TRUE(res2.data);
+ EXPECT_EQ("Response", *res2.data.uncompressedData());
EXPECT_TRUE(bool(res2.expires));
EXPECT_TRUE(res2.mustRevalidate);
EXPECT_EQ(Timestamp{ Seconds(1420070400) }, *res2.modified);
@@ -158,7 +158,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateModified)) {
req2.reset();
EXPECT_EQ(nullptr, res2.error);
EXPECT_TRUE(res2.notModified);
- EXPECT_FALSE(res2.data.get());
+ EXPECT_FALSE(res2.data);
EXPECT_TRUE(bool(res2.expires));
EXPECT_TRUE(res2.mustRevalidate);
EXPECT_EQ(Timestamp{ Seconds(1420070400) }, *res2.modified);
@@ -184,8 +184,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateEtag)) {
req1.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Response 1", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Response 1", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_TRUE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -196,9 +196,9 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateEtag)) {
req2.reset();
EXPECT_EQ(nullptr, res2.error);
- ASSERT_TRUE(res2.data.get());
- EXPECT_NE(res.data, res2.data);
- EXPECT_EQ("Response 2", *res2.data);
+ ASSERT_TRUE(res2.data);
+ EXPECT_FALSE(*res.data.uncompressedData() == *res2.data.uncompressedData());
+ EXPECT_EQ("Response 2", *res2.data.uncompressedData());
EXPECT_FALSE(bool(res2.expires));
EXPECT_TRUE(res2.mustRevalidate);
EXPECT_FALSE(bool(res2.modified));
@@ -235,8 +235,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(HTTPIssue1369)) {
req = fs.request(resource, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Hello World!", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Hello World!", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -256,7 +256,7 @@ TEST(DefaultFileSource, OptionalNonExpired) {
using namespace std::chrono_literals;
Response response;
- response.data = std::make_shared<std::string>("Cached value");
+ response.data = Blob{ "Cached value", false };
response.expires = util::now() + 1h;
fs.put(optionalResource, response);
@@ -264,8 +264,8 @@ TEST(DefaultFileSource, OptionalNonExpired) {
req = fs.request(optionalResource, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Cached value", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Cached value", *res.data.uncompressedData());
ASSERT_TRUE(bool(res.expires));
EXPECT_EQ(*response.expires, *res.expires);
EXPECT_FALSE(res.mustRevalidate);
@@ -286,7 +286,7 @@ TEST(DefaultFileSource, OptionalExpired) {
using namespace std::chrono_literals;
Response response;
- response.data = std::make_shared<std::string>("Cached value");
+ response.data = Blob{ "Cached value", false };
response.expires = util::now() - 1h;
fs.put(optionalResource, response);
@@ -294,8 +294,8 @@ TEST(DefaultFileSource, OptionalExpired) {
req = fs.request(optionalResource, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Cached value", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Cached value", *res.data.uncompressedData());
ASSERT_TRUE(bool(res.expires));
EXPECT_EQ(*response.expires, *res.expires);
EXPECT_FALSE(res.mustRevalidate);
@@ -361,7 +361,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshEtagNotModified)) {
// Put a fake value into the cache to make sure we're not retrieving anything from the cache.
Response response;
- response.data = std::make_shared<std::string>("Cached value");
+ response.data = Blob{ "Cached value", false };
response.expires = util::now() + 1h;
fs.put(resource, response);
@@ -370,7 +370,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshEtagNotModified)) {
req.reset();
EXPECT_EQ(nullptr, res.error);
EXPECT_TRUE(res.notModified);
- EXPECT_FALSE(res.data.get());
+ EXPECT_FALSE(res.data);
ASSERT_TRUE(bool(res.expires));
EXPECT_LT(util::now(), *res.expires);
EXPECT_TRUE(res.mustRevalidate);
@@ -396,7 +396,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshEtagModified)) {
// Put a fake value into the cache to make sure we're not retrieving anything from the cache.
Response response;
- response.data = std::make_shared<std::string>("Cached value");
+ response.data = Blob{ "Cached value", false };
response.expires = util::now() + 1h;
fs.put(resource, response);
@@ -405,8 +405,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshEtagModified)) {
req.reset();
EXPECT_EQ(nullptr, res.error);
EXPECT_FALSE(res.notModified);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Response", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Response", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_TRUE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -430,7 +430,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheFull)) {
// Put a fake value into the cache to make sure we're not retrieving anything from the cache.
Response response;
- response.data = std::make_shared<std::string>("Cached value");
+ response.data = Blob{ "Cached value", false };
response.expires = util::now() + 1h;
fs.put(resource, response);
@@ -439,8 +439,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheFull)) {
req.reset();
EXPECT_EQ(nullptr, res.error);
EXPECT_FALSE(res.notModified);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Response", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Response", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_TRUE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -466,7 +466,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshModifiedNotModified))
// Put a fake value into the cache to make sure we're not retrieving anything from the cache.
Response response;
- response.data = std::make_shared<std::string>("Cached value");
+ response.data = Blob{ "Cached value", false };
response.expires = util::now() + 1h;
fs.put(resource, response);
@@ -475,7 +475,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshModifiedNotModified))
req.reset();
EXPECT_EQ(nullptr, res.error);
EXPECT_TRUE(res.notModified);
- EXPECT_FALSE(res.data.get());
+ EXPECT_FALSE(res.data);
ASSERT_TRUE(bool(res.expires));
EXPECT_LT(util::now(), *res.expires);
EXPECT_TRUE(res.mustRevalidate);
@@ -502,7 +502,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshModifiedModified)) {
// Put a fake value into the cache to make sure we're not retrieving anything from the cache.
Response response;
- response.data = std::make_shared<std::string>("Cached value");
+ response.data = Blob{ "Cached value", false };
response.expires = util::now() + 1h;
fs.put(resource, response);
@@ -511,8 +511,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshModifiedModified)) {
req.reset();
EXPECT_EQ(nullptr, res.error);
EXPECT_FALSE(res.notModified);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Response", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Response", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_TRUE(res.mustRevalidate);
EXPECT_EQ(Timestamp{ Seconds(1420070400) }, *res.modified);
@@ -543,8 +543,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(SetResourceTransform)) {
req = fs.request(resource1, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Hello World!", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Hello World!", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -560,8 +560,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(SetResourceTransform)) {
req = fs.request(resource2, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Hello World!", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Hello World!", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -584,7 +584,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(RespondToStaleMustRevalidate)) {
// Put an existing value in the cache that has expired, and has must-revalidate set.
Response response;
- response.data = std::make_shared<std::string>("Cached value");
+ response.data = Blob{ "Cached value", false };
response.modified = Timestamp(Seconds(1417392000)); // December 1, 2014
response.expires = Timestamp(Seconds(1417392000));
response.mustRevalidate = true;
@@ -598,8 +598,8 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(RespondToStaleMustRevalidate)) {
EXPECT_EQ(Response::Error::Reason::NotFound, res.error->reason);
EXPECT_EQ("Cached resource is unusable", res.error->message);
EXPECT_FALSE(res.notModified);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Cached value", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Cached value", *res.data.uncompressedData());
ASSERT_TRUE(res.expires);
EXPECT_EQ(Timestamp{ Seconds(1417392000) }, *res.expires);
EXPECT_TRUE(res.mustRevalidate);
@@ -622,7 +622,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(RespondToStaleMustRevalidate)) {
// request. We're replacing the data so that we can check that the DefaultFileSource doesn't
// attempt another database access if we already have the value.
resource.loadingMethod = Resource::LoadingMethod::NetworkOnly;
- resource.priorData = std::make_shared<std::string>("Prior value");
+ resource.priorData = Blob{ "Prior value", false };
req = fs.request(resource, [&](Response res) {
req.reset();
@@ -632,11 +632,11 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(RespondToStaleMustRevalidate)) {
// OnlineFileSource to ensure that requestors know that this is the first time they're
// seeing this data.
EXPECT_FALSE(res.notModified);
- ASSERT_TRUE(res.data.get());
+ ASSERT_TRUE(res.data);
// Ensure that it's the value that we manually inserted into the cache rather than the value
// the server returns, since we should be executing a revalidation request which doesn't
// return new data, only a 304 Not Modified response.
- EXPECT_EQ("Prior value", *res.data);
+ EXPECT_EQ("Prior value", *res.data.uncompressedData());
ASSERT_TRUE(res.expires);
EXPECT_LE(util::now(), *res.expires);
EXPECT_TRUE(res.mustRevalidate);
diff --git a/test/storage/http_file_source.test.cpp b/test/storage/http_file_source.test.cpp
index 006b7a0fb3..093a5c1ced 100644
--- a/test/storage/http_file_source.test.cpp
+++ b/test/storage/http_file_source.test.cpp
@@ -23,8 +23,8 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(HTTP200)) {
auto req = fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, [&](Response res) {
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Hello World!", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Hello World!", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -43,7 +43,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(HTTP404)) {
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::NotFound, res.error->reason);
EXPECT_EQ("HTTP status code 404", res.error->message);
- EXPECT_FALSE(bool(res.data));
+ EXPECT_FALSE(res.data);
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -61,7 +61,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(HTTPTile404)) {
auto req = fs.request({ Resource::Tile, "http://127.0.0.1:3000/doesnotexist" }, [&](Response res) {
EXPECT_TRUE(res.noContent);
EXPECT_FALSE(bool(res.error));
- EXPECT_FALSE(bool(res.data));
+ EXPECT_FALSE(res.data);
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -79,7 +79,8 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(HTTP200EmptyData)) {
auto req = fs.request({ Resource::Unknown, "http://127.0.0.1:3000/empty-data" }, [&](Response res) {
EXPECT_FALSE(res.noContent);
EXPECT_FALSE(bool(res.error));
- EXPECT_EQ(*res.data, std::string());
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ(0u, res.data.uncompressedData()->size());
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -97,7 +98,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(HTTP204)) {
auto req = fs.request({ Resource::Unknown, "http://127.0.0.1:3000/no-content" }, [&](Response res) {
EXPECT_TRUE(res.noContent);
EXPECT_FALSE(bool(res.error));
- EXPECT_FALSE(bool(res.data));
+ EXPECT_FALSE(res.data);
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -116,7 +117,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(HTTP500)) {
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::Server, res.error->reason);
EXPECT_EQ("HTTP status code 500", res.error->message);
- EXPECT_FALSE(bool(res.data));
+ EXPECT_FALSE(res.data);
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -134,8 +135,8 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(ExpiresParsing)) {
auto req = fs.request({ Resource::Unknown,
"http://127.0.0.1:3000/test?modified=1420794326&expires=1420797926&etag=foo" }, [&](Response res) {
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Hello World!", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Hello World!", *res.data.uncompressedData());
EXPECT_EQ(Timestamp{ Seconds(1420797926) }, res.expires);
EXPECT_FALSE(res.mustRevalidate);
EXPECT_EQ(Timestamp{ Seconds(1420794326) }, res.modified);
@@ -152,8 +153,8 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(CacheControlParsing)) {
auto req = fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test?cachecontrol=max-age=120" }, [&](Response res) {
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Hello World!", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Hello World!", *res.data.uncompressedData());
EXPECT_GT(Seconds(2), util::abs(*res.expires - util::now() - Seconds(120))) << "Expiration date isn't about 120 seconds in the future";
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -181,8 +182,8 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(Load)) {
[&, i, current](Response res) {
reqs[i].reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ(std::string("Request ") + std::to_string(current), *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ(std::string("Request ") + std::to_string(current), *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
diff --git a/test/storage/local_file_source.test.cpp b/test/storage/local_file_source.test.cpp
index e1756f8e7d..76848f6682 100644
--- a/test/storage/local_file_source.test.cpp
+++ b/test/storage/local_file_source.test.cpp
@@ -37,8 +37,8 @@ TEST(LocalFileSource, EmptyFile) {
std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, toAbsoluteURL("empty") }, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("", *res.data.uncompressedData());
loop.stop();
});
@@ -53,8 +53,8 @@ TEST(LocalFileSource, NonEmptyFile) {
std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, toAbsoluteURL("nonempty") }, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("content is here\n", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("content is here\n", *res.data.uncompressedData());
loop.stop();
});
@@ -70,7 +70,7 @@ TEST(LocalFileSource, NonExistentFile) {
req.reset();
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::NotFound, res.error->reason);
- ASSERT_FALSE(res.data.get());
+ ASSERT_FALSE(res.data);
// Do not assert on platform-specific error message.
loop.stop();
});
@@ -88,7 +88,7 @@ TEST(LocalFileSource, InvalidURL) {
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::Other, res.error->reason);
EXPECT_EQ("Invalid file URL", res.error->message);
- ASSERT_FALSE(res.data.get());
+ ASSERT_FALSE(res.data);
loop.stop();
});
@@ -104,7 +104,7 @@ TEST(LocalFileSource, ReadDirectory) {
req.reset();
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::NotFound, res.error->reason);
- ASSERT_FALSE(res.data.get());
+ ASSERT_FALSE(res.data);
// Do not assert on platform-specific error message.
loop.stop();
});
@@ -120,8 +120,8 @@ TEST(LocalFileSource, URLEncoding) {
std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, toAbsoluteURL("%6eonempty") }, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("content is here\n", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("content is here\n", *res.data.uncompressedData());
loop.stop();
});
@@ -142,7 +142,7 @@ TEST(LocalFileSource, URLLimit) {
req.reset();
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::Other, res.error->reason);
- ASSERT_FALSE(res.data.get());
+ ASSERT_FALSE(res.data);
loop.stop();
});
diff --git a/test/storage/offline_database.test.cpp b/test/storage/offline_database.test.cpp
index 94daf59c02..23e70448b0 100644
--- a/test/storage/offline_database.test.cpp
+++ b/test/storage/offline_database.test.cpp
@@ -34,8 +34,8 @@ void deleteFile(const char* name) {
}
}
-void writeFile(const char* name, const std::string& data) {
- mbgl::util::write_file(name, data);
+void writeFile(const char* name, mbgl::Blob&& data) {
+ mbgl::util::writeFile(name, data);
}
} // namespace
@@ -79,7 +79,7 @@ TEST(OfflineDatabase, TEST_REQUIRES_WRITE(Invalid)) {
createDir("test/fixtures/offline_database");
deleteFile("test/fixtures/offline_database/invalid.db");
- writeFile("test/fixtures/offline_database/invalid.db", "this is an invalid file");
+ writeFile("test/fixtures/offline_database/invalid.db", Blob{ "this is an invalid file", false });
Log::setObserver(std::make_unique<FixtureLogObserver>());
@@ -124,23 +124,23 @@ TEST(OfflineDatabase, PutResource) {
Resource resource { Resource::Style, "http://example.com/" };
Response response;
- response.data = std::make_shared<std::string>("first");
+ response.data = Blob{ "first", false };
auto insertPutResult = db.put(resource, response);
EXPECT_TRUE(insertPutResult.first);
EXPECT_EQ(5u, insertPutResult.second);
auto insertGetResult = db.get(resource);
EXPECT_EQ(nullptr, insertGetResult->error.get());
- EXPECT_EQ("first", *insertGetResult->data);
+ EXPECT_EQ("first", *insertGetResult->data.uncompressedData());
- response.data = std::make_shared<std::string>("second");
+ response.data = Blob{ "second", false };
auto updatePutResult = db.put(resource, response);
EXPECT_FALSE(updatePutResult.first);
EXPECT_EQ(6u, updatePutResult.second);
auto updateGetResult = db.get(resource);
EXPECT_EQ(nullptr, updateGetResult->error.get());
- EXPECT_EQ("second", *updateGetResult->data);
+ EXPECT_EQ("second", *updateGetResult->data.uncompressedData());
}
TEST(OfflineDatabase, PutTile) {
@@ -158,23 +158,23 @@ TEST(OfflineDatabase, PutTile) {
};
Response response;
- response.data = std::make_shared<std::string>("first");
+ response.data = Blob{ "first", false };
auto insertPutResult = db.put(resource, response);
EXPECT_TRUE(insertPutResult.first);
EXPECT_EQ(5u, insertPutResult.second);
auto insertGetResult = db.get(resource);
EXPECT_EQ(nullptr, insertGetResult->error.get());
- EXPECT_EQ("first", *insertGetResult->data);
+ EXPECT_EQ("first", *insertGetResult->data.uncompressedData());
- response.data = std::make_shared<std::string>("second");
+ response.data = Blob{ "second", false };
auto updatePutResult = db.put(resource, response);
EXPECT_FALSE(updatePutResult.first);
EXPECT_EQ(6u, updatePutResult.second);
auto updateGetResult = db.get(resource);
EXPECT_EQ(nullptr, updateGetResult->error.get());
- EXPECT_EQ("second", *updateGetResult->data);
+ EXPECT_EQ("second", *updateGetResult->data.uncompressedData());
}
TEST(OfflineDatabase, PutResourceNoContent) {
@@ -190,7 +190,7 @@ TEST(OfflineDatabase, PutResourceNoContent) {
auto res = db.get(resource);
EXPECT_EQ(nullptr, res->error);
EXPECT_TRUE(res->noContent);
- EXPECT_FALSE(res->data.get());
+ EXPECT_FALSE(res->data);
}
TEST(OfflineDatabase, PutTileNotFound) {
@@ -213,7 +213,7 @@ TEST(OfflineDatabase, PutTileNotFound) {
auto res = db.get(resource);
EXPECT_EQ(nullptr, res->error);
EXPECT_TRUE(res->noContent);
- EXPECT_FALSE(res->data.get());
+ EXPECT_FALSE(res->data);
}
TEST(OfflineDatabase, CreateRegion) {
@@ -344,15 +344,15 @@ TEST(OfflineDatabase, TEST_REQUIRES_WRITE(ConcurrentUse)) {
thread2.join();
}
-static std::shared_ptr<std::string> randomString(size_t size) {
- auto result = std::make_shared<std::string>(size, 0);
+static mbgl::Blob randomBlob(size_t size) {
+ auto result = std::string(size, char());
std::mt19937 random;
for (size_t i = 0; i < size; i++) {
- (*result)[i] = random();
+ result[i] = random();
}
- return result;
+ return { std::move(result), false };
}
TEST(OfflineDatabase, PutReturnsSize) {
@@ -361,11 +361,11 @@ TEST(OfflineDatabase, PutReturnsSize) {
OfflineDatabase db(":memory:");
Response compressible;
- compressible.data = std::make_shared<std::string>(1024, 0);
+ compressible.data = Blob{ std::string(1024, char()), false };
EXPECT_EQ(17u, db.put(Resource::style("http://example.com/compressible"), compressible).second);
Response incompressible;
- incompressible.data = randomString(1024);
+ incompressible.data = randomBlob(1024);
EXPECT_EQ(1024u, db.put(Resource::style("http://example.com/incompressible"), incompressible).second);
Response noContent;
@@ -379,7 +379,7 @@ TEST(OfflineDatabase, PutEvictsLeastRecentlyUsedResources) {
OfflineDatabase db(":memory:", 1024 * 100);
Response response;
- response.data = randomString(1024);
+ response.data = randomBlob(1024);
for (uint32_t i = 1; i <= 100; i++) {
Resource resource = Resource::style("http://example.com/"s + util::toString(i));
@@ -398,7 +398,7 @@ TEST(OfflineDatabase, PutRegionResourceDoesNotEvict) {
OfflineRegion region = db.createRegion(definition, OfflineRegionMetadata());
Response response;
- response.data = randomString(1024);
+ response.data = randomBlob(1024);
for (uint32_t i = 1; i <= 100; i++) {
db.putRegionResource(region.getID(), Resource::style("http://example.com/"s + util::toString(i)), response);
@@ -414,7 +414,7 @@ TEST(OfflineDatabase, PutFailsWhenEvictionInsuffices) {
OfflineDatabase db(":memory:", 1024 * 100);
Response big;
- big.data = randomString(1024 * 100);
+ big.data = randomBlob(1024 * 100);
EXPECT_FALSE(db.put(Resource::style("http://example.com/big"), big).first);
EXPECT_FALSE(bool(db.get(Resource::style("http://example.com/big"))));
@@ -435,7 +435,7 @@ TEST(OfflineDatabase, GetRegionCompletedStatus) {
EXPECT_EQ(0u, status1.completedTileSize);
Response response;
- response.data = std::make_shared<std::string>("data");
+ response.data = Blob{ "data", false };
uint64_t styleSize = db.putRegionResource(region.getID(), Resource::style("http://example.com/"), response);
@@ -465,7 +465,7 @@ TEST(OfflineDatabase, HasRegionResource) {
EXPECT_FALSE(bool(db.hasRegionResource(region.getID(), Resource::style("http://example.com/20"))));
Response response;
- response.data = randomString(1024);
+ response.data = randomBlob(1024);
for (uint32_t i = 1; i <= 100; i++) {
db.putRegionResource(region.getID(), Resource::style("http://example.com/"s + util::toString(i)), response);
@@ -493,7 +493,7 @@ TEST(OfflineDatabase, HasRegionResourceTile) {
};
Response response;
- response.data = std::make_shared<std::string>("first");
+ response.data = Blob{ "first", false };
EXPECT_FALSE(bool(db.hasRegionResource(region.getID(), resource)));
db.putRegionResource(region.getID(), resource, response);
@@ -522,7 +522,7 @@ TEST(OfflineDatabase, OfflineMapboxTileCount) {
Resource mapboxTile2 = Resource::tile("mapbox://tiles/2", 1.0, 0, 0, 1, Tileset::Scheme::XYZ);
Response response;
- response.data = std::make_shared<std::string>("data");
+ response.data = Blob{ "data", false };
// Count is initially zero.
EXPECT_EQ(0u, db.getOfflineMapboxTileCount());
@@ -609,7 +609,7 @@ TEST(OfflineDatabase, MigrateFromV2Schema) {
// v2.db is a v2 database containing a single offline region with a small number of resources.
deleteFile("test/fixtures/offline_database/migrated.db");
- writeFile("test/fixtures/offline_database/migrated.db", util::read_file("test/fixtures/offline_database/v2.db"));
+ writeFile("test/fixtures/offline_database/migrated.db", util::readFile("test/fixtures/offline_database/v2.db"));
{
OfflineDatabase db("test/fixtures/offline_database/migrated.db", 0);
@@ -630,7 +630,7 @@ TEST(OfflineDatabase, MigrateFromV3Schema) {
// v3.db is a v3 database, migrated from v2.
deleteFile("test/fixtures/offline_database/migrated.db");
- writeFile("test/fixtures/offline_database/migrated.db", util::read_file("test/fixtures/offline_database/v3.db"));
+ writeFile("test/fixtures/offline_database/migrated.db", util::readFile("test/fixtures/offline_database/v3.db"));
{
OfflineDatabase db("test/fixtures/offline_database/migrated.db", 0);
@@ -649,7 +649,7 @@ TEST(OfflineDatabase, MigrateFromV4Schema) {
// v4.db is a v4 database, migrated from v2 & v3. This database used `journal_mode = WAL` and `synchronous = NORMAL`.
deleteFile("test/fixtures/offline_database/migrated.db");
- writeFile("test/fixtures/offline_database/migrated.db", util::read_file("test/fixtures/offline_database/v4.db"));
+ writeFile("test/fixtures/offline_database/migrated.db", util::readFile("test/fixtures/offline_database/v4.db"));
{
OfflineDatabase db("test/fixtures/offline_database/migrated.db", 0);
@@ -675,7 +675,7 @@ TEST(OfflineDatabase, MigrateFromV5Schema) {
// v5.db is a v5 database, migrated from v2, v3 & v4.
deleteFile("test/fixtures/offline_database/migrated.db");
- writeFile("test/fixtures/offline_database/migrated.db", util::read_file("test/fixtures/offline_database/v5.db"));
+ writeFile("test/fixtures/offline_database/migrated.db", util::readFile("test/fixtures/offline_database/v5.db"));
{
OfflineDatabase db("test/fixtures/offline_database/migrated.db", 0);
@@ -703,7 +703,7 @@ TEST(OfflineDatabase, DowngradeSchema) {
// and recreated with the current schema.
deleteFile("test/fixtures/offline_database/migrated.db");
- writeFile("test/fixtures/offline_database/migrated.db", util::read_file("test/fixtures/offline_database/v999.db"));
+ writeFile("test/fixtures/offline_database/migrated.db", util::readFile("test/fixtures/offline_database/v999.db"));
{
OfflineDatabase db("test/fixtures/offline_database/migrated.db", 0);
diff --git a/test/storage/offline_download.test.cpp b/test/storage/offline_download.test.cpp
index 57780eba40..f7528fb024 100644
--- a/test/storage/offline_download.test.cpp
+++ b/test/storage/offline_download.test.cpp
@@ -14,7 +14,6 @@
#include <iostream>
using namespace mbgl;
-using namespace std::literals::string_literals;
class MockObserver : public OfflineRegionObserver {
public:
@@ -50,10 +49,11 @@ public:
Response response(const std::string& path) {
Response result;
- result.data = std::make_shared<std::string>(util::read_file("test/fixtures/offline_download/"s + path));
- size_t uncompressed = result.data->size();
- size_t compressed = util::compress(*result.data).size();
- size += std::min(uncompressed, compressed);
+ result.data = util::readFile("test/fixtures/offline_download/" + path);
+ const auto data = util::isCompressible(*result.data.uncompressedData())
+ ? result.data.compressedData()
+ : result.data.uncompressedData();
+ size += data->size();
return result;
}
};
diff --git a/test/storage/online_file_source.test.cpp b/test/storage/online_file_source.test.cpp
index 70bfe3ac95..9744c0a02e 100644
--- a/test/storage/online_file_source.test.cpp
+++ b/test/storage/online_file_source.test.cpp
@@ -33,8 +33,8 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(CancelMultiple)) {
std::unique_ptr<AsyncRequest> req = fs.request(resource, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Hello World!", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Hello World!", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -61,7 +61,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(TemporaryError)) {
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::Server, res.error->reason);
EXPECT_EQ("HTTP status code 500", res.error->message);
- ASSERT_FALSE(bool(res.data));
+ ASSERT_FALSE(res.data);
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -72,8 +72,8 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(TemporaryError)) {
EXPECT_LT(0.99, duration) << "Backoff timer didn't wait 1 second";
EXPECT_GT(1.2, duration) << "Backoff timer fired too late";
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Hello World!", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Hello World!", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -100,7 +100,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(ConnectionError)) {
EXPECT_GT(wait + 0.2, duration) << "Backoff timer fired too late";
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::Connection, res.error->reason);
- ASSERT_FALSE(res.data.get());
+ ASSERT_FALSE(res.data);
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -127,8 +127,8 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(Timeout)) {
std::unique_ptr<AsyncRequest> req = fs.request(resource, [&](Response res) {
counter++;
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Hello World!", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Hello World!", *res.data.uncompressedData());
EXPECT_TRUE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -244,8 +244,8 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(Load)) {
[&, i, current](Response res) {
reqs[i].reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ(std::string("Request ") + std::to_string(current), *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ(std::string("Request ") + std::to_string(current), *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -282,8 +282,8 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(NetworkStatusChange)) {
std::unique_ptr<AsyncRequest> req = fs.request(resource, [&](Response res) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("Response", *res.data);
+ ASSERT_TRUE(res.data);
+ EXPECT_EQ("Response", *res.data.uncompressedData());
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -322,7 +322,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(NetworkStatusChangePreempt)) {
}
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::Connection, res.error->reason);
- ASSERT_FALSE(res.data.get());
+ ASSERT_FALSE(res.data);
EXPECT_FALSE(bool(res.expires));
EXPECT_FALSE(res.mustRevalidate);
EXPECT_FALSE(bool(res.modified));
@@ -361,7 +361,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(NetworkStatusOnlineOffline)) {
req.reset();
EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
+ ASSERT_TRUE(res.data);
EXPECT_EQ(NetworkStatus::Get(), NetworkStatus::Status::Online) << "Triggered before set back to Online";
diff --git a/test/style/expression/expression.test.cpp b/test/style/expression/expression.test.cpp
index 694569695c..c40f3fb863 100644
--- a/test/style/expression/expression.test.cpp
+++ b/test/style/expression/expression.test.cpp
@@ -16,8 +16,9 @@ using namespace mbgl;
using namespace mbgl::style;
TEST(Expression, IsExpression) {
+ const auto file = util::readFile("mapbox-gl-js/src/style-spec/reference/v8.json").uncompressedData();
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> spec;
- spec.Parse<0>(util::read_file("mapbox-gl-js/src/style-spec/reference/v8.json").c_str());
+ spec.Parse<0>(file->c_str());
ASSERT_FALSE(spec.HasParseError());
ASSERT_TRUE(spec.IsObject() &&
spec.HasMember("expression_name") &&
@@ -44,8 +45,9 @@ TEST_P(ExpressionEqualityTest, ExpressionEquality) {
std::string error;
auto parse = [&](std::string filename, std::string& error_) -> std::unique_ptr<expression::Expression> {
+ const auto file = util::readFile(filename).uncompressedData();
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> document;
- document.Parse<0>(util::read_file(filename).c_str());
+ document.Parse<0>(file->c_str());
assert(!document.HasParseError());
const JSValue* expression = &document;
expression::ParsingContext ctx;
diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp
index 6cb01146f6..94eb66a789 100644
--- a/test/style/source.test.cpp
+++ b/test/style/source.test.cpp
@@ -121,7 +121,7 @@ TEST(Source, LoadingCorrupt) {
test.fileSource.sourceResponse = [&] (const Resource& resource) {
EXPECT_EQ("url", resource.url);
Response response;
- response.data = std::make_unique<std::string>("CORRUPTED");
+ response.data = Blob{ "CORRUPTED", false };
return response;
};
@@ -375,7 +375,7 @@ TEST(Source, RasterTileCorrupt) {
test.fileSource.tileResponse = [&] (const Resource&) {
Response response;
- response.data = std::make_unique<std::string>("CORRUPTED");
+ response.data = Blob{ "CORRUPTED", false };
return response;
};
@@ -412,7 +412,7 @@ TEST(Source, RasterDEMTileCorrupt) {
test.fileSource.tileResponse = [&] (const Resource&) {
Response response;
- response.data = std::make_unique<std::string>("CORRUPTED");
+ response.data = Blob{ "CORRUPTED", false };
return response;
};
@@ -449,7 +449,7 @@ TEST(Source, VectorTileCorrupt) {
test.fileSource.tileResponse = [&] (const Resource&) {
Response response;
- response.data = std::make_unique<std::string>("CORRUPTED");
+ response.data = Blob{ "CORRUPTED", false };
return response;
};
@@ -610,9 +610,10 @@ TEST(Source, RasterTileAttribution) {
test.fileSource.sourceResponse = [&] (const Resource& resource) {
EXPECT_EQ("url", resource.url);
Response response;
- response.data = std::make_unique<std::string>(R"TILEJSON({ "tilejson": "2.1.0", "attribution": ")TILEJSON" +
- mapboxOSM +
- R"TILEJSON(", "tiles": [ "tiles" ] })TILEJSON");
+ response.data =
+ Blob{ R"TILEJSON({ "tilejson": "2.1.0", "attribution": ")TILEJSON" + mapboxOSM +
+ R"TILEJSON(", "tiles": [ "tiles" ] })TILEJSON",
+ false };
return response;
};
@@ -653,9 +654,10 @@ TEST(Source, RasterDEMTileAttribution) {
test.fileSource.sourceResponse = [&] (const Resource& resource) {
EXPECT_EQ("url", resource.url);
Response response;
- response.data = std::make_unique<std::string>(R"TILEJSON({ "tilejson": "2.1.0", "attribution": ")TILEJSON" +
- mapbox +
- R"TILEJSON(", "tiles": [ "tiles" ] })TILEJSON");
+ response.data =
+ Blob{ R"TILEJSON({ "tilejson": "2.1.0", "attribution": ")TILEJSON" + mapbox +
+ R"TILEJSON(", "tiles": [ "tiles" ] })TILEJSON",
+ false };
return response;
};
@@ -684,7 +686,7 @@ TEST(Source, GeoJSonSourceUrlUpdate) {
test.fileSource.sourceResponse = [&] (const Resource& resource) {
EXPECT_EQ("url", resource.url);
Response response;
- response.data = std::make_unique<std::string>(R"({"geometry": {"type": "Point", "coordinates": [1.1, 1.1]}, "type": "Feature", "properties": {}})");
+ response.data = Blob{ R"({"geometry": {"type": "Point", "coordinates": [1.1, 1.1]}, "type": "Feature", "properties": {}})", false };
return response;
};
@@ -714,7 +716,7 @@ TEST(Source, ImageSourceImageUpdate) {
test.fileSource.response = [&] (const Resource& resource) {
EXPECT_EQ("http://url", resource.url);
Response response;
- response.data = std::make_unique<std::string>(util::read_file("test/fixtures/image/no_profile.png"));
+ response.data = util::readFile("test/fixtures/image/no_profile.png");
return response;
};
test.styleObserver.sourceChanged = [&] (Source&) {
diff --git a/test/style/style.test.cpp b/test/style/style.test.cpp
index 9bdab37ac6..91ecbe8d22 100644
--- a/test/style/style.test.cpp
+++ b/test/style/style.test.cpp
@@ -23,27 +23,27 @@ TEST(Style, Properties) {
StubFileSource fileSource;
Style::Impl style { threadPool, fileSource, 1.0 };
- style.loadJSON(R"STYLE({"name": "Test"})STYLE");
+ style.loadJSON(Blob{ R"STYLE({"name": "Test"})STYLE", false });
ASSERT_EQ("Test", style.getName());
- style.loadJSON(R"STYLE({"center": [10, 20]})STYLE");
+ style.loadJSON(Blob{ R"STYLE({"center": [10, 20]})STYLE", false });
ASSERT_EQ("", style.getName());
ASSERT_EQ((LatLng{20, 10}), *style.getDefaultCamera().center);
- style.loadJSON(R"STYLE({"bearing": 24})STYLE");
+ style.loadJSON(Blob{ R"STYLE({"bearing": 24})STYLE", false });
ASSERT_EQ("", style.getName());
ASSERT_EQ(LatLng {}, *style.getDefaultCamera().center);
ASSERT_EQ(24, *style.getDefaultCamera().angle);
- style.loadJSON(R"STYLE({"zoom": 13.3})STYLE");
+ style.loadJSON(Blob{ R"STYLE({"zoom": 13.3})STYLE", false });
ASSERT_EQ("", style.getName());
ASSERT_EQ(13.3, *style.getDefaultCamera().zoom);
- style.loadJSON(R"STYLE({"pitch": 60})STYLE");
+ style.loadJSON(Blob{ R"STYLE({"pitch": 60})STYLE", false });
ASSERT_EQ("", style.getName());
ASSERT_EQ(60, *style.getDefaultCamera().pitch);
- style.loadJSON(R"STYLE({"name": 23, "center": {}, "bearing": "north", "zoom": null, "pitch": "wide"})STYLE");
+ style.loadJSON(Blob{ R"STYLE({"name": 23, "center": {}, "bearing": "north", "zoom": null, "pitch": "wide"})STYLE", false });
ASSERT_EQ("", style.getName());
ASSERT_EQ(LatLng {}, *style.getDefaultCamera().center);
ASSERT_EQ(0, *style.getDefaultCamera().zoom);
@@ -58,7 +58,7 @@ TEST(Style, DuplicateSource) {
StubFileSource fileSource;
Style::Impl style { threadPool, fileSource, 1.0 };
- style.loadJSON(util::read_file("test/fixtures/resources/style-unused-sources.json"));
+ style.loadJSON(util::readFile("test/fixtures/resources/style-unused-sources.json"));
style.addSource(std::make_unique<VectorSource>("sourceId", "mapbox://mapbox.mapbox-terrain-v2"));
@@ -80,7 +80,7 @@ TEST(Style, RemoveSourceInUse) {
StubFileSource fileSource;
Style::Impl style { threadPool, fileSource, 1.0 };
- style.loadJSON(util::read_file("test/fixtures/resources/style-unused-sources.json"));
+ style.loadJSON(util::readFile("test/fixtures/resources/style-unused-sources.json"));
style.addSource(std::make_unique<VectorSource>("sourceId", "mapbox://mapbox.mapbox-terrain-v2"));
style.addLayer(std::make_unique<LineLayer>("layerId", "sourceId"));
diff --git a/test/style/style_layer.test.cpp b/test/style/style_layer.test.cpp
index 77acca2868..36fd7de3f4 100644
--- a/test/style/style_layer.test.cpp
+++ b/test/style/style_layer.test.cpp
@@ -276,7 +276,7 @@ TEST(Layer, DuplicateLayer) {
ThreadPool threadPool{ 1 };
StubFileSource fileSource;
Style::Impl style { threadPool, fileSource, 1.0 };
- style.loadJSON(util::read_file("test/fixtures/resources/style-unused-sources.json"));
+ style.loadJSON(util::readFile("test/fixtures/resources/style-unused-sources.json"));
// Add initial layer
style.addLayer(std::make_unique<LineLayer>("line", "unusedsource"));
diff --git a/test/style/style_parser.test.cpp b/test/style/style_parser.test.cpp
index 43b982c3b9..c6b78cf6d6 100644
--- a/test/style/style_parser.test.cpp
+++ b/test/style/style_parser.test.cpp
@@ -24,16 +24,18 @@ class StyleParserTest : public ::testing::TestWithParam<std::string> {};
TEST_P(StyleParserTest, ParseStyle) {
const std::string base = std::string("test/fixtures/style_parser/") + GetParam();
+ const auto infoFile = util::readFile(base + ".info.json").uncompressedData();
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> infoDoc;
- infoDoc.Parse<0>(util::read_file(base + ".info.json").c_str());
+ infoDoc.Parse<0>(infoFile->c_str());
ASSERT_FALSE(infoDoc.HasParseError());
ASSERT_TRUE(infoDoc.IsObject());
auto observer = new FixtureLogObserver();
Log::setObserver(std::unique_ptr<Log::Observer>(observer));
+ const auto styleFile = util::readFile(base + ".style.json").uncompressedData();
style::Parser parser;
- auto error = parser.parse(util::read_file(base + ".style.json"));
+ auto error = parser.parse(*styleFile);
if (error) {
Log::Error(Event::ParseStyle, "Failed to parse style: %s", util::toString(error).c_str());
@@ -95,7 +97,7 @@ INSTANTIATE_TEST_CASE_P(StyleParser, StyleParserTest, ::testing::ValuesIn([] {
TEST(StyleParser, FontStacks) {
style::Parser parser;
- parser.parse(util::read_file("test/fixtures/style_parser/font_stacks.json"));
+ parser.parse(*util::readFile("test/fixtures/style_parser/font_stacks.json").uncompressedData());
auto result = parser.fontStacks();
ASSERT_EQ(3u, result.size());
ASSERT_EQ(FontStack({"a"}), result[0]);
diff --git a/test/text/glyph_manager.test.cpp b/test/text/glyph_manager.test.cpp
index a96e1b970c..be1c13eefc 100644
--- a/test/text/glyph_manager.test.cpp
+++ b/test/text/glyph_manager.test.cpp
@@ -92,7 +92,7 @@ TEST(GlyphManager, LoadingSuccess) {
test.fileSource.glyphsResponse = [&] (const Resource& resource) {
EXPECT_EQ(Resource::Kind::Glyphs, resource.kind);
Response response;
- response.data = std::make_shared<std::string>(util::read_file("test/fixtures/resources/glyphs.pbf"));
+ response.data = util::readFile("test/fixtures/resources/glyphs.pbf");
return response;
};
@@ -163,7 +163,7 @@ TEST(GlyphManager, LoadingCorrupted) {
test.fileSource.glyphsResponse = [&] (const Resource&) {
Response response;
- response.data = std::make_unique<std::string>("CORRUPTED");
+ response.data = Blob{ "CORRUPTED", false };
return response;
};
@@ -260,7 +260,7 @@ TEST(GlyphManager, LoadingInvalid) {
test.fileSource.glyphsResponse = [&] (const Resource& resource) {
EXPECT_EQ(Resource::Kind::Glyphs, resource.kind);
Response response;
- response.data = std::make_shared<std::string>(util::read_file("test/fixtures/resources/fake_glyphs-0-255.pbf"));
+ response.data = util::readFile("test/fixtures/resources/fake_glyphs-0-255.pbf");
return response;
};
@@ -320,7 +320,7 @@ TEST(GlyphManager, ImmediateFileSource) {
test.fileSource.glyphsResponse = [&] (const Resource&) {
Response response;
- response.data = std::make_shared<std::string>(util::read_file("test/fixtures/resources/glyphs.pbf"));
+ response.data = util::readFile("test/fixtures/resources/glyphs.pbf");
return response;
};
diff --git a/test/text/glyph_pbf.test.cpp b/test/text/glyph_pbf.test.cpp
index c222ec1dd9..8c6b8a2028 100644
--- a/test/text/glyph_pbf.test.cpp
+++ b/test/text/glyph_pbf.test.cpp
@@ -7,7 +7,7 @@ using namespace mbgl;
TEST(GlyphPBF, Parsing) {
// The fake glyphs contain a number of invalid glyphs, which should be skipped by the parser.
- auto sdfs = parseGlyphPBF(GlyphRange { 0, 255 }, util::read_file("test/fixtures/resources/fake_glyphs-0-255.pbf"));
+ auto sdfs = parseGlyphPBF(GlyphRange { 0, 255 }, util::readFile("test/fixtures/resources/fake_glyphs-0-255.pbf"));
EXPECT_TRUE(sdfs.size() == 1);
auto& sdf = sdfs[0];
diff --git a/test/text/local_glyph_rasterizer.test.cpp b/test/text/local_glyph_rasterizer.test.cpp
index 84c685d66f..49ef1e18ef 100644
--- a/test/text/local_glyph_rasterizer.test.cpp
+++ b/test/text/local_glyph_rasterizer.test.cpp
@@ -60,10 +60,10 @@ TEST(LocalGlyphRasterizer, PingFang) {
test.fileSource.glyphsResponse = [&] (const Resource& resource) {
EXPECT_EQ(Resource::Kind::Glyphs, resource.kind);
Response response;
- response.data = std::make_shared<std::string>(util::read_file("test/fixtures/resources/glyphs.pbf"));
+ response.data = util::readFile("test/fixtures/resources/glyphs.pbf");
return response;
};
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/local_glyphs/mixed.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/local_glyphs/mixed.json"));
test.checkRendering("ping_fang");
}
@@ -77,10 +77,10 @@ TEST(LocalGlyphRasterizer, NoLocal) {
test.fileSource.glyphsResponse = [&] (const Resource& resource) {
EXPECT_EQ(Resource::Kind::Glyphs, resource.kind);
Response response;
- response.data = std::make_shared<std::string>(util::read_file("test/fixtures/resources/glyphs.pbf"));
+ response.data = util::readFile("test/fixtures/resources/glyphs.pbf");
return response;
};
- test.map.getStyle().loadJSON(util::read_file("test/fixtures/local_glyphs/mixed.json"));
+ test.map.getStyle().loadJSON(util::readFile("test/fixtures/local_glyphs/mixed.json"));
test.checkRendering("no_local");
}
diff --git a/test/util/image.test.cpp b/test/util/image.test.cpp
index f4a6473040..f9389a694a 100644
--- a/test/util/image.test.cpp
+++ b/test/util/image.test.cpp
@@ -35,7 +35,7 @@ TEST(Image, PNGRoundTripAlpha) {
}
TEST(Image, PNGReadNoProfile) {
- PremultipliedImage image = decodeImage(util::read_file("test/fixtures/image/no_profile.png"));
+ PremultipliedImage image = decodeImage(util::readFile("test/fixtures/image/no_profile.png"));
EXPECT_EQ(128, image.data[0]);
EXPECT_EQ(0, image.data[1]);
EXPECT_EQ(0, image.data[2]);
@@ -43,7 +43,7 @@ TEST(Image, PNGReadNoProfile) {
}
TEST(Image, PNGReadNoProfileAlpha) {
- PremultipliedImage image = decodeImage(util::read_file("test/fixtures/image/no_profile_alpha.png"));
+ PremultipliedImage image = decodeImage(util::readFile("test/fixtures/image/no_profile_alpha.png"));
EXPECT_EQ(64, image.data[0]);
EXPECT_EQ(0, image.data[1]);
EXPECT_EQ(0, image.data[2]);
@@ -51,7 +51,7 @@ TEST(Image, PNGReadNoProfileAlpha) {
}
TEST(Image, PNGReadProfile) {
- PremultipliedImage image = decodeImage(util::read_file("test/fixtures/image/profile.png"));
+ PremultipliedImage image = decodeImage(util::readFile("test/fixtures/image/profile.png"));
EXPECT_EQ(128, image.data[0]);
EXPECT_EQ(0, image.data[1]);
EXPECT_EQ(0, image.data[2]);
@@ -59,7 +59,7 @@ TEST(Image, PNGReadProfile) {
}
TEST(Image, PNGReadProfileAlpha) {
- PremultipliedImage image = decodeImage(util::read_file("test/fixtures/image/profile_alpha.png"));
+ PremultipliedImage image = decodeImage(util::readFile("test/fixtures/image/profile_alpha.png"));
EXPECT_EQ(64, image.data[0]);
EXPECT_EQ(0, image.data[1]);
EXPECT_EQ(0, image.data[2]);
@@ -67,20 +67,20 @@ TEST(Image, PNGReadProfileAlpha) {
}
TEST(Image, PNGTile) {
- PremultipliedImage image = decodeImage(util::read_file("test/fixtures/image/tile.png"));
+ PremultipliedImage image = decodeImage(util::readFile("test/fixtures/image/tile.png"));
EXPECT_EQ(256u, image.size.width);
EXPECT_EQ(256u, image.size.height);
}
TEST(Image, JPEGTile) {
- PremultipliedImage image = decodeImage(util::read_file("test/fixtures/image/tile.jpeg"));
+ PremultipliedImage image = decodeImage(util::readFile("test/fixtures/image/tile.jpeg"));
EXPECT_EQ(256u, image.size.width);
EXPECT_EQ(256u, image.size.height);
}
#if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(QT_IMAGE_DECODERS)
TEST(Image, WebPTile) {
- PremultipliedImage image = decodeImage(util::read_file("test/fixtures/image/tile.webp"));
+ PremultipliedImage image = decodeImage(util::readFile("test/fixtures/image/tile.webp"));
EXPECT_EQ(256u, image.size.width);
EXPECT_EQ(256u, image.size.height);
}
diff --git a/test/util/memory.test.cpp b/test/util/memory.test.cpp
index 6befb521f0..4f14c762b4 100644
--- a/test/util/memory.test.cpp
+++ b/test/util/memory.test.cpp
@@ -45,9 +45,7 @@ private:
if (it != cache.end()) {
result.data = it->second;
} else {
- auto data = std::make_shared<std::string>(
- util::read_file("test/fixtures/resources/"s + path));
-
+ auto data = util::readFile("test/fixtures/resources/" + path);
cache.insert(it, std::make_pair(path, data));
result.data = data;
}
@@ -63,7 +61,7 @@ private:
}
};
- std::unordered_map<std::string, std::shared_ptr<std::string>> cache;
+ std::unordered_map<std::string, Blob> cache;
};
TEST(Memory, Vector) {