Skip to content

Commit

Permalink
implement simple recordfile
Browse files Browse the repository at this point in the history
  • Loading branch information
name5566 committed Aug 5, 2014
1 parent 4b45d8f commit 5e8520c
Showing 1 changed file with 73 additions and 20 deletions.
93 changes: 73 additions & 20 deletions recordfile/recordfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import (
"fmt"
"os"
"reflect"
"strconv"
)

const (
defComma = ','
defComment = '#'
)
var Comma rune = ','
var Comment rune = '#'

type RecordFile struct {
Comma rune
Comment rune
kindFields []reflect.Kind
tagFields []reflect.StructTag
typeRecord reflect.Type
records []interface{}
indexes [](map[interface{}]interface{})
}
Expand All @@ -31,18 +31,19 @@ func New(st interface{}) (*RecordFile, error) {
rf := new(RecordFile)
rf.kindFields = make([]reflect.Kind, t.NumField())
rf.tagFields = make([]reflect.StructTag, t.NumField())
rf.typeRecord = t

for i := 0; i < t.NumField(); i++ {
f := t.Field(i)

// kind
k := f.Type.Kind()
if k == reflect.Bool ||
k == reflect.Int8 ||
k == reflect.Int16 ||
k == reflect.Int32 ||
k == reflect.Int64 ||
k == reflect.Uint8 ||
k == reflect.Uint16 ||
k == reflect.Uint32 ||
k == reflect.Uint64 ||
k == reflect.Float32 ||
Expand All @@ -53,7 +54,6 @@ func New(st interface{}) (*RecordFile, error) {
return nil, errors.New("invalid type: " + k.String())
}

// tag
tag := f.Tag
if tag == "" ||
tag == "index" {
Expand All @@ -74,10 +74,10 @@ func (rf *RecordFile) Read(name string) error {
defer f.Close()

if rf.Comma == 0 {
rf.Comma = defComma
rf.Comma = Comma
}
if rf.Comment == 0 {
rf.Comment = defComment
rf.Comment = Comment
}

reader := csv.NewReader(f)
Expand All @@ -88,22 +88,75 @@ func (rf *RecordFile) Read(name string) error {
return err
}

for n, line := range lines {
// kind
if n == 0 {
for i, k := range rf.kindFields {
fmt.Println(i, k)
fmt.Println(line[i])
}
}
records := make([]interface{}, len(lines)-1)
for n := 1; n < len(lines); n++ {
v := reflect.New(rf.typeRecord)
records[n-1] = v.Interface()
record := v.Elem()

// desc
if n == 1 {
continue
line := lines[n]
if len(line) != len(rf.kindFields) {
return errors.New(fmt.Sprintf("line %v, field count mismatch: %v %v",
n, len(line), len(rf.kindFields)))
}

// data
for i, k := range rf.kindFields {
fieldStr := line[i]
field := record.Field(i)

var err error

if k == reflect.Bool {
var v bool
v, err = strconv.ParseBool(fieldStr)
if err == nil {
field.SetBool(v)
}
} else if k == reflect.Int8 ||
k == reflect.Int16 ||
k == reflect.Int32 ||
k == reflect.Int64 {
var v int64
v, err = strconv.ParseInt(fieldStr, 0, field.Type().Bits())
if err == nil {
field.SetInt(v)
}
} else if k == reflect.Uint8 ||
k == reflect.Uint16 ||
k == reflect.Uint32 ||
k == reflect.Uint64 {
var v uint64
v, err = strconv.ParseUint(fieldStr, 0, field.Type().Bits())
if err == nil {
field.SetUint(v)
}
} else if k == reflect.Float32 ||
k == reflect.Float64 {
var v float64
v, err = strconv.ParseFloat(fieldStr, field.Type().Bits())
if err == nil {
field.SetFloat(v)
}
} else if k == reflect.String {
field.SetString(fieldStr)
}

if err != nil {
return errors.New(fmt.Sprintf("parse field (row=%v, col=%v) error: %v",
n, i, err))
}
}
}

rf.records = records

return nil
}

func (rf *RecordFile) Record(i int) interface{} {
return rf.records[i]
}

func (rf *RecordFile) NumRecord() int {
return len(rf.records)
}

0 comments on commit 5e8520c

Please sign in to comment.