'Adds a file to the hash file store.
We take a file in the client space:
aff4:/C.123123123/fs/os/usr/local/blah
Hash it, update the hash in the original file if its different to the
one calculated on the client, and copy the original AFF4 object to
aff4:/files/hash/generic/sha256/123123123 (canonical reference)
We then create symlinks for all other hash types:
aff4:/files/hash/generic/sha1/345345345
aff4:/files/hash/generic/md5/456456456
aff4:/files/hash/pecoff/md5/aaaaaaaa (only for PEs)
aff4:/files/hash/pecoff/sha1/bbbbbbbb (only for PEs)
When present in PE files, the signing data (revision, cert_type,
certificate) is added to the original object.
This can\'t be done simply in the FileStore.Write() method with fixed hash
buffer sizes because the authenticode hashes need to track hashing of
different-sized regions based on the signature information.
Args:
fd: File open for reading.
sync: Should the file be synced immediately.
Raises:
IOError: If there was an error writing the file.'

def AddFile(self, fd, sync=False):

    hashes = self._HashFile(fd)
    empty_hash = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
    if (hashes.sha256 == empty_hash):
        return
    fd.Set(fd.Schema.HASH, hashes)
    fd.Flush()
    canonical_urn = self.PATH.Add('generic/sha256').Add(str(hashes.sha256))
    if (not list(aff4.FACTORY.Stat(canonical_urn, token=self.token))):
        aff4.FACTORY.Copy(fd.urn, canonical_urn, sync=True, token=self.token)
        with aff4.FACTORY.Open(canonical_urn, mode='rw', token=self.token) as new_fd:
            new_fd.Set(new_fd.Schema.STAT(None))
    self._AddToIndex(canonical_urn, fd.urn)
    for (hash_type, hash_digest) in hashes.ListSetFields():
        hash_type = hash_type.name
        if (hash_type == 'sha256'):
            continue
        hash_digest = str(hash_digest)
        fingerprint_type = 'generic'
        if hash_type.startswith('pecoff_'):
            fingerprint_type = 'pecoff'
            hash_type = hash_type[len('pecoff_'):]
        if (hash_type not in self.HASH_TYPES[fingerprint_type]):
            continue
        file_store_urn = self.PATH.Add(fingerprint_type).Add(hash_type).Add(hash_digest)
        with aff4.FACTORY.Create(file_store_urn, aff4.AFF4Symlink, token=self.token) as symlink:
            symlink.Set(symlink.Schema.SYMLINK_TARGET, canonical_urn)
    return None
