Browse Source

Add default-case lint rule

Lutz Roeder 3 years ago
parent
commit
372d8cde44

+ 1 - 0
package.json

@@ -40,6 +40,7 @@
             "array-callback-return": "error",
             "brace-style": [ "error", "stroustrup", { "allowSingleLine": true } ],
             "curly": "error",
+            "default-case": "error",
             "default-case-last": "error",
             "indent": [ "error", 4, { "SwitchCase": 1 } ],
             "linebreak-style": "off",

+ 6 - 0
source/caffe.js

@@ -426,6 +426,9 @@ caffe.Node = class {
                 type = layer.type;
                 break;
             }
+            default: {
+                throw new new caffe.Error("Unsupported Caffe version '" + version + "'.");
+            }
         }
         this._type = metadata.type(type) || { name: type };
 
@@ -474,6 +477,9 @@ caffe.Node = class {
                 initializers = layer.blobs.map((blob) => new caffe.Tensor(blob));
                 break;
             }
+            default: {
+                throw new caffe.Error("Unsupported Caffe version '" + version + "'.");
+            }
         }
         this._inputs = [];
         const inputs = layer.input.concat(initializers);

+ 41 - 49
source/caffe2.js

@@ -7,44 +7,39 @@ caffe2.ModelFactory = class {
     match(context) {
         const identifier = context.identifier.toLowerCase();
         const extension = identifier.split('.').pop().toLowerCase();
-        switch (extension) {
-            case 'pb': {
-                const tags = context.tags('pb');
-                if (tags.size > 0 &&
-                    Array.from(tags.keys()).every((tag) => tag <= 9) &&
-                    Array.from(tags.values()).every((type) => type <= 4)) {
-                    if (tags.size === 1 && tags.get(2) === 2 && identifier.endsWith('saved_model.pb')) {
-                        return undefined;
-                    }
-                    const schema = [[1,2],[2,2],[3,2],[4,0],[5,2],[6,2],[7,2],[8,2],[9,2]];
-                    if (schema.every((pair) => !tags.has(pair[0]) || tags.get(pair[0]) === pair[1])) {
-                        const stream = context.stream;
-                        if (stream.length > 3) {
-                            const buffer = stream.peek(Math.min(stream.length, 67));
-                            if (buffer[0] == 0x0A) {
-                                const size = buffer[1];
-                                if (size < 64 &&
-                                    buffer.length > 2 + size + 1 &&
-                                    buffer.slice(2, 2 + size).every((c) => c >= 32 && c <= 127) &&
-                                    buffer[2 + size] == 0x12) {
-                                    return 'caffe2.pb';
-                                }
-                            }
-                            if (buffer[0] == 0x12) {
+        if (extension === 'pb') {
+            const tags = context.tags('pb');
+            if (tags.size > 0 &&
+                Array.from(tags.keys()).every((tag) => tag <= 9) &&
+                Array.from(tags.values()).every((type) => type <= 4)) {
+                if (tags.size === 1 && tags.get(2) === 2 && identifier.endsWith('saved_model.pb')) {
+                    return undefined;
+                }
+                const schema = [[1,2],[2,2],[3,2],[4,0],[5,2],[6,2],[7,2],[8,2],[9,2]];
+                if (schema.every((pair) => !tags.has(pair[0]) || tags.get(pair[0]) === pair[1])) {
+                    const stream = context.stream;
+                    if (stream.length > 3) {
+                        const buffer = stream.peek(Math.min(stream.length, 67));
+                        if (buffer[0] == 0x0A) {
+                            const size = buffer[1];
+                            if (size < 64 &&
+                                buffer.length > 2 + size + 1 &&
+                                buffer.slice(2, 2 + size).every((c) => c >= 32 && c <= 127) &&
+                                buffer[2 + size] == 0x12) {
                                 return 'caffe2.pb';
                             }
                         }
+                        if (buffer[0] == 0x12) {
+                            return 'caffe2.pb';
+                        }
                     }
                 }
-                break;
             }
-            case 'pbtxt':
-            case 'prototxt': {
-                const tags = context.tags('pbtxt');
-                if (tags.has('op') && !tags.has('op.attr') && !tags.has('op.graph_op_name') && !tags.has('op.endpoint')) {
-                    return 'caffe2.pbtxt';
-                }
-                break;
+        }
+        if (extension === 'pbtxt' || extension === 'prototxt') {
+            const tags = context.tags('pbtxt');
+            if (tags.has('op') && !tags.has('op.attr') && !tags.has('op.graph_op_name') && !tags.has('op.endpoint')) {
+                return 'caffe2.pbtxt';
             }
         }
         return undefined;
@@ -180,6 +175,9 @@ caffe2.ModelFactory = class {
                             return openBinary(context.stream.peek(), null);
                         });
                     }
+                    default: {
+                        throw new caffe2.Error("Unsupported Caffe2 format '" + match + "'.");
+                    }
                 }
             });
         });
@@ -416,12 +414,8 @@ caffe2.Node = class {
         this._device = op.engine || '';
         this._metadata = metadata;
         this._chain = [];
-        this._attributes = [];
         this._type = metadata.type(op.type);
-        for (const arg of op.arg) {
-            const attribute = new caffe2.Attribute(metadata, metadata.attribute(this._type.name, arg.name), arg);
-            this._attributes.push(attribute);
-        }
+        this._attributes = op.arg.map((arg) => new caffe2.Attribute(metadata, this._type.name, arg));
         const inputs = op.input;
         const outputs = op.output;
         const tensors = {};
@@ -515,7 +509,7 @@ caffe2.Node = class {
 
 caffe2.Attribute = class {
 
-    constructor(metadata, schema, arg) {
+    constructor(metadata, type, arg) {
         this._name = arg.name;
         if (arg.floats && arg.floats.length > 0) {
             this._value = arg.floats;
@@ -537,24 +531,22 @@ caffe2.Attribute = class {
         else {
             this._value = arg.i;
         }
-        if (schema) {
-            if (Object.prototype.hasOwnProperty.call(schema, 'type')) {
-                this._type = schema.type;
+        metadata = metadata.attribute(type, arg.name);
+        if (metadata) {
+            if (Object.prototype.hasOwnProperty.call(metadata, 'type')) {
+                this._type = metadata.type;
                 if (this._type == 'boolean') {
-                    switch (this._value) {
-                        case 1: this._value = true; break;
-                        case 0: this._value = false; break;
-                    }
+                    this._value = this._value !== 0 && this._value.toString() !== '0' ? true : false;
                 }
             }
         }
 
-        if (schema) {
-            if (Object.prototype.hasOwnProperty.call(schema, 'visible') && !schema.visible) {
+        if (metadata) {
+            if (Object.prototype.hasOwnProperty.call(metadata, 'visible') && !metadata.visible) {
                 this._visible = false;
             }
-            else if (Object.prototype.hasOwnProperty.call(schema, 'default')) {
-                if (this._value == schema.default || (this._value && this._value.toString() == schema.default.toString())) {
+            else if (metadata.default !== undefined) {
+                if (this._value == metadata.default || (this._value && this._value.toString() == metadata.default.toString())) {
                     this._visible = false;
                 }
             }

+ 6 - 199
source/circle.js

@@ -1,7 +1,7 @@
 
 var circle = circle || {};
 var flatbuffers = flatbuffers || require('./flatbuffers');
-var flexbuffers = {};
+var flexbuffers = flexbuffers || require('./flexbuffers');
 var zip = zip || require('./zip');
 
 circle.ModelFactory = class {
@@ -115,6 +115,9 @@ circle.Model = class {
                         }
                         break;
                     }
+                    default: {
+                        break;
+                    }
                 }
             }
         }
@@ -210,8 +213,10 @@ circle.Graph = class {
                     else if (contentProperties instanceof circle.schema.ImageProperties) {
                         denotation = 'Image';
                         switch(contentProperties.color_space) {
+                            case 0: denotation += '(Unknown)'; break;
                             case 1: denotation += '(RGB)'; break;
                             case 2: denotation += '(Grayscale)'; break;
+                            default: throw circle.Error("Unsupported image color space '" + contentProperties.color_space + "'.");
                         }
                     }
                     else if (contentProperties instanceof circle.schema.BoundingBoxProperties) {
@@ -844,204 +849,6 @@ circle.Error = class extends Error {
     }
 };
 
-flexbuffers.Reader = class {
-
-    static open(buffer) {
-        return new flexbuffers.Reader(buffer);
-    }
-
-    constructor(buffer) {
-        this._reader = new flexbuffers.BinaryReader(buffer);
-    }
-
-    read() {
-        const end = this._reader.length;
-        if (end < 3) {
-            throw new flexbuffers.Error('Invalid buffer size.');
-        }
-        const byteWidth = this._reader.uint(end - 1, 1);
-        if (byteWidth > 8) {
-            throw new flexbuffers.Error('Invalid byte size.');
-        }
-        const packedType = this._reader.uint(end - 2, 1);
-        const reference = new flexbuffers.Reference(this._reader, end - 2 - byteWidth, byteWidth, 1 << (packedType & 3), packedType >> 2);
-        return reference.read();
-    }
-};
-
-flexbuffers.Reference = class {
-
-    constructor(reader, offset, parentWidth, byteWidth, type) {
-        this._reader = reader;
-        this._offset = offset;
-        this._parentWidth = parentWidth;
-        this._byteWidth = byteWidth;
-        this._type = type;
-    }
-
-    read() {
-        switch (this._type) {
-            case 0x00:   // null
-                return null;
-            case 0x01:   // int
-                return this._reader.int(this._offset, this._parentWidth);
-            case 0x02:   // uint
-                return this._reader.uint(this._offset, this._parentWidth);
-            case 0x03:   // float
-                return this._reader.float(this._offset, this._parentWidth);
-            case 0x04: { // key
-                return this._reader.string(this._indirect());
-            }
-            case 0x05: { // string
-                const offset = this._indirect();
-                const size = this._reader.uint(offset - this._byteWidth, this._byteWidth);
-                return this._reader.string(offset, size);
-            }
-            case 0x06: // indirect int
-                return this._reader.int(this._indirect(), this._byteWidth);
-            case 0x07: // indirect uint
-                return this._reader.uint(this._indirect(), this._byteWidth);
-            case 0x08:   // indirect float
-                return this._reader.float(this._indirect(), this._byteWidth);
-            case 0x09: { // map
-                const offset = this._indirect();
-                const keysOffset = offset - (this._byteWidth * 3);
-                const keysVectorOffset = keysOffset - this._reader.uint(keysOffset, this._byteWidth);
-                const keysByteWidth = this._reader.uint(keysOffset + this._byteWidth, this._byteWidth);
-                const keys = this._typedVector(keysVectorOffset, keysByteWidth, 0x04);
-                const values = this._vector(offset, this._byteWidth);
-                const map = {};
-                for (let i = 0; i < keys.length; i++) {
-                    map[keys[i]] = values[i];
-                }
-                return map;
-            }
-            case 0x0a: { // vector
-                return this._vector(this._indirect(), this._byteWidth);
-            }
-            case 0x0b:   // vector int
-            case 0x0c:   // vector uint
-            case 0x0d:   // vector float
-            case 0x0e:   // vector key
-            case 0x0f:   // vector string deprecated
-            case 0x24: { // vector bool
-                return this._typedVector(this._indirect(), this._byteWidth, this._type - 0x0b + 0x01);
-            }
-            case 0x10:   // vector int2
-            case 0x11:   // vector uint2
-            case 0x12:   // vector float2
-            case 0x13:   // vector int3
-            case 0x14:   // vector uint3
-            case 0x15:   // vector float3
-            case 0x16:   // vector int4
-            case 0x17:   // vector uint4
-            case 0x18: { // vector float4
-                const offset = this._indirect();
-                const size = (((this._type - 0x10) / 3) >> 0) + 2;
-                const type = ((this._type - 0x10) % 3) + 0x01;
-                return this._typedVector(offset, this._byteWidth, type, size);
-            }
-            case 0x19: { // blob
-                const offset = this._indirect();
-                const size = this._reader.uint(offset - this._byteWidth, this._byteWidth);
-                return this._reader.bytes(offset, size);
-            }
-            case 0x1a: { // bool
-                return this._reader.uint(this._offset, this._parentWidth) !== 0;
-            }
-        }
-        return undefined;
-    }
-
-    _indirect() {
-        return this._offset - this._reader.uint(this._offset, this._parentWidth);
-    }
-
-    _vector(offset, byteWidth) {
-        const size = this._reader.uint(offset - byteWidth, byteWidth);
-        const packedTypeOffset = offset + (size * byteWidth);
-        const vector = new Array(size);
-        for (let i = 0; i < size; i++) {
-            const packedType = this._reader.uint(packedTypeOffset + i, 1);
-            const reference = new flexbuffers.Reference(this._reader, offset + (i * byteWidth), byteWidth, 1 << (packedType & 3), packedType >> 2);
-            vector[i] = reference.read();
-        }
-        return vector;
-    }
-
-    _typedVector(offset, byteWidth, type, size) {
-        size = size === undefined ? this._reader.uint(offset - byteWidth, byteWidth) : size;
-        const vector = new Array(size);
-        for (let i = 0; i < size; i++) {
-            const reference = new flexbuffers.Reference(this._reader, offset + (i * byteWidth), byteWidth, 1, type);
-            vector[i] = reference.read();
-        }
-        return vector;
-    }
-};
-
-flexbuffers.BinaryReader = class {
-
-    constructor(buffer) {
-        this._buffer = buffer;
-        this._length = buffer.length;
-        this._view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
-        this._utf8Decoder = new TextDecoder('utf-8');
-    }
-
-    get length() {
-        return this._length;
-    }
-
-    int(offset, size) {
-        switch (size) {
-            case 1: return this._view.getInt8(offset);
-            case 2: return this._view.getInt16(offset, true);
-            case 4: return this._view.getInt32(offset, true);
-            case 8: return this._view.getInt64(offset, true);
-        }
-        throw new flexbuffers.Error("Invalid int size '" + size + "'.");
-    }
-
-    uint(offset, size) {
-        switch (size) {
-            case 1: return this._view.getUint8(offset);
-            case 2: return this._view.getUint16(offset, true);
-            case 4: return this._view.getUint32(offset, true);
-            case 8: return this._view.getUint64(offset, true);
-        }
-        throw new flexbuffers.Error("Invalid uint size '" + size + "'.");
-    }
-
-    float(offset, size) {
-        switch (size) {
-            case 4: return this._view.getFloat32(offset, true);
-            case 8: return this._view.getFloat64(offset, true);
-        }
-        throw new flexbuffers.Error("Invalid float size '" + size + "'.");
-    }
-
-    string(offset, size) {
-        let end = size === undefined ? this._buffer.indexOf(0, offset) : offset + size;
-        end = end === -1 ? this._buffer.length : end;
-        const bytes = this._buffer.subarray(offset, end);
-        return this._utf8Decoder.decode(bytes);
-    }
-
-    bytes(offset, size) {
-        return this._buffer.slice(offset, offset + size);
-    }
-};
-
-flexbuffers.Error = class extends Error {
-
-    constructor(message) {
-        super(message);
-        this.name = 'FlexBuffers Error';
-        this.message = message;
-    }
-};
-
 if (typeof module !== 'undefined' && typeof module.exports === 'object') {
     module.exports.ModelFactory = circle.ModelFactory;
 }

+ 4 - 0
source/cntk.js

@@ -172,6 +172,8 @@ cntk.Graph = class {
                         case 'LearnableParameter':
                             arg(node.name, version, node);
                             break;
+                        default:
+                            break;
                     }
                 }
                 for (const name of Object.keys(obj.nodes)) {
@@ -664,6 +666,7 @@ cntk.TensorType = class {
                     case 'double': this._dataType = 'float64'; break;
                     case 'half': this._dataType = 'float16'; break;
                     case '': this._dataType = 'float32'; break;
+                    default: throw new cntk.Error("Unsupported tensor data type '" + dataType + "'.");
                 }
                 this._shape = new cntk.TensorShape(version, shape);
                 break;
@@ -671,6 +674,7 @@ cntk.TensorType = class {
                 dataType = dataType.toNumber();
                 switch (dataType) {
                     case 1: this._dataType = 'float32'; break;
+                    default: throw new cntk.Error("Unsupported tensor data type '" + dataType + "'.");
                 }
                 this._shape = new cntk.TensorShape(version, shape);
                 break;

+ 54 - 27
source/coreml.js

@@ -31,30 +31,25 @@ coreml.ModelFactory = class {
             }
             return 'coreml.pb';
         }
-        switch (identifier) {
-            case 'manifest.json': {
-                const obj = context.open('json');
-                if (obj && obj.rootModelIdentifier && obj.itemInfoEntries) {
-                    const entries = Object.keys(obj.itemInfoEntries).map((key) => obj.itemInfoEntries[key]);
-                    if (entries.filter((entry) => entry.path.toLowerCase().endsWith('.mlmodel').length === 1)){
-                        return 'coreml.manifest';
-                    }
+        if (identifier === 'manifest.json') {
+            const obj = context.open('json');
+            if (obj && obj.rootModelIdentifier && obj.itemInfoEntries) {
+                const entries = Object.keys(obj.itemInfoEntries).map((key) => obj.itemInfoEntries[key]);
+                if (entries.filter((entry) => entry.path.toLowerCase().endsWith('.mlmodel').length === 1)){
+                    return 'coreml.manifest';
                 }
-                break;
             }
-            case 'metadata.json': {
-                const obj = context.open('json');
-                if (obj && obj.rootModelIdentifier && obj.itemInfoEntries) {
-                    return 'coreml.metadata';
-                }
-                break;
+        }
+        if (identifier === 'metadata.json') {
+            const obj = context.open('json');
+            if (obj && obj.rootModelIdentifier && obj.itemInfoEntries) {
+                return 'coreml.metadata';
             }
-            case 'featuredescriptions.json': {
-                const obj = context.open('json');
-                if (obj && (obj.Inputs || obj.Outputs)) {
-                    return 'coreml.featuredescriptions';
-                }
-                break;
+        }
+        if (identifier === 'featuredescriptions.json') {
+            const obj = context.open('json');
+            if (obj && (obj.Inputs || obj.Outputs)) {
+                return 'coreml.featuredescriptions';
             }
         }
         if (extension === 'bin' && stream.length > 16) {
@@ -684,8 +679,10 @@ coreml.Graph = class {
                     }
                     return new coreml.Tensor('Blob', type, data);
                 }
+                default: {
+                    throw new coreml.Error("Unsupported value '" + value.value + "'.");
+                }
             }
-            throw new coreml.Error("Unsupported value '" + value.value + "'.");
         };
 
         const args = new Map();
@@ -1013,8 +1010,9 @@ coreml.Graph = class {
             case 'nonMaximumSuppression':
                 data.stringClassLabels = this._convertVector(data.stringClassLabels);
                 return {};
+            default:
+                return {};
         }
-        return {};
     }
 
     _convertVector(value) {
@@ -1311,7 +1309,8 @@ coreml.Tensor = class {
                         results.push(context.data.getBits(context.index, context.bits));
                         context.index++;
                         break;
-
+                    default:
+                        break;
                 }
                 context.count++;
             }
@@ -1398,10 +1397,26 @@ coreml.MapType = class {
     }
 };
 
+coreml.SequenceType = class {
+
+    constructor(type) {
+        this._type = type;
+    }
+
+    get type() {
+        return this._type;
+    }
+
+    toString() {
+        return 'sequence<' + this._type + '>';
+    }
+};
+
 coreml.ImageType = class {
 
     constructor(colorSpace, width, height) {
-        this._colorSpace = '?';
+        this._width = width;
+        this._height = height;
         switch (colorSpace) {
             case coreml.proto.ImageFeatureType.ColorSpace.GRAYSCALE:
                 this._colorSpace = 'Grayscale';
@@ -1412,9 +1427,9 @@ coreml.ImageType = class {
             case coreml.proto.ImageFeatureType.ColorSpace.BGR:
                 this._colorSpace = 'BGR';
                 break;
+            default:
+                throw new coreml.Error("Unsupported image color space '" + colorSpace + "'.");
         }
-        this._width = width;
-        this._height = height;
     }
 
     toString() {
@@ -1466,6 +1481,9 @@ coreml.Utility = class {
                     }
                     let dataType = '?';
                     switch (type.multiArrayType.dataType) {
+                        case coreml.proto.ArrayFeatureType.ArrayDataType.INVALID_ARRAY_DATA_TYPE:
+                            dataType = '?';
+                            break;
                         case coreml.proto.ArrayFeatureType.ArrayDataType.FLOAT32:
                             dataType = 'float32';
                             break;
@@ -1475,6 +1493,8 @@ coreml.Utility = class {
                         case coreml.proto.ArrayFeatureType.ArrayDataType.DOUBLE:
                             dataType = 'float64';
                             break;
+                        default:
+                            throw new coreml.Error("Unsupported array data type '" + type.multiArrayType.dataType + "'.");
                     }
                     result = new coreml.TensorType(dataType, shape);
                     break;
@@ -1495,10 +1515,17 @@ coreml.Utility = class {
                     result = new coreml.MapType(type.dictionaryType.KeyType.replace('KeyType', ''), 'float64');
                     break;
                 }
+                case 'sequenceType': {
+                    result = new coreml.SequenceType(coreml.Utility.featureType(type[type.Type]));
+                    break;
+                }
                 case 'imageType': {
                     result = new coreml.ImageType(type.imageType.colorSpace, type.imageType.width, type.imageType.height);
                     break;
                 }
+                default: {
+                    throw new coreml.Error("Unsupported feature type '" + type.Type + "'.");
+                }
             }
             if (type.isOptional) {
                 result = new coreml.OptionalType(result);

+ 3 - 0
source/dagre.js

@@ -1485,6 +1485,7 @@ dagre.layout = (graph, options) => {
                                 switch (vLabel.labelpos) {
                                     case 'l': delta = -vLabel.width / 2; break;
                                     case 'r': delta = vLabel.width / 2; break;
+                                    default: throw new dagre.Error("Unsupported label position '" + vLabel.labelpos + "'.");
                                 }
                             }
                             if (delta) {
@@ -1498,6 +1499,7 @@ dagre.layout = (graph, options) => {
                                 switch (wLabel.labelpos) {
                                     case 'l': delta = wLabel.width / 2; break;
                                     case 'r': delta = -wLabel.width / 2; break;
+                                    default: throw new dagre.Error("Unsupported label position '" + wLabel.labelpos + "'.");
                                 }
                             }
                             if (delta) {
@@ -1859,6 +1861,7 @@ dagre.layout = (graph, options) => {
                     switch (edge.labelpos) {
                         case 'l': edge.x -= edge.width / 2 + edge.labeloffset; break;
                         case 'r': edge.x += edge.width / 2 + edge.labeloffset; break;
+                        default: throw new dagre.Error("Unsupported label position '" + edge.labelpos + "'.");
                     }
                 }
             }

+ 206 - 0
source/flexbuffers.js

@@ -0,0 +1,206 @@
+
+var flexbuffers = {};
+
+flexbuffers.Reader = class {
+
+    static open(buffer) {
+        return new flexbuffers.Reader(buffer);
+    }
+
+    constructor(buffer) {
+        this._reader = new flexbuffers.BinaryReader(buffer);
+    }
+
+    read() {
+        const end = this._reader.length;
+        if (end < 3) {
+            throw new flexbuffers.Error('Invalid buffer size.');
+        }
+        const byteWidth = this._reader.uint(end - 1, 1);
+        if (byteWidth > 8) {
+            throw new flexbuffers.Error('Invalid byte size.');
+        }
+        const packedType = this._reader.uint(end - 2, 1);
+        const reference = new flexbuffers.Reference(this._reader, end - 2 - byteWidth, byteWidth, 1 << (packedType & 3), packedType >> 2);
+        return reference.read();
+    }
+};
+
+flexbuffers.Reference = class {
+
+    constructor(reader, offset, parentWidth, byteWidth, type) {
+        this._reader = reader;
+        this._offset = offset;
+        this._parentWidth = parentWidth;
+        this._byteWidth = byteWidth;
+        this._type = type;
+    }
+
+    read() {
+        switch (this._type) {
+            case 0x00:   // null
+                return null;
+            case 0x01:   // int
+                return this._reader.int(this._offset, this._parentWidth);
+            case 0x02:   // uint
+                return this._reader.uint(this._offset, this._parentWidth);
+            case 0x03:   // float
+                return this._reader.float(this._offset, this._parentWidth);
+            case 0x04: { // key
+                return this._reader.string(this._indirect());
+            }
+            case 0x05: { // string
+                const offset = this._indirect();
+                const size = this._reader.uint(offset - this._byteWidth, this._byteWidth);
+                return this._reader.string(offset, size);
+            }
+            case 0x06: // indirect int
+                return this._reader.int(this._indirect(), this._byteWidth);
+            case 0x07: // indirect uint
+                return this._reader.uint(this._indirect(), this._byteWidth);
+            case 0x08:   // indirect float
+                return this._reader.float(this._indirect(), this._byteWidth);
+            case 0x09: { // map
+                const offset = this._indirect();
+                const keysOffset = offset - (this._byteWidth * 3);
+                const keysVectorOffset = keysOffset - this._reader.uint(keysOffset, this._byteWidth);
+                const keysByteWidth = this._reader.uint(keysOffset + this._byteWidth, this._byteWidth);
+                const keys = this._typedVector(keysVectorOffset, keysByteWidth, 0x04);
+                const values = this._vector(offset, this._byteWidth);
+                const map = {};
+                for (let i = 0; i < keys.length; i++) {
+                    map[keys[i]] = values[i];
+                }
+                return map;
+            }
+            case 0x0a: { // vector
+                return this._vector(this._indirect(), this._byteWidth);
+            }
+            case 0x0b:   // vector int
+            case 0x0c:   // vector uint
+            case 0x0d:   // vector float
+            case 0x0e:   // vector key
+            case 0x0f:   // vector string deprecated
+            case 0x24: { // vector bool
+                return this._typedVector(this._indirect(), this._byteWidth, this._type - 0x0b + 0x01);
+            }
+            case 0x10:   // vector int2
+            case 0x11:   // vector uint2
+            case 0x12:   // vector float2
+            case 0x13:   // vector int3
+            case 0x14:   // vector uint3
+            case 0x15:   // vector float3
+            case 0x16:   // vector int4
+            case 0x17:   // vector uint4
+            case 0x18: { // vector float4
+                const offset = this._indirect();
+                const size = (((this._type - 0x10) / 3) >> 0) + 2;
+                const type = ((this._type - 0x10) % 3) + 0x01;
+                return this._typedVector(offset, this._byteWidth, type, size);
+            }
+            case 0x19: { // blob
+                const offset = this._indirect();
+                const size = this._reader.uint(offset - this._byteWidth, this._byteWidth);
+                return this._reader.bytes(offset, size);
+            }
+            case 0x1a: { // bool
+                return this._reader.uint(this._offset, this._parentWidth) !== 0;
+            }
+            default: {
+                throw new flexbuffers.Error("Unsupported reference type '" + this._type);
+            }
+        }
+    }
+
+    _indirect() {
+        return this._offset - this._reader.uint(this._offset, this._parentWidth);
+    }
+
+    _vector(offset, byteWidth) {
+        const size = this._reader.uint(offset - byteWidth, byteWidth);
+        const packedTypeOffset = offset + (size * byteWidth);
+        const vector = new Array(size);
+        for (let i = 0; i < size; i++) {
+            const packedType = this._reader.uint(packedTypeOffset + i, 1);
+            const reference = new flexbuffers.Reference(this._reader, offset + (i * byteWidth), byteWidth, 1 << (packedType & 3), packedType >> 2);
+            vector[i] = reference.read();
+        }
+        return vector;
+    }
+
+    _typedVector(offset, byteWidth, type, size) {
+        size = size === undefined ? this._reader.uint(offset - byteWidth, byteWidth) : size;
+        const vector = new Array(size);
+        for (let i = 0; i < size; i++) {
+            const reference = new flexbuffers.Reference(this._reader, offset + (i * byteWidth), byteWidth, 1, type);
+            vector[i] = reference.read();
+        }
+        return vector;
+    }
+};
+
+flexbuffers.BinaryReader = class {
+
+    constructor(buffer) {
+        this._buffer = buffer;
+        this._length = buffer.length;
+        this._view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
+        this._utf8Decoder = new TextDecoder('utf-8');
+    }
+
+    get length() {
+        return this._length;
+    }
+
+    int(offset, size) {
+        switch (size) {
+            case 1: return this._view.getInt8(offset);
+            case 2: return this._view.getInt16(offset, true);
+            case 4: return this._view.getInt32(offset, true);
+            case 8: return this._view.getInt64(offset, true);
+            default: throw new flexbuffers.Error("Invalid int size '" + size + "'.");
+        }
+    }
+
+    uint(offset, size) {
+        switch (size) {
+            case 1: return this._view.getUint8(offset);
+            case 2: return this._view.getUint16(offset, true);
+            case 4: return this._view.getUint32(offset, true);
+            case 8: return this._view.getUint64(offset, true);
+            default: throw new flexbuffers.Error("Invalid uint size '" + size + "'.");
+        }
+    }
+
+    float(offset, size) {
+        switch (size) {
+            case 4: return this._view.getFloat32(offset, true);
+            case 8: return this._view.getFloat64(offset, true);
+            default: throw new flexbuffers.Error("Invalid float size '" + size + "'.");
+        }
+    }
+
+    string(offset, size) {
+        let end = size === undefined ? this._buffer.indexOf(0, offset) : offset + size;
+        end = end === -1 ? this._buffer.length : end;
+        const bytes = this._buffer.subarray(offset, end);
+        return this._utf8Decoder.decode(bytes);
+    }
+
+    bytes(offset, size) {
+        return this._buffer.slice(offset, offset + size);
+    }
+};
+
+flexbuffers.Error = class extends Error {
+
+    constructor(message) {
+        super(message);
+        this.name = 'FlexBuffers Error';
+        this.message = message;
+    }
+};
+
+if (typeof module !== 'undefined' && typeof module.exports === 'object') {
+    module.exports.Reader = flexbuffers.Reader;
+}

+ 26 - 9
source/hdf5.js

@@ -406,8 +406,10 @@ hdf5.Reader = class {
                 }
                 return value;
             }
+            default: {
+                throw new hdf5.Error('Unsupported offset size \'' + this._offsetSize + '\'.');
+            }
         }
-        throw new hdf5.Error('Unsupported offset size \'' + this._offsetSize + '\'.');
     }
 
     length() {
@@ -428,8 +430,10 @@ hdf5.Reader = class {
                 }
                 return value;
             }
+            default: {
+                throw new hdf5.Error('Unsupported length size \'' + this._lengthSize + '\'.');
+            }
         }
-        throw new hdf5.Error('Unsupported length size \'' + this._lengthSize + '\'.');
     }
 
     at(position) {
@@ -806,12 +810,12 @@ hdf5.Datatype = class {
                 this._flags = reader.byte() | reader.byte() << 8 | reader.byte() << 16;
                 this._size = reader.uint32();
                 switch (this._class) {
-                    case 0: {
+                    case 0: { // fixed-Point
                         this._bitOffset = reader.uint16();
                         this._bitPrecision = reader.uint16();
                         break;
                     }
-                    case 8: {
+                    case 8: { // enumerated
                         this._base = new hdf5.Datatype(reader);
                         this._names = [];
                         this._values = [];
@@ -826,11 +830,15 @@ hdf5.Datatype = class {
                         }
                         break;
                     }
+                    default: {
+                        break;
+                    }
                 }
                 break;
             }
-            default:
+            default: {
                 throw new hdf5.Error('Unsupported datatype version \'' + version + '\'.');
+            }
         }
     }
 
@@ -896,8 +904,9 @@ hdf5.Datatype = class {
             case 0: // fixed-point
             case 1: // floating-point
                 return (this.flags & 0x01) == 0;
+            default:
+                return true;
         }
-        return true;
     }
 
     read(reader) {
@@ -933,8 +942,9 @@ hdf5.Datatype = class {
                         return hdf5.Reader.decode(reader.read(this._size), 'ascii');
                     case 1:
                         return hdf5.Reader.decode(reader.read(this._size), 'utf-8');
+                    default:
+                        throw new hdf5.Error('Unsupported character encoding.');
                 }
-                throw new hdf5.Error('Unsupported character encoding.');
             case 5: // opaque
                 return reader.read(this._size);
             case 8: // enumerated
@@ -944,8 +954,9 @@ hdf5.Datatype = class {
                     length: reader.uint32(),
                     globalHeapID: new hdf5.GlobalHeapID(reader)
                 };
+            default:
+                throw new hdf5.Error('Unsupported datatype class \'' + this._class + '\'.');
         }
-        throw new hdf5.Error('Unsupported datatype class \'' + this._class + '\'.');
     }
 
     decode(data, globalHeap) {
@@ -969,8 +980,9 @@ hdf5.Datatype = class {
                             return hdf5.Reader.decode(globalHeapObject.data, 'ascii');
                         case 1:
                             return hdf5.Reader.decode(globalHeapObject.data, 'utf-8');
+                        default:
+                            throw new hdf5.Error('Unsupported character encoding.');
                     }
-                    throw new hdf5.Error('Unsupported character encoding.');
                 }
                 break;
             }
@@ -1043,6 +1055,8 @@ hdf5.Link = class {
                         break;
                     case 1: // soft link
                         break;
+                    default:
+                        throw new hdf5.Error('Unsupported link message type \'' + this.type + '\'.');
                 }
                 break;
             }
@@ -1277,6 +1291,9 @@ hdf5.ObjectModificationTime = class {
                 }
                 break;
             }
+            default: {
+                throw new hdf5.Error('Unsupported object modification time message type \'' + type + '\'.');
+            }
         }
     }
 };

+ 1 - 0
source/index.html

@@ -21,6 +21,7 @@
 <script type="text/javascript" src="python.js"></script>
 <script type="text/javascript" src="protobuf.js"></script>
 <script type="text/javascript" src="flatbuffers.js"></script>
+<script type="text/javascript" src="flexbuffers.js"></script>
 <script type="text/javascript" src="zip.js"></script>
 <script type="text/javascript" src="gzip.js"></script>
 <script type="text/javascript" src="tar.js"></script>

+ 6 - 0
source/index.js

@@ -870,6 +870,10 @@ if (typeof TextDecoder === "undefined") {
                             const c3 = buffer[i++];
                             const c4 = buffer[i++];
                             result += String.fromCodePoint(((c & 0x07) << 18) | ((c2 & 0x3F) << 12) | ((c3 & 0x3F) << 6) | (c4 & 0x3F));
+                            break;
+                        }
+                        default: {
+                            break;
                         }
                     }
                 }
@@ -879,6 +883,8 @@ if (typeof TextDecoder === "undefined") {
                     result += String.fromCharCode(buffer[i++]);
                 }
                 break;
+            default:
+                break;
         }
         return result;
     };

+ 7 - 1
source/json.js

@@ -52,6 +52,8 @@ json.TextReader = class {
                     }
                     state = '';
                     continue;
+                default:
+                    break;
             }
         }
         return new json.TextReader(data);
@@ -154,6 +156,8 @@ json.TextReader = class {
                         case 'constructor':
                         case 'prototype':
                             throw new json.Error("Invalid key '" + key + "'" + this._location());
+                        default:
+                            break;
                     }
                     this._whitespace();
                     if (this._char !== ':') {
@@ -247,8 +251,8 @@ json.TextReader = class {
             case 'N': this._expect('NaN'); return NaN;
             case 'I': this._expect('Infinity'); return Infinity;
             case '-': return this._number();
+            default: this._unexpected();
         }
-        this._unexpected();
     }
 
     _number() {
@@ -538,6 +542,8 @@ json.BinaryReader = class {
                     case 'constructor':
                     case 'prototype':
                         throw new json.Error("Invalid key '" + key + "' at " + position.toString() + "'.", true);
+                    default:
+                        break;
                 }
                 obj[key] = value;
             }

+ 4 - 0
source/keras.js

@@ -851,6 +851,8 @@ keras.Node = class {
                             inputName = innerSchema.inputs[inputIndex].name;
                         }
                         break;
+                    default:
+                        break;
                 }
             }
             const input = !list ? [ inputs.shift() ] : inputs.splice(0, inputs.length);
