Beispiel #1
0
        /// <summary>
        /// Parses an array from the current parsing position.
        /// The prerequisite for calling this method is, that an array begin token has been read.
        /// </summary>
        /// <returns>The array found at the parsing position.</returns>
        NSArray ParseArray()
        {
            //Skip begin token
            int startPosition = this.index;

            Skip();
            SkipWhitespacesAndComments();
            List <NSObject> objects = new List <NSObject>();

            while (!Accept(ARRAY_END_TOKEN))
            {
                objects.Add(ParseObject());
                SkipWhitespacesAndComments();
                if (Accept(ARRAY_ITEM_DELIMITER_TOKEN))
                {
                    Skip();
                }
                else
                {
                    break; //must have reached end of array
                }
                SkipWhitespacesAndComments();
            }
            //parse end token
            Read(ARRAY_END_TOKEN);
            return(new NSArray(objects.ToArray(), BinaryOrigin.FromRange(startPosition, this.index)));
        }
Beispiel #2
0
        /// <summary>
        /// Parses the NSObject found at the current position in the property list
        /// data stream.
        /// </summary>
        /// <returns>The parsed NSObject.</returns>
        /// <seealso cref="ASCIIPropertyListParser.index"/>
        NSObject ParseObject()
        {
            switch (data[index])
            {
            case ARRAY_BEGIN_TOKEN:
            {
                return(ParseArray());
            }

            case DICTIONARY_BEGIN_TOKEN:
            {
                return(ParseDictionary());
            }

            case DATA_BEGIN_TOKEN:
            {
                return(ParseData());
            }

            case QUOTEDSTRING_BEGIN_TOKEN:
            {
                int    startIndex   = this.index;
                string quotedString = ParseQuotedString();
                //apple dates are quoted strings of length 20 and after the 4 year digits a dash is found
                if (quotedString.Length == 20 && quotedString[4] == DATE_DATE_FIELD_DELIMITER)
                {
                    try
                    {
                        return(new NSDate(quotedString, BinaryOrigin.FromRange(startIndex, this.index)));
                    }
                    catch (Exception)
                    {
                        //not a date? --> return string
                        return(new NSString(quotedString, BinaryOrigin.FromRange(startIndex, this.index)));
                    }
                }
                return(new NSString(quotedString, BinaryOrigin.FromRange(startIndex, this.index)));
            }

            default:
            {
                //0-9
                if (data[index] > 0x2F && data[index] < 0x3A)
                {
                    //could be a date or just a string
                    return(ParseDateString());
                }
                else
                {
                    //non-numerical -> string or boolean
                    var    startIndex   = this.index;
                    string parsedString = ParseString();
                    return(new NSString(parsedString, BinaryOrigin.FromRange(startIndex, this.index)));
                }
            }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Attempts to parse a plain string as a date if possible.
        /// </summary>
        /// <returns>A NSDate if the string represents such an object. Otherwise a NSString is returned.</returns>
        NSObject ParseDateString()
        {
            var    startIndex      = this.index;
            string numericalString = ParseString();

            if (numericalString.Length > 4 && numericalString[4] == DATE_DATE_FIELD_DELIMITER)
            {
                try
                {
                    return(new NSDate(numericalString, BinaryOrigin.FromRange(startIndex, this.index)));
                }
                catch (Exception)
                {
                    //An exception occurs if the string is not a date but just a string
                }
            }
            return(new NSString(numericalString, BinaryOrigin.FromRange(startIndex, this.index)));
        }
Beispiel #4
0
        /// <summary>
        /// Parses a dictionary from the current parsing position.
        /// The prerequisite for calling this method is, that a dictionary begin token has been read.
        /// </summary>
        /// <returns>The dictionary found at the parsing position.</returns>
        NSDictionary ParseDictionary()
        {
            //Skip begin token
            var origin = new BinaryOrigin(this.index, 0);

            Skip();
            SkipWhitespacesAndComments();
            NSDictionary dict = new NSDictionary(origin);

            while (!Accept(DICTIONARY_END_TOKEN))
            {
                //Parse key
                string keyString;
                if (Accept(QUOTEDSTRING_BEGIN_TOKEN))
                {
                    keyString = ParseQuotedString();
                }
                else
                {
                    keyString = ParseString();
                }
                SkipWhitespacesAndComments();

                //Parse assign token
                Read(DICTIONARY_ASSIGN_TOKEN);
                SkipWhitespacesAndComments();

                NSObject nso = ParseObject();
                dict.Add(keyString, nso);
                SkipWhitespacesAndComments();
                Read(DICTIONARY_ITEM_DELIMITER_TOKEN);
                SkipWhitespacesAndComments();
            }
            //skip end token
            Skip();

            origin.SetEndPosition(this.index);

            return(dict);
        }
Beispiel #5
0
        /// <summary>
        /// Parses a data object from the current parsing position.
        /// This can either be a NSData object or a GnuStep NSNumber or NSDate.
        /// The prerequisite for calling this method is, that a data begin token has been read.
        /// </summary>
        /// <returns>The data object found at the parsing position.</returns>
        NSObject ParseData()
        {
            NSObject obj = null;
            //Skip begin token
            var origin = new BinaryOrigin(this.index, 0);

            Skip();
            if (Accept(DATA_GSOBJECT_BEGIN_TOKEN))
            {
                Skip();
                Expect(DATA_GSBOOL_BEGIN_TOKEN, DATA_GSDATE_BEGIN_TOKEN, DATA_GSINT_BEGIN_TOKEN, DATA_GSREAL_BEGIN_TOKEN);
                if (Accept(DATA_GSBOOL_BEGIN_TOKEN))
                {
                    //Boolean
                    Skip();
                    Expect(DATA_GSBOOL_TRUE_TOKEN, DATA_GSBOOL_FALSE_TOKEN);
                    if (Accept(DATA_GSBOOL_TRUE_TOKEN))
                    {
                        obj = new NSNumber(true, origin);
                    }
                    else
                    {
                        obj = new NSNumber(false, origin);
                    }
                    //Skip the parsed boolean token
                    Skip();
                }
                else if (Accept(DATA_GSDATE_BEGIN_TOKEN))
                {
                    //Date
                    Skip();
                    string dateString = ReadInputUntil(DATA_END_TOKEN);
                    obj = new NSDate(dateString, origin);
                }
                else if (Accept(DATA_GSINT_BEGIN_TOKEN, DATA_GSREAL_BEGIN_TOKEN))
                {
                    //Number
                    Skip();
                    string numberString = ReadInputUntil(DATA_END_TOKEN);
                    obj = new NSNumber(numberString, origin);
                }
                //parse data end token
                Read(DATA_END_TOKEN);
            }
            else
            {
                string dataString = ReadInputUntil(DATA_END_TOKEN);
                dataString = Regex.Replace(dataString, "\\s+", "");

                int    numBytes = dataString.Length / 2;
                byte[] bytes    = new byte[numBytes];
                for (int i = 0; i < bytes.Length; i++)
                {
                    string byteString = dataString.Substring(i * 2, 2);
                    int    byteValue  = Convert.ToInt32(byteString, 16);
                    bytes[i] = (byte)byteValue;
                }
                obj = new NSData(bytes, origin);

                //skip end token
                Skip();
            }

            origin.SetEndPosition(this.index);
            return(obj);
        }