/// <summary> /// Checks the prefix is as expected /// <p /> /// If the prefix is not as expected and <paramref name="errorOnFail"/> is set to true, an exception will be thrown /// </summary> /// <param name="dataReader">The data reader.</param> /// <param name="prefix">The prefix.</param> /// <param name="errorOnFail">if set to <c>true</c> will throw an exception on fail.</param> /// <returns>true if it the prefix is as expected; otherwise false.</returns> /// <exception cref="System.ArgumentException">Expecting prefix : ' <c> prefix.GetPrefix() </c> ' but got ' <c> dataReader.LineType </c> '</exception> public static bool AssertPrefix(IEdiReader dataReader, EdiPrefix prefix, bool errorOnFail) { if (dataReader.LineType != prefix) { if (errorOnFail) { throw new ArgumentException("Expecting prefix : '" + prefix.GetPrefix() + "' but got '" + dataReader.LineType + "'"); } return false; } return true; }
/// <summary> /// Moves the file pointer to the next line. /// </summary> /// <returns>false if there is no next line.</returns> public override bool MoveNext() { string linePrefix; if (this._tmpStore != null) { // If there are entries in the temporaryStore, pop the first entry, make it the currentLine // and remember to increment the filePosition counter of the superclass, otherwise we'll end up // with a mismatch of actual to expected lines. this.CurrentLine = this._tmpStore[0]; this._tmpStore.RemoveAt(0); this.FilePosition++; if (this._tmpStore.Count > 0) { this._tmpStore = null; } this._lineType = EdiPrefixExtension.ParseString(this.CurrentLine); linePrefix = this._lineType.GetPrefix(); this.CurrentLine = this.CurrentLine.Substring(linePrefix.Length); return true; } if (this.BackLine) { this.BackLine = false; return true; } bool nextLine = base.MoveNext(); if (!nextLine) { return false; } // We cannot use the string method Trim() here, since it is important to trim Only the leading // whitespace. There could be trailing whitespace which has meaning in Edi. At this point the // variable currentLine does not contain the end-marker character. // So the Edi "Una:+.? '" would now be in currentLine as "Una:+.? ". // The trailing whitespace is Vital in this case, so only trim the leading whitespace // otherwise we may produce errors. this.CurrentLine = this.CurrentLine.TrimStart(); if (this._endOfFileReached) { if (this.CurrentLine.Trim().Length == 0) { // There is whitespace after the end of the file. Just simply ignore it. this.CurrentLine = string.Empty; return true; } } // Does this line contain a ' character? If so, this line needs splitting int idx = this.CurrentLine.IndexOf(EdiConstants.EndTag, StringComparison.Ordinal); if (idx != -1) { // Reset the temporaryStore and evaluate the entire "current line" this._tmpStore = new List<string>(); string evaluationString = this.CurrentLine; while (idx != -1) { // Count the number of sequential ? characters at the end of the evaluation valueOfString int questionMarkCount = 0; for (int j = idx - 1; j >= 0; j--) { if (evaluationString[j] == '?') { questionMarkCount++; } else { break; } } if (questionMarkCount == 0 || questionMarkCount % 2 == 0) { // This should have been a split but wasn't. // Put the 1st part of the evaluation valueOfString into the temporary store, and the process everything after the 1st ' character // So if the evaluation valueOfString is currently: foo??'bar // foo?? goes into temporary store // bar becomes the next bit to evaluate this._tmpStore.Add(evaluationString.Substring(0, idx)); evaluationString = evaluationString.Substring(idx + 1); // The +1 here ensures that the ' character is not included idx = evaluationString.IndexOf(EdiConstants.EndTag, StringComparison.Ordinal); } else { // This was an escaped ' character so hunt for the next one idx = evaluationString.IndexOf(EdiConstants.EndTag[0], idx + 1); } if (idx == -1) { // There are no more ' characters so put whatever remains into the temporary store this._tmpStore.Add(evaluationString); } } // Pop the first item out of the temporary store // Note: there is no need to increment the filePosition counter of the superclass since it was // done in the prior call: super.MoveNext(); this.CurrentLine = this._tmpStore[0]; this._tmpStore.RemoveAt(0); if (this._tmpStore.Count > 0) { this._tmpStore = null; } } this._lineType = EdiPrefixExtension.ParseString(this.CurrentLine); linePrefix = this._lineType.GetPrefix(); if (linePrefix.Equals("UNZ+")) { this._endOfFileReached = true; } this.CurrentLine = this.CurrentLine.Substring(linePrefix.Length); return true; }
/// <summary> /// Checks the attribute value validity. /// </summary> /// <param name="attributeConceptId"> /// The attribute concept identifier. /// </param> /// <param name="attributeValue"> /// The attribute value. /// </param> /// <param name="ediPrefix"> /// The EDI prefix. /// </param> /// <exception cref="SdmxSyntaxException"> /// Processing Un-coded Dataset Attribute (IDE+Z11) encountered illegal empty value for attribute: + attributeConceptId /// or /// Processing Coded Dataset Attribute (IDE+Z10) encountered illegal empty code for attribute: + attributeConceptId /// </exception> private void CheckAttributeValueValidity(string attributeConceptId, string attributeValue, EdiPrefix ediPrefix) { DatasetAction action = null; if (this.CurrentDatasetHeader != null) { action = this.CurrentDatasetHeader.Action; } if (action == null && this._header != null && this._header.Action != null) { action = this._header.Action; } // If the action is Not delete then the value must be legal. // Spaces are considered legal values if (action != DatasetActionEnumType.Delete) { if (string.IsNullOrEmpty(attributeValue)) { if (ediPrefix.Equals(EdiPrefix.DatasetAttributeUncoded)) { throw new SdmxSyntaxException("Processing Uncoded Dataset Attribute (IDE+Z11) encountered illegal empty value for attribute: " + attributeConceptId); } throw new SdmxSyntaxException("Processing Coded Dataset Attribute (IDE+Z10) encountered illegal empty code for attribute: " + attributeConceptId); } } }