예제 #1
0
파일: sheet.go 프로젝트: jwk000/tabtoy
// 解析a.b.c字段,由给定的msg找到这些字段病返回字段访问器
func makeCompactAccessor(fieldName string, inputMsg *data.DynamicMessage) (*data.DynamicMessage, *pbmeta.FieldDescriptor) {

	// 将路径按点分割
	fieldNameList := strings.Split(fieldName, ".")

	msg := inputMsg

	for _, fieldName := range fieldNameList {

		// 这个路径对应的描述器
		fd := msg.Desc.FieldByName(fieldName)
		if fd == nil {
			log.Errorf("field type name not found, %s in %s", fieldName, fieldName)
			return nil, nil
		}

		// 消息进行添加并迭代
		if fd.Type() == pbprotos.FieldDescriptorProto_TYPE_MESSAGE {

			// 字段中带repeated message的不支持, 使用string2struct解析字段
			fdmeta := data.GetFieldMeta(fd)
			if fd.IsRepeated() && fdmeta != nil && !fdmeta.String2Struct {
				log.Errorf("DO NOT support repeated message field, use 'string2struct' instead")
				return nil, nil
			}

			existMsg := msg.GetMessage(fd)

			if existMsg == nil {
				newMsg := data.NewDynamicMessage(fd.MessageDesc())

				if !msg.SetMessage(fd, newMsg) {
					return nil, nil
				}

				msg = newMsg
			} else {
				msg = existMsg
			}

		} else {
			// 非消息返回当前层的反射器

			return msg, fd
		}

	}

	// 纯消息, 字段使用父级
	return msg, inputMsg.Desc.FieldByName(fieldName)
}
예제 #2
0
파일: valconv.go 프로젝트: jwk000/tabtoy
func ValueConvetor(fd *pbmeta.FieldDescriptor, value string) (string, bool) {

	// 空单元格时, 给定一个这个类型对应的值
	if value == "" {
		value = data.GetDefaultValue(fd)
	}

	switch fd.Type() {
	case pbprotos.FieldDescriptorProto_TYPE_FLOAT:

		_, err := strconv.ParseFloat(value, 32)

		if err != nil {

			return "", false
		}

	case pbprotos.FieldDescriptorProto_TYPE_INT64:

		_, err := strconv.ParseInt(value, 10, 64)
		if err != nil {

			return "", false
		}

	case pbprotos.FieldDescriptorProto_TYPE_UINT64:

		_, err := strconv.ParseUint(value, 10, 64)
		if err != nil {
			return "", false
		}

	case pbprotos.FieldDescriptorProto_TYPE_INT32:

		_, err := strconv.ParseInt(value, 10, 32)
		if err != nil {
			return "", false
		}

	case pbprotos.FieldDescriptorProto_TYPE_UINT32:

		_, err := strconv.ParseUint(value, 10, 32)

		if err != nil {
			return "", false
		}

	case pbprotos.FieldDescriptorProto_TYPE_BOOL:

		var final string

		for {
			if value == "是" {
				final = "true"
				break
			} else if value == "否" {
				final = "false"
				break
			}

			v, err := strconv.ParseBool(value)

			if err != nil {
				return "", false
			}

			if v {
				final = "true"
			} else {
				final = "false"
			}

			break
		}

		value = final

	case pbprotos.FieldDescriptorProto_TYPE_ENUM:
		ed := fd.EnumDesc()

		if ed.ValueCount() == 0 {
			return "", false
		}

		// 枚举值从表格读出时可能是中文枚举值, 需要根据meta信息转换为程序枚举值
		var convValue string = value

		// 遍历这个枚举类型
		for i := 0; i < ed.ValueCount(); i++ {

			evd := ed.Value(i)

			// 取出每个字段的meta
			meta := data.GetFieldMeta(evd)

			if meta == nil {
				continue
			}

			// 这个枚举值的别名是否与给定的一致
			if meta.Alias == value {
				convValue = evd.Name()
				break
			}
		}

		if ed.ValueByName(convValue) == nil {
			log.Errorf("enum doesn't contain this value, %s in %s", convValue, fd.Name())
			return "", false
		}

		value = convValue

	}

	return value, true
}
예제 #3
0
파일: sheet.go 프로젝트: jwk000/tabtoy
func (self *Sheet) IterateData(callback func(*RecordInfo) bool) (*data.DynamicMessage, bool) {

	// 检查引导头
	if !self.ParseProtoField() {
		return nil, true
	}

	// 是否继续读行
	var readingLine bool = true

	// 检查引导Proto字段
	sheetMsg, rowMsgDesc, lineFieldDesc := self.checkProtoHeader()

	if sheetMsg == nil {
		goto ErrorStop
	}

	// 遍历每一行
	for self.cursor = DataIndex_DataBegin; readingLine; self.cursor++ {

		// 第一列是空的,结束
		if self.GetCellData(self.cursor, 0) == "" {
			break
		}

		lineMsg := data.NewDynamicMessage(rowMsgDesc)

		if lineMsg == nil {
			break
		}

		// 遍历每一列
		for self.index = 0; self.index < len(self.FieldHeader); self.index++ {

			ri := new(RecordInfo)

			// Proto字段头
			ri.FieldName = self.FieldHeader[self.index]

			// 原始值
			ri.Value = self.GetCellData(self.cursor, self.index)

			// #开头表示注释, 跳过
			if strings.Index(ri.FieldName, "#") == 0 {
				continue
			}

			ri.FieldMsg, ri.FieldDesc = makeCompactAccessor(ri.FieldName, lineMsg)

			// 字段匹配错误
			if ri.FieldMsg == nil || ri.FieldDesc == nil {
				goto ErrorStop
			}

			// 取扩展元信息
			ri.FieldMeta = data.GetFieldMeta(ri.FieldDesc)

			if data.DebuggingLevel >= 1 {
				r, c := self.GetRC()
				log.Debugf("(%s) %s=%s", data.ConvR1C1toA1(r, c), ri.FieldName, ri.Value)
			}

			if !callback(ri) {
				goto ErrorStop
			}

		}

		sheetMsg.AddRepeatedMessage(lineFieldDesc, lineMsg)

	}

	return sheetMsg, true

ErrorStop:

	r, c := self.GetRC()

	log.Errorf("%s|%s(%s)", self.file.FileName, self.Name, data.ConvR1C1toA1(r, c))
	return nil, false
}