@@ -1164,6 +1166,8 @@ keras.Tensor = class {
                         results.push(context.view[context.index]);
                         context.index++;
                         break;
+                    default:
+                        throw new keras.Error("Unsupported tensor data type '" + context.dataType + "'.");
                 }
                 context.count++;
             }

+ 9 - 5
source/mnn.js

@@ -49,6 +49,7 @@ mnn.Model = class {
             case NetSource.TFLITE: this._source = 'TensorFlow Lite'; break;
             case NetSource.ONNX: this._source = 'ONNX'; break;
             case NetSource.TORCH: this._source = 'Torch'; break;
+            default: throw new mnn.Error("Unsupported model source '" + net.sourceType + "'.");
         }
         this._graphs = [ new mnn.Graph(metadata, net) ];
     }
@@ -469,11 +470,14 @@ mnn.TensorType = class {
     constructor(dataType, shape, format) {
         this._dataType = mnn.Utility.dataType(dataType);
         this._shape = shape;
-        switch (format) {
-            case mnn.schema.MNN_DATA_FORMAT.NCHW:   this._denotation = 'NCHW'; break;
-            case mnn.schema.MNN_DATA_FORMAT.NHWC:   this._denotation = 'NHWC'; break;
-            case mnn.schema.MNN_DATA_FORMAT.NC4HW4: this._denotation = 'NC4HW4'; break;
-            case mnn.schema.MNN_DATA_FORMAT.NHWC4:  this._denotation = 'NHWC4'; break;
+        if (format) {
+            switch (format) {
+                case mnn.schema.MNN_DATA_FORMAT.NCHW: this._denotation = 'NCHW'; break;
+                case mnn.schema.MNN_DATA_FORMAT.NHWC: this._denotation = 'NHWC'; break;
+                case mnn.schema.MNN_DATA_FORMAT.NC4HW4: this._denotation = 'NC4HW4'; break;
+                case mnn.schema.MNN_DATA_FORMAT.NHWC4: this._denotation = 'NHWC4'; break;
+                default: throw new mnn.Error("Unsupported tensor type format '" + format + "'.");
+            }
         }
     }
 

+ 7 - 6
source/mxnet.js

@@ -677,12 +677,9 @@ mxnet.Attribute = class {
             switch (schema.type) {
                 case 'boolean':
                     switch (value) {
-                        case 'True':
-                            this._value = true;
-                            break;
-                        case 'False':
-                            this._value = false;
-                            break;
+                        case 'True': this._value = true; break;
+                        case 'False': this._value = false; break;
+                        default: throw new mxnet.Error("Unsupported attribute boolean value '" + value + "'.");
                     }
                     break;
                 case 'int32':
@@ -714,6 +711,8 @@ mxnet.Attribute = class {
                         }
                     }
                     break;
+                default:
+                    throw new mxnet.Error("Unsupported attribute type '" + schema.type + "'.");
             }
         }
 
@@ -876,6 +875,8 @@ mxnet.Tensor = class {
                         context.index += 8;
                         context.count++;
                         break;
+                    default:
+                        throw new mxnet.Error("Unsupported tensor data type '" + context.dataType + "'.");
                 }
             }
         }

