Пример #1
0
func TestFlags(t *testing.T) {
	type td struct {
		count int
		bits  uint
		name  string
	}
	tests := []td{
		{_FLAG_ACC_COUNT, FLAG_ACC_BITS, "Access"},
		{_FLAG_TYPE_COUNT, FLAG_TYPE_BITS, "Type"},
		{_FLAG_LANG_COUNT, FLAG_LANG_BITS, "Language"},
		{1 << _FLAG_BOOL_COUNT, _FLAG_BOOL_COUNT, "Bool"},
	}
	totSize := 0
	for _, test := range tests {
		if current, actual := test.bits, util.Bits(test.count); actual != current {
			t.Errorf("Bit mismatch for %s bits: %d != %d", test.name, current, actual)
		}
		totSize += int(test.bits)
	}
	var f Flags
	ty := reflect.TypeOf(f)
	if bits := ty.Bits(); totSize > bits {
		t.Errorf("The number of bits used does not fit in %s's size: %d > %d", ty.Name(), totSize, bits)
	}
	t.Logf("Bits used: %d", totSize)
}
Пример #2
0
func (m *MetadataUtil) Size(t reflect.Type) (uint, error) {
	size := uint(0)
	name := t.Name()
	switch name {
	case "StringIndex":
		size = uint(m.StringHeap.RowSize)
	case "Guid":
		size = uint(m.GuidHeap.RowSize)
	case "BlobIndex":
		size = uint(m.BlobHeap.RowSize)
	default:
		if strings.HasSuffix(name, "EncodedIndex") {
			id := idx_name_lut[name]
			var (
				tables = enc_lut[id]
				rows   uint32
			)
			for _, t := range tables {
				if t == id_nullTable {
					continue
				}
				if s2 := m.Tables[t].Rows; s2 > rows {
					rows = s2
				}
			}
			if rows<<util.Bits(len(tables)) < 1<<16 {
				size = 2
			} else {
				size = 4
			}
		} else if strings.HasSuffix(name, "Index") {
			if m.Tables[idx_name_lut[name]].Rows < 1<<16 {
				size = 2
			} else {
				size = 4
			}
		} else {
			switch t.Kind() {
			case reflect.Struct:
				for i := 0; i < t.NumField(); i++ {
					f := t.Field(i)
					if s, err := m.Size(f.Type); err != nil {
						return 0, err
					} else {
						size += s
					}
				}
			case reflect.Uint8:
				return 1, nil
			case reflect.Uint16:
				return 2, nil
			case reflect.Uint32:
				return 4, nil
			case reflect.Uint64:
				return 8, nil
			default:
				return 0, errors.New(fmt.Sprintf("Don't know the size of: %s, %s", t.Name(), t.Kind()))
			}
		}
	}
	return size, nil
}
Пример #3
0
func (m *MetadataUtil) Create(br *binary.BinaryReader, v interface{}) error {
	t := reflect.ValueOf(v)
	if t.Kind() != reflect.Ptr {
		return errors.New(fmt.Sprintf("Expected a pointer not %s", t.Kind()))
	}
	v2 := t.Elem()
	name := v2.Type().Name()

	if name == "StringIndex" {
		size := m.StringHeap.RowSize
		index, err := m.ReadIndex(br, uint(size))
		if err != nil {
			return err
		}
		data := m.StringHeap.data[index:m.StringHeap.Rows]

		for i := range data {
			if data[i] == '\u0000' {
				data = data[:i]
				break
			}
		}
		v2.SetString(string(data))
	} else if name == "Guid" {
		size := m.GuidHeap.RowSize
		if index, err := m.ReadIndex(br, uint(size)); err != nil {
			return err
		} else if index != 0 {
			index = (index - 1) * 16
			g := Guid(m.GuidHeap.data[index : index+16])
			v2.Set(reflect.ValueOf(g))
		}
	} else if strings.HasSuffix(name, "EncodedIndex") {
		size, err := m.Size(v2.Type())
		if err != nil {
			return err
		}
		idx, err := m.ReadIndex(br, size)
		if err != nil {
			return err
		}
		var (
			tables = enc_lut[idx_name_lut[name]]
			b      = util.Bits(len(tables))
			mask   = uint32(0xffff << b)
			tbl    = idx &^ mask
			ti     ConcreteTableIndex
		)
		idx = idx >> b
		ti.index = idx
		ti.table = tables[int(tbl)]
		ti.metadataUtil = m
		v2.Set(reflect.ValueOf(&ti))
	} else if strings.HasSuffix(name, "Index") {
		size, err := m.Size(v2.Type())
		if err != nil {
			return err
		}
		var ti ConcreteTableIndex
		if ti.index, err = m.ReadIndex(br, size); err != nil {
			return err
		}
		if name == "BlobIndex" {
			ti.table = id_Blob
		} else {
			ti.table = idx_name_lut[name]
		}
		ti.metadataUtil = m
		v2.Set(reflect.ValueOf(&ti))
	} else {
		if v2.Kind() != reflect.Struct {
			return br.ReadInterface(v)
		}
		for i := 0; i < v2.NumField(); i++ {
			f := v2.Field(i)
			a := f.Addr()
			if err := m.Create(br, a.Interface()); err != nil {
				return err
			}
		}
	}
	return nil
}