VgaGames 3 - Hashmap man-pages

[.. upper level ..]

Hashmap functions

Hashmaps are like arrays with the key being a string instead of an integer.


Example

  /* Read current directory into hashmap and list it,
   * remove from it all besides regular files and list it again
   */

  struct vg3_hash *hmap;
  int quantity;

  /* create a hashmap */
  hmap = VG3_hash_new();

  /* number of files */
  quantity = 0;

  /* read in the current directory */
  { DIR *dirp;
    struct dirent *direntp;
    struct stat sbuf;

    dirp = opendir(".");
    if (dirp == NULL) { fprintf(stderr, "opendir: %s\n", strerror(errno)); exit(1); }

    while ((direntp = readdir(dirp)) != NULL) {
      if (stat(direntp->d_name, &sbuf) == 0) {
        const char *valptr;
        switch (sbuf.st_mode & S_IFMT) {
          case S_IFBLK:  valptr = "block device"; break;
          case S_IFCHR:  valptr = "character device"; break;
          case S_IFDIR:  valptr = "directory"; break;
          case S_IFIFO:  valptr = "FIFO/pipe"; break;
          case S_IFLNK:  valptr = "symlink"; break;
          case S_IFREG:  valptr = "regular file"; break;
          case S_IFSOCK: valptr = "socket"; break;
          default:       valptr = "unknown?"; break;
        }
        /* set into hashmap: <filename> = <filetype> */
        VG3_hash_set(hmap, direntp->d_name, strlen(direntp->d_name) + 1, valptr, strlen(valptr) + 1);
        /* increment number of files */
        quantity++;
      }
    }
    closedir(dirp);
  }

  /* insert quantity into hashmap */
  VG3_hash_setint(hmap, "quantity", sizeof("quantity"), quantity);

  /* list hashmap and remove all from it besides regular files */
  printf("Current directory contains:\n");
  { void *vpos;
    const char *key;
    char *val;
    size_t keysize;

    vpos = NULL;
    for (key = VG3_hash_list(hmap, &vpos, &keysize); vpos != NULL; key = VG3_hash_list(hmap, &vpos, &keysize)) {
      /* print only files, not quantity */
      if (!VG3_hash_isnum(hmap, key, keysize)) {
        /* as val is a null-terminated string, we can omit valsize, (this would be valid also for key) */
        val = (char *)VG3_hash_get(hmap, key, keysize, NULL);
        printf("  - %.*s = %s\n", (int)keysize, key, val);
        /* remove entry if not a regular file */
        if (strcmp(val, "regular file") != 0) {
          vpos = VG3_hash_del(hmap, key, keysize);
        }
      }
    }
    /* now print quantity */
    quantity = VG3_hash_getint(hmap, "quantity", sizeof("quantity"));
    printf("  Number of files: %d\n", quantity);
  }

  /* list hashmap again: contains just regular files */
  printf("\nCurrent directory contains regular files:\n");
  { void *vpos;
    const char *key;
    char *val;
    size_t keysize;

    vpos = NULL;
    for (key = VG3_hash_list(hmap, &vpos, &keysize); vpos != NULL; key = VG3_hash_list(hmap, &vpos, &keysize)) {
      /* print only files, not quantity */
      if (!VG3_hash_isnum(hmap, key, keysize)) {
        /* as val is a null-terminated string, we can omit valsize, (this would be valid also for key) */
        val = (char *)VG3_hash_get(hmap, key, keysize, NULL);
        printf("  - %.*s = %s\n", (int)keysize, key, val);
      }
    }
  }

  /* destroy hashmap */
  VG3_hash_free(hmap);