+ 8 - 3
source/onnx.js

@@ -1005,6 +1005,8 @@ onnx.Tensor = class {
                         data[i] = view.getUint64(i << 3, true);
                     }
                     break;
+                default:
+                    throw new onnx.Error("Unsupported tensor data type '" + type + "'.");
             }
             return data;
         };
@@ -1033,6 +1035,8 @@ onnx.Tensor = class {
                         case 'int64':
                         case 'uint64':
                             break;
+                        default:
+                            break;
                     }
                     if (indices.length > 0) {
                         if (Object.prototype.hasOwnProperty.call(indices[0], 'low')) {
@@ -1625,9 +1629,10 @@ onnx.GraphContext = class {
             case 'opaque_type': {
                 return new onnx.OpaqueType(type.opaque_type.domain, type.opaque_type.name);
             }
-            // default: {
-            //     throw new onnx.Error("Unsupported tensor type '" + type.value + "'.");
-            // }
+            default: {
+                // throw new onnx.Error("Unsupported tensor type '" + type.value + "'.");
+                break;
+            }
         }
     }
 

+ 5 - 10
source/openvino-metadata.json

@@ -463,8 +463,7 @@
         "default": 1,
         "description": " if \"true\", variance is encoded in target. Otherwise, we need to adjust the predicted offset accordingly.",
         "name": "variance_encoded_in_target",
-        "required": true,
-        "type": " logical values"
+        "required": true
       },
       {
         "default": 1,
@@ -490,8 +489,7 @@
         "default": 1,
         "description": " bounding boxes are shared among different classes.",
         "name": "share_location",
-        "required": true,
-        "type": " logical values"
+        "required": true
       },
       {
         "default": 1,
@@ -715,15 +713,13 @@
         "default": 1,
         "description": " *across_spatial* is a flag that denotes if normalization is performed over CHW or HW. For example, *across_spatial* equals 0 means that normalization is not shared across channels.",
         "name": "across_spatial",
-        "required": true,
-        "type": "\n    * 0\n    * 1 - not supported"
+        "required": true
       },
       {
         "default": 1,
         "description": " *channel_shared* is a flag that denotes if scale parameters are shared across channels. For example, *channel_shared* equal 0 means that scale parameters are not shared across channels.",
         "name": "channel_shared",
-        "required": true,
-        "type": "\n    * 0 - scale parameters are not shared across channels\n    * 1 - not supported"
+        "required": true
       },
       {
         "default": 1,
@@ -892,8 +888,7 @@
         "default": "ceil",
         "description": " *rounding_type* is a type of rounding to be applied.",
         "name": "rounding-type",
-        "required": true,
-        "type": "\n    * *ceil*\n    * *floor*"
+        "required": true
       }
     ],
     "support_level": "default"

