Commits

Fazlul Shahriar committed 00c99e8

hdf4: set File.Info

Comments (0)

Files changed (2)

 import (
 	"bufio"
 	"bytes"
+	"fmt"
 	"io"
 	"os"
 )
 
-var hdfMagic = []byte{0x0E, 0x03, 0x13, 0x01}
-
 type File struct {
 	fd      *os.File
 	r       *bufio.Reader
 	Tag, Ref    uint16
 	offset, len uint32
 	file        *File
-	info        interface{}
+	Info        interface{}
 }
 
 func get8(b []byte) (uint8, []byte) {
 	file.fd = fd
 	file.r = bufio.NewReader(fd)
 
+	var hdfMagic = []byte{0x0E, 0x03, 0x13, 0x01}
 	magic := make([]byte, len(hdfMagic))
 	if _, err = io.ReadFull(file.r, magic); err != nil {
 		return nil, err
 		return nil, err
 	}
 
-	rec := file.LookupRecord(DFTAG_VERSION, -1)
-	if rec == nil {
-		return nil, os.NewError("version descriptor missing")
-	}
-	b, err := rec.readPayload()
+	rec, err := file.LookupRecord(DFTAG_VERSION, -1)
 	if err != nil {
 		return nil, err
 	}
-	file.Version = parseVersion(b)
+	file.Version = rec.Info.(*Version)
 
 	return file, nil
 }
 // LookupRecord returns the first record matching tag
 // and ref, which uniquely identifies a record. If ref < 0,
 // first record matching tag is returns.
-func (file *File) LookupRecord(tag, ref int) *Record {
-	for _, rec := range file.Records {
+func (file *File) LookupRecord(tag, ref int) (*Record, os.Error) {
+	var rec *Record
+	for i := 0; i < len(file.Records); i++ {
+		rec = &file.Records[i]
 		if ref < 0 && int(rec.Tag) == tag {
-			return &rec
+			goto found
 		}
 		if int(rec.Ref) == ref && int(rec.Tag) == tag {
-			return &rec
+			goto found
 		}
 	}
-	return nil
+	return nil, os.NewError("tag/ref not found")
+
+found:
+	if rec.Info == nil {
+		b, err := rec.readPayload()
+		if err != nil {
+			return nil, err
+		}
+		switch rec.Tag {
+		case DFTAG_VERSION:
+			rec.Info = parseVersion(b)
+		case DFTAG_NT:
+			rec.Info = parseNumType(b)
+		case DFTAG_SDD:
+			rec.Info = parseSDD(b)
+		case DFTAG_NDG:
+			rec.Info = parseNDG(b)
+		case DFTAG_VG:
+			rec.Info = parseVGroup(b)
+		default:
+			return nil, fmt.Errorf("unknown tag %d", int(rec.Tag))
+		}
+	}
+	return rec, nil
 }
 
 func (rec *Record) readPayload() ([]byte, os.Error) {

hdf4/hdf4_test.go

 
 const hdfPath = "/home/fhs/glasslab/src/cmd/modis_crefl/tbase.hdf"
 
-func readRecord(t *testing.T, file *File, tag, ref int) []byte {
-	rec := file.LookupRecord(tag, ref)
-	if rec == nil {
-		t.Fatalf("descriptor missing")
-	}
-	b, err := rec.readPayload()
-	if err != nil {
-		t.Fatalf("descriptor read failed: %v", err)
-	}
-	return b
-}
-
 func TestOpen(t *testing.T) {
 	file, err := Open(hdfPath)
 	if err != nil {
 	}
 	defer file.Close()
 
+	rec, err := file.LookupRecord(DFTAG_NT, -1)
+	if err != nil {
+		t.Errorf("LookupRecord failed: %v", err)
+	}
+	log.Printf("nt = %v\n", rec.Info.(*NumType))
+
+	rec, err = file.LookupRecord(DFTAG_SDD, -1)
+	if err != nil {
+		t.Errorf("LookupRecord failed: %v", err)
+	}
+	log.Printf("sdd = %v\n", rec.Info.(*SDD))
+
+	rec, err = file.LookupRecord(DFTAG_NDG, -1)
+	if err != nil {
+		t.Errorf("LookupRecord failed: %v", err)
+	}
+	log.Printf("sdd = %v\n", rec.Info.(*NDG))
+
+	rec, err = file.LookupRecord(DFTAG_VG, -1)
+	if err != nil {
+		t.Errorf("LookupRecord failed: %v", err)
+	}
+	vg := rec.Info.(*VGroup)
+	log.Printf("vg = %v (name=%s, class=%s)\n", vg, string(vg.Name), string(vg.Class))
+
 	log.Printf("Records=%v\n", file.Records)
 	log.Printf("Version=%v\n", file.Version)
-
-	b := readRecord(t, file, DFTAG_NT, -1)
-	nt := parseNumType(b)
-	log.Printf("nt = %v\n", nt)
-
-	b = readRecord(t, file, DFTAG_SDD, -1)
-	sdd := parseSDD(b)
-	log.Printf("sdd = %v\n", sdd)
-
-	b = readRecord(t, file, DFTAG_NDG, -1)
-	ndg := parseNDG(b)
-	log.Printf("ndg = %v\n", ndg)
-
-	b = readRecord(t, file, DFTAG_VG, -1)
-	vg := parseVGroup(b)
-	log.Printf("vg = %v (name=%s, class=%s)\n", vg, string(vg.Name), string(vg.Class))
 }