Beispiel #1
0
func (self *Sheet) checkProtoHeader() (*data.DynamicMessage, *pbmeta.Descriptor, *pbmeta.FieldDescriptor) {

	// 指定的导出文件类型获得描述
	fileDesc := self.file.descpool.MessageByFullName(self.header.ProtoTypeName)

	if fileDesc == nil {
		log.Errorf("can not found record descriptor, %s", self.header.ProtoTypeName)
		return nil, nil, nil
	}

	lineMsgDesc := fileDesc.FieldByName(self.header.RowFieldName)

	// 找不到定义
	if lineMsgDesc == nil {
		log.Errorf("row field type not found: %s", self.header.RowFieldName)
		return nil, nil, nil
	}

	// 行描述类型必须是数组
	if !lineMsgDesc.IsRepeated() {
		log.Errorf("row field type must be repeated type: %s", self.header.RowFieldName)
		return nil, nil, nil
	}

	// 根据描述创建输出文件消息及每一行的消息结构类型
	return data.NewDynamicMessage(fileDesc), lineMsgDesc.MessageDesc(), lineMsgDesc
}
Beispiel #2
0
// 解析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)
}
Beispiel #3
0
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
}