+ 11 - 0
source/openvino.js

@@ -563,6 +563,8 @@ openvino.Node = class {
                         }
                         break;
                     }
+                    default:
+                        break;
                 }
             }
             const shape = dimensions ? new openvino.TensorShape(dimensions) : null;
@@ -657,6 +659,9 @@ openvino.Attribute = class {
             if (Object.prototype.hasOwnProperty.call(schema, 'type')) {
                 this._type = schema.type;
                 switch (schema.type) {
+                    case '':
+                    case 'string':
+                        break;
                     case 'boolean':
                         switch (value) {
                             case '1':
@@ -669,6 +674,8 @@ openvino.Attribute = class {
                             case 'False':
                                 this._value = false;
                                 break;
+                            default:
+                                throw new openvino.Error("Unsupported attribute boolean value '" + value + "'.");
                         }
                         break;
                     case 'int32': {
@@ -718,6 +725,8 @@ openvino.Attribute = class {
                             }
                         }
                         break;
+                    default:
+                        throw new openvino.Error("Unsupported attribute type '" + schema.type + "'.");
                 }
             }
             if (Object.prototype.hasOwnProperty.call(schema, 'visible') && schema.visible == false) {
@@ -901,6 +910,8 @@ openvino.Tensor = class {
                         context.index += 8;
                         context.count++;
                         break;
+                    default:
+                        throw new openvino.Error("Unsupported tensor data type '" + this._type.dataType + "'.");
                 }
             }
         }

+ 71 - 64
source/paddle.js

@@ -374,10 +374,7 @@ paddle.Node = class {
         this._outputs = [];
         this._chain = [];
         if (op.attrs) {
-            for (const attr of op.attrs) {
-                const schema = metadata.attribute(type, this._name);
-                this._attributes.push(new paddle.Attribute(schema, attr));
-            }
+            this._attributes = op.attrs.map((attr) => new paddle.Attribute(metadata.attribute(type, this._name), attr));
         }
         if (op.inputs) {
             for (const input of op.inputs) {
@@ -495,6 +492,8 @@ paddle.Attribute = class {
             case 'is_test':
                 this._visible = false;
                 break;
+            default:
+                break;
         }
         if (schema) {
             if (Object.prototype.hasOwnProperty.call(schema, 'default')) {
@@ -626,6 +625,8 @@ paddle.Tensor = class {
                         context.index += 8;
                         context.count++;
                         break;
+                    default:
+                        throw new paddle.Error("Unsupported tensor data type '" + context.dataType + "'.");
                 }
             }
         }
@@ -717,19 +718,13 @@ paddle.Utility = class {
 
     static createTensorType(data_type, shape) {
         if (!paddle.Utility._dataTypes) {
-            const length = Math.max.apply(null, Object.values(paddle.DataType));
+            const length = Math.max.apply(null, Object.entries(paddle.DataType).map((entry) => entry[1]));
             paddle.Utility._dataTypes = new Array(length);
-            for (const key of Object.keys(paddle.DataType)) {
-                const index = paddle.DataType[key];
-                let name = key.toLowerCase();
-                switch (name) {
-                    case 'bool': name = 'boolean'; break;
-                    case 'bf16': name = 'bfloat16'; break;
-                    case 'fp16': name = 'float16'; break;
-                    case 'fp32': name = 'float32'; break;
-                    case 'fp64': name = 'float64'; break;
-                }
-                paddle.Utility._dataTypes[index] = name;
+            const map = new Map([ [ 'bool', 'boolean' ], [ 'bf16', 'bfloat16' ], [ 'fp16', 'float16' ], [ 'fp32', 'float32' ], [ 'fp64', 'float64' ] ]);
+            for (const entry of Object.entries(paddle.DataType)) {
+                const index = entry[1];
+                const key = entry[0].toLowerCase();
+                paddle.Utility._dataTypes[index] = map.has(key) ? map.get(key) : key;
             }
         }
         const dataType = data_type < paddle.Utility._dataTypes.length ? paddle.Utility._dataTypes[data_type] : '?';
@@ -786,29 +781,25 @@ paddle.Weights = class {
         if (extension) {
             const entries = new Map(Array.from(context.entries(extension)).filter((entry) => !entry[0].endsWith('/') && !entry[0].split('/').pop().startsWith('.')).slice());
             if (entries.size > 2 && Array.from(entries).every((entry) => entry[0].split('_').length > 0 && entry[1].peek(16).every((value) => value === 0x00))) {
-                return new paddle.Weights('entries', entries);
+                return new paddle.Weights.Entries(entries);
             }
         }
         const obj = context.open('pkl');
         if (obj && !Array.isArray(obj) && Object(obj) === obj) {
-            return new paddle.Weights('pdparams', obj);
+            return new paddle.Weights.Pickle(obj);
         }
         return null;
     }
+};
 
-    constructor(format, data) {
-        this._format = format;
+paddle.Weights.Entries = class {
+
+    constructor(data) {
         this._data = data;
     }
 
     get format() {
-        switch (this._format) {
-            case 'entries':
-                return 'PaddlePaddle Weights';
-            case 'pdparams':
-                return 'PaddlePaddle Pickle';
-        }
-        return null;
+        return 'PaddlePaddle Weights';
     }
 
     get model() {
@@ -823,46 +814,62 @@ paddle.Weights = class {
 
     _initialize() {
         if (!this._weights) {
-            switch (this._format) {
-                case 'entries': {
-                    let rootFolder = null;
-                    for (const entry of this._data) {
-                        const name = entry[0];
-                        if (name.startsWith('.') && !name.startsWith('./')) {
-                            continue;
-                        }
-                        const parts = name.split('/');
-                        const folder = ((parts.length > 2 && parts[0] === '.') ? ('./' + parts[1] + '/') : (parts.length > 1 ? parts[0] + '/' : ''));
-                        rootFolder = (rootFolder === null) ? folder : (rootFolder !== '' && folder !== rootFolder) ? '' : folder;
-                    }
-                    this._weights = new Map();
-                    for (const entry of this._data) {
-                        if (entry[0].startsWith(rootFolder)) {
-                            const name = entry[0].substring(rootFolder.length);
-                            const stream = entry[1];
-                            const tensor = paddle.Utility.openTensor(stream);
-                            this._weights.set(name, tensor);
-                        }
-                    }
-                    break;
+            let rootFolder = null;
+            for (const entry of this._data) {
+                const name = entry[0];
+                if (!name.startsWith('.') || name.startsWith('./')) {
+                    const parts = name.split('/');
+                    const folder = ((parts.length > 2 && parts[0] === '.') ? ('./' + parts[1] + '/') : (parts.length > 1 ? parts[0] + '/' : ''));
+                    rootFolder = (rootFolder === null) ? folder : (rootFolder !== '' && folder !== rootFolder) ? '' : folder;
                 }
-                case 'pdparams': {
-                    const map = null; // this._data['StructuredToParameterName@@'];
-                    this._weights = new Map();
-                    for (const key of Object.keys(this._data)) {
-                        const value = this._data[key];
-                        if (value && !Array.isArray(value) && value.__class__ && value.__class__.__module__ === 'numpy' && value.__class__.__name__ === 'ndarray') {
-                            const name = map ? map[key] : key;
-                            const type = new paddle.TensorType(value.dtype.name, new paddle.TensorShape(value.shape));
-                            const data = value.data;
-                            const tensor = new paddle.Tensor(type, data, 'NumPy Array');
-                            this._weights.set(name, tensor);
-                        }
-                    }
-                    break;
+            }
+            this._weights = new Map();
+            for (const entry of this._data) {
+                if (entry[0].startsWith(rootFolder)) {
+                    const name = entry[0].substring(rootFolder.length);
+                    const stream = entry[1];
+                    const tensor = paddle.Utility.openTensor(stream);
+                    this._weights.set(name, tensor);
+                }
+            }
+        }
+    }
+};
+
+paddle.Weights.Pickle = class {
+
+    constructor(data) {
+        this._data = data;
+    }
+
+    get format() {
+        return 'PaddlePaddle Pickle';
+    }
+
+    get model() {
+        this._initialize();
+        return this._model;
+    }
+
+    get weights() {
+        this._initialize();
+        return this._weights;
+    }
+
+    _initialize() {
+        if (!this._weights) {
+            const map = null; // this._data['StructuredToParameterName@@'];
+            this._weights = new Map();
+            for (const key of Object.keys(this._data)) {
+                const value = this._data[key];
+                if (value && !Array.isArray(value) && value.__class__ && value.__class__.__module__ === 'numpy' && value.__class__.__name__ === 'ndarray') {
+                    const name = map ? map[key] : key;
+                    const type = new paddle.TensorType(value.dtype.name, new paddle.TensorShape(value.shape));
+                    const data = value.data;
+                    const tensor = new paddle.Tensor(type, data, 'NumPy Array');
+                    this._weights.set(name, tensor);
                 }
             }
-            delete this._format;
         }
     }
 };

+ 41 - 19
source/pytorch.js

@@ -48,6 +48,8 @@ pytorch.Model = class {
                     this._graphs.push(new pytorch.Graph(metadata, type, data, container));
                 }
                 break;
+            default:
+                throw new pytorch.Error("Unsupported container type '" + type + "'.");
         }
     }
 
@@ -193,6 +195,10 @@ pytorch.Graph = class {
                     };
                     this._nodes.push(new pytorch.Node(metadata, '', obj, null));
                 }
+                break;
+            }
+            default: {
+                throw new pytorch.Error("Unsupported container type '" + type + "'.");
             }
         }
     }
@@ -772,6 +778,8 @@ pytorch.Tensor = class {
                         context.index += 8;
                         context.count++;
                         break;
+                    default:
+                        throw new pytorch.Error("Unsupported tensor data type '" + context.dataType + "'.");
                 }
             }
         }
@@ -2002,12 +2010,17 @@ pytorch.Execution = class extends python.Execution {
             }
             __setstate__(state) {
                 switch (state.length) {
+                    case 3:
+                        this.data = null;
+                        break;
                     case 4:
                         this.data = state[0];
                         break;
                     case 5:
                         this.data = state[0];
                         break;
+                    default:
+                        throw new pytorch.Error("Unsupported parameter state length '" + state.length + "'.");
                 }
             }
         });
@@ -2752,6 +2765,8 @@ pytorch.Container.Zip = class {
                                     return false;
                                 case 'Optional':
                                     return undefined;
+                                default:
+                                    break;
                             }
                         }
                         throw new pytorch.Error("Unsupported function parameter type '" + JSON.stringify(type) + "'.");
@@ -2881,6 +2896,8 @@ pytorch.Container.Zip.Execution = class extends pytorch.Execution {
                                     copyArgs.shift();
                                     copyEvalArgs.shift();
                                     continue;
+                                default:
+                                    break;
                             }
                         }
 
