1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549 |
- 'use strict';
- var common = require('./common');
- var YAMLException = require('./exception');
- var Mark = require('./mark');
- var NIL = common.NIL;
- var SAFE_SCHEMA = require('./schema/safe');
- var DEFAULT_SCHEMA = require('./schema/default');
- var _hasOwnProperty = Object.prototype.hasOwnProperty;
- var KIND_STRING = 'string';
- var KIND_ARRAY = 'array';
- var KIND_OBJECT = 'object';
- var CONTEXT_FLOW_IN = 1;
- var CONTEXT_FLOW_OUT = 2;
- var CONTEXT_BLOCK_IN = 3;
- var CONTEXT_BLOCK_OUT = 4;
- var CHOMPING_CLIP = 1;
- var CHOMPING_STRIP = 2;
- var CHOMPING_KEEP = 3;
- var CHAR_TAB = 0x09; /* Tab */
- var CHAR_LINE_FEED = 0x0A; /* LF */
- var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */
- var CHAR_SPACE = 0x20; /* Space */
- var CHAR_EXCLAMATION = 0x21; /* ! */
- var CHAR_DOUBLE_QUOTE = 0x22; /* " */
- var CHAR_SHARP = 0x23; /* # */
- var CHAR_PERCENT = 0x25; /* % */
- var CHAR_AMPERSAND = 0x26; /* & */
- var CHAR_SINGLE_QUOTE = 0x27; /* ' */
- var CHAR_ASTERISK = 0x2A; /* * */
- var CHAR_PLUS = 0x2B; /* + */
- var CHAR_COMMA = 0x2C; /* , */
- var CHAR_MINUS = 0x2D; /* - */
- var CHAR_DOT = 0x2E; /* . */
- var CHAR_SLASH = 0x2F; /* / */
- var CHAR_DIGIT_ZERO = 0x30; /* 0 */
- var CHAR_DIGIT_ONE = 0x31; /* 1 */
- var CHAR_DIGIT_NINE = 0x39; /* 9 */
- var CHAR_COLON = 0x3A; /* : */
- var CHAR_LESS_THAN = 0x3C; /* < */
- var CHAR_GREATER_THAN = 0x3E; /* > */
- var CHAR_QUESTION = 0x3F; /* ? */
- var CHAR_COMMERCIAL_AT = 0x40; /* @ */
- var CHAR_CAPITAL_A = 0x41; /* A */
- var CHAR_CAPITAL_F = 0x46; /* F */
- var CHAR_CAPITAL_L = 0x4C; /* L */
- var CHAR_CAPITAL_N = 0x4E; /* N */
- var CHAR_CAPITAL_P = 0x50; /* P */
- var CHAR_CAPITAL_U = 0x55; /* U */
- var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */
- var CHAR_BACKSLASH = 0x5C; /* \ */
- var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */
- var CHAR_UNDERSCORE = 0x5F; /* _ */
- var CHAR_GRAVE_ACCENT = 0x60; /* ` */
- var CHAR_SMALL_A = 0x61; /* a */
- var CHAR_SMALL_B = 0x62; /* b */
- var CHAR_SMALL_E = 0x65; /* e */
- var CHAR_SMALL_F = 0x66; /* f */
- var CHAR_SMALL_N = 0x6E; /* n */
- var CHAR_SMALL_R = 0x72; /* r */
- var CHAR_SMALL_T = 0x74; /* t */
- var CHAR_SMALL_U = 0x75; /* u */
- var CHAR_SMALL_V = 0x76; /* v */
- var CHAR_SMALL_X = 0x78; /* x */
- var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */
- var CHAR_VERTICAL_LINE = 0x7C; /* | */
- var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */
- var SIMPLE_ESCAPE_SEQUENCES = {};
- SIMPLE_ESCAPE_SEQUENCES[CHAR_DIGIT_ZERO] = '\x00';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_A] = '\x07';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_B] = '\x08';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_T] = '\x09';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_TAB] = '\x09';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_N] = '\x0A';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_V] = '\x0B';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_F] = '\x0C';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_R] = '\x0D';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_E] = '\x1B';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_SPACE] = ' ';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_DOUBLE_QUOTE] = '\x22';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_SLASH] = '/';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_BACKSLASH] = '\x5C';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_CAPITAL_N] = '\x85';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_UNDERSCORE] = '\xA0';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_CAPITAL_L] = '\u2028';
- SIMPLE_ESCAPE_SEQUENCES[CHAR_CAPITAL_P] = '\u2029';
- var HEXADECIMAL_ESCAPE_SEQUENCES = {};
- HEXADECIMAL_ESCAPE_SEQUENCES[CHAR_SMALL_X] = 2;
- HEXADECIMAL_ESCAPE_SEQUENCES[CHAR_SMALL_U] = 4;
- HEXADECIMAL_ESCAPE_SEQUENCES[CHAR_CAPITAL_U] = 8;
- var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uD800-\uDFFF\uFFFE\uFFFF]/;
- var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;
- var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/;
- var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i;
- var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
- function loadAll(input, output, options) {
- options = options || {};
- var filename = options['filename'] || null,
- schema = options['schema'] || DEFAULT_SCHEMA,
- resolve = options['resolve'] || true,
- validate = options['validate'] || true,
- strict = options['strict'] || false,
- legacy = options['legacy'] || false,
- directiveHandlers = {},
- implicitTypes = schema.compiledImplicit,
- typeMap = schema.compiledTypeMap,
- length = input.length,
- position = 0,
- line = 0,
- lineStart = 0,
- lineIndent = 0,
- character = input.charCodeAt(position),
- version,
- checkLineBreaks,
- tagMap,
- anchorMap,
- tag,
- anchor,
- kind,
- result;
- function generateError(message) {
- return new YAMLException(
- message,
- new Mark(filename, input, position, line, (position - lineStart)));
- }
- function throwError(message) {
- throw generateError(message);
- }
- function throwWarning(message) {
- var error = generateError(message);
- if (strict) {
- throw error;
- } else {
- console.warn(error.toString());
- }
- }
- directiveHandlers['YAML'] = function handleYamlDirective(name, args) {
- var match, major, minor;
- if (null !== version) {
- throwError('duplication of %YAML directive');
- }
- if (1 !== args.length) {
- throwError('YAML directive accepts exactly one argument');
- }
- match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
- if (null === match) {
- throwError('ill-formed argument of the YAML directive');
- }
- major = parseInt(match[1], 10);
- minor = parseInt(match[2], 10);
- if (1 !== major) {
- throwError('unacceptable YAML version of the document');
- }
- version = args[0];
- checkLineBreaks = (minor < 2);
- if (1 !== minor && 2 !== minor) {
- throwWarning('unsupported YAML version of the document');
- }
- };
- directiveHandlers['TAG'] = function handleTagDirective(name, args) {
- var handle, prefix;
- if (2 !== args.length) {
- throwError('TAG directive accepts exactly two arguments');
- }
- handle = args[0];
- prefix = args[1];
- if (!PATTERN_TAG_HANDLE.test(handle)) {
- throwError('ill-formed tag handle (first argument) of the TAG directive');
- }
- if (_hasOwnProperty.call(tagMap, handle)) {
- throwError('there is a previously declared suffix for "' + handle + '" tag handle');
- }
- if (!PATTERN_TAG_URI.test(prefix)) {
- throwError('ill-formed tag prefix (second argument) of the TAG directive');
- }
- tagMap[handle] = prefix;
- };
- function captureSegment(start, end, checkJson) {
- var _position, _length, _character, _result;
- if (start < end) {
- _result = input.slice(start, end);
- if (checkJson && validate) {
- for (_position = 0, _length = _result.length;
- _position < _length;
- _position += 1) {
- _character = _result.charCodeAt(_position);
- if (!(0x09 === _character ||
- 0x20 <= _character && _character <= 0x10FFFF)) {
- throwError('expected valid JSON character');
- }
- }
- }
- result += _result;
- }
- }
- function mergeMappings(destination, source) {
- var sourceKeys, key, index, quantity;
- if (!common.isObject(source)) {
- throwError('cannot merge mappings; the provided source object is unacceptable');
- }
- sourceKeys = Object.keys(source);
- for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
- key = sourceKeys[index];
- if (!_hasOwnProperty.call(destination, key)) {
- destination[key] = source[key];
- }
- }
- }
- function storeMappingPair(_result, keyTag, keyNode, valueNode) {
- var index, quantity;
- keyNode = String(keyNode);
- if (null === _result) {
- _result = {};
- }
- if ('tag:yaml.org,2002:merge' === keyTag) {
- if (Array.isArray(valueNode)) {
- for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {
- mergeMappings(_result, valueNode[index]);
- }
- } else {
- mergeMappings(_result, valueNode);
- }
- } else {
- _result[keyNode] = valueNode;
- }
- return _result;
- }
- function readLineBreak() {
- if (CHAR_LINE_FEED === character) {
- position += 1;
- } else if (CHAR_CARRIAGE_RETURN === character) {
- if (CHAR_LINE_FEED === input.charCodeAt(position + 1)) {
- position += 2;
- } else {
- position += 1;
- }
- } else {
- throwError('a line break is expected');
- }
- line += 1;
- lineStart = position;
- character = input.charCodeAt(position);
- }
- function skipSeparationSpace(allowComments, checkIndent) {
- var lineBreaks = 0;
- while (position < length) {
- while (CHAR_SPACE === character || CHAR_TAB === character) {
- character = input.charCodeAt(++position);
- }
- if (allowComments && CHAR_SHARP === character) {
- do { character = input.charCodeAt(++position); }
- while (position < length &&
- CHAR_LINE_FEED !== character &&
- CHAR_CARRIAGE_RETURN !== character);
- }
- if (CHAR_LINE_FEED === character || CHAR_CARRIAGE_RETURN === character) {
- readLineBreak();
- lineBreaks += 1;
- lineIndent = 0;
- while (CHAR_SPACE === character) {
- lineIndent += 1;
- character = input.charCodeAt(++position);
- }
- if (lineIndent < checkIndent) {
- throwWarning('deficient indentation');
- }
- } else {
- break;
- }
- }
- return lineBreaks;
- }
- function testDocumentSeparator() {
- var _position, _character;
- if (position === lineStart &&
- (CHAR_MINUS === character || CHAR_DOT === character) &&
- input.charCodeAt(position + 1) === character &&
- input.charCodeAt(position + 2) === character) {
- _position = position + 3;
- _character = input.charCodeAt(_position);
- if (_position >= length ||
- CHAR_SPACE === _character ||
- CHAR_TAB === _character ||
- CHAR_LINE_FEED === _character ||
- CHAR_CARRIAGE_RETURN === _character) {
- return true;
- }
- }
- return false;
- }
- function writeFoldedLines(count) {
- if (1 === count) {
- result += ' ';
- } else if (count > 1) {
- result += common.repeat('\n', count - 1);
- }
- }
- function readPlainScalar(nodeIndent, withinFlowCollection) {
- var preceding,
- following,
- captureStart,
- captureEnd,
- hasPendingContent,
- _line,
- _lineStart,
- _lineIndent,
- _kind = kind,
- _result = result;
- if (CHAR_SPACE === character ||
- CHAR_TAB === character ||
- CHAR_LINE_FEED === character ||
- CHAR_CARRIAGE_RETURN === character ||
- CHAR_COMMA === character ||
- CHAR_LEFT_SQUARE_BRACKET === character ||
- CHAR_RIGHT_SQUARE_BRACKET === character ||
- CHAR_LEFT_CURLY_BRACKET === character ||
- CHAR_RIGHT_CURLY_BRACKET === character ||
- CHAR_SHARP === character ||
- CHAR_AMPERSAND === character ||
- CHAR_ASTERISK === character ||
- CHAR_EXCLAMATION === character ||
- CHAR_VERTICAL_LINE === character ||
- CHAR_GREATER_THAN === character ||
- CHAR_SINGLE_QUOTE === character ||
- CHAR_DOUBLE_QUOTE === character ||
- CHAR_PERCENT === character ||
- CHAR_COMMERCIAL_AT === character ||
- CHAR_GRAVE_ACCENT === character) {
- return false;
- }
- if (CHAR_QUESTION === character ||
- CHAR_MINUS === character) {
- following = input.charCodeAt(position + 1);
- if (CHAR_SPACE === following ||
- CHAR_TAB === following ||
- CHAR_LINE_FEED === following ||
- CHAR_CARRIAGE_RETURN === following ||
- withinFlowCollection &&
- (CHAR_COMMA === following ||
- CHAR_LEFT_SQUARE_BRACKET === following ||
- CHAR_RIGHT_SQUARE_BRACKET === following ||
- CHAR_LEFT_CURLY_BRACKET === following ||
- CHAR_RIGHT_CURLY_BRACKET === following)) {
- return false;
- }
- }
- kind = KIND_STRING;
- result = '';
- captureStart = captureEnd = position;
- hasPendingContent = false;
- while (position < length) {
- if (CHAR_COLON === character) {
- following = input.charCodeAt(position + 1);
- if (CHAR_SPACE === following ||
- CHAR_TAB === following ||
- CHAR_LINE_FEED === following ||
- CHAR_CARRIAGE_RETURN === following ||
- withinFlowCollection &&
- (CHAR_COMMA === following ||
- CHAR_LEFT_SQUARE_BRACKET === following ||
- CHAR_RIGHT_SQUARE_BRACKET === following ||
- CHAR_LEFT_CURLY_BRACKET === following ||
- CHAR_RIGHT_CURLY_BRACKET === following)) {
- break;
- }
- } else if (CHAR_SHARP === character) {
- preceding = input.charCodeAt(position - 1);
- if (CHAR_SPACE === preceding ||
- CHAR_TAB === preceding ||
- CHAR_LINE_FEED === preceding ||
- CHAR_CARRIAGE_RETURN === preceding) {
- break;
- }
- } else if ((position === lineStart && testDocumentSeparator()) ||
- withinFlowCollection &&
- (CHAR_COMMA === character ||
- CHAR_LEFT_SQUARE_BRACKET === character ||
- CHAR_RIGHT_SQUARE_BRACKET === character ||
- CHAR_LEFT_CURLY_BRACKET === character ||
- CHAR_RIGHT_CURLY_BRACKET === character)) {
- break;
- } else if (CHAR_LINE_FEED === character ||
- CHAR_CARRIAGE_RETURN === character) {
- _line = line;
- _lineStart = lineStart;
- _lineIndent = lineIndent;
- skipSeparationSpace(false, -1);
- if (lineIndent >= nodeIndent) {
- hasPendingContent = true;
- continue;
- } else {
- position = captureEnd;
- line = _line;
- lineStart = _lineStart;
- lineIndent = _lineIndent;
- character = input.charCodeAt(position);
- break;
- }
- }
- if (hasPendingContent) {
- captureSegment(captureStart, captureEnd, false);
- writeFoldedLines(line - _line);
- captureStart = captureEnd = position;
- hasPendingContent = false;
- }
- if (CHAR_SPACE !== character && CHAR_TAB !== character) {
- captureEnd = position + 1;
- }
- character = input.charCodeAt(++position);
- }
- captureSegment(captureStart, captureEnd, false);
- if (result) {
- return true;
- } else {
- kind = _kind;
- result = _result;
- return false;
- }
- }
- function readSingleQuotedScalar(nodeIndent) {
- var captureStart, captureEnd;
- if (CHAR_SINGLE_QUOTE !== character) {
- return false;
- }
- kind = KIND_STRING;
- result = '';
- character = input.charCodeAt(++position);
- captureStart = captureEnd = position;
- while (position < length) {
- if (CHAR_SINGLE_QUOTE === character) {
- captureSegment(captureStart, position, true);
- character = input.charCodeAt(++position);
- if (CHAR_SINGLE_QUOTE === character) {
- captureStart = captureEnd = position;
- character = input.charCodeAt(++position);
- } else {
- return true;
- }
- } else if (CHAR_LINE_FEED === character ||
- CHAR_CARRIAGE_RETURN === character) {
- captureSegment(captureStart, captureEnd, true);
- writeFoldedLines(skipSeparationSpace(false, nodeIndent));
- captureStart = captureEnd = position;
- character = input.charCodeAt(position);
- } else if (position === lineStart && testDocumentSeparator()) {
- throwError('unexpected end of the document within a single quoted scalar');
- } else {
- character = input.charCodeAt(++position);
- captureEnd = position;
- }
- }
- throwError('unexpected end of the stream within a single quoted scalar');
- }
- function readDoubleQuotedScalar(nodeIndent) {
- var captureStart,
- captureEnd,
- hexLength,
- hexIndex,
- hexOffset,
- hexResult;
- if (CHAR_DOUBLE_QUOTE !== character) {
- return false;
- }
- kind = KIND_STRING;
- result = '';
- character = input.charCodeAt(++position);
- captureStart = captureEnd = position;
- while (position < length) {
- if (CHAR_DOUBLE_QUOTE === character) {
- captureSegment(captureStart, position, true);
- character = input.charCodeAt(++position);
- return true;
- } else if (CHAR_BACKSLASH === character) {
- captureSegment(captureStart, position, true);
- character = input.charCodeAt(++position);
- if (CHAR_LINE_FEED === character ||
- CHAR_CARRIAGE_RETURN === character) {
- skipSeparationSpace(false, nodeIndent);
- } else if (SIMPLE_ESCAPE_SEQUENCES[character]) {
- result += SIMPLE_ESCAPE_SEQUENCES[character];
- character = input.charCodeAt(++position);
- } else if (HEXADECIMAL_ESCAPE_SEQUENCES[character]) {
- hexLength = HEXADECIMAL_ESCAPE_SEQUENCES[character];
- hexResult = 0;
- for (hexIndex = 1; hexIndex <= hexLength; hexIndex += 1) {
- hexOffset = (hexLength - hexIndex) * 4;
- character = input.charCodeAt(++position);
- if (CHAR_DIGIT_ZERO <= character && character <= CHAR_DIGIT_NINE) {
- hexResult |= (character - CHAR_DIGIT_ZERO) << hexOffset;
- } else if (CHAR_CAPITAL_A <= character && character <= CHAR_CAPITAL_F) {
- hexResult |= (character - CHAR_CAPITAL_A + 10) << hexOffset;
- } else if (CHAR_SMALL_A <= character && character <= CHAR_SMALL_F) {
- hexResult |= (character - CHAR_SMALL_A + 10) << hexOffset;
- } else {
- throwError('expected hexadecimal character');
- }
- }
- result += String.fromCharCode(hexResult);
- character = input.charCodeAt(++position);
- } else {
- throwError('unknown escape sequence');
- }
- captureStart = captureEnd = position;
- } else if (CHAR_LINE_FEED === character ||
- CHAR_CARRIAGE_RETURN === character) {
- captureSegment(captureStart, captureEnd, true);
- writeFoldedLines(skipSeparationSpace(false, nodeIndent));
- captureStart = captureEnd = position;
- character = input.charCodeAt(position);
- } else if (position === lineStart && testDocumentSeparator()) {
- throwError('unexpected end of the document within a double quoted scalar');
- } else {
- character = input.charCodeAt(++position);
- captureEnd = position;
- }
- }
- throwError('unexpected end of the stream within a double quoted scalar');
- }
- function readFlowCollection(nodeIndent) {
- var readNext = true,
- _line,
- _tag = tag,
- _result,
- following,
- terminator,
- isPair,
- isExplicitPair,
- isMapping,
- keyNode,
- keyTag,
- valueNode;
- switch (character) {
- case CHAR_LEFT_SQUARE_BRACKET:
- terminator = CHAR_RIGHT_SQUARE_BRACKET;
- isMapping = false;
- _result = [];
- break;
- case CHAR_LEFT_CURLY_BRACKET:
- terminator = CHAR_RIGHT_CURLY_BRACKET;
- isMapping = true;
- _result = {};
- break;
- default:
- return false;
- }
- if (null !== anchor) {
- anchorMap[anchor] = _result;
- }
- character = input.charCodeAt(++position);
- while (position < length) {
- skipSeparationSpace(true, nodeIndent);
- if (character === terminator) {
- character = input.charCodeAt(++position);
- tag = _tag;
- kind = isMapping ? KIND_OBJECT : KIND_ARRAY;
- result = _result;
- return true;
- } else if (!readNext) {
- throwError('missed comma between flow collection entries');
- }
- keyTag = keyNode = valueNode = null;
- isPair = isExplicitPair = false;
- if (CHAR_QUESTION === character) {
- following = input.charCodeAt(position + 1);
- if (CHAR_SPACE === following ||
- CHAR_TAB === following ||
- CHAR_LINE_FEED === following ||
- CHAR_CARRIAGE_RETURN === following) {
- isPair = isExplicitPair = true;
- position += 1;
- character = following;
- skipSeparationSpace(true, nodeIndent);
- }
- }
- _line = line;
- composeNode(nodeIndent, CONTEXT_FLOW_IN, false, true);
- keyTag = tag;
- keyNode = result;
- if ((isExplicitPair || line === _line) && CHAR_COLON === character) {
- isPair = true;
- character = input.charCodeAt(++position);
- skipSeparationSpace(true, nodeIndent);
- composeNode(nodeIndent, CONTEXT_FLOW_IN, false, true);
- valueNode = result;
- }
- if (isMapping) {
- storeMappingPair(_result, keyTag, keyNode, valueNode);
- } else if (isPair) {
- _result.push(storeMappingPair(null, keyTag, keyNode, valueNode));
- } else {
- _result.push(keyNode);
- }
- skipSeparationSpace(true, nodeIndent);
- if (CHAR_COMMA === character) {
- readNext = true;
- character = input.charCodeAt(++position);
- } else {
- readNext = false;
- }
- }
- throwError('unexpected end of the stream within a flow collection');
- }
- function readBlockScalar(nodeIndent) {
- var captureStart,
- folding,
- chomping = CHOMPING_CLIP,
- detectedIndent = false,
- textIndent = nodeIndent,
- emptyLines = -1;
- switch (character) {
- case CHAR_VERTICAL_LINE:
- folding = false;
- break;
- case CHAR_GREATER_THAN:
- folding = true;
- break;
- default:
- return false;
- }
- kind = KIND_STRING;
- result = '';
- while (position < length) {
- character = input.charCodeAt(++position);
- if (CHAR_PLUS === character || CHAR_MINUS === character) {
- if (CHOMPING_CLIP === chomping) {
- chomping = (CHAR_PLUS === character) ? CHOMPING_KEEP : CHOMPING_STRIP;
- } else {
- throwError('repeat of a chomping mode identifier');
- }
- } else if (CHAR_DIGIT_ZERO <= character && character <= CHAR_DIGIT_NINE) {
- if (CHAR_DIGIT_ZERO === character) {
- throwError('bad explicit indentation width of a block scalar; it cannot be less than one');
- } else if (!detectedIndent) {
- textIndent = nodeIndent + (character - CHAR_DIGIT_ONE);
- detectedIndent = true;
- } else {
- throwError('repeat of an indentation width identifier');
- }
- } else {
- break;
- }
- }
- if (CHAR_SPACE === character || CHAR_TAB === character) {
- do { character = input.charCodeAt(++position); }
- while (CHAR_SPACE === character || CHAR_TAB === character);
- if (CHAR_SHARP === character) {
- do { character = input.charCodeAt(++position); }
- while (position < length &&
- CHAR_LINE_FEED !== character &&
- CHAR_CARRIAGE_RETURN !== character);
- }
- }
- while (position < length) {
- readLineBreak();
- lineIndent = 0;
- while ((!detectedIndent || lineIndent < textIndent) &&
- (CHAR_SPACE === character)) {
- lineIndent += 1;
- character = input.charCodeAt(++position);
- }
- if (!detectedIndent && lineIndent > textIndent) {
- textIndent = lineIndent;
- }
- if (CHAR_LINE_FEED === character || CHAR_CARRIAGE_RETURN === character) {
- emptyLines += 1;
- continue;
- }
- // End of the scalar. Perform the chomping.
- if (lineIndent < textIndent) {
- if (CHOMPING_KEEP === chomping) {
- result += common.repeat('\n', emptyLines + 1);
- } else if (CHOMPING_CLIP === chomping) {
- result += '\n';
- }
- break;
- }
- detectedIndent = true;
- if (folding) {
- if (CHAR_SPACE === character || CHAR_TAB === character) {
- result += common.repeat('\n', emptyLines + 1);
- emptyLines = 1;
- } else if (0 === emptyLines) {
- result += ' ';
- emptyLines = 0;
- } else {
- result += common.repeat('\n', emptyLines);
- emptyLines = 0;
- }
- } else {
- result += common.repeat('\n', emptyLines + 1);
- emptyLines = 0;
- }
- captureStart = position;
- do { character = input.charCodeAt(++position); }
- while (position < length &&
- CHAR_LINE_FEED !== character &&
- CHAR_CARRIAGE_RETURN !== character);
- captureSegment(captureStart, position, false);
- }
- return true;
- }
- function readBlockSequence(nodeIndent) {
- var _line,
- _tag = tag,
- _result = [],
- following,
- detected = false;
- if (null !== anchor) {
- anchorMap[anchor] = _result;
- }
- while (position < length) {
- if (CHAR_MINUS !== character) {
- break;
- }
- following = input.charCodeAt(position + 1);
- if (CHAR_SPACE !== following &&
- CHAR_TAB !== following &&
- CHAR_LINE_FEED !== following &&
- CHAR_CARRIAGE_RETURN !== following) {
- break;
- }
- detected = true;
- position += 1;
- character = following;
- if (skipSeparationSpace(true, -1)) {
- if (lineIndent <= nodeIndent) {
- _result.push(null);
- continue;
- }
- }
- _line = line;
- composeNode(nodeIndent, CONTEXT_BLOCK_IN, false, true);
- _result.push(result);
- skipSeparationSpace(true, -1);
- if ((line === _line || lineIndent > nodeIndent) && position < length) {
- throwError('bad indentation of a sequence entry');
- } else if (lineIndent < nodeIndent) {
- break;
- }
- }
- if (detected) {
- tag = _tag;
- kind = KIND_ARRAY;
- result = _result;
- return true;
- } else {
- return false;
- }
- }
- function readBlockMapping(nodeIndent) {
- var following,
- allowCompact,
- _line,
- _tag = tag,
- _result = {},
- keyTag = null,
- keyNode = null,
- valueNode = null,
- atExplicitKey = false,
- detected = false;
- if (null !== anchor) {
- anchorMap[anchor] = _result;
- }
- while (position < length) {
- following = input.charCodeAt(position + 1);
- _line = line; // Save the current line.
- if ((CHAR_QUESTION === character ||
- CHAR_COLON === character) &&
- (CHAR_SPACE === following ||
- CHAR_TAB === following ||
- CHAR_LINE_FEED === following ||
- CHAR_CARRIAGE_RETURN === following)) {
- if (CHAR_QUESTION === character) {
- if (atExplicitKey) {
- storeMappingPair(_result, keyTag, keyNode, null);
- keyTag = keyNode = valueNode = null;
- }
- detected = true;
- atExplicitKey = true;
- allowCompact = true;
- } else if (atExplicitKey) {
- // i.e. CHAR_COLON === character after the explicit key.
- atExplicitKey = false;
- allowCompact = true;
- } else {
- throwError('incomplete explicit mapping pair; a key node is missed');
- }
- position += 1;
- character = following;
- } else if (composeNode(nodeIndent, CONTEXT_FLOW_OUT, false, true)) {
- if (line === _line) {
- // TODO: Remove this cycle when the flow readers will consume
- // trailing whitespaces like the block readers.
- while (CHAR_SPACE === character ||
- CHAR_TAB === character) {
- character = input.charCodeAt(++position);
- }
- if (CHAR_COLON === character) {
- character = input.charCodeAt(++position);
- if (CHAR_SPACE !== character &&
- CHAR_TAB !== character &&
- CHAR_LINE_FEED !== character &&
- CHAR_CARRIAGE_RETURN !== character) {
- throwError('a whitespace character is expected after the key-value separator within a block mapping');
- }
- if (atExplicitKey) {
- storeMappingPair(_result, keyTag, keyNode, null);
- keyTag = keyNode = valueNode = null;
- }
- detected = true;
- atExplicitKey = false;
- allowCompact = false;
- keyTag = tag;
- keyNode = result;
- } else if (detected) {
- throwError('can not read an implicit mapping pair; a colon is missed');
- } else {
- tag = _tag;
- return true; // Keep the result of `composeNode`.
- }
- } else if (detected) {
- throwError('can not read a block mapping entry; a multiline key may not be an implicit key');
- } else {
- tag = _tag;
- return true; // Keep the result of `composeNode`.
- }
- } else {
- break;
- }
- if (line === _line || lineIndent > nodeIndent) {
- if (composeNode(nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {
- if (atExplicitKey) {
- keyNode = result;
- } else {
- valueNode = result;
- }
- }
- if (!atExplicitKey) {
- storeMappingPair(_result, keyTag, keyNode, valueNode);
- keyTag = keyNode = valueNode = null;
- }
- // TODO: It is needed only for flow node readers. It should be removed
- // when the flow readers will consume trailing whitespaces as well as
- // the block readers.
- skipSeparationSpace(true, -1);
- }
- if (lineIndent > nodeIndent && position < length) {
- throwError('bad indentation of a mapping entry');
- } else if (lineIndent < nodeIndent) {
- break;
- }
- }
- if (atExplicitKey) {
- storeMappingPair(_result, keyTag, keyNode, null);
- }
- if (detected) {
- tag = _tag;
- kind = KIND_OBJECT;
- result = _result;
- }
- return detected;
- }
- function readTagProperty() {
- var _position,
- isVerbatim = false,
- isNamed = false,
- tagHandle,
- tagName;
- if (CHAR_EXCLAMATION !== character) {
- return false;
- }
- if (null !== tag) {
- throwError('duplication of a tag property');
- }
- character = input.charCodeAt(++position);
- if (CHAR_LESS_THAN === character) {
- isVerbatim = true;
- character = input.charCodeAt(++position);
- } else if (CHAR_EXCLAMATION === character) {
- isNamed = true;
- tagHandle = '!!';
- character = input.charCodeAt(++position);
- } else {
- tagHandle = '!';
- }
- _position = position;
- if (isVerbatim) {
- do { character = input.charCodeAt(++position); }
- while (position < length && CHAR_GREATER_THAN !== character);
- if (position < length) {
- tagName = input.slice(_position, position);
- character = input.charCodeAt(++position);
- } else {
- throwError('unexpected end of the stream within a verbatim tag');
- }
- } else {
- while (position < length &&
- CHAR_SPACE !== character &&
- CHAR_TAB !== character &&
- CHAR_LINE_FEED !== character &&
- CHAR_CARRIAGE_RETURN !== character) {
- if (CHAR_EXCLAMATION === character) {
- if (!isNamed) {
- tagHandle = input.slice(_position - 1, position + 1);
- if (validate && !PATTERN_TAG_HANDLE.test(tagHandle)) {
- throwError('named tag handle cannot contain such characters');
- }
- isNamed = true;
- _position = position + 1;
- } else {
- throwError('tag suffix cannot contain exclamation marks');
- }
- }
- character = input.charCodeAt(++position);
- }
- tagName = input.slice(_position, position);
- if (validate && PATTERN_FLOW_INDICATORS.test(tagName)) {
- throwError('tag suffix cannot contain flow indicator characters');
- }
- }
- if (validate && tagName && !PATTERN_TAG_URI.test(tagName)) {
- throwError('tag name cannot contain such characters: ' + tagName);
- }
- if (isVerbatim) {
- tag = tagName;
- } else if (_hasOwnProperty.call(tagMap, tagHandle)) {
- tag = tagMap[tagHandle] + tagName;
- } else if ('!' === tagHandle) {
- tag = '!' + tagName;
- } else if ('!!' === tagHandle) {
- tag = 'tag:yaml.org,2002:' + tagName;
- } else {
- throwError('undeclared tag handle "' + tagHandle + '"');
- }
- return true;
- }
- function readAnchorProperty() {
- var _position;
- if (CHAR_AMPERSAND !== character) {
- return false;
- }
- if (null !== anchor) {
- throwError('duplication of an anchor property');
- }
- character = input.charCodeAt(++position);
- _position = position;
- while (position < length &&
- CHAR_SPACE !== character &&
- CHAR_TAB !== character &&
- CHAR_LINE_FEED !== character &&
- CHAR_CARRIAGE_RETURN !== character &&
- CHAR_COMMA !== character &&
- CHAR_LEFT_SQUARE_BRACKET !== character &&
- CHAR_RIGHT_SQUARE_BRACKET !== character &&
- CHAR_LEFT_CURLY_BRACKET !== character &&
- CHAR_RIGHT_CURLY_BRACKET !== character) {
- character = input.charCodeAt(++position);
- }
- if (position === _position) {
- throwError('name of an anchor node must contain at least one character');
- }
- anchor = input.slice(_position, position);
- return true;
- }
- function readAlias() {
- var _position, alias;
- if (CHAR_ASTERISK !== character) {
- return false;
- }
- character = input.charCodeAt(++position);
- _position = position;
- while (position < length &&
- CHAR_SPACE !== character &&
- CHAR_TAB !== character &&
- CHAR_LINE_FEED !== character &&
- CHAR_CARRIAGE_RETURN !== character &&
- CHAR_COMMA !== character &&
- CHAR_LEFT_SQUARE_BRACKET !== character &&
- CHAR_RIGHT_SQUARE_BRACKET !== character &&
- CHAR_LEFT_CURLY_BRACKET !== character &&
- CHAR_RIGHT_CURLY_BRACKET !== character) {
- character = input.charCodeAt(++position);
- }
- if (position === _position) {
- throwError('name of an alias node must contain at least one character');
- }
- alias = input.slice(_position, position);
- if (!anchorMap.hasOwnProperty(alias)) {
- throwError('unidentified alias "' + alias + '"');
- }
- result = anchorMap[alias];
- skipSeparationSpace(true, -1);
- return true;
- }
- function composeNode(parentIndent, nodeContext, allowToSeek, allowCompact) {
- var allowBlockStyles,
- allowBlockScalars,
- allowBlockCollections,
- atNewLine = false,
- isIndented = true,
- hasContent = false,
- typeIndex,
- typeQuantity,
- type,
- typeLoader,
- flowIndent,
- blockIndent,
- _result;
- tag = null;
- anchor = null;
- kind = null;
- result = null;
- allowBlockStyles = allowBlockScalars = allowBlockCollections =
- CONTEXT_BLOCK_OUT === nodeContext ||
- CONTEXT_BLOCK_IN === nodeContext;
- if (allowToSeek) {
- if (skipSeparationSpace(true, -1)) {
- atNewLine = true;
- if (lineIndent === parentIndent) {
- isIndented = false;
- } else if (lineIndent > parentIndent) {
- isIndented = true;
- } else {
- return false;
- }
- }
- }
- if (isIndented) {
- while (readTagProperty() || readAnchorProperty()) {
- if (skipSeparationSpace(true, -1)) {
- atNewLine = true;
- if (lineIndent > parentIndent) {
- isIndented = true;
- allowBlockCollections = allowBlockStyles;
- } else if (lineIndent === parentIndent) {
- isIndented = false;
- allowBlockCollections = allowBlockStyles;
- } else {
- return true;
- }
- } else {
- allowBlockCollections = false;
- }
- }
- }
- if (allowBlockCollections) {
- allowBlockCollections = atNewLine || allowCompact;
- }
- if (isIndented || CONTEXT_BLOCK_OUT === nodeContext) {
- if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {
- flowIndent = parentIndent;
- } else {
- flowIndent = parentIndent + 1;
- }
- blockIndent = position - lineStart;
- if (isIndented) {
- if (allowBlockCollections &&
- (readBlockSequence(blockIndent) ||
- readBlockMapping(blockIndent)) ||
- readFlowCollection(flowIndent)) {
- hasContent = true;
- } else {
- if ((allowBlockScalars && readBlockScalar(flowIndent)) ||
- readSingleQuotedScalar(flowIndent) ||
- readDoubleQuotedScalar(flowIndent)) {
- hasContent = true;
- } else if (readAlias()) {
- hasContent = true;
- if (null !== tag || null !== anchor) {
- throwError('alias node should not have any properties');
- }
- } else if (readPlainScalar(flowIndent, CONTEXT_FLOW_IN === nodeContext)) {
- hasContent = true;
- if (null === tag) {
- tag = '?';
- }
- }
- if (null !== anchor) {
- anchorMap[anchor] = result;
- }
- }
- } else {
- hasContent = allowBlockCollections && readBlockSequence(blockIndent);
- }
- }
- if (null !== tag && '!' !== tag) {
- if ('?' === tag) {
- if (resolve) {
- for (typeIndex = 0, typeQuantity = implicitTypes.length;
- typeIndex < typeQuantity;
- typeIndex += 1) {
- type = implicitTypes[typeIndex];
- // Implicit resolving is not allowed for non-scalar types, and '?'
- // non-specific tag is only assigned to plain scalars. So, it isn't
- // needed to check for 'kind' conformity.
- _result = type.loader.resolver(result, false);
- if (NIL !== _result) {
- tag = type.tag;
- result = _result;
- break;
- }
- }
- }
- } else if (_hasOwnProperty.call(typeMap, tag)) {
- typeLoader = typeMap[tag].loader;
- if (null !== result && typeLoader.kind !== kind) {
- throwError('unacceptable node kind for !<' + tag + '> tag; it should be "' + typeLoader.kind + '", not "' + kind + '"');
- }
- if (typeLoader.resolver) {
- _result = typeLoader.resolver(result, true);
- if (NIL !== _result) {
- result = _result;
- } else {
- throwError('cannot resolve a node with !<' + tag + '> explicit tag');
- }
- }
- } else {
- throwWarning('unknown tag !<' + tag + '>');
- }
- }
- return null !== tag || null !== anchor || hasContent;
- }
- function readDocument() {
- var documentStart = position,
- _position,
- directiveName,
- directiveArgs,
- hasDirectives = false;
- version = null;
- checkLineBreaks = legacy;
- tagMap = {};
- anchorMap = {};
- while (position < length) {
- skipSeparationSpace(true, -1);
- if (lineIndent > 0 || CHAR_PERCENT !== character) {
- break;
- }
- hasDirectives = true;
- character = input.charCodeAt(++position);
- _position = position;
- while (position < length &&
- CHAR_SPACE !== character &&
- CHAR_TAB !== character &&
- CHAR_LINE_FEED !== character &&
- CHAR_CARRIAGE_RETURN !== character) {
- character = input.charCodeAt(++position);
- }
- directiveName = input.slice(_position, position);
- directiveArgs = [];
- if (directiveName.length < 1) {
- throwError('directive name must not be less than one character in length');
- }
- while (position < length) {
- while (CHAR_SPACE === character || CHAR_TAB === character) {
- character = input.charCodeAt(++position);
- }
- if (CHAR_SHARP === character) {
- do { character = input.charCodeAt(++position); }
- while (position < length &&
- CHAR_LINE_FEED !== character &&
- CHAR_CARRIAGE_RETURN !== character);
- break;
- }
- if (CHAR_LINE_FEED === character || CHAR_CARRIAGE_RETURN === character) {
- break;
- }
- _position = position;
- while (position < length &&
- CHAR_SPACE !== character &&
- CHAR_TAB !== character &&
- CHAR_LINE_FEED !== character &&
- CHAR_CARRIAGE_RETURN !== character) {
- character = input.charCodeAt(++position);
- }
- directiveArgs.push(input.slice(_position, position));
- }
- if (position < length) {
- readLineBreak();
- }
- if (_hasOwnProperty.call(directiveHandlers, directiveName)) {
- directiveHandlers[directiveName](directiveName, directiveArgs);
- } else {
- throwWarning('unknown document directive "' + directiveName + '"');
- }
- }
- skipSeparationSpace(true, -1);
- if (0 === lineIndent &&
- CHAR_MINUS === character &&
- CHAR_MINUS === input.charCodeAt(position + 1) &&
- CHAR_MINUS === input.charCodeAt(position + 2)) {
- position += 3;
- character = input.charCodeAt(position);
- skipSeparationSpace(true, -1);
- } else if (hasDirectives) {
- throwError('directives end mark is expected');
- }
- composeNode(lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);
- skipSeparationSpace(true, -1);
- if (validate && checkLineBreaks &&
- PATTERN_NON_ASCII_LINE_BREAKS.test(input.slice(documentStart, position))) {
- throwWarning('non-ASCII line breaks are interpreted as content');
- }
- output(result);
- if (position === lineStart && testDocumentSeparator()) {
- if (CHAR_DOT === character) {
- position += 3;
- character = input.charCodeAt(position);
- skipSeparationSpace(true, -1);
- }
- return;
- }
- if (position < length) {
- throwError('end of the stream or a document separator is expected');
- } else {
- return;
- }
- }
- if (validate && PATTERN_NON_PRINTABLE.test(input)) {
- throwError('the stream contains non-printable characters');
- }
- while (CHAR_SPACE === character) {
- lineIndent += 1;
- character = input.charCodeAt(++position);
- }
- while (position < length) {
- readDocument();
- }
- }
- function load(input, options) {
- var result = null, received = false;
- function callback(data) {
- if (!received) {
- result = data;
- received = true;
- } else {
- throw new YAMLException('expected a single document in the stream, but found more');
- }
- }
- loadAll(input, callback, options);
- return result;
- }
- function safeLoadAll(input, output, options) {
- loadAll(input, output, common.extend({ schema: SAFE_SCHEMA }, options));
- }
- function safeLoad(input, options) {
- return load(input, common.extend({ schema: SAFE_SCHEMA }, options));
- }
- module.exports.loadAll = loadAll;
- module.exports.load = load;
- module.exports.safeLoadAll = safeLoadAll;
- module.exports.safeLoad = safeLoad;
|