1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/chai2010-tiff

Клонировать/Скачать
gen_helper.go 9.5 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
chaishushan@gmail.com Отправлено 25.02.2015 06:52 0751529
// Copyright 2014 <chaishushan{AT}gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ingore
package main
import (
"bufio"
"bytes"
"fmt"
"go/format"
"io/ioutil"
"log"
"strconv"
"strings"
"text/scanner"
)
type Type struct {
TypeName string
FileName string
FileData []byte
TypeList []string
TypeCommentMap map[string]string
TagTypeMap map[string][]string
TagNumMap map[string][]int
MapCode string
}
func main() {
var types = []Type{
Type{
TypeName: "TiffType",
FileName: "tiff_types.go",
},
Type{
TypeName: "ImageType",
FileName: "tiff_types.go",
},
Type{
TypeName: "DataType",
FileName: "tiff_types.go",
},
Type{
TypeName: "TagType",
FileName: "tiff_types.go",
},
Type{
TypeName: "TagValue_PhotometricType",
FileName: "tiff_types.go",
},
Type{
TypeName: "TagValue_CompressionType",
FileName: "tiff_types.go",
},
Type{
TypeName: "TagValue_PredictorType",
FileName: "tiff_types.go",
},
Type{
TypeName: "TagValue_ResolutionUnitType",
FileName: "tiff_types.go",
},
}
var buf bytes.Buffer
fmt.Fprintf(&buf, `
// Copyright 2014 <chaishushan{AT}gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Auto generated by gen_helper.go, DO NOT EDIT!!!
package tiff
import (
"fmt"
"time"
)
`[1:])
for _, v := range types {
v.Init()
v.GenMapCode()
fmt.Fprintf(&buf, "%s\n", v.MapCode)
}
data, err := format.Source(buf.Bytes())
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile("z_tiff_types_string.go", data, 0644)
if err != nil {
log.Fatal(err)
}
}
func (p *Type) Init() {
if p.TypeCommentMap == nil {
p.TypeCommentMap = make(map[string]string)
}
if p.TagTypeMap == nil {
p.TagTypeMap = make(map[string][]string)
}
if p.TagNumMap == nil {
p.TagNumMap = make(map[string][]int)
}
data, err := ioutil.ReadFile(p.FileName)
if err != nil {
log.Fatal(err)
}
p.FileData = data
var s scanner.Scanner
s.Init(bytes.NewReader(p.FileData))
for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
if tok&scanner.ScanIdents != 0 {
if strings.HasPrefix(s.TokenText(), p.TypeName+"_") {
typeName := s.TokenText()
if _, ok := p.TypeCommentMap[typeName]; !ok {
comment, _, _ := bufio.NewReader(bytes.NewReader(p.FileData[s.Pos().Offset:])).ReadLine()
if idx := bytes.Index(comment, []byte("//")); idx >= 0 {
comment = comment[idx:]
} else {
comment = nil
}
p.TypeList = append(p.TypeList, typeName)
p.TypeCommentMap[typeName] = string(comment)
}
}
}
}
if p.TypeName == "TagType" {
p.parseTagComment()
}
}
func (p *Type) parseTagComment() {
if p.TypeName != "TagType" {
return
}
// Type(A/B/C/*), Num(1/*), Required, # comment
for typeName, comment := range p.TypeCommentMap {
if strings.HasPrefix(comment, "//") {
comment = strings.TrimSpace(comment[len("//"):])
}
if idx := strings.Index(comment, "#"); idx >= 0 {
comment = comment[:idx]
}
if comment == "" {
continue
}
ss := strings.Split(comment, ",")
if len(ss) > 0 {
var types []string
for _, dataType := range strings.Split(strings.TrimSpace(ss[0]), "/") {
switch dataType {
case "BYTE":
types = append(types, "DataType_Byte")
case "ASCII":
types = append(types, "DataType_ASCII")
case "SHORT":
types = append(types, "DataType_Short")
case "LONG":
types = append(types, "DataType_Long")
case "RATIONAL":
types = append(types, "DataType_Rational")
case "SBYTE":
types = append(types, "DataType_SByte")
case "UNDEFINED":
types = append(types, "DataType_Undefined")
case "SSHORT":
types = append(types, "DataType_SShort")
case "SLONG":
types = append(types, "DataType_SLong")
case "SRATIONAL":
types = append(types, "DataType_SRational")
case "FLOAT":
types = append(types, "DataType_Float")
case "DOUBLE":
types = append(types, "DataType_Double")
case "IFD":
types = append(types, "DataType_IFD")
case "UNICODE":
types = append(types, "DataType_Unicode")
case "COMPLEX":
types = append(types, "DataType_Complex")
case "LONG8":
types = append(types, "DataType_Long8")
case "SLONG8":
types = append(types, "DataType_SLong8")
case "IFD8":
types = append(types, "DataType_IFD8")
}
}
p.TagTypeMap[typeName] = types
}
if len(ss) > 1 {
var nums []int
for _, numName := range strings.Split(strings.TrimSpace(ss[1]), "/") {
if v, err := strconv.Atoi(numName); err == nil {
nums = append(nums, v)
}
}
p.TagNumMap[typeName] = nums
}
}
}
func (p *Type) GenMapCode() {
var buf bytes.Buffer
fmt.Fprintf(&buf, "var _%sTable = map[%s]string {\n", p.TypeName, p.TypeName)
for _, s := range p.TypeList {
fmt.Fprintf(&buf, "\t%s: `%s`, %s\n", s, s, p.TypeCommentMap[s])
}
fmt.Fprintf(&buf, "}\n")
if p.TypeName == "TagType" && len(p.TagTypeMap) > 0 {
fmt.Fprintf(&buf, "\nvar _TagType_TypesTable = map[TagType][]DataType {\n")
for _, s := range p.TypeList {
if v, ok := p.TagTypeMap[s]; ok && len(v) > 0 {
fmt.Fprintf(&buf, "%s: []DataType{ ", s)
for j := 0; j < len(v); j++ {
fmt.Fprintf(&buf, `%s, `, v[j])
}
fmt.Fprintf(&buf, "},\n")
}
}
fmt.Fprintf(&buf, "}\n")
}
if p.TypeName == "TagType" && len(p.TagNumMap) > 0 {
fmt.Fprintf(&buf, "\nvar _TagType_NumsTable = map[TagType][]int {\n")
for _, s := range p.TypeList {
if v, ok := p.TagNumMap[s]; ok && len(v) > 0 {
fmt.Fprintf(&buf, "%s: []int{ ", s)
for j := 0; j < len(v); j++ {
fmt.Fprintf(&buf, `%d, `, v[j])
}
fmt.Fprintf(&buf, "},\n")
}
}
fmt.Fprintf(&buf, "}\n")
}
if p.TypeName == "TagType" {
fmt.Fprintf(&buf, "\ntype TagGetter interface {\n")
for _, s := range p.TypeList {
fmt.Fprintf(&buf, "Get%s() (value %s, ok bool)\n", s[len("TagType_"):], p.getValueType(s))
}
fmt.Fprintf(&buf, "\n")
fmt.Fprintf(&buf, "GetUnknown(tag TagType) (value []byte, ok bool)\n")
fmt.Fprintf(&buf, "\n")
fmt.Fprintf(&buf, "private()\n")
fmt.Fprintf(&buf, "}\n")
fmt.Fprintf(&buf, "\ntype TagSetter interface {\n")
for _, s := range p.TypeList {
fmt.Fprintf(&buf, "Set%s(value %s) (ok bool)\n", s[len("TagType_"):], p.getValueType(s))
}
fmt.Fprintf(&buf, "\n")
fmt.Fprintf(&buf, "SetUnknown(tag TagType, value interface{}) (ok bool)\n")
fmt.Fprintf(&buf, "\n")
fmt.Fprintf(&buf, "private()\n")
fmt.Fprintf(&buf, "}\n")
}
fmt.Fprintf(&buf, `
func (p %s) String() string {
if name, ok := _%sTable[p]; ok {
return name
}
return fmt.Sprintf("%s_Unknown(%%d)", uint16(p))
}
`,
p.TypeName,
p.TypeName,
p.TypeName,
)
p.MapCode = buf.String()
}
func (p *Type) getValueType(typeName string) string {
switch typeName {
case "TagType_Compression":
return "TagValue_CompressionType"
case "TagType_PhotometricInterpretation":
return "TagValue_PhotometricType"
case "TagType_Predictor":
return "TagValue_PredictorType"
case "TagType_ResolutionUnit":
return "TagValue_ResolutionUnitType"
case "TagType_ColorMap":
return "[][3]uint16"
case "TagType_SMinSampleValue", "TagType_SMaxSampleValue":
return "[]float64"
case "TagType_DateTime":
return "time.Time"
}
switch types, _ := p.TagTypeMap[typeName]; {
case p.isIntType(types):
if p.isOnlyOneValue(p.TagNumMap[typeName]) {
return `int64`
} else {
return `[]int64`
}
case p.isFloatType(types):
if p.isOnlyOneValue(p.TagNumMap[typeName]) {
return `float64`
} else {
return `[]float64`
}
case p.isRationalType(types):
if p.isOnlyOneValue(p.TagNumMap[typeName]) {
return `[2]int64`
} else {
return `[][2]int64`
}
case p.isComplexType(types):
if p.isOnlyOneValue(p.TagNumMap[typeName]) {
return `complex128`
} else {
return `[]complex128`
}
case p.isStringType(types):
return `string`
case p.isUndefinedType(types):
return `[]byte`
default:
return `[]byte`
}
}
func (p *Type) isOnlyOneValue(nums []int) bool {
return len(nums) == 1 && nums[0] == 1
}
func (p *Type) isIntType(dataTypes []string) bool {
if len(dataTypes) == 0 {
return false
}
for _, s := range dataTypes {
switch s {
case "DataType_Byte", "DataType_Short", "DataType_Long", "DataType_Long8":
case "DataType_SByte", "DataType_SShort", "DataType_SLong", "DataType_SLong8":
case "DataType_IFD", "DataType_IFD8":
default:
return false
}
}
return true
}
func (p *Type) isFloatType(dataTypes []string) bool {
if len(dataTypes) == 0 {
return false
}
for _, s := range dataTypes {
if s != "DataType_Float" && s != "DataType_Double" {
return false
}
}
return true
}
func (p *Type) isRationalType(dataTypes []string) bool {
if len(dataTypes) == 0 {
return false
}
for _, s := range dataTypes {
if s != "DataType_Rational" && s != "DataType_SRational" {
return false
}
}
return true
}
func (p *Type) isComplexType(dataTypes []string) bool {
if len(dataTypes) == 0 {
return false
}
for _, s := range dataTypes {
if s != "DataType_Complex" {
return false
}
}
return true
}
func (p *Type) isStringType(dataTypes []string) bool {
if len(dataTypes) == 0 {
return false
}
for _, s := range dataTypes {
if s != "DataType_ASCII" && s != "DataType_Unicode" {
return false
}
}
return true
}
func (p *Type) isUndefinedType(dataTypes []string) bool {
if len(dataTypes) == 0 {
return true
}
for _, s := range dataTypes {
if s == "DataType_Undefined" {
return true
}
}
return false
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/chai2010-tiff.git
git@api.gitlife.ru:oschina-mirror/chai2010-tiff.git
oschina-mirror
chai2010-tiff
chai2010-tiff
master