コード例 #1
0
        private void CreateStringIndexerImpl()
        {
            //Create a string from the start/end provided, use a bit of cache to ensure we're not chugging memory, the memory we use here speeds things up by a factor of about 18.
            var stringIndexer = this.CharStream.Indexers.Add(_identityManager.ObtainTypeReference(RuntimeCoreType.String), new TypedNameSeries(new TypedName("start", RuntimeCoreType.Int32, _identityManager), new TypedName("end", RuntimeCoreType.Int32, _identityManager)), true, false);
            var startParam    = stringIndexer.Parameters["start"];
            var endParam      = stringIndexer.Parameters["end"];

            stringIndexer.SummaryText = string.Format("Obtains the @s:String; value inclusively between the @p:{0}; @p:{1}; provided.", startParam.Name, endParam.Name);
            startParam.SummaryText    = string.Format("The @s:Int32; value denoting the start character offset within the @s:{0}; to retrieve the string of.", CharStream.Name);
            endParam.SummaryText      = string.Format("The @s:Int32; value denoting the end character offset within the @s:{0}; to retrieve the string of.", CharStream.Name);
            var stringTypeRef = this._identityManager.ObtainTypeReference(RuntimeCoreType.String);

            stringIndexer.GetMethod.Comment(@"Create a string from the start/end provided, use a bit of cache to ensure we're not chugging memory, the memory we use here speeds things up by a factor of about 18.");
            var resultLocal = stringIndexer.GetMethod.Locals.Add(new TypedName("result", RuntimeCoreType.String, this._identityManager));
            // if (!cache.TryGetValue(start, end, out result)) { ...
            var cacheCheck = stringIndexer.GetMethod.If(this.StringCacheImpl.GetReference().GetMethod("TryGetValue").Invoke(startParam.GetReference(), endParam.GetReference(), resultLocal.GetReference().Direct(ParameterCoercionDirection.Out)).Not());

            cacheCheck.Comment("Index patch-up.  If we receive a value beyond the end of the stream, fix-up the end value, we make note of the original index because it might result in two cache entries, but only one string.");
            var endValue    = cacheCheck.Locals.Add(new TypedName("endValue", RuntimeCoreType.Int32, this._identityManager), CharIndexerImpl.GetReference(new SpecialReferenceExpression(SpecialReferenceKind.This), endParam.GetReference()));
            var originalEnd = cacheCheck.Locals.Add(new TypedName("originalEnd", RuntimeCoreType.Int32, this._identityManager), endParam.GetReference());
            var endCheck    = cacheCheck.If(endValue.EqualTo(-1));

            endCheck.Assign(endParam.GetReference(), ActualBufferLength.GetReference().Cast(endParam.ParameterType));
            endCheck.Comment("If we went past the end, make one final check with the new end to make sure the data is read, if you seek past the end it skips the read because it logically knows there's nothing there.");
            // if (this.buffer[end] == char.MinValue)
            var readSkipCheck = endCheck.If(endValue.EqualTo(this._identityManager.ObtainTypeReference(RuntimeCoreType.Char).GetTypeExpression().GetField("MinValue")));

            // endValue = this[end];
            readSkipCheck.Assign(endValue.GetReference(), CharIndexerImpl.GetReference(new SpecialReferenceExpression(SpecialReferenceKind.This), endParam.GetReference()));
            // if (end <= start)
            var rangeCheck = cacheCheck.If(endParam.LessThanOrEqualTo(startParam));

            //     return string.Empty;
            rangeCheck.Return(stringTypeRef.GetTypeExpression().GetField("Empty"));

            // else if (originalEnd == end)
            rangeCheck.CreateNext(originalEnd.EqualTo(endParam));
            var rangeNext = (IConditionBlockStatement)rangeCheck.Next;

            //cache.Try(start, end, result = new string(this.buffer, start, end - start));
            rangeNext.Call(StringCacheImpl.GetReference().GetMethod("Add").Invoke(startParam.GetReference(), endParam.GetReference(), resultLocal.GetReference().Assign(stringTypeRef.GetNewExpression(this.BufferArrayField.GetReference(), startParam.GetReference(), endParam.Subtract(startParam)))));

            rangeNext.CreateNext(this.StringCacheImpl.GetReference().GetMethod("TryGetValue").Invoke(startParam.GetReference(), endParam.GetReference(), resultLocal.GetReference().Direct(ParameterCoercionDirection.Out)).Not());
            rangeNext = (IConditionBlockStatement)rangeNext.Next;
            //cache.Add(start, end, result = new string(this.buffer, start, end - start));
            rangeNext.Call(StringCacheImpl.GetReference().GetMethod("Add").Invoke(startParam.GetReference(), endParam.GetReference(), resultLocal.GetReference().Assign(stringTypeRef.GetNewExpression(this.BufferArrayField.GetReference(), startParam.GetReference(), endParam.Subtract(startParam)))));
            //cache.Add(start, originalEnd, result);
            rangeNext.Call(StringCacheImpl.GetReference().GetMethod("Add").Invoke(startParam.GetReference(), originalEnd.GetReference(), resultLocal.GetReference()));
            rangeNext.CreateNext();
            var finalNext = rangeNext.Next;

            //cache.Add(start, originalEnd, result);
            finalNext.Call(StringCacheImpl.GetReference().GetMethod("Add").Invoke(startParam.GetReference(), originalEnd.GetReference(), resultLocal.GetReference()));
            //return result;
            stringIndexer.GetMethod.Return(resultLocal.GetReference());
            stringIndexer.AccessLevel = AccessLevelModifiers.Public;
            this.StringIndexerImpl    = stringIndexer;
        }