@@ -3128,6 +3145,8 @@ pytorch.Container.Zip.Execution = class extends pytorch.Execution {
                                         case 'torch.contiguous':
                                             parameter.__source__ = evalArgs[0];
                                             break;
+                                        default:
+                                            break;
                                     }
                                 }
                                 parameter.__variable__ = this.variable();
@@ -3154,6 +3173,8 @@ pytorch.Container.Zip.Execution = class extends pytorch.Execution {
                                             count = context.target[context.target.length - 1].length;
                                         }
                                         break;
+                                    default:
+                                        break;
                                 }
                                 const tensors = [];
                                 const outputs = [];
@@ -3537,29 +3558,29 @@ pytorch.Utility = class {
     }
 
     static isTensor(obj) {
-        if (obj && obj.__class__) {
-            switch (obj.__class__.__module__) {
-                case 'torch':
-                case 'torch.cuda':
-                    return obj.__class__.__name__.endsWith('Tensor');
-                case 'torch.nn.parameter':
-                    return obj.__class__.__name__ === 'Parameter';
-            }
+        const name = obj && obj.__class__ ? obj.__class__.__module__ : null;
+        switch (name) {
+            case 'torch':
+            case 'torch.cuda':
+                return obj.__class__.__name__.endsWith('Tensor');
+            case 'torch.nn.parameter':
+                return obj.__class__.__name__ === 'Parameter';
+            default:
+                return false;
         }
-        return false;
     }
 
     static toTensor(obj) {
-        if (obj && obj.__class__) {
-            switch (obj.__class__.__module__) {
-                case 'torch':
-                case 'torch.cuda':
-                    return obj.__class__.__name__.endsWith('Tensor') ? obj : null;
-                case 'torch.nn.parameter':
-                    return obj.__class__.__name__ === 'Parameter' ? obj.data : null;
-            }
+        const name = obj && obj.__class__ ? obj.__class__.__module__ : null;
+        switch (name) {
+            case 'torch':
+            case 'torch.cuda':
+                return obj.__class__.__name__.endsWith('Tensor') ? obj : null;
+            case 'torch.nn.parameter':
+                return obj.__class__.__name__ === 'Parameter' ? obj.data : null;
+            default:
+                return null;
         }
-        return null;
     }
 
     static createTensor(name, tensor, littleEndian) {
@@ -3596,8 +3617,9 @@ pytorch.Utility = class {
                 return Number.isInteger(obj) || obj === null;
             case 'Device':
                 return obj === null || obj === Object(obj);
+            default:
+                return true;
         }
-        return true;
     }
 
     static isCall(expression, name, size) {

+ 2 - 0
source/sklearn.js

@@ -375,6 +375,8 @@ sklearn.Tensor = class {
             case 'int64':
             case 'uint64':
                 return sklearn.Tensor._stringify(value, '', '    ');
+            default:
+                break;
         }
         return JSON.stringify(value, null, 4);
     }

+ 12 - 5
source/tf.js

@@ -1157,11 +1157,8 @@ tf.Attribute = class {
                                 throw new tf.Error(JSON.stringify(defaultValue));
                         }
                     }
-                    switch (typeof value) {
-                        case 'boolean':
-                        case 'number':
-                        case 'string':
-                            return value === defaultValue;
+                    if (typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string') {
+                        return value === defaultValue;
                     }
                     if (value instanceof base.Int64 || value instanceof base.Uint64) {
                         return value.toNumber() === defaultValue;
@@ -1250,6 +1247,8 @@ tf.Tensor = class {
                     case DataType.DT_STRING:
                         this._data = tensor.string_val || null;
                         break;
+                    default:
+                        throw new tf.Error("Unsupported tensor data type '" + tensor.dtype + "'.");
                 }
             }
         }
@@ -1345,6 +1344,8 @@ tf.Tensor = class {
                     }
                     context.rawData = new DataView(this._buffer.buffer, this._buffer.byteOffset, this._buffer.byteLength);
                     break;
+                default:
+                    break;
             }
         }
         else if (this._data) {
@@ -1667,6 +1668,9 @@ tf.TensorBundle = class {
                 });
                 break;
             }
