public bool EndsWith(string value) { if (IsDisposed) { ThrowAlreadyDisposed(); } if (_string != null) { return(_string.EndsWith(value)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } // Every UTF8 character uses at least 1 byte if (value.Length > Size) { return(false); } if (value.Length == 0) { return(true); } // We are assuming these values are going to be relatively constant throughout the object lifespan LazyStringValue converted = _context.GetLazyStringForFieldWithCaching(value); return(EndsWith(converted)); }
public void WritePropertyName(string prop) { var lazyProp = _context.GetLazyStringForFieldWithCaching(prop); WriteString(lazyProp); EnsureBuffer(1); _buffer[_pos++] = Colon; }
public int GetPropertyId(LazyStringValue propName) { PropertyName prop; if (_propertyNameToId.TryGetValue(propName, out prop) == false) { var propIndex = _docPropNames.Count; propName = _context.GetLazyStringForFieldWithCaching(propName); prop = new PropertyName { Comparer = propName, GlobalSortOrder = -1, PropertyId = propIndex }; _docPropNames.Add(prop); _propertiesSortOrder.Add(prop, prop); _propertyNameToId[propName] = prop; _propertiesNeedSorting = true; if (_docPropNames.Count > PropertiesDiscovered + 1) { prop = SwapPropertyIds(prop); } PropertiesDiscovered++; } else if (prop.PropertyId >= PropertiesDiscovered) { if (prop.PropertyId != PropertiesDiscovered) { prop = SwapPropertyIds(prop); } PropertiesDiscovered++; } return(prop.PropertyId); }
public int WritePropertyNames(int rootOffset) { // Write the property names and register their positions var propertyArrayOffset = new int[_context.CachedProperties.PropertiesDiscovered]; for (var index = 0; index < propertyArrayOffset.Length; index++) { propertyArrayOffset[index] = WriteValue(_context.GetLazyStringForFieldWithCaching(_context.CachedProperties.GetProperty(index))); } // Register the position of the properties offsets start var propertiesStart = _position; // Find the minimal space to store the offsets (byte,short,int) and raise the appropriate flag in the properties metadata BlittableJsonToken propertiesSizeMetadata = 0; var propertyNamesOffset = _position - rootOffset; var propertyArrayOffsetValueByteSize = SetOffsetSizeFlag(ref propertiesSizeMetadata, propertyNamesOffset); WriteNumber((int)propertiesSizeMetadata, sizeof(byte)); // Write property names offsets foreach (int offset in propertyArrayOffset) { WriteNumber(propertiesStart - offset, propertyArrayOffsetValueByteSize); } return(propertiesStart); }
public void StartArrayDocument() { var currentState = new BuildingState { State = ContinuationState.ReadArrayDocument, }; var fakeFieldName = _context.GetLazyStringForFieldWithCaching(UnderscoreSegment); var prop = _writer.CachedProperties.GetProperty(fakeFieldName); currentState.CurrentProperty = prop; currentState.MaxPropertyId = prop.PropertyId; currentState.FirstWrite = _writer.Position; currentState.Properties = _propertiesCache.Allocate(); currentState.Properties.Add(new PropertyTag { Property = prop }); _continuationState.Push(currentState); }
public void Renew(string debugTag, UsageMode mode) { Reset(); _debugTag = debugTag; _mode = mode; _writer.ResetAndRenew(); _modifier?.Reset(_context); _fakeFieldName = _context.GetLazyStringForFieldWithCaching(UnderscoreSegment); }
public void Renew(string debugTag, UsageMode mode) { _writeToken = default(WriteToken); _debugTag = debugTag; _mode = mode; _continuationState.Clear(); _cacheItem.Reset(); _writer.ResetAndRenew(); _modifier?.Reset(_context); _fakeFieldName = _context.GetLazyStringForFieldWithCaching(UnderscoreSegment); }
public void StartArrayDocument() { var currentState = new BuildingState { State = ContinuationState.ReadArrayDocument }; var fakeFieldName = _context.GetLazyStringForFieldWithCaching("_"); var propIndex = _context.CachedProperties.GetPropertyId(fakeFieldName); currentState.CurrentPropertyId = propIndex; currentState.MaxPropertyId = propIndex; currentState.FirstWrite = _writer.Position; currentState.Properties = new List <PropertyTag> { new PropertyTag { PropertyId = propIndex } }; _continuationState.Push(currentState); }
private int WritePropertyNames(int rootOffset) { var cachedProperties = _context.CachedProperties; int propertiesDiscovered = cachedProperties.PropertiesDiscovered; // Write the property names and register their positions if (_propertyArrayOffset == null || _propertyArrayOffset.Length < propertiesDiscovered) { _propertyArrayOffset = new int[Bits.NextPowerOf2(propertiesDiscovered)]; } unsafe { for (var index = 0; index < propertiesDiscovered; index++) { var str = _context.GetLazyStringForFieldWithCaching(cachedProperties.GetProperty(index)); if (str.EscapePositions == null || str.EscapePositions.Length == 0) { _propertyArrayOffset[index] = WriteValue(str.Buffer, str.Size); continue; } _propertyArrayOffset[index] = WriteValue(str.Buffer, str.Size, str.EscapePositions); } } // Register the position of the properties offsets start var propertiesStart = _position; // Find the minimal space to store the offsets (byte,short,int) and raise the appropriate flag in the properties metadata BlittableJsonToken propertiesSizeMetadata = 0; var propertyNamesOffset = _position - rootOffset; var propertyArrayOffsetValueByteSize = SetOffsetSizeFlag(ref propertiesSizeMetadata, propertyNamesOffset); WriteNumber((int)propertiesSizeMetadata, sizeof(byte)); // Write property names offsets // PERF: Using for to avoid the cost of the enumerator. for (int i = 0; i < propertiesDiscovered; i++) { int offset = _propertyArrayOffset[i]; WriteNumber(propertiesStart - offset, propertyArrayOffsetValueByteSize); } return(propertiesStart); }
private PropertyName UnlikelyGetProperty(LazyStringValue propName) { var propIndex = _docPropNames.Count; propName = _context.GetLazyStringForFieldWithCaching(propName); // PERF: The hash for the property needs to be a hash code, if its not // we will be paying the cost of hash collisions in the sort checks. var prop = new PropertyName(propName.GetHashCode(), propName, -1, propIndex); _docPropNames.Add(prop); _propertiesSortOrder.Add(prop, prop); _propertyNameToId[propName] = prop; _propertiesNeedSorting = true; if (_docPropNames.Count > PropertiesDiscovered + 1) { prop = SwapPropertyIds(prop); } PropertiesDiscovered++; return(prop); }
private PropertyName UnlikelyGetProperty(LazyStringValue propName) { var propIndex = _docPropNames.Count; propName = _context.GetLazyStringForFieldWithCaching(propName); var prop = new PropertyName(_propertyNameCounter++) { Comparer = propName, GlobalSortOrder = -1, PropertyId = propIndex }; _docPropNames.Add(prop); _propertiesSortOrder.Add(prop, prop); _propertyNameToId[propName] = prop; _propertiesNeedSorting = true; if (_docPropNames.Count > PropertiesDiscovered + 1) { prop = SwapPropertyIds(prop); } PropertiesDiscovered++; return(prop); }
public bool Read() { if (_continuationState.Count == 0) { return(false); //nothing to do } var currentState = _continuationState.Pop(); while (true) { switch (currentState.State) { case ContinuationState.ReadObjectDocument: if (_reader.Read() == false) { _continuationState.Push(currentState); return(false); } currentState.State = ContinuationState.ReadObject; continue; case ContinuationState.ReadArrayDocument: if (_reader.Read() == false) { _continuationState.Push(currentState); return(false); } var fakeFieldName = _context.GetLazyStringForFieldWithCaching("_"); var propIndex = _context.CachedProperties.GetPropertyId(fakeFieldName); currentState.CurrentPropertyId = propIndex; currentState.MaxPropertyId = propIndex; currentState.FirstWrite = _position; currentState.Properties = new List <PropertyTag> { new PropertyTag { PropertyId = propIndex } }; currentState.State = ContinuationState.CompleteDocumentArray; _continuationState.Push(currentState); currentState = new BuildingState { State = ContinuationState.ReadArray }; continue; case ContinuationState.CompleteDocumentArray: currentState.Properties[0].Type = (byte)_writeToken.WrittenToken; currentState.Properties[0].Position = _writeToken.ValuePos; // Register property position, name id (PropertyId) and type (object type and metadata) _writeToken = FinalizeObjectWrite(currentState.Properties, currentState.FirstWrite, currentState.MaxPropertyId); return(true); case ContinuationState.ReadObject: if (_state.CurrentTokenType != JsonParserToken.StartObject) { throw new InvalidDataException("Expected start of object, but got " + _state.CurrentTokenType); } currentState.State = ContinuationState.ReadPropertyName; currentState.Properties = new List <PropertyTag>(); currentState.FirstWrite = _position; continue; case ContinuationState.ReadArray: if (_state.CurrentTokenType != JsonParserToken.StartArray) { throw new InvalidDataException("Expected start of array, but got " + _state.CurrentTokenType); } currentState.Types = new List <BlittableJsonToken>(); currentState.Positions = new List <int>(); currentState.State = ContinuationState.ReadArrayValue; continue; case ContinuationState.ReadArrayValue: if (_reader.Read() == false) { _continuationState.Push(currentState); return(false); } if (_state.CurrentTokenType == JsonParserToken.EndArray) { currentState.State = ContinuationState.CompleteArray; continue; } currentState.State = ContinuationState.CompleteArrayValue; _continuationState.Push(currentState); currentState = new BuildingState { State = ContinuationState.ReadValue }; continue; case ContinuationState.CompleteArrayValue: currentState.Types.Add(_writeToken.WrittenToken); currentState.Positions.Add(_writeToken.ValuePos); currentState.State = ContinuationState.ReadArrayValue; continue; case ContinuationState.CompleteArray: var arrayInfoStart = _position; var arrayToken = BlittableJsonToken.StartArray; _position += WriteVariableSizeInt(currentState.Positions.Count); if (currentState.Positions.Count == 0) { arrayToken |= BlittableJsonToken.OffsetSizeByte; _writeToken = new WriteToken { ValuePos = arrayInfoStart, WrittenToken = arrayToken }; } else { var distanceFromFirstItem = arrayInfoStart - currentState.Positions[0]; var distanceTypeSize = SetOffsetSizeFlag(ref arrayToken, distanceFromFirstItem); for (var i = 0; i < currentState.Positions.Count; i++) { WriteNumber(arrayInfoStart - currentState.Positions[i], distanceTypeSize); _position += distanceTypeSize; _stream.WriteByte((byte)currentState.Types[i]); _position++; } _writeToken = new WriteToken { ValuePos = arrayInfoStart, WrittenToken = arrayToken }; } currentState = _continuationState.Pop(); continue; case ContinuationState.ReadPropertyName: if (_reader.Read() == false) { _continuationState.Push(currentState); return(false); } if (_state.CurrentTokenType == JsonParserToken.EndObject) { _writeToken = FinalizeObjectWrite(currentState.Properties, currentState.FirstWrite, currentState.MaxPropertyId); if (_continuationState.Count == 0) { return(true); } currentState = _continuationState.Pop(); continue; } if (_state.CurrentTokenType != JsonParserToken.String) { throw new InvalidDataException("Expected property, but got " + _state.CurrentTokenType); } var property = CreateLazyStringValueFromParserState(); if (_state.EscapePositions.Count > 0) { property.EscapePositions = _state.EscapePositions.ToArray(); } currentState.CurrentPropertyId = _context.CachedProperties.GetPropertyId(property); currentState.MaxPropertyId = Math.Max(currentState.MaxPropertyId, currentState.CurrentPropertyId); currentState.State = ContinuationState.ReadPropertyValue; continue; case ContinuationState.ReadPropertyValue: if (_reader.Read() == false) { _continuationState.Push(currentState); return(false); } currentState.State = ContinuationState.CompleteReadingPropertyValue; _continuationState.Push(currentState); currentState = new BuildingState { State = ContinuationState.ReadValue }; continue; case ContinuationState.CompleteReadingPropertyValue: // Register property position, name id (PropertyId) and type (object type and metadata) currentState.Properties.Add(new PropertyTag { Position = _writeToken.ValuePos, Type = (byte)_writeToken.WrittenToken, PropertyId = currentState.CurrentPropertyId }); currentState.State = ContinuationState.ReadPropertyName; continue; case ContinuationState.ReadValue: ReadJsonValue(); currentState = _continuationState.Pop(); break; } } }
public virtual bool Read() { if (_continuationState.Count == 0) { return(false); //nothing to do } var currentState = _continuationState.Pop(); while (true) { switch (currentState.State) { case ContinuationState.ReadObjectDocument: if (_reader.Read() == false) { _continuationState.Push(currentState); return(false); } currentState.State = ContinuationState.ReadObject; continue; case ContinuationState.ReadArrayDocument: if (_reader.Read() == false) { _continuationState.Push(currentState); return(false); } var fakeFieldName = _context.GetLazyStringForFieldWithCaching("_"); var propIndex = _context.CachedProperties.GetPropertyId(fakeFieldName); currentState.CurrentPropertyId = propIndex; currentState.MaxPropertyId = propIndex; currentState.FirstWrite = _writer.Position; currentState.Properties = new List <PropertyTag> { new PropertyTag { PropertyId = propIndex } }; currentState.State = ContinuationState.CompleteDocumentArray; _continuationState.Push(currentState); currentState = new BuildingState { State = ContinuationState.ReadArray }; continue; case ContinuationState.CompleteDocumentArray: currentState.Properties[0].Type = (byte)_writeToken.WrittenToken; currentState.Properties[0].Position = _writeToken.ValuePos; // Register property position, name id (PropertyId) and type (object type and metadata) _writeToken = _writer.WriteObjectMetadata(currentState.Properties, currentState.FirstWrite, currentState.MaxPropertyId); return(true); case ContinuationState.ReadObject: if (_state.CurrentTokenType != JsonParserToken.StartObject) { throw new InvalidDataException("Expected start of object, but got " + _state.CurrentTokenType); } currentState.State = ContinuationState.ReadPropertyName; currentState.Properties = new List <PropertyTag>(); currentState.FirstWrite = _writer.Position; continue; case ContinuationState.ReadArray: if (_state.CurrentTokenType != JsonParserToken.StartArray) { throw new InvalidDataException("Expected start of array, but got " + _state.CurrentTokenType); } currentState.Types = new List <BlittableJsonToken>(); currentState.Positions = new List <int>(); currentState.State = ContinuationState.ReadArrayValue; continue; case ContinuationState.ReadArrayValue: if (_reader.Read() == false) { _continuationState.Push(currentState); return(false); } if (_state.CurrentTokenType == JsonParserToken.EndArray) { currentState.State = ContinuationState.CompleteArray; continue; } currentState.State = ContinuationState.CompleteArrayValue; _continuationState.Push(currentState); currentState = new BuildingState { State = ContinuationState.ReadValue }; continue; case ContinuationState.CompleteArrayValue: currentState.Types.Add(_writeToken.WrittenToken); currentState.Positions.Add(_writeToken.ValuePos); currentState.State = ContinuationState.ReadArrayValue; continue; case ContinuationState.CompleteArray: var arrayToken = BlittableJsonToken.StartArray; var arrayInfoStart = _writer.WriteArrayMetadata(currentState.Positions, currentState.Types, ref arrayToken); _writeToken = new WriteToken { ValuePos = arrayInfoStart, WrittenToken = arrayToken }; currentState = _continuationState.Pop(); continue; case ContinuationState.ReadPropertyName: if (_reader.Read() == false) { _continuationState.Push(currentState); return(false); } if (_state.CurrentTokenType == JsonParserToken.EndObject) { _writeToken = _writer.WriteObjectMetadata(currentState.Properties, currentState.FirstWrite, currentState.MaxPropertyId); if (_continuationState.Count == 0) { return(true); } currentState = _continuationState.Pop(); continue; } if (_state.CurrentTokenType != JsonParserToken.String) { throw new InvalidDataException("Expected property, but got " + _state.CurrentTokenType); } var property = CreateLazyStringValueFromParserState(); currentState.CurrentPropertyId = _context.CachedProperties.GetPropertyId(property); currentState.MaxPropertyId = Math.Max(currentState.MaxPropertyId, currentState.CurrentPropertyId); currentState.State = ContinuationState.ReadPropertyValue; continue; case ContinuationState.ReadPropertyValue: if (_reader.Read() == false) { _continuationState.Push(currentState); return(false); } currentState.State = ContinuationState.CompleteReadingPropertyValue; _continuationState.Push(currentState); currentState = new BuildingState { State = ContinuationState.ReadValue }; continue; case ContinuationState.CompleteReadingPropertyValue: // Register property position, name id (PropertyId) and type (object type and metadata) currentState.Properties.Add(new PropertyTag { Position = _writeToken.ValuePos, Type = (byte)_writeToken.WrittenToken, PropertyId = currentState.CurrentPropertyId }); currentState.State = ContinuationState.ReadPropertyName; continue; case ContinuationState.ReadValue: ReadJsonValue(); currentState = _continuationState.Pop(); break; } } }