コード例 #1
0
ファイル: patchfile.go プロジェクト: davyxu/tabtoy
func patchMsg(input, patch *data.DynamicMessage, indent int, sheetName string) bool {

	return patch.IterateFieldDesc(func(fd *pbmeta.FieldDescriptor) bool {

		if fd.Type() == pbprotos.FieldDescriptorProto_TYPE_MESSAGE {

			if fd.IsRepeated() {

				// 顶级的消息肯定是repeated的, 因此直接进入
				if indent == 0 {

					nextInputMsgArray := input.GetRepeatedMessage(fd)
					nextPatchMsgArray := patch.GetRepeatedMessage(fd)

					if len(nextInputMsgArray) != len(nextPatchMsgArray) {
						log.Errorf("patch rows diff from input msg")
						return false
					}

					// 相同的行数才可以进去继续迭代
					for index, nextInputMsg := range nextInputMsgArray {

						patchMsg(nextInputMsg, nextPatchMsgArray[index], indent+1, sheetName)
					}

				} else {

					// 直接替换值数组
					pathMsgArray := patch.GetRepeatedMessage(fd)

					input.ClearFieldValue(fd)
					for _, msg := range pathMsgArray {
						input.AddRepeatedMessage(fd, msg)
					}

				}

			} else {

				nextInputMsg := input.GetMessage(fd)
				nextPatchMsg := patch.GetMessage(fd)

				patchMsg(nextInputMsg, nextPatchMsg, indent+1, sheetName)
			}

		} else {

			if fd.IsRepeated() {

				log.Infof("patch repeated field: '%s' = '%s'", fd.Name(), patch.GetRepeatedValue(fd))

				// 直接用patch的覆盖多值
				input.ClearFieldValue(fd)
				for _, v := range patch.GetRepeatedValue(fd) {

					input.AddRepeatedValue(fd, v)
				}

			} else {

				v, _ := patch.GetValue(fd)

				log.Infof("patch field: '%s' = '%s'", fd.Name(), v)

				// 单值设置
				input.SetValue(fd, v)

			}

		}

		return true
	})

	return true
}
コード例 #2
0
ファイル: shared.go プロジェクト: davyxu/tabtoy
func rawWriteMessage(printer *bytes.Buffer, writer dataWriter, msg *data.DynamicMessage, indent int) (valueWrite int) {

	for i := 0; i < msg.Desc.FieldCount(); i++ {
		fd := msg.Desc.Field(i)

		var needSpliter bool

		pos := printer.Len()

		if i > 0 && valueWrite > 0 {
			writer.WriteFieldSpliter()
		}

		if fd.Type() == pbprotos.FieldDescriptorProto_TYPE_MESSAGE {

			if fd.IsRepeated() {

				// 多结构
				if msgList := msg.GetRepeatedMessage(fd); msgList != nil {

					writer.RepeatedMessageBegin(fd, msg, len(msgList), indent+1)

					for msgIndex, msg := range msgList {

						beginPos := printer.Len()
						writer.WriteMessage(fd, msg, indent+1)
						endPos := printer.Len()

						// 是否有数据写入
						if endPos > beginPos {
							valueWrite++

							// 最后一个不要加
							if msgIndex < len(msgList)-1 {
								writer.WriteFieldSpliter()
							}
						}

						if indent == 0 {
							printer.WriteString("\n")
						}

					}

					writer.RepeatedMessageEnd(fd, msg, len(msgList), indent+1)

					needSpliter = true

					continue
				}

			} else {
				// 单结构
				if msg := msg.GetMessage(fd); msg != nil {

					beginPos := printer.Len()
					writer.WriteMessage(fd, msg, indent+1)
					endPos := printer.Len()

					// 是否有数据写入
					if endPos > beginPos {
						valueWrite++

						needSpliter = true
					}

				}
			}

		} else {

			// 多值
			if fd.IsRepeated() {

				if valuelist := msg.GetRepeatedValue(fd); valuelist != nil {

					writer.RepeatedValueBegin(fd)

					for vIndex, value := range valuelist {

						writer.WriteValue(fd, value, indent)
						valueWrite++

						if vIndex < len(valuelist)-1 {
							writer.WriteFieldSpliter()

						}
					}

					writer.RepeatedValueEnd(fd)

					needSpliter = true
				}

			} else {

				// 单值
				if value, ok := msg.GetValue(fd); ok {

					writer.WriteValue(fd, value, indent)
					valueWrite++

					needSpliter = true
				}

			}

		}

		//没有值输出, 把打分割之前的位置恢复
		if !needSpliter {
			printer.Truncate(pos)
		}

	}

	return

}