+            default: {
+                throw new tf.Error("Unsupported Tensor Bundle format '" + format + "'.");
+            }
         }
     }
 
@@ -1889,6 +1893,9 @@ tf.BinaryReader = class {
                     data.set(data.subarray(position - offset, position - offset + length), position);
                     break;
                 }
+                default: {
+                    break;
+                }
             }
             position += length;
         }

+ 1 - 201
source/tflite.js

@@ -1,7 +1,7 @@
 
 var tflite = tflite || {};
 var flatbuffers = flatbuffers || require('./flatbuffers');
-var flexbuffers = {};
+var flexbuffers = flexbuffers || require('./flexbuffers');
 var zip = zip || require('./zip');
 
 tflite.ModelFactory = class {
@@ -872,206 +872,6 @@ tflite.Error = class extends Error {
     }
 };
 
-flexbuffers.Reader = class {
-
-    static open(buffer) {
-        return new flexbuffers.Reader(buffer);
-    }
-
-    constructor(buffer) {
-        this._reader = new flexbuffers.BinaryReader(buffer);
-    }
-
-    read() {
-        const end = this._reader.length;
-        if (end < 3) {
-            throw new flexbuffers.Error('Invalid buffer size.');
-        }
-        const byteWidth = this._reader.uint(end - 1, 1);
-        if (byteWidth > 8) {
-            throw new flexbuffers.Error('Invalid byte size.');
-        }
-        const packedType = this._reader.uint(end - 2, 1);
-        const reference = new flexbuffers.Reference(this._reader, end - 2 - byteWidth, byteWidth, 1 << (packedType & 3), packedType >> 2);
-        return reference.read();
-    }
-};
-
-flexbuffers.Reference = class {
-
-    constructor(reader, offset, parentWidth, byteWidth, type) {
-        this._reader = reader;
-        this._offset = offset;
-        this._parentWidth = parentWidth;
-        this._byteWidth = byteWidth;
-        this._type = type;
-    }
-
-    read() {
-        switch (this._type) {
-            case 0x00:   // null
-                return null;
-            case 0x01:   // int
-                return this._reader.int(this._offset, this._parentWidth);
-            case 0x02:   // uint
-                return this._reader.uint(this._offset, this._parentWidth);
-            case 0x03:   // float
-                return this._reader.float(this._offset, this._parentWidth);
-            case 0x04: { // key
-                return this._reader.string(this._indirect());
-            }
-            case 0x05: { // string
-                const offset = this._indirect();
-                const size = this._reader.uint(offset - this._byteWidth, this._byteWidth);
-                return this._reader.string(offset, size);
-            }
-            case 0x06: // indirect int
-                return this._reader.int(this._indirect(), this._byteWidth);
-            case 0x07: // indirect uint
-                return this._reader.uint(this._indirect(), this._byteWidth);
-            case 0x08:   // indirect float
-                return this._reader.float(this._indirect(), this._byteWidth);
-            case 0x09: { // map
-                const offset = this._indirect();
-                const keysOffset = offset - (this._byteWidth * 3);
-                const keysVectorOffset = keysOffset - this._reader.uint(keysOffset, this._byteWidth);
-                const keysByteWidth = this._reader.uint(keysOffset + this._byteWidth, this._byteWidth);
-                const keys = this._typedVector(keysVectorOffset, keysByteWidth, 0x04);
-                const values = this._vector(offset, this._byteWidth);
-                const map = {};
-                for (let i = 0; i < keys.length; i++) {
-                    map[keys[i]] = values[i];
-                }
-                return map;
-            }
-            case 0x0a: { // vector
-                return this._vector(this._indirect(), this._byteWidth);
-            }
-            case 0x0b:   // vector int
-            case 0x0c:   // vector uint
-            case 0x0d:   // vector float
-            case 0x0e:   // vector key
-            case 0x0f:   // vector string deprecated
-            case 0x24: { // vector bool
-                return this._typedVector(this._indirect(), this._byteWidth, this._type - 0x0b + 0x01);
-            }
-            case 0x10:   // vector int2
-            case 0x11:   // vector uint2
-            case 0x12:   // vector float2
-            case 0x13:   // vector int3
-            case 0x14:   // vector uint3
-            case 0x15:   // vector float3
-            case 0x16:   // vector int4
-            case 0x17:   // vector uint4
-            case 0x18: { // vector float4
-                const offset = this._indirect();
-                const size = (((this._type - 0x10) / 3) >> 0) + 2;
-                const type = ((this._type - 0x10) % 3) + 0x01;
-                return this._typedVector(offset, this._byteWidth, type, size);
-            }
-            case 0x19: { // blob
-                const offset = this._indirect();
-                const size = this._reader.uint(offset - this._byteWidth, this._byteWidth);
-                return this._reader.bytes(offset, size);
-            }
-            case 0x1a: { // bool
-                return this._reader.uint(this._offset, this._parentWidth) !== 0;
-            }
-            default: {
-                throw new flexbuffers.Error("Unsupported reference type '" + this._type);
-            }
-        }
-    }
-
-    _indirect() {
-        return this._offset - this._reader.uint(this._offset, this._parentWidth);
-    }
-
-    _vector(offset, byteWidth) {
-        const size = this._reader.uint(offset - byteWidth, byteWidth);
-        const packedTypeOffset = offset + (size * byteWidth);
-        const vector = new Array(size);
-        for (let i = 0; i < size; i++) {
-            const packedType = this._reader.uint(packedTypeOffset + i, 1);
-            const reference = new flexbuffers.Reference(this._reader, offset + (i * byteWidth), byteWidth, 1 << (packedType & 3), packedType >> 2);
-            vector[i] = reference.read();
-        }
-        return vector;
-    }
-
-    _typedVector(offset, byteWidth, type, size) {
-        size = size === undefined ? this._reader.uint(offset - byteWidth, byteWidth) : size;
-        const vector = new Array(size);
-        for (let i = 0; i < size; i++) {
-            const reference = new flexbuffers.Reference(this._reader, offset + (i * byteWidth), byteWidth, 1, type);
-            vector[i] = reference.read();
-        }
-        return vector;
-    }
-};
-
-flexbuffers.BinaryReader = class {
-
-    constructor(buffer) {
-        this._buffer = buffer;
-        this._length = buffer.length;
-        this._view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
-        this._utf8Decoder = new TextDecoder('utf-8');
-    }
-
-    get length() {
-        return this._length;
-    }
-
-    int(offset, size) {
-        switch (size) {
-            case 1: return this._view.getInt8(offset);
-            case 2: return this._view.getInt16(offset, true);
-            case 4: return this._view.getInt32(offset, true);
-            case 8: return this._view.getInt64(offset, true);
-            default: throw new flexbuffers.Error("Invalid int size '" + size + "'.");
-        }
-    }
-
-    uint(offset, size) {
-        switch (size) {
-            case 1: return this._view.getUint8(offset);
-            case 2: return this._view.getUint16(offset, true);
-            case 4: return this._view.getUint32(offset, true);
-            case 8: return this._view.getUint64(offset, true);
-            default: throw new flexbuffers.Error("Invalid uint size '" + size + "'.");
-        }
-    }
-
-    float(offset, size) {
-        switch (size) {
-            case 4: return this._view.getFloat32(offset, true);
-            case 8: return this._view.getFloat64(offset, true);
-            default: throw new flexbuffers.Error("Invalid float size '" + size + "'.");
-        }
-    }
-
-    string(offset, size) {
-        let end = size === undefined ? this._buffer.indexOf(0, offset) : offset + size;
-        end = end === -1 ? this._buffer.length : end;
-        const bytes = this._buffer.subarray(offset, end);
-        return this._utf8Decoder.decode(bytes);
-    }
-
-    bytes(offset, size) {
-        return this._buffer.slice(offset, offset + size);
-    }
-};
-
-flexbuffers.Error = class extends Error {
-
-    constructor(message) {
-        super(message);
-        this.name = 'FlexBuffers Error';
-        this.message = message;
-    }
-};
-
 if (typeof module !== 'undefined' && typeof module.exports === 'object') {
     module.exports.ModelFactory = tflite.ModelFactory;
 }

+ 7 - 0
source/view-sidebar.js

@@ -301,6 +301,8 @@ sidebar.NodeSidebar = class {
                 return value.type.name;
             case 'function[]':
                 return value ? value.map((item) => item.type.name).join(', ') : '(null)';
+            default:
+                break;
         }
         if (typeof value === 'string' && (!type || type != 'string')) {
             return quote ? '"' + value + '"' : value;
@@ -1816,6 +1818,8 @@ markdown.Generator = class {
                                     i = ref.length;
                                 }
                                 break;
+                            default:
+                                break;
                         }
                     }
                 }
@@ -1978,6 +1982,9 @@ markdown.Generator = class {
                     }
                     break;
                 }
+                default: {
+                    break;
+                }
             }
         }
     }

+ 4 - 0
source/xml.js

@@ -492,6 +492,10 @@ xml.TextReader = class {
                             else {
                                 this._unexpected();
                             }
+                            break;
+                        }
+                        default: {
+                            break;
                         }
                     }
                     break;