コード例 #2
0
        private void CreateLookAheadMethodImpl()
        {
            var mathTypeExp   = typeof(Math).ObtainCILibraryType <IClassType>(this._identityManager).GetTypeExpression();
            var maxMethod     = mathTypeExp.GetMethod("Max");
            var lookAheadImpl = this.CharStream.Methods.Add(new TypedName("LookAhead", this._identityManager.ObtainTypeReference(RuntimeCoreType.Int32)), new TypedNameSeries(new TypedName("distance", this._identityManager.ObtainTypeReference(RuntimeCoreType.Int32))));

            this.LookAheadImpl = lookAheadImpl;
            var dist = lookAheadImpl.Parameters[TypeSystemIdentifiers.GetMemberIdentifier("distance")];

            lookAheadImpl.AccessLevel = AccessLevelModifiers.Private;
            lookAheadImpl.SummaryText = "Returns the @s:Char; value at the @p:distance;.";
            dist.SummaryText          = "The distance from the the start of the @s:BaseStream; to read a character.";

            IConditionBlockStatement posCheck;
            {
                /* *
                 * if (distance >= this.Length ||
                 *     /* End of file correction: sometimes, things like a Unicode header, take a few bytes. *//*
                 *     this.eofEncountered && distance >= this.actualBufferLength)
                 *     return -1;
                 * */
                posCheck =
                    LookAheadImpl
                    .If(
                        dist
                        .GreaterThanOrEqualTo(
                            this.LengthImpl)
                        .LogicalOr(
                            this.EofEncountered.GetReference()
                            .LeftNewLine()
                            .LeftComment("End of file correction: sometimes, things like a Unicode header, take a few bytes.")
                            .LeftNewLine()
                            .LogicalAnd(
                                dist
                                .GreaterThanOrEqualTo(
                                    ActualBufferLength))));
                posCheck.Return(-1);
            }
            //if (this.actualBufferLength <= distance) { ...
            var bufferDataAvailCheck = LookAheadImpl.If(ActualBufferLength.LessThanOrEqualTo(dist));
            //long bytesRead = Math.Max(distance + 1L - this.actualBufferLength, 4096);
            var availCheckReadCount = bufferDataAvailCheck.Locals.Add(new TypedName("bytesRead", dist.ParameterType), maxMethod.Invoke(dist.Add(1).Subtract(ActualBufferLength), 4096.ToPrimitive()).Cast(lookAheadImpl.ReturnType));

            availCheckReadCount.AutoDeclare = false;
            bufferDataAvailCheck.DefineLocal(availCheckReadCount);

            var checkBufferCheck = bufferDataAvailCheck.If(BufferArrayField.EqualTo(IntermediateGateway.NullValue).LogicalOr(ActualBufferLength.Add(availCheckReadCount).GreaterThan(BufferArrayField.GetReference().GetProperty("LongLength"))));

            checkBufferCheck.Call(this.CheckBufferImpl.GetReference().Invoke(ActualBufferLength.Add(availCheckReadCount)));

            //if (bytesRead > 0) { ...
            var readCheck = bufferDataAvailCheck.If(availCheckReadCount.GreaterThan(IntermediateGateway.NumberZero));

            /* Make sure the stream is in place for the read. */

            /* *
             *     if (this._baseStream.Position != this.actualBufferLength)
             *         this._baseStream.Seek(this.actualBufferLength, SeekOrigin.Begin);
             *
             * ** REMOVED **
             * Causes synchronization issues, unknown cause.
             * */
            //var readSeekCheck = readCheck.If(this._BaseStreamImpl.GetReference().GetProperty("Position").InequalTo(this.ActualBufferLength));
            //readSeekCheck.Call(this._BaseStreamImpl.GetReference().GetMethod("Seek").Invoke(this.ActualBufferLength.GetReference(), this._identityManager.ObtainTypeReference(typeof(SeekOrigin)).GetTypeExpression().GetField("Begin")));
            var actualBytesRead = readCheck.Locals.Add(new TypedName("actualBytesRead", RuntimeCoreType.Int32, this._identityManager));

            actualBytesRead.AutoDeclare = false;
            readCheck.DefineLocal(actualBytesRead);

            //     int actualBytesRead = this.StreamReader.ReadBlock(this.buffer, (int)this.actualBufferLength, (int)bytesRead);
            actualBytesRead.InitializationExpression = this.StreamReaderImpl.GetReference().GetMethod("ReadBlock").Invoke(BufferArrayField.GetReference(), ActualBufferLength.GetReference().Cast(lookAheadImpl.ReturnType), availCheckReadCount.GetReference().Cast(lookAheadImpl.ReturnType));
            //     this.actualBufferLength += actualBytesRead;
            readCheck.Assign(ActualBufferLength.GetReference(), AssignmentOperation.AddAssign, actualBytesRead.GetReference());

            /* *
             *     if (actualBytesRead != bytesRead)
             *         this.eofEncountered = true;
             * */
            var eofCheck = readCheck.If(actualBytesRead.InequalTo(availCheckReadCount));

            eofCheck.Assign(this.EofEncountered.GetReference(), IntermediateGateway.TrueValue);

            /* *
             *     } // //if (bytesRead > 0)
             * } // if (this.actualBufferLength <= distance)
             * return ((int)(this.buffer[distance]));
             * */
            LookAheadImpl.Return(BufferArrayField.GetReference().GetIndexer(dist.GetReference()).Cast(lookAheadImpl.ReturnType));
        }