// Hash returns the hash of the file at the given path. func (h *Hasher) Hash(p string) (string, error) { chash, ok := h.c.Get(p) if ok { switch chash := chash.(type) { default: return "", fmt.Errorf("unexpected type %T", chash) case string: return chash, nil case error: return "", chash } } hl, ok := h.getPathLock(p) if ok { hl.Lock() hl.Unlock() return h.Hash(p) } defer h.deletePathLock(p) b := <-h.b phash, err := rh.Hash(p, h.h(), b) h.b <- b if err != nil { h.c.Add(p, err) return "", err } h.c.Add(p, phash) return phash, nil }
// ProcessROM does all the processing of the ROM. It hashes, // downloads the metadata, and downloads the images. // The results are stored in the ROMs XML property. func (r *ROM) ProcessROM(ds *datasources) error { log.Printf("INFO: Starting: %s", r.Path) r.PopulatePaths() var xml *GameXML var err error if *mame { log.Printf("INFO: Attempting lookup in MAMEDB: %s", r.Path) xml, err = GetMAMEGame(r) } else { h, err := rh.Hash(r.Path, sha1.New()) if err != nil { return err } r.Hash = h } if xml == nil && *useGDB { log.Printf("INFO: Attempting lookup in GDB: %s", r.Path) xml, err = GetGDBGame(r, ds) } if xml == nil && *useOVGDB { log.Printf("INFO: Attempting lookup in OVGDB: %s", r.Path) xml, err = GetOVGDBGame(r, ds) } if r.Cue && err != nil && err == NotFound { for _, bin := range r.Bins { h, herr := rh.Hash(bin, sha1.New()) if herr != nil { return herr } r.Hash = h if xml == nil && *useGDB { log.Printf("INFO: Attempting lookup in GDB: %s", filepath.Base(bin)) xml, err = GetGDBGame(r, ds) } if xml == nil && *useOVGDB { log.Printf("INFO: Attempting lookup in OVGDB: %s", filepath.Base(bin)) xml, err = GetOVGDBGame(r, ds) } if err != NotFound { break } } } if err != nil { if err == ovgdb.NotFound { err = NotFound } if err == mamedb.NotFound { err = NotFound } if *addNotFound && err == NotFound { log.Printf("INFO: %s: %s", r.Path, err) xml = &GameXML{Path: fixPath(*romPath + "/" + strings.TrimPrefix(r.Path, *romDir)), GameTitle: r.bName} if *useNoIntroName && *useGDB { n, ok := ds.HM.GetName(r.Hash) if ok { xml.GameTitle = n } } } else { return err } } if *useFilename { xml.GameTitle = r.bName } if *stripUnicode { xml.Overview = strings.Map(StripChars, xml.Overview) xml.GameTitle = strings.Map(StripChars, xml.GameTitle) } iPath, tPath := GetImgPaths(r) iExists := exists(iPath) tExists := exists(tPath) if xml.Image == "" && iExists { xml.Image = fixPath(*imagePath + "/" + strings.TrimPrefix(iPath, *imageDir)) } if xml.Thumb == "" && tExists { xml.Thumb = fixPath(*imagePath + "/" + strings.TrimPrefix(tPath, *imageDir)) } r.XML = xml return nil }