private ODocument parseDocument(BinaryReader reader, ODocument document) { List<FieldDefinition> fd = new List<FieldDefinition>(); var prop = String.Empty; while (true) { int len = readAsInteger(reader); if (len == 0) break; if (len > 0) { prop = Encoding.UTF8.GetString(reader.ReadBytesRequired(len)); int valuePos = reader.ReadInt32EndianAware(); OType valuetype = (OType)reader.ReadByte(); fd.Add(new FieldDefinition { FieldName = prop, Pointer = valuePos, DataType = valuetype }); } else { //TODO: Implement schema aware read var propid = (len * -1) - 1; prop = "no_schema"; int valuePos = reader.ReadInt32EndianAware(); fd.Add(new FieldDefinition { FieldName = prop, Pointer = valuePos, DataType = OType.Date }); } } foreach (var f in fd) { if (f.Pointer != 0) { readOType(reader, f.FieldName, document, f.DataType); } else { document[f.FieldName] = null; } } return document; }
internal byte[] ReadToken(BinaryReader reader) { var size = reader.ReadInt32EndianAware(); var token = reader.ReadBytesRequired(size); // if token renewed if (token.Length > 0) _database.GetConnection().Token = token; return token; }
private ODocument ParseDocument(BinaryReader reader) { ODocument document = null; short classId = reader.ReadInt16EndianAware(); if (classId == -2) // NULL { } else if (classId == -3) // record id { ORID orid = new ORID(); orid.ClusterId = reader.ReadInt16EndianAware(); orid.ClusterPosition = reader.ReadInt64EndianAware(); document = new ODocument(); document.ORID = orid; document.OClassId = classId; } else { ORecordType type = (ORecordType)reader.ReadByte(); ORID orid = new ORID(); orid.ClusterId = reader.ReadInt16EndianAware(); orid.ClusterPosition = reader.ReadInt64EndianAware(); int version = reader.ReadInt32EndianAware(); int recordLength = reader.ReadInt32EndianAware(); byte[] rawRecord = reader.ReadBytes(recordLength); document = new ODocument { ORID = orid, OVersion = version, OType = ORecordType.Document, OClassId = classId }; document = Serializer.Deserialize(rawRecord, document); } return document; }
//public static int IntParseFast(string value) //{ // int result = 0; // for (int i = 0; i < value.Length; i++) // { // char letter = value[i]; // result = 10 * result + (letter - 48); // } // return result; //} /// <summary> /// Parse RidBags ex. %[content:binary]; where [content:binary] is the actual binary base64 content. /// </summary> /// <param name="i"></param> /// <param name="recordString"></param> /// <param name="document"></param> /// <param name="fieldName"></param> /// <returns></returns> private static int ParseRidBags(int i, string recordString, ODocument document, string fieldName) { //move to first base64 char i++; StringBuilder builder = new StringBuilder(); while (recordString[i] != ';') { builder.Append(recordString[i]); i++; } // use a list as it preserves order at this stage which may be important when using ordered edges var rids = new List<ORID>(); var value = Convert.FromBase64String(builder.ToString()); using (var stream = new MemoryStream(value)) using (var reader = new BinaryReader(stream)) { var first = reader.ReadByte(); int offset = 1; if ((first & 2) == 2) { // uuid parsing is not implemented offset += 16; } if ((first & 1) == 1) // 1 - embedded,0 - tree-based { var entriesSize = reader.ReadInt32EndianAware(); for (int j = 0; j < entriesSize; j++) { var clusterid = reader.ReadInt16EndianAware(); var clusterposition = reader.ReadInt64EndianAware(); rids.Add(new ORID(clusterid, clusterposition)); } } else { throw new NotImplementedException("tree based ridbag"); } } document[fieldName] = rids; //move past ';' i++; return i; }
private void ReadAssociatedResult(BinaryReader reader) { var zero = reader.ReadInt16EndianAware(); if (zero != 0) throw new InvalidOperationException("Unsupported record format"); ORecordType recordType = (ORecordType)reader.ReadByte(); if (recordType != ORecordType.Document) throw new InvalidOperationException("Unsupported record type"); short clusterId = reader.ReadInt16EndianAware(); long clusterPosition = reader.ReadInt64EndianAware(); int recordVersion = reader.ReadInt32EndianAware(); var recordLength = reader.ReadInt32EndianAware(); var record = reader.ReadBytes(recordLength); //var document = RecordCSVSerializer.Deserialize(new ORID(clusterId, clusterPosition), recordVersion, ORecordType.Document, 0, record); var document = Serializer .Deserialize(record, new ODocument { ORID = new ORID(clusterId, clusterPosition), OVersion = recordVersion, OType = ORecordType.Document }); _database.ClientCache[document.ORID] = document; }
private void ReadPrimaryResult(ODocument responseDocument, BinaryReader reader) { responseDocument.SetField("PayloadStatus", PayloadStatus.SingleRecord); int contentLength; byte[] readBytes; int version; ORecordType recordType; if (OClient.ProtocolVersion < 28) { contentLength = reader.ReadInt32EndianAware(); readBytes = reader.ReadBytes(contentLength); version = reader.ReadInt32EndianAware(); recordType = (ORecordType)reader.ReadByte(); } else { recordType = (ORecordType)reader.ReadByte(); version = reader.ReadInt32EndianAware(); contentLength = reader.ReadInt32EndianAware(); readBytes = reader.ReadBytes(contentLength); } var document = new ODocument(); switch (recordType) { case ORecordType.Document: document = Serializer.Deserialize(readBytes, new ODocument()); document.ORID = _orid; document.OVersion = version; responseDocument.SetField("Content", document); break; case ORecordType.RawBytes: document.SetField("RawBytes", readBytes); responseDocument.SetField("Content", document); break; case ORecordType.FlatData: break; } }
private void readOType(BinaryReader reader, string fieldName, ODocument document, OType type) { switch (type) { case OType.Integer: document.SetField<int>(fieldName, readAsInteger(reader)); break; case OType.Long: document.SetField<long>(fieldName, readAsLong(reader)); break; case OType.Short: document.SetField<short>(fieldName, readAsShort(reader)); break; case OType.String: document.SetField<string>(fieldName, readString(reader)); break; case OType.Double: document.SetField<double>(fieldName, BitConverter.Int64BitsToDouble(readLong(reader))); break; case OType.Float: document.SetField<float>(fieldName, readFloat(reader)); break; case OType.Decimal: var scale = reader.ReadInt32EndianAware(); var valueSize = reader.ReadInt32EndianAware(); // read Fine the value var valuex = reader.ReadBytesRequired(valueSize); Int64 x1 = 0; if ((valuex[0] & 0x80) == 0x80) x1 = (sbyte)valuex[0]; else x1 = valuex[0]; for (int i = 1; i < valuex.Length; i++) { x1 = (x1 << 8) | valuex[i]; } try { document.SetField(fieldName, new Decimal(x1 * Math.Pow(10, (-1) * scale))); } catch (OverflowException) { document.SetField(fieldName, x1 * Math.Pow(10, (-1) * scale)); } break; case OType.Byte: document.SetField<byte>(fieldName, reader.ReadByte()); break; case OType.Boolean: document.SetField<bool>(fieldName, reader.ReadByte() == 1 ? true : false); break; case OType.DateTime: document.SetField<DateTime>(fieldName, readDateTime(reader)); break; case OType.Date: document.SetField<DateTime>(fieldName, readDate(reader)); break; case OType.EmbeddedList: var listLength = readAsInteger(reader); OType embeddedListRecorType = (OType)reader.ReadByte(); List<Object> embeddedList = new List<Object>(); for (int i = 0; i < listLength; i++) { var d = new ODocument(); OType dataType = (OType)reader.ReadByte(); readOType(reader, i.ToString(), d, dataType); embeddedList.AddRange(d.Values); } document.SetField(fieldName, embeddedList); break; case OType.EmbeddedSet: var embeddedSetLen = readAsInteger(reader); OType embeddedSetRecorType = (OType)reader.ReadByte(); HashSet<ODocument> embeddedSet = new HashSet<ODocument>(); for (int i = 0; i < embeddedSetLen; i++) { var d = new ODocument(); OType dataType = (OType)reader.ReadByte(); readOType(reader, "", d, dataType); embeddedSet.Add(d); } document.SetField(fieldName, embeddedSet); break; case OType.EmbeddedMap: /* * header:headerStructure | values:valueStructure * headerStructure * =============== * keyType:byte | keyValue:byte[] * * valueStructure * ============== * valueType:byte | value:byte[] */ var size = readAsInteger(reader); var fd = new FieldDefinition[size]; Dictionary<string, Object> map = new Dictionary<string, object>(); for (int i = 0; i < size; i++) { fd[i] = new FieldDefinition(); var d = new ODocument(); var keyType = (OType)reader.ReadByte(); if (keyType != OType.String) throw new NotImplementedException("key type " + keyType + " not implemented for EmbededMap"); readOType(reader, "key", d, keyType); fd[i].FieldName = d.GetField<string>("key"); fd[i].Pointer = reader.ReadInt32EndianAware(); fd[i].DataType = (OType)reader.ReadByte(); } for (int i = 0; i < size; i++) { var d = new ODocument(); if (fd[i].Pointer > 0) { readOType(reader, "value", d, fd[i].DataType); map.Add(fd[i].FieldName, d.GetField<object>("value")); } else { map.Add(fd[i].FieldName, null); } } document.SetField<Dictionary<string, Object>>(fieldName, map); break; case OType.Embedded: var version = reader.ReadByte(); parseDocument(reader, document); break; case OType.Link: var claster = readAsLong(reader); var record = readAsLong(reader); document.SetField(fieldName, new ORID((short)claster, record)); break; case OType.LinkBag: var rids = new HashSet<ORID>(); var config = reader.ReadByte(); if ((config & 2) == 2) { // uuid parsing is not implemented config += 16; } if ((config & 1) == 1) // 1 - embedded,0 - tree-based { var entriesSize = reader.ReadInt32EndianAware(); for (int j = 0; j < entriesSize; j++) { var clusterid = reader.ReadInt16EndianAware(); var clusterposition = reader.ReadInt64EndianAware(); rids.Add(new ORID(clusterid, clusterposition)); } } else { throw new NotImplementedException("tree based ridbag"); } document.SetField(fieldName, rids); break; case OType.LinkList: var linkList = readLinkCollection(reader); document.SetField(fieldName, linkList); break; case OType.LinkSet: var linkSet = new HashSet<ORID>(readLinkCollection(reader)); document.SetField(fieldName, linkSet); break; case OType.Any: break; default: throw new OException(OExceptionType.Deserialization, "The field type: " + type.ToString() + "not implemented"); } }
//public int IntParseFast(string value) //{ // int result = 0; // for (int i = 0; i < value.Length; i++) // { // char letter = value[i]; // result = 10 * result + (letter - 48); // } // return result; //} /// <summary> /// Parse RidBags ex. %[content:binary]; where [content:binary] is the actual binary base64 content. /// </summary> /// <param name="i"></param> /// <param name="recordString"></param> /// <param name="document"></param> /// <param name="fieldName"></param> /// <returns></returns> private int ParseRidBags(int i, string recordString, ODocument document, string fieldName) { //move to first base64 char i++; StringBuilder builder = new StringBuilder(); while (recordString[i] != ';') { builder.Append(recordString[i]); i++; } // use a list as it preserves order at this stage which may be important when using ordered edges var rids = new List<ORID>(); var value = Convert.FromBase64String(builder.ToString()); using (var stream = new MemoryStream(value)) using (var reader = new BinaryReader(stream)) { var first = reader.ReadByte(); int offset = 1; if ((first & 2) == 2) { // uuid parsing is not implemented offset += 16; } if ((first & 1) == 1) // 1 - embedded,0 - tree-based { var entriesSize = reader.ReadInt32EndianAware(); for (int j = 0; j < entriesSize; j++) { var clusterid = reader.ReadInt16EndianAware(); var clusterposition = reader.ReadInt64EndianAware(); rids.Add(new ORID(clusterid, clusterposition)); } } else { // Maybe not parse this type of Field and only then Requested retrieve ? // Lazy loading if (_connection == null || !_connection.IsActive) throw new OException(OExceptionType.Connection, "Connection is not opened or is null"); // Tree based RidBag - (collectionPointer)(size:int)(changes) // Collection Pointer - (fileId:long)(pageIndex:long)(pageOffset:int) var fileId = reader.ReadInt64EndianAware(); var pageIndex = reader.ReadInt64EndianAware(); var pageOffset = reader.ReadInt32EndianAware(); // size var size = reader.ReadInt32EndianAware(); //only process ridbag if size > 0, otherwise the call to SBTreeBonsaiFirstKey operation makes the connection crash (the server probably isn't expecting this use case) if (size > 0) { // Changes - (changesSize:int)[(link:rid)(changeType:byte)(value:int)]* var changesSize = reader.ReadInt32EndianAware(); if (changesSize > 0) //for (int j = 0; j < changesSize; j++) { throw new NotImplementedException("RidBag Changes not yet implemented"); } var operation = new SBTreeBonsaiFirstKey(null); operation.FileId = fileId; operation.PageIndex = pageIndex; operation.PageOffset = pageOffset; // Not realy quiete about this var connection = OClient.ReleaseConnection(_connection.Alias); var entries = new Dictionary<ORID, int>(); try { var orid = connection.ExecuteOperation(operation); var ft = true; var key = orid.GetField<ORID>("rid"); do { var op = new SBTreeBonsaiGetEntriesMajor(null); op.FileId = fileId; op.PageIndex = pageIndex; op.PageOffset = pageOffset; op.FirstKey = key; op.Inclusive = ft; var res = connection.ExecuteOperation(op); entries = res.GetField<Dictionary<ORID, int>>("entries"); rids.AddRange(entries.Keys); if (entries.Count == 0) break; key = entries.Last().Key; ft = false; } while (true); } finally { OClient.ReturnConnection(connection); } } } } document[fieldName] = rids; //move past ';' i++; return i; }
private int ParseRidBags(int i, byte[] serializedRecord, out object result) { i++; var startIndex = i; StringBuilder builder = new StringBuilder(); while (serializedRecord[i] != SEMI_COLON) { i++; } var value = Convert.FromBase64String(ToString(startIndex, i, serializedRecord)); List<ORID> rids = new List<ORID>(); using (var ms = new MemoryStream(value)) { using (var br = new BinaryReader(ms)) { var first = br.ReadByte(); int offset = 1; startIndex++; if ((first & 2) == 2) { // uuid parsing is not implemented offset += 16; } if ((first & 1) == 1) { var entriesSize = br.ReadInt32EndianAware(); for (int j = 0; j < entriesSize; j++) { var clusterid = br.ReadInt16EndianAware(); var clusterposition = br.ReadInt64EndianAware(); rids.Add(new ORID(clusterid, clusterposition)); } } else throw new NotImplementedException("Tree-based RID Bags are not supported."); } } result = rids; i++; return i; }
private void ReadPrimaryResult(ODocument responseDocument, BinaryReader reader) { responseDocument.SetField("PayloadStatus", PayloadStatus.SingleRecord); var contentLength = reader.ReadInt32EndianAware(); byte[] readBytes = reader.ReadBytes(contentLength); var version = reader.ReadInt32EndianAware(); var recordType = (ORecordType)reader.ReadByte(); var document = new ODocument(); switch (recordType) { case ORecordType.Document: string serialized = System.Text.Encoding.Default.GetString(readBytes); document = RecordSerializer.Deserialize(serialized); document.ORID = _orid; document.OVersion = version; responseDocument.SetField("Content", document); break; case ORecordType.RawBytes: document.SetField("RawBytes", readBytes); responseDocument.SetField("Content", document); break; case ORecordType.FlatData: break; } }