示例#1
0
//
// In Progress attempt to rewrite writeSerializedRecord and related fns
// using a seekable/skipping WriteBuf
//
func (serde ORecordSerializerV0) writeSerializedRecord(wbuf *obuf.WriteBuf, doc *oschema.ODocument) (err error) {
	nfields := len(doc.FieldNames())
	ptrPos := make([]int, 0, nfields) // position in buf where data ptr int needs to be written

	currDB := serde.dbc.GetCurrDB()
	oclass, ok := currDB.Classes[doc.Classname]

	docFields := doc.GetFields()
	for _, fld := range docFields {
		var oprop *oschema.OProperty
		if ok {
			oprop = oclass.Properties[fld.Name]
		}

		// FROM THE JAVA CLIENT:
		// if (properties[i] != null) {
		//   OVarIntSerializer.write(bytes, (properties[i].getId() + 1) * -1);
		//   if (properties[i].getType() != OType.ANY)
		//     pos[i] = bytes.alloc(OIntegerSerializer.INT_SIZE);
		//   else
		//     pos[i] = bytes.alloc(OIntegerSerializer.INT_SIZE + 1);   // TODO: why does ANY required an additional byte?
		// } else {
		//   writeString(bytes, entry.getKey());
		//   pos[i] = bytes.alloc(OIntegerSerializer.INT_SIZE + 1);

		if oprop != nil {
			// if property is known in the global properties, then
			// just write its encoded id
			varint.EncodeAndWriteVarInt32(wbuf, encodeFieldIDForHeader(oprop.ID))
			ptrPos = append(ptrPos, wbuf.Len())
			wbuf.Skip(4)
			// Note: no need to write property type when writing property ID

		} else {
			// property Name
			err = varint.WriteString(wbuf, fld.Name)
			if err != nil {
				return oerror.NewTrace(err)
			}
			ptrPos = append(ptrPos, wbuf.Len())
			wbuf.Skip(4)

			// property Type
			err = rw.WriteByte(wbuf, byte(fld.Type))
			if err != nil {
				return oerror.NewTrace(err)
			}
		}
	}
	wbuf.WriteByte(0) // End of Header sentinel

	// now write out the data values
	for i, fld := range docFields {
		currPos := wbuf.Len()
		wbuf.Seek(uint(ptrPos[i]))
		err = rw.WriteInt(wbuf, int32(currPos))
		if err != nil {
			return oerror.NewTrace(err)
		}
		wbuf.Seek(uint(currPos))
		err = serde.writeDataValue(wbuf, fld.Value, fld.Type)
		if err != nil {
			return oerror.NewTrace(err)
		}
	}

	return nil
}