Browse Source

Extract bufferToUrl filter into plain-JS helper function

Danilo Bargen 7 years ago
parent
commit
d6f7200296
2 changed files with 40 additions and 24 deletions
  1. 8 24
      src/filters.ts
  2. 32 0
      src/helpers.ts

+ 8 - 24
src/filters.ts

@@ -15,7 +15,7 @@
  * along with Threema Web. If not, see <http://www.gnu.org/licenses/>.
  */
 
-import {escapeRegExp, filter} from './helpers';
+import {bufferToUrl, escapeRegExp, filter} from './helpers';
 import {MimeService} from './services/mime';
 import {NotificationService} from './services/notification';
 import {WebClientService} from './services/webclient';
@@ -245,6 +245,12 @@ angular.module('3ema.filters', [])
         return padLeft + left + ':' + padRight + right;
     };
 })
+
+/**
+ * Convert an ArrayBuffer to a data URL.
+ *
+ * Warning: Make sure that this is not called repeatedly on big data, or performance will decrease.
+ */
 .filter('bufferToUrl', ['$sce', '$log', function($sce, $log) {
     const logTag = '[filters.bufferToUrl]';
     return function(buffer: ArrayBuffer, mimeType: string, trust: boolean = true) {
@@ -252,29 +258,7 @@ angular.module('3ema.filters', [])
             $log.error(logTag, 'Could not apply bufferToUrl filter: buffer is', buffer);
             return '';
         }
-        let binary = '';
-        const bytes = new Uint8Array(buffer);
-        const len = bytes.byteLength;
-        for (let i = 0; i < len; i++) {
-            binary += String.fromCharCode(bytes[i]);
-        }
-        switch (mimeType) {
-            case 'image/jpg':
-            case 'image/jpeg':
-            case 'image/png':
-            case 'image/webp':
-            case 'audio/mp4':
-            case 'audio/aac':
-            case 'audio/ogg':
-            case 'audio/webm':
-                // OK
-                break;
-            default:
-                $log.warn(logTag, 'Unknown mimeType: ' + mimeType);
-                mimeType = 'image/jpeg';
-                break;
-        }
-        const uri = 'data:' + mimeType + ';base64,' + btoa(binary);
+        const uri = bufferToUrl(buffer, mimeType, (msg: string) => $log.warn(logTag, msg));
         if (trust) {
             return $sce.trustAsResourceUrl(uri);
         } else {

+ 32 - 0
src/helpers.ts

@@ -280,3 +280,35 @@ export function hasFeature(contactReceiver: threema.ContactReceiver,
     $log.warn(logTag, 'Cannot check featureMask of a undefined contactReceiver');
     return false;
 }
+
+/**
+ * Convert an ArrayBuffer to a data URL.
+ */
+export function bufferToUrl(buffer: ArrayBuffer, mimeType: string, logWarning: (msg: string) => void) {
+    if (buffer === null || buffer === undefined) {
+        throw new Error('Called bufferToUrl on null or undefined');
+    }
+    let binary = '';
+    const bytes = new Uint8Array(buffer);
+    const len = bytes.byteLength;
+    for (let i = 0; i < len; i++) {
+        binary += String.fromCharCode(bytes[i]);
+    }
+    switch (mimeType) {
+        case 'image/jpg':
+        case 'image/jpeg':
+        case 'image/png':
+        case 'image/webp':
+        case 'audio/mp4':
+        case 'audio/aac':
+        case 'audio/ogg':
+        case 'audio/webm':
+            // OK
+            break;
+        default:
+            logWarning('bufferToUrl: Unknown mimeType: ' + mimeType);
+            mimeType = 'image/jpeg';
+            break;
+    }
+    return 'data:' + mimeType + ';base64,' + btoa(binary);
+}