Blob Blame Raw
From e366e583018ab1f31f1ff51db5448cb886b0bc45 Mon Sep 17 00:00:00 2001
From: James Westman <flyingpimonster@flyingpimonster.net>
Date: Sat, 1 Dec 2018 13:54:01 -0600
Subject: [PATCH] Fix issues with parsing JSON from buffers

Does so in a way that works on both 3.28 and 3.30. Adds a function to
`utils.js` to detect whether an object is a Uint8Array or ByteArray and
convert it to a string accordingly.

Closes #139.
---
 scripts/extractPoiTypesFromID.js | 14 ++++++++++++--
 src/geoJSONShapeLayer.js         |  3 ++-
 src/osmTypes.js                  |  4 ++--
 src/placeStore.js                |  2 +-
 src/service.js                   |  2 +-
 src/utils.js                     | 14 +++++++++++++-
 6 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/scripts/extractPoiTypesFromID.js b/scripts/extractPoiTypesFromID.js
index 10689f0..73dc226 100755
--- a/scripts/extractPoiTypesFromID.js
+++ b/scripts/extractPoiTypesFromID.js
@@ -31,6 +31,8 @@
 
 const Gio = imports.gi.Gio;
 
+const ByteArray = imports.byteArray;
+
 const PRESETS_PATH = 'data/presets/presets';
 const LOCALES_PATH = 'dist/locales';
 const PRESET_TYPES = [ 'aeroway',
@@ -43,10 +45,18 @@ const PRESET_TYPES = [ 'aeroway',
 
 const OUTPUT = {};
 
+function getBufferText(buffer) {
+    if (buffer instanceof Uint8Array) {
+        return ByteArray.toString(buffer);
+    } else {
+        return buffer.toString();
+    }
+}
+
 function parseJson(dirPath, fileName) {
     let file = Gio.File.new_for_path(dirPath + '/' + fileName);
     let [status, buffer] = file.load_contents(null);
-    let {tags, name} = JSON.parse(buffer);
+    let {tags, name} = JSON.parse(getBufferText(buffer));
 
     for (let key in tags) {
         let value = tags[key];
@@ -82,7 +92,7 @@ function processTypes(basePath) {
 function processLocale(dirPath, fileName) {
     let file = Gio.File.new_for_path(dirPath + '/' + fileName);
     let [status, buffer] = file.load_contents(null);
-    let object = JSON.parse(buffer);
+    let object = JSON.parse(getBufferText(buffer));
     let lang = fileName.substring(0, fileName.indexOf('.json'));
 
     for (let type in OUTPUT) {
diff --git a/src/geoJSONShapeLayer.js b/src/geoJSONShapeLayer.js
index 46dcc47..5b9b1b1 100644
--- a/src/geoJSONShapeLayer.js
+++ b/src/geoJSONShapeLayer.js
@@ -21,6 +21,7 @@ const GObject = imports.gi.GObject;
 
 const GeoJSONSource = imports.geoJSONSource;
 const ShapeLayer = imports.shapeLayer;
+const Utils = imports.utils;
 
 var GeoJSONShapeLayer = GObject.registerClass(
 class GeoJSONShapeLayer extends ShapeLayer.ShapeLayer {
@@ -44,7 +45,7 @@ class GeoJSONShapeLayer extends ShapeLayer.ShapeLayer {
     }
 
     _parseContent() {
-        this._mapSource.parse(JSON.parse(this._fileContents));
+        this._mapSource.parse(JSON.parse(Utils.getBufferText(this._fileContents)));
     }
 });
 
diff --git a/src/osmTypes.js b/src/osmTypes.js
index 40980c6..8020043 100644
--- a/src/osmTypes.js
+++ b/src/osmTypes.js
@@ -29,7 +29,7 @@ const _NUM_RECENT_TYPES = 10;
 
 const _file = Gio.file_new_for_uri('resource://org/gnome/Maps/osm-types.json');
 const [_status, _buffer] = _file.load_contents(null);
-const OSM_TYPE_MAP = JSON.parse(_buffer);
+const OSM_TYPE_MAP = JSON.parse(Utils.getBufferText(_buffer));
 
 /* Lists the OSM tags we base our notion of location types on */
 var OSM_TYPE_TAGS = ['aeroway', 'amenity', 'leisure', 'office', 'place', 'shop', 'tourism' ];
@@ -128,7 +128,7 @@ var RecentTypesStore = class RecentTypesStore {
             return;
         }
 
-        this._recentTypes = JSON.parse(buffer);
+        this._recentTypes = JSON.parse(Utils.getBufferText(buffer));
     }
 
     _save() {
diff --git a/src/placeStore.js b/src/placeStore.js
index 7b3abc7..3757509 100644
--- a/src/placeStore.js
+++ b/src/placeStore.js
@@ -165,7 +165,7 @@ class PlaceStore extends Gtk.ListStore {
         if (buffer === null)
             return;
         try {
-            let jsonArray = JSON.parse(buffer);
+            let jsonArray = JSON.parse(Utils.getBufferText(buffer));
             jsonArray.forEach(({ place, type, added }) => {
                 // We expect exception to be thrown in this line when parsing
                 // gnome-maps 3.14 or below place stores since the "place"
diff --git a/src/service.js b/src/service.js
index cf0654c..4d71a99 100644
--- a/src/service.js
+++ b/src/service.js
@@ -36,7 +36,7 @@ function _getServiceFromFile(filename) {
         log('Failed to open service file: ' + filename);
         System.exit(1);
     }
-    _service = JSON.parse(data);
+    _service = JSON.parse(Utils.getBufferText(data));
     return _service;
 }
 
diff --git a/src/utils.js b/src/utils.js
index 133c485..86c008d 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -27,6 +27,7 @@ const Geocode = imports.gi.GeocodeGlib;
 const Gio = imports.gi.Gio;
 const Gtk = imports.gi.Gtk;
 const Soup = imports.gi.Soup;
+const ByteArray = imports.byteArray;
 
 var METRIC_SYSTEM = 1;
 var IMPERIAL_SYSTEM = 2;
@@ -363,4 +364,15 @@ function showDialog(msg, type, transientFor) {
 
     messageDialog.connect('response', () => messageDialog.destroy());
     messageDialog.show_all();
-}
\ No newline at end of file
+}
+
+/* Gets a string from either a ByteArray or Uint8Array. This is for
+compatibility between two different Gjs versions, see discussion at
+https://gitlab.gnome.org/GNOME/gnome-maps/merge_requests/19 */
+function getBufferText(buffer) {
+    if (buffer instanceof Uint8Array) {
+        return ByteArray.toString(buffer);
+    } else {
+        return buffer.toString();
+    }
+}
-- 
2.18.1