fork download
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. typedef int fd;
  5.  
  6. struct fs;
  7.  
  8. struct fs_methods {
  9. const char* (*name)(struct fs*);
  10. void (*sync)(struct fs*);
  11. void (*release)(struct fs*);
  12. // fd create_file(fs*, sconst char*);
  13. // int write(fs*, fd, const char*, int);
  14. // ...
  15. };
  16.  
  17. struct fs {
  18. struct fs_methods* methods;
  19. // common fields can live here
  20. };
  21.  
  22.  
  23. // Helper functions for convenience of calls
  24. const char* name(struct fs* fs) { return fs->methods->name(fs); }
  25. void sync(struct fs* fs) { return fs->methods->sync(fs); }
  26. void release(struct fs* fs) { return fs->methods->release(fs); }
  27.  
  28. ////////////////////////////////////////////////////////////
  29. // FAT32
  30. ////////////////////////////////////////////////////////////
  31.  
  32. struct fat32_fs {
  33. struct fs fs;
  34. const char* message;
  35. // fat32 specific fields ...
  36. };
  37.  
  38. const char* fat32_name(struct fs* fs) { return "fat32"; }
  39.  
  40. void fat32_sync(struct fs* f) {
  41. // get the real instance back:
  42. struct fat32_fs* instance = (struct fat32_fs*)f;
  43. printf("Sync FAT32: %s\n", instance->message);
  44. }
  45.  
  46. void fat32_release(struct fs* f) { printf("releasing FAT32 fs\n"); free(f); }
  47.  
  48. // Actual VTable
  49. static struct fs_methods fat32_methods = {
  50. &fat32_name, &fat32_sync, &fat32_release
  51. };
  52.  
  53. // Constructor
  54. struct fs* make_fat32(const char *message) {
  55. struct fat32_fs* this = calloc(sizeof(struct fat32_fs), 1);
  56. this->fs.methods = &fat32_methods;
  57. this->message = message;
  58. return &this->fs;
  59. }
  60.  
  61.  
  62. ////////////////////////////////////////////////////////////
  63. // EXT 4
  64. ////////////////////////////////////////////////////////////
  65.  
  66. struct ext4_fs {
  67. struct fs fs;
  68. int journal_size;
  69. // ext4 specific fields ...
  70. };
  71.  
  72. const char* ext4_name(struct fs* fs) { return "ext4"; }
  73.  
  74. void ext4_sync(struct fs* f) {
  75. // get the real instance back:
  76. struct ext4_fs* this = (struct ext4_fs*)f;
  77. printf("Sync EXT4, journal size: %d\n", this->journal_size);
  78. }
  79.  
  80. void ext4_release(struct fs* f) { printf("releasing EXT4 fs\n"); free(f); }
  81.  
  82. // Actual VTable
  83. static struct fs_methods ext4_methods = {
  84. &ext4_name, &ext4_sync, &ext4_release
  85. };
  86.  
  87. // Constructor
  88. struct fs* make_ext4(int journal_size) {
  89. struct ext4_fs* this = calloc(sizeof(struct ext4_fs), 1);
  90. this->fs.methods = &ext4_methods;
  91. this->journal_size = journal_size;
  92. return &this->fs;
  93. }
  94.  
  95.  
  96. ////////////////////////////////////////////////////////////
  97. // Testing
  98. ////////////////////////////////////////////////////////////
  99.  
  100. void test_fs(struct fs* fs) {
  101. printf("============================================================\n");
  102. printf("fs name: %s\n", name(fs));
  103. sync(fs);
  104. release(fs);
  105. }
  106.  
  107. int main() {
  108. test_fs(make_fat32(" wow, so OOP, very interfaces"));
  109. test_fs(make_ext4(3000000));
  110. return 0;
  111. }
  112.  
Success #stdin #stdout 0s 4356KB
stdin
Standard input is empty
stdout
============================================================
fs name: fat32
Sync FAT32:  wow, so OOP, very interfaces
releasing FAT32 fs
============================================================
fs name: ext4
Sync EXT4, journal size: 3000000
releasing EXT4 fs