示例#1
0
        public void ToBlittableJsonReaderObject(ManualBlittalbeJsonDocumentBuilder <UnmanagedWriteBuffer> writer, ObjectInstance jsObject, string propertyKey = null,
                                                bool recursiveCall = false)
        {
            if (jsObject.Class == "Function")
            {
                // getting a Function instance here,
                // means that we couldn't evaluate it using Jint
                return;
            }
            writer.StartWriteObject();
            foreach (var property in jsObject.GetOwnProperties())
            {
                if (property.Key == Constants.Indexing.Fields.ReduceKeyFieldName || property.Key == Constants.Indexing.Fields.DocumentIdFieldName)
                {
                    continue;
                }

                var value = property.Value.Value;
                if (value.HasValue == false)
                {
                    continue;
                }

                if (value.Value.IsRegExp())
                {
                    continue;
                }

                var recursive = jsObject == value;
                writer.WritePropertyName(property.Key);
                if (recursiveCall && recursive)
                {
                    writer.WriteValueNull();
                }
                else
                {
                    ToBlittableJsonReaderValue(writer, value.Value, CreatePropertyKey(property.Key, propertyKey), recursive);
                }
            }
            writer.WriteObjectEnd();
        }
示例#2
0
        private void ToBlittableJsonReaderValue(ManualBlittalbeJsonDocumentBuilder <UnmanagedWriteBuffer> writer, JsValue v, string propertyKey, bool recursiveCall)
        {
            if (v.IsBoolean())
            {
                writer.WriteValue(v.AsBoolean());
                return;
            }

            if (v.IsString())
            {
                const string RavenDataByteArrayToBase64 = "raven-data:byte[];base64,";
                var          valueAsObject = v.ToObject();
                var          value         = valueAsObject?.ToString();
                if (value != null && value.StartsWith(RavenDataByteArrayToBase64))
                {
                    value = value.Remove(0, RavenDataByteArrayToBase64.Length);
                    var byteArray = Convert.FromBase64String(value);
                    writer.WriteValue(Encoding.UTF8.GetString(byteArray));
                    return;
                }
                writer.WriteValue(value);
                return;
            }

            if (v.IsNumber())
            {
                var num = v.AsNumber();

                KeyValuePair <object, JsValue> property;
                if (_propertiesByValue.TryGetValue(propertyKey, out property))
                {
                    var originalValue = property.Key;
                    if (originalValue is float || originalValue is int)
                    {
                        // If the current value is exactly as the original value, we can return the original value before we made the JS conversion,
                        // which will convert a Int64 to jsFloat.
                        var jsValue = property.Value;
                        if (jsValue.IsNumber() && Math.Abs(num - jsValue.AsNumber()) < double.Epsilon)
                        {
                            writer.WriteValue((int)originalValue);
                            return;
                        }

                        //We might have change the type of num from Integer to long in the script by design
                        //Making sure the number isn't a real float before returning it as integer
                        if (originalValue is int &&
                            (Math.Abs(num - Math.Floor(num)) <= double.Epsilon ||
                             Math.Abs(num - Math.Ceiling(num)) <= double.Epsilon))
                        {
                            writer.WriteValue((long)num);
                            return;
                        }
                        writer.WriteValue((float)num);
                        return; //float
                    }
                }

                // If we don't have the type, assume that if the number ending with ".0" it actually an integer.
                var integer = Math.Truncate(num);
                if (Math.Abs(num - integer) < double.Epsilon)
                {
                    writer.WriteValue((long)integer);
                    return;
                }
                writer.WriteValue(num);
                return;
            }
            if (v.IsNull() || v.IsUndefined())
            {
                writer.WriteValueNull();
                return;
            }
            if (v.IsArray())
            {
                var jsArray = v.AsArray();
                writer.StartWriteArray();
                foreach (var property in jsArray.GetOwnProperties())
                {
                    if (InheritedProperties.Contains(property.Key))
                    {
                        continue;
                    }

                    var jsInstance = property.Value.Value;
                    if (!jsInstance.HasValue)
                    {
                        continue;
                    }

                    ToBlittableJsonReaderValue(writer, jsInstance.Value, propertyKey + "[" + property.Key + "]",
                                               recursiveCall);
                }
                writer.WriteArrayEnd();
                return;
            }
            if (v.IsDate())
            {
                writer.WriteValue(v.AsDate().ToDateTime().ToString(Abstractions.Default.DateTimeFormatsToWrite));
                return;
            }
            if (v.IsObject())
            {
                ToBlittableJsonReaderObject(writer, v.AsObject(), propertyKey, recursiveCall);
                return;
            }
            if (v.IsRegExp())
            {
                writer.WriteValueNull();
                return;
            }

            throw new NotSupportedException(v.Type.ToString());
        }
        private void WriteMetadata()
        {
            if (_documentInfo == null)
            {
                return;
            }
            if (_documentInfo.Metadata?.Modifications != null && (_documentInfo.Metadata.Modifications.Properties.Count > 0))
            {
                _manualBlittalbeJsonDocumentBuilder.WritePropertyName(Constants.Metadata.Key);
                _manualBlittalbeJsonDocumentBuilder.StartWriteObject();

                foreach (var prop in _documentInfo.Metadata.Modifications.Properties)
                {
                    _manualBlittalbeJsonDocumentBuilder.WritePropertyName(prop.Item1);
                    _manualBlittalbeJsonDocumentBuilder.WriteValue(prop.Item2.ToString());
                }

                _manualBlittalbeJsonDocumentBuilder.WriteObjectEnd();
                _documentInfo.Metadata.Modifications = null;
            }
            else if (_documentInfo.Metadata != null)
            {
                _manualBlittalbeJsonDocumentBuilder.WritePropertyName(Constants.Metadata.Key);
                _manualBlittalbeJsonDocumentBuilder.StartWriteObject();
                var ids = _documentInfo.Metadata.GetPropertiesByInsertionOrder();

                foreach (var id in ids)
                {
                    var propertyDetails = new BlittableJsonReaderObject.PropertyDetails();
                    _documentInfo.Metadata.GetPropertyByIndex(id, ref propertyDetails);

                    _manualBlittalbeJsonDocumentBuilder.WritePropertyName(propertyDetails.Name);
                    switch (propertyDetails.Token)
                    {
                    case BlittableJsonToken.Integer:
                        _manualBlittalbeJsonDocumentBuilder.WriteValue((long)propertyDetails.Value);
                        break;

                    case BlittableJsonToken.Float:
                        _manualBlittalbeJsonDocumentBuilder.WriteValue((float)propertyDetails.Value);
                        break;

                    case BlittableJsonToken.String:
                        _manualBlittalbeJsonDocumentBuilder.WriteValue(propertyDetails.Value.ToString());
                        break;

                    case BlittableJsonToken.CompressedString:
                        _manualBlittalbeJsonDocumentBuilder.WriteValue(propertyDetails.Value.ToString());
                        break;

                    case BlittableJsonToken.Boolean:
                        _manualBlittalbeJsonDocumentBuilder.WriteValue((bool)propertyDetails.Value);
                        break;

                    case BlittableJsonToken.Null:
                        _manualBlittalbeJsonDocumentBuilder.WriteValueNull();
                        break;

                    default:
                        throw new NotSupportedException();
                    }
                }
                _manualBlittalbeJsonDocumentBuilder.WriteObjectEnd();
            }
        }