aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2018-02-20 15:06:26 +0100
committerKonstantin Käfer <mail@kkaefer.com>2018-02-21 14:50:13 +0100
commit021e1ae596440cfdee5ffe75907b76069ae44307 (patch)
treeebf15ff8a72e5f14291ba37b6f297ca9a738eea4
parent06213d9145d3b20b63e235cc25678fd76dc296d0 (diff)
[core] introduce Blob for compressed and uncompressed dataupstream/blob
- Blob is a wrapper type for a shared_ptr<const string> that has accessor functions for getting compressed and uncompressed data - Moved util::writeFile, util::readFile, util::compress, util::uncompress, decodeImage, and encodePNG to the Blob interface - Added Blob support to Request and file sources - Added Blob support to VectorTile objects - Added support for gzip decoding to util::uncompress - We're no longer compressing WebP, PNG, and JPEG data when storing in the OfflineDatabase - Android's HTTPRequest returns compressed Blobs by default One caveat is that our previous decompress function didn't support gzip, so once users upgrade to this version, their offline cache may contain both zlib-compressed data and gzip-compressed data, but older versions won't be able to decompress gzip data. On the other hand, we don't support downgrading SDKs anyway, so this shouldn't be a problem. To be on the safe side, we could bump the user_version of the SQLite DB.
-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 769458552..f9cbbff32 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 a1b557777..8c783c6a0 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 24623dbda..fab22ae38 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 6ceb32eb0..4b15ced9a 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 f24482e30..a0523a6f4 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 318fa389f..d9da494e4 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 508400141..81a84effb 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 d6fdbd8f2..dffdbf99e 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 000000000..df8fddc77
--- /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 93a3ddb8b..cbce76468 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 4887058f7..1cb3cca8c 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 000000000..4debc33ee
--- /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 caee493e6..942b88f1f 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 aa65e3ff4..404177ba9 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 8eb9416e9..7602c1914 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 2a33944b1..dd98a3a6c 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 67fc13220..c52aad640 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 4a16ad82f..6840740c4 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 3a5adcca0..f08fb9a25 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 28c663302..f0d54f81b 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 3063bf88a..0b57a6dce 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 cb602995a..5dcd28fac 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 a9c442c2d..1a0ae577b 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 447c6bcd6..4fde1898c 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 0635e86d8..9a8f5ae51 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 65c209718..d7022f1c8 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 91b544a9e..fba1a3c23 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 ba504c1f9..d8fe8c646 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 d685109b9..fe77df8c0 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 9ef905215..d3297b8eb 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 07fae5945..c29c2ec89 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 432767091..58f29ed2a 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 ac14df022..a4f6f6a9d 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 de16710f7..7b2b57fd1 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 ea3f388bd..4e2143ba8 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 414b65255..e054d8848 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 a5c92514c..ff45b02ef 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 2a56b346a..607cdd6ba 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 3b54ec194..64e3a355d 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 da629194b..e5943bb5d 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 8690f3fd6..2d3ea45aa 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 93d6dfd9a..3bc8add16 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 4bded33d5..a2e3f331e 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 d61e07d14..4f2e38be2 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 1a36e3e99..c93d97ba7 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 f602818d3..b17f4cc45 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 207dd2ee6..9bc8495d5 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 4e3478322..48308ccbc 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 fa268da0e..5be1b5441 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 53f29d660..c3c47567a 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 ccdd453c7..d88622f1b 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 bd8631fc5..82f421ecd 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 d330b3120..a952ccb8c 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 3dc222bfa..9dc270439 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 313041890..37574eff1 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 cfaf803f7..77ea5ec2c 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 28a28b411..0c82343ce 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 5db298cf4..10f22e378 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 0c8dd7596..0c5b3e7bf 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 7338e578c..ec5aba380 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 5a8222bc2..5b9bce1a1 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 ff23d4493..4bc9830fd 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 e25329119..c1fa6caa9 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 4afa87642..d0dd8918a 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 520973c3c..c56da82d0 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 1b2963826..48b3b7c87 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 0756d3e52..a815f31e4 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 7dae414fe..87abf2f59 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 2d4a01bda..eaa91dc9c 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 48beaf9d0..ce120e97c 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 000000000..53d764400
--- /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 30e813cbb..4d4e094f0 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 6a6ed7b25..2dc6cabf0 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 847271acf..b74f89485 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 07257851a..8b25fa482 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 83d1543a0..3397bef9e 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 eb1d7e0d3..5eaa73a37 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 c67ff9064..43067dd57 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 ca6abac8c..1055eda5a 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 df9b6ff2a..a16d5322d 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 179ce5de5..157732d72 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 9b34ea89b..bb0ff2a20 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 4c82b2c96..7cb8ea154 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 a5cf7b6e3..7fc2acbf7 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 ebe1bcd72..e1d9030d4 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 369157226..d773afd53 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 529e4c75e..14d5f6586 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 028a0a9d5..82d2af6cd 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 978a41a30..694d56be6 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 c11d44227..f74a515d8 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 006b7a0fb..093a5c1ce 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 e1756f8e7..76848f668 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 94daf59c0..23e70448b 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 57780eba4..f7528fb02 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 70bfe3ac9..9744c0a02 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 694569695..c40f3fb86 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 6cb01146f..94eb66a78 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 9bdab37ac..91ecbe8d2 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 77acca286..36fd7de3f 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 43b982c3b..c6b78cf6d 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 a96e1b970..be1c13eef 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 c222ec1dd..8c6b8a202 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 84c685d66..49ef1e18e 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 f4a647304..f9389a694 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 6befb521f..4f14c762b 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) {