UNPKG

link-rdflib

Version:

an RDF library for node.js, patched for speed.

210 lines (168 loc) 7.62 kB
"use strict"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var XSD = require('./xsd'); module.exports = /*#__PURE__*/ function () { function NQuadsParser(store) { _classCallCheck(this, NQuadsParser); this.store = store; this.nnClosingTagError = new Error("named node without closing angle bracket"); this.unexpectedCharError = function (identifier) { return new Error("Unexpected character '".concat(identifier, "'")); }; this.nnOpeningToken = '<'; this.nnOpeningTokenOffset = this.nnOpeningToken.length; this.nnClosingToken = '>'; this.nnClosingPostfix = '> '; this.nnClosingPostfixOffset = this.nnClosingPostfix.length; this.bnOpeningToken = '_'; this.bnOpeningPrefix = '_:'; this.bnOpeningPrefixOffset = this.bnOpeningPrefix.length; this.bnClosingToken = ' '; this.bnClosingTokenOffset = this.bnClosingToken.length; this.ltOpeningToken = '"'; this.ltOpeningTokenOffset = this.ltOpeningToken.length; this.ltWhitespaceReplace = /\\r\\n/g; this.ltNewline = '\n'; this.lgOpeningToken = '@'; this.lgOpeningTokenOffset = this.lgOpeningToken.length; this.lgClosingToken = ' '; this.dtSplitPrefix = '"^^<'; this.dtSplitPrefixOffset = this.dtSplitPrefix.length; } _createClass(NQuadsParser, [{ key: "loadBuf", value: function loadBuf(str) { this.addArr(this.parseString(str)); } }, { key: "parseString", value: function parseString(str) { if (!str || str.length === 0) { return []; } var rawStatements = str.split('\n'); var i, len = rawStatements.length; var quads = new Array(len); var cleaned, rightBoundary, leftBoundary; var subject, predicate, object, graph; var dtOrLgBoundary, lang, datatype; for (i = 0; i < len; i++) { try { cleaned = rawStatements[i].trim(); if (cleaned.length === 0) { quads.length--; continue; } rightBoundary = -1; leftBoundary = -1; /* * Parse the subject */ switch (cleaned.charAt(0)) { case '#': quads.length--; continue; case this.nnOpeningToken: rightBoundary = cleaned.indexOf(this.nnClosingPostfix); if (rightBoundary === -1) { throw this.nnClosingTagError; } subject = this.store.sym(cleaned.substring(this.nnOpeningTokenOffset, rightBoundary)); leftBoundary = rightBoundary + this.nnClosingPostfixOffset; break; case this.bnOpeningToken: rightBoundary = cleaned.indexOf(this.bnClosingToken); subject = this.store.bnode(cleaned.substring(this.bnOpeningPrefixOffset, rightBoundary)); leftBoundary = rightBoundary + this.bnClosingTokenOffset; break; default: throw this.unexpectedCharError(cleaned.charAt(0)); } /* * Parse the predicate */ // We currently assume blank nodes can't be predicates rightBoundary = cleaned.indexOf(this.nnClosingPostfix, leftBoundary); if (rightBoundary === -1) { throw this.nnClosingTagError; } leftBoundary = cleaned.indexOf(this.nnOpeningToken, leftBoundary) + this.nnOpeningTokenOffset; predicate = this.store.sym(cleaned.substring(leftBoundary, rightBoundary)); leftBoundary = rightBoundary + this.nnClosingPostfixOffset; /* * Parse the object */ dtOrLgBoundary = -1; switch (cleaned.charAt(leftBoundary)) { case this.nnOpeningToken: leftBoundary = leftBoundary + this.nnOpeningTokenOffset; // When parsing ntriples, the space of the nnClosingPostfix might not exist, so it can't be used rightBoundary = cleaned.indexOf(this.nnClosingToken, leftBoundary); if (rightBoundary === -1) { throw this.nnClosingTagError; } object = this.store.sym(cleaned.substring(leftBoundary, rightBoundary)); break; case this.bnOpeningToken: leftBoundary = cleaned.indexOf(this.bnOpeningPrefix, leftBoundary) + this.bnOpeningPrefixOffset; rightBoundary = cleaned.indexOf(this.bnClosingToken, leftBoundary); // Doesn't contain a comment, nor is a quad, so the bn id is followed by the newline if (rightBoundary === -1) { rightBoundary = Infinity; } object = this.store.bnode(cleaned.substring(leftBoundary, rightBoundary)); break; case '"': leftBoundary = leftBoundary + this.ltOpeningTokenOffset; object = cleaned.substring(leftBoundary, cleaned.lastIndexOf(this.ltOpeningToken)).replace(this.ltWhitespaceReplace, this.ltNewline); leftBoundary += object.length; dtOrLgBoundary = cleaned.indexOf(this.dtSplitPrefix, leftBoundary); if (dtOrLgBoundary >= 0) { // Typed literal rightBoundary = cleaned.indexOf(this.nnClosingToken, dtOrLgBoundary); datatype = this.store.sym(cleaned.substring(dtOrLgBoundary + this.dtSplitPrefixOffset, rightBoundary)); leftBoundary = rightBoundary; } else { dtOrLgBoundary = cleaned.indexOf(this.lgOpeningToken, leftBoundary); if (dtOrLgBoundary >= 0) { lang = cleaned.substring(leftBoundary + this.lgOpeningTokenOffset, cleaned.lastIndexOf(this.lgClosingToken)); datatype = XSD.langString; } else { // Implicit literals are strings datatype = XSD.string; } } object = this.store.literal(object, lang, datatype); break; default: throw this.unexpectedCharError(cleaned.charAt(leftBoundary)); } /* * Parse the graph, if any */ leftBoundary = cleaned.indexOf(this.nnOpeningToken, leftBoundary) + this.nnOpeningTokenOffset; graph = leftBoundary - this.nnOpeningTokenOffset >= 0 ? this.store.sym(cleaned.substring(leftBoundary, cleaned.indexOf(this.nnClosingPostfix, leftBoundary))) : this.store.defaultGraphIRI; quads[i] = [subject, predicate, object, graph]; } catch (e) { console.error(e, rawStatements[i]); } } return quads; } }, { key: "addArr", value: function addArr(quads) { var q; for (var i = 0, len = quads.length; i < len; i++) { q = quads[i]; if (q) { this.store.add(q[0], q[1], q[2], q[3]); } } } }]); return NQuadsParser; }();