Advertisement
Bebras

[INC] Bini - easy file reading and writing

May 25th, 2015
668
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 11.85 KB | None | 0 0
  1. /*
  2.                     bini.inc by Bebras
  3.                     Biblioteka skirta tekstinių failų rašymui, redagavimui.
  4.                     Bibliotekos principas: caching. bini_Open pakrauna failą į atmintį, bini_Set funkcijos nustato k/v reikšmes, bini_Get funkcijos gražina pateikto key reikšmę. Failas vėl išsaugomas su bini_Save.
  5. */
  6.  
  7. //#define BINI_DEBUG_MODE
  8.  
  9.  
  10.  
  11. // Maksimalus key ilgis
  12. #define BINI_MAX_KEY_LENGTH     32
  13.  
  14. // Maksimali value reikšmė
  15. #define BINI_MAX_VALUE_LENGTH   256
  16.  
  17. // Maksimalus vienu metu atidarytų failų skaičius
  18. #define BINI_MAX_OPENED_FILES   2
  19.  
  20. // Ilgiausias leidžiamas failo pavadinimas
  21. #define BINI_MAX_FILE_NAME      32
  22.  
  23. // Maksimalus eilučių skaičius viename faile
  24. #define BINI_MAX_FILE_LINES     256
  25.  
  26. // Netinkamas failo indeksas
  27. #define BINI_INVALID_FILE_ID            -1
  28.  
  29.  
  30.  
  31. #define bini_fexist fexist
  32.  
  33.  
  34. // Function written by Y_Less
  35. #define bini_strcpy(%0,%1,%2)           strcat((%0[0] = '\0', %0), %1, %2)
  36.  
  37.  
  38. #if defined BINI_DEBUG_MODE
  39.     #define bini_debug(%0);             printf(%0);
  40. #else
  41.     #define bini_debug(%0);
  42. #endif
  43.  
  44. /*                                      
  45.                                        
  46.     `7MM"""Yb.            mm            
  47.       MM    `Yb.          MM            
  48.       MM     `Mb  ,6"Yb.mmMMmm  ,6"Yb.  
  49.       MM      MM 8)   MM  MM   8)   MM  
  50.       MM     ,MP  ,pm9MM  MM    ,pm9MM  
  51.       MM    ,dP' 8M   MM  MM   8M   MM  
  52.     .JMMmmmdP'   `Moo9^Yo.`Mbmo`Moo9^Yo.
  53.                                        
  54.                                          */
  55.  
  56. enum E_BINI_CACHE_DATA
  57. {
  58.     e_Key[BINI_MAX_KEY_LENGTH],
  59.     e_Value[BINI_MAX_VALUE_LENGTH],
  60. };
  61.  
  62. enum E_BINI_FILE_DATA
  63. {
  64.     e_FileName[BINI_MAX_FILE_NAME],
  65.     bool:e_IsFileOpen
  66. };
  67.  
  68. static  BiniCache[ BINI_MAX_OPENED_FILES ][ BINI_MAX_FILE_LINES ][ E_BINI_CACHE_DATA ],
  69.         BiniFileData[ BINI_MAX_OPENED_FILES ][ E_BINI_FILE_DATA ];
  70.  
  71.  
  72.  
  73. /*                                
  74.                                  
  75.           db      `7MM"""Mq.`7MMF'
  76.          ;MM:       MM   `MM. MM  
  77.         ,V^MM.      MM   ,M9  MM  
  78.        ,M  `MM      MMmmdM9   MM  
  79.        AbmmmqMA     MM        MM  
  80.       A'     VML    MM        MM  
  81.     .AMA.   .AMMA..JMML.    .JMML.
  82.                                  
  83.                                    */
  84.  
  85. stock bini_fcreate(const filename[])
  86. {
  87.     if(fexist(filename))
  88.         return false;
  89.     new File:fhandle = fopen(filename, io_append);
  90.     fclose(fhandle);
  91.     return true;
  92. }
  93.  
  94. stock bini_Set(const filename[], const key[], const value[])
  95. {      
  96.     bini_debug("bini_Set(%s, %s, %s) called", filename, key, value);
  97.     new freeKeyIndex = -1,
  98.         fileindex = bini_GetFileIndex(filename);
  99.  
  100.     // Jeu nurodė neegzistuojantį failą.
  101.     if(fileindex == BINI_INVALID_FILE_ID)
  102.     {
  103.         bini_debug("bini_Set file %s does not exist", filename);
  104.         return 0;
  105.     }
  106.  
  107.     for(new i = 0; i < BINI_MAX_FILE_LINES; i++)
  108.     {
  109.         if(isnull(BiniCache[ fileindex ][ i ][ e_Key ]) && freeKeyIndex == -1)
  110.         {
  111.             freeKeyIndex = i;
  112.             continue;
  113.         }
  114.         // Jeigu toks key jau nustatytas, tada pakeičiam jo reikšmę.
  115.         if(!isnull(BiniCache[ fileindex ][ i ][ e_Key ]) && !strcmp(BiniCache[ fileindex ][ i ][ e_Key ], key))
  116.         {
  117.             bini_strcpy(BiniCache[ fileindex ][ i ][ e_Value ], value, BINI_MAX_VALUE_LENGTH);
  118.             bini_debug("bini_Set updating %s value to %s at %d", key, value, i);
  119.             return 1;
  120.         }
  121.     }
  122.     if(freeKeyIndex != -1)
  123.     {
  124.         bini_strcpy(BiniCache[ fileindex ][ freeKeyIndex ][ e_Key ], key, BINI_MAX_KEY_LENGTH);
  125.         bini_strcpy(BiniCache[ fileindex ][ freeKeyIndex ][ e_Value ], value, BINI_MAX_VALUE_LENGTH);
  126.         bini_debug("bini_Set adding %s value %s at %d", key, value, freeKeyIndex);
  127.         return 1;
  128.     }
  129.     bini_debug("bini_Set key could not be set.");
  130.     return 0;
  131. }
  132. stock bini_IntSet(const filename[], key[], value)
  133. {
  134.     bini_debug("bini_IntSet(%s, %s, %d) called", filename, key, value);
  135.     new str[12];
  136.     #if defined _inc_fixes
  137.         valstr(str, value);
  138.     #else
  139.         format(str,sizeof(str),"%d",value);
  140.     #endif
  141.     return bini_Set(filename,key,str);
  142. }
  143. stock bini_FloatSet(const filename[], key[], Float:value)
  144. {
  145.     bini_debug("bini_IntSet(%s, %s, %f) called", filename, key, value);
  146.     new str[11];
  147.     format(str,sizeof(str),"%f", value);
  148.     return bini_Set(filename, key, str);
  149. }
  150. stock bini_BoolSet(filename[], key[], bool:value)
  151. {
  152.     bini_debug("bini_IntSet(%s, %s, %d) called", filename, key, value);
  153.     return bini_Set(filename, key, (value) ? ("true") : ("false"));
  154. }
  155.  
  156. stock bini_Remove(const filename[], const key[])
  157. {
  158.     bini_debug("bini_Remove(%s, %s)", filename, key);
  159.     new fileindex = bini_GetFileIndex(filename);
  160.  
  161.     if(fileindex == BINI_INVALID_FILE_ID)
  162.     {
  163.         bini_debug("bini_Remove invalid file %s", filename);
  164.         return 0;
  165.     }
  166.  
  167.     for(new i = 0; i < BINI_MAX_FILE_LINES; i++)
  168.         if(!isnull(BiniCache[ fileindex ][ i ][ e_Key ]) && !strcmp(BiniCache[ fileindex ][ i ][ e_Key], key))
  169.         {
  170.             bini_debug("bini_Remove removing %s from %s", key, filename);
  171.             BiniCache[ fileindex ][ i ][ e_Key ][ 0 ] = '\0';
  172.             return 1;
  173.         }
  174.     bini_debug("bini_Remove %s not found in %s", key, filename);
  175.     return 0;
  176. }
  177.  
  178. stock bini_IsFileOpen(const filename[])
  179. {
  180.     bini_debug("bini_IsFileOpen(%s) called", filename);
  181.     new fileindex = bini_GetFileIndex(filename);
  182.     if(fileindex != BINI_INVALID_FILE_ID)
  183.     {
  184.         bini_debug("bini_IsFileOpen invalid file name %s", filename);
  185.         return 0;
  186.     }
  187.     return BiniFileData[ fileindex ][ e_IsFileOpen ];
  188. }
  189.  
  190.  
  191.  
  192.  
  193. stock bini_Get(const filename[], const key[], string[], size = sizeof(string))
  194. {
  195.     bini_debug("bini_Get(%s, %s, %s, %d) called", filename, key, string, size);
  196.     new fileindex = bini_GetFileIndex(filename);
  197.     if(fileindex == -1)
  198.     {
  199.         bini_debug("bini_Get file %s is not open", filename);
  200.         return 0;
  201.     }
  202.  
  203.     for(new i = 0; i < BINI_MAX_FILE_LINES; i++)
  204.     {
  205.         if(!isnull(BiniCache[ fileindex ][ i ][ e_Key ]) && !strcmp(BiniCache[ fileindex ][ i ][ e_Value ], key))
  206.         {
  207.             bini_strcpy(string, BiniCache[ fileindex ][ i ][ e_Value ], size);
  208.             return 1;
  209.         }
  210.     }
  211.     return 0;
  212. }
  213.  
  214. stock bini_IntGet(const filename[], const key[])
  215. {
  216.     bini_debug("bini_IntGet(%s, %s) called", filename, key);
  217.     new tmp[ BINI_MAX_VALUE_LENGTH ];
  218.     bini_Get(filename, key, tmp, sizeof(tmp));
  219.     return strval(tmp);
  220. }  
  221.  
  222. stock Float:bini_FloatGet(const filename[], const key[])
  223. {
  224.     bini_debug("bini_FloatGet(%s, %s) called", filename, key);
  225.     new tmp[ BINI_MAX_VALUE_LENGTH ];
  226.     bini_Get(filename, key, tmp, sizeof(tmp));
  227.     return floatstr(tmp);
  228. }
  229.  
  230. stock bool:bini_BoolGet(const filename[], const key[])
  231. {
  232.     bini_debug("bini_BoolGet(%s, %s) called", filename, key);
  233.     return (bini_IntGet(filename, key)) ? (true) : (false);
  234. }
  235.  
  236.  
  237.  
  238.  
  239. stock bini_Open(const filename[])
  240. {
  241.     bini_debug("bini_Open(%s) called", filename);
  242.  
  243.     if(!bini_fexist(filename))
  244.         bini_fcreate(filename);
  245.  
  246.     new freeindex = BINI_INVALID_FILE_ID;
  247.  
  248.     // Reikia patikrinti galbūt tas failas jau atidarytas.
  249.     for(new i; i < BINI_MAX_OPENED_FILES; i++)
  250.     {
  251.         // Tikrindami taippat susirandame laisva indeksa
  252.         if(freeindex == -1 && !BiniFileData[i][e_IsFileOpen])
  253.         {
  254.             freeindex = i;
  255.             continue;
  256.         }
  257.  
  258.         if(!isnull(BiniFileData[ i ][ e_FileName ]) && !strcmp(BiniFileData[ i ][ e_FileName ], filename))
  259.         {
  260.             bini_debug("bini_Open %s already open in handle %d", filename, i);
  261.             bini_LoadFile(filename, i);
  262.             return i;
  263.         }
  264.     }
  265.     if(freeindex != -1)
  266.     {
  267.         BiniFileData[ freeindex ][ e_IsFileOpen ] = true;
  268.         bini_strcpy(BiniFileData[ freeindex ][ e_FileName ], filename, BINI_MAX_FILE_NAME);
  269.         bini_debug("bini_Open %s successfully opened in handle %d.", filename, freeindex);
  270.         bini_LoadFile(filename, freeindex);
  271.         return freeindex;
  272.     }
  273.     bini_debug("bini_Open %s could not be opened", filename);
  274.     return BINI_INVALID_FILE_ID;
  275. }
  276.  
  277. stock bini_Save(const filename[])
  278. {
  279.     bini_debug("bini_Save(%s) called", filename);
  280.     new fileindex = bini_GetFileIndex(filename),
  281.         File:handle;
  282.  
  283.     // Jeu nurodė neegzistuojantį failą.
  284.     if(fileindex == BINI_INVALID_FILE_ID)
  285.     {
  286.         bini_debug("bini_Save %s was never open.", filename);
  287.         return 0;
  288.     }
  289.  
  290.     handle = fopen(filename, io_write);
  291.     if(!handle)
  292.     {
  293.         bini_debug("bini_Save could not open file.");
  294.         return 0;
  295.     }
  296.  
  297.     for(new i = 0; i < BINI_MAX_FILE_LINES; i++)
  298.     {
  299.         if(!isnull(BiniCache[ fileindex ][ i ][ e_Key ]))
  300.         {
  301.             fwrite(handle, BiniCache[ fileindex ][ i ][ e_Key ]);
  302.             fwrite(handle, " = ");
  303.             fwrite(handle, BiniCache[ fileindex ][ i ][ e_Value ]);
  304.             fwrite(handle, "\r\n");
  305.             bini_debug("bini_Save added %s value in %s", BiniCache[ fileindex ][ i ][ e_Key ], filename);
  306.             BiniCache[ fileindex ][ i ][ e_Key ][ 0 ] = '\0';
  307.             BiniCache[ fileindex ][ i ][ e_Value ][ 0 ] = '\0';
  308.         }
  309.     }
  310.     BiniFileData[ fileindex ][ e_IsFileOpen ] = false;
  311.     fclose(handle);
  312.     return 1;
  313. }
  314.  
  315.  
  316.  
  317. /*
  318.                                                                                  
  319.                                                                               ,,  
  320.                 `7MMF'            mm                                        `7MM  
  321.                   MM              MM                                          MM  
  322.                   MM  `7MMpMMMb.mmMMmm .gP"Ya `7Mb,od8 `7MMpMMMb.   ,6"Yb.    MM  
  323.                   MM    MM    MM  MM  ,M'   Yb  MM' "'   MM    MM  8)   MM    MM  
  324.                   MM    MM    MM  MM  8M""""""  MM       MM    MM   ,pm9MM    MM  
  325.                   MM    MM    MM  MM  YM.    ,  MM       MM    MM  8M   MM    MM  
  326.                 .JMML..JMML  JMML.`Mbmo`Mbmmd'.JMML.   .JMML  JMML.`Moo9^Yo..JMML.
  327.                                                                                  
  328.                                                                                  
  329. */
  330.  
  331. static stock bini_GetFileIndex(const filename[])
  332. {
  333.     for(new i = 0; i < BINI_MAX_OPENED_FILES; i++)
  334.     {
  335.         if(!isnull(BiniFileData[i][e_FileName]) && !strcmp(BiniFileData[i][e_FileName], filename))
  336.             return i;
  337.     }
  338.     return BINI_INVALID_FILE_ID;
  339. }
  340.  
  341. static stock bini_GetFreeLineIndex(fileindex)
  342. {
  343.     bini_debug("bini_GetFreeLineIndex(%d) called");
  344.     for(new i = 0; i < BINI_MAX_FILE_LINES; i++)
  345.         if(isnull(BiniCache[ fileindex ][ i ][ e_Key ]))
  346.         {  
  347.             bini_debug("bini_GetFreeLineIndex found free index at %d", i);
  348.             return i;
  349.         }
  350.     bini_debug("bini_GetFreeLineIndex free index not found");
  351.     return -1;
  352. }
  353.  
  354. static stock bini_StripNewLine(string[])
  355. {
  356.     new len = strlen(string);
  357.     if(!string[0])
  358.         return;
  359.  
  360.     if((string[len - 1] == '\n') || (string[len - 1] == '\r'))
  361.     {
  362.         string[len - 1] = 0;
  363.         if(string[0]==0) return ;
  364.         if((string[len - 2] == '\n') || (string[len - 2] == '\r'))
  365.             string[len - 2] = 0;
  366.     }
  367. }
  368.  
  369. static stock bini_Trim(string[])
  370. {
  371.     new len = strlen(string),
  372.         i = 0;
  373.     while((i = strfind(string, " ")) != -1 || (i = strfind(string, "\t")) != -1)
  374.     {
  375.         if(i + 1 == len)
  376.             string[ i ] = '\0';
  377.         else
  378.         {
  379.             for(new j = i; j < len-1; j++)
  380.                 string[ j ] = string[ j + 1 ];
  381.             len--;
  382.             string[ len ] = '\0';
  383.         }
  384.     }
  385. }
  386.  
  387.  
  388. static stock bini_LoadFile(const filename[], fileindex)
  389. {
  390.     bini_debug("bini_LoadFile(%s, %d) called", filename, fileindex);
  391.     new File:handle = fopen(filename, io_read),
  392.         buffer[ BINI_MAX_KEY_LENGTH + 8 + BINI_MAX_VALUE_LENGTH ],
  393.         key[ BINI_MAX_KEY_LENGTH ],
  394.         value[ BINI_MAX_VALUE_LENGTH ],
  395.         lineindex = -1,
  396.         index = -1;
  397.  
  398.     if(!handle)
  399.     {
  400.         bini_debug("bini_LoadFile could not open %s", filename);
  401.         return 0;
  402.     }
  403.  
  404.     while(fread(handle, buffer))
  405.     {
  406.         // Jeigu tai komentaras(prasideda ;) arba nėra lygybės, tiesiog ignoruojam
  407.         if(buffer[ 0 ] == ';' || (index = strfind(buffer, "=")) == -1)
  408.         {
  409.             continue;
  410.         }
  411.         bini_StripNewLine(buffer);
  412.  
  413.         strmid(key, buffer, 0, index);
  414.         bini_Trim(key);
  415.  
  416.         strmid(value, buffer, index+1, strlen(buffer));
  417.         bini_Trim(value);
  418.  
  419.         lineindex = bini_GetFreeLineIndex(fileindex);
  420.  
  421.         if(lineindex != -1 || !isnull(key) || !isnull(value))
  422.         {
  423.             bini_strcpy(BiniCache[ fileindex ][ lineindex ][ e_Key ], key, BINI_MAX_KEY_LENGTH);
  424.             bini_strcpy(BiniCache[ fileindex ][ lineindex ][ e_Value ], value, BINI_MAX_VALUE_LENGTH);
  425.         }
  426.         else
  427.         {
  428.             bini_debug("bini_LoadFile invalid lineindex, key or value.");
  429.         }
  430.     }
  431.     fclose(handle);
  432.     bini_debug("bini_LoadFile file %s successfully read", filename);
  433.     return 1;
  434. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement