home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0040 - 0049 / ibm0040-0049 / ibm0040.tar / ibm0040 / ZINC_6.ZIP / DOSSRC.ZIP / STORE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-01  |  9.7 KB  |  385 lines

  1. //    Zinc Interface Library - STORAGE.CPP
  2. //    COPYRIGHT (C) 1990, 1991.  All Rights Reserved.
  3. //    Zinc Software Incorporated.  Pleasant Grove, Utah  USA
  4.  
  5. #include "ui_gen.hpp"
  6. #include <io.h>
  7. #include <dos.h>
  8. #include <dir.h>
  9. #include <stdio.h>
  10. #include <fcntl.h>
  11. #include <sys\stat.h>
  12. #include <string.h>
  13.  
  14. #define MAGIC_NUMBER    0x05AF
  15. #define MAJOR_VERSION    1
  16. #define MINOR_VERSION    0
  17.  
  18. struct ZINC_SIGNATURE
  19. {
  20.     char copyrightNotice[64];
  21.       UCHAR majorVersion;
  22.     UCHAR minorVersion;
  23.     USHORT magicNumber;
  24. };
  25.  
  26. static ZINC_SIGNATURE _signature =
  27.     { "Zinc Data File Version 1.0\032", MAJOR_VERSION, MINOR_VERSION, MAGIC_NUMBER };
  28. int UI_STORAGE::defaultCacheSize = 2048;
  29. UI_STORAGE *_storage = NULL;
  30.  
  31. UI_STORAGE::UI_STORAGE(const char *_name, int readWrite) :
  32.     UI_LIST(UI_STORAGE::CompareFunction), cache(NULL),
  33.     cacheSize(defaultCacheSize), cacheOffset(0), cacheRemaining(0),
  34.     stStatus(STS_NO_STATUS)
  35. {
  36.     strcpy(name, _name);
  37.     access = readWrite ? O_BINARY | O_RDWR : O_BINARY | O_RDONLY;
  38.  
  39.     // Open the file.
  40.     file = _path->OpenFile(name, access);
  41.     if (file != -1)
  42.     {
  43.         ZINC_SIGNATURE signature;
  44.         read(file, &signature, sizeof(signature));
  45.         if (signature.magicNumber != MAGIC_NUMBER)
  46.         {
  47.             close (file);
  48.             file = -1;
  49.         }
  50.         majorVersion = signature.majorVersion;
  51.         minorVersion = signature.minorVersion;
  52.     }
  53.     if (file != -1)
  54.     {
  55.         lseek(file, sizeof(_signature), SEEK_SET);
  56.         short noOfObjects;
  57.         read(file, &noOfObjects, sizeof(noOfObjects));
  58.         for (int i = 0; i < noOfObjects; i++)
  59.         {
  60.             UI_STORAGE_ELEMENT *element = new UI_STORAGE_ELEMENT;
  61.             read(file, &element->search, sizeof(element->search));
  62.             if (element->search.size)
  63.                 Add(element);
  64.         }
  65.     }
  66.     else if (readWrite)
  67.     {
  68.         file = open(name, O_CREAT | O_TRUNC | access, S_IREAD | S_IWRITE);
  69.         majorVersion = MAJOR_VERSION;
  70.         minorVersion = MINOR_VERSION;
  71.     }
  72.     if (file == -1)
  73.     {
  74.         stStatus |= STS_OPEN_ERROR;
  75.         return;
  76.     }
  77.  
  78.     // Initialize the cache sheme.
  79.     if (cacheSize)
  80.         cache = new char[cacheSize];
  81. }
  82.  
  83. UI_STORAGE::~UI_STORAGE()
  84. {
  85.     if (cache)
  86.         delete cache;
  87.     if (file != -1)
  88.         close(file);
  89.     if (_storage == this)
  90.         _storage = NULL;
  91. }
  92.  
  93. void UI_STORAGE::AppendFullPath(char *fullPath, const char *pathName, const char *fileName, const char *extension)
  94. {
  95.     if (pathName != fullPath)
  96.         strcpy(fullPath, pathName);
  97.     if (fullPath[0] != '\0' && fullPath[strlen(fullPath)-1] != '\\')
  98.         strcat(fullPath, "\\");
  99.     strcat(fullPath, fileName);
  100.     if (extension)
  101.         UI_STORAGE::ChangeExtension(fullPath, extension);
  102.     strupr(fullPath);
  103. }
  104.  
  105. void UI_STORAGE::ChangeExtension(char *name, const char *newExtension)
  106. {
  107.     char *oldExtension = strrchr(name, '.');
  108.     if (oldExtension)
  109.         *oldExtension = '\0';
  110.     if (newExtension)
  111.         strcat(name, newExtension);
  112. }
  113.  
  114. int UI_STORAGE::CompareFunction(void *element1, void *element2)
  115. {
  116.     return (strcmp(((UI_STORAGE_ELEMENT *)element1)->search.stringID, ((UI_STORAGE_ELEMENT *)element2)->search.stringID));
  117. }
  118.  
  119. int UI_STORAGE::FindName(void *object, void *matchName)
  120. {
  121.     return (strcmp(((UI_STORAGE_ELEMENT *)object)->search.stringID, (char *)matchName));
  122. }
  123.  
  124. int UI_STORAGE::FindNumber(void *object, void *matchNumber)
  125. {
  126.     return ((((UI_STORAGE_ELEMENT *)object)->search.numberID == *(USHORT *)matchNumber) ? 0 : -1);
  127. }
  128.  
  129. int UI_STORAGE::Load(void *buffer, int length)
  130. {
  131.     // See if cache is turned on.
  132.     if (!cache)
  133.         return (read(file, buffer, length));
  134.  
  135.     // See if there is enough cached to read.
  136.     if (length > cacheRemaining)
  137.     {
  138.         if (cacheRemaining)
  139.             memmove(cache, &cache[cacheOffset], cacheRemaining);
  140.         read(file, &cache[cacheRemaining], cacheSize - cacheRemaining);
  141.         cacheRemaining = cacheSize;
  142.         cacheOffset = 0;
  143.     }
  144.  
  145.     // Copy the cached buffer to the specified read buffer.
  146.     if (length >= cacheSize)
  147.     {
  148.         char *tBuffer = (char *)buffer;
  149.         memmove(tBuffer, cache, cacheSize);
  150.         read(file, &tBuffer[cacheSize], length - cacheSize);
  151.         cacheRemaining = cacheOffset = 0;
  152.     }
  153.     else
  154.     {
  155.         memmove(buffer, &cache[cacheOffset], length);
  156.         cacheOffset += length;
  157.         cacheRemaining -= length;
  158.     }
  159.     return (length);
  160. }
  161.  
  162. int UI_STORAGE::Load(char **string)
  163. {
  164.     USHORT size;
  165.     UI_STORAGE::Load(&size, sizeof(short));
  166.     if (size)
  167.     {
  168.         char *readString = new char[size + 1];
  169.         UI_STORAGE::Load(readString, size);
  170.         readString[size] = '\0';
  171.         *string = readString;
  172.     }
  173.     else
  174.         *string = NULL;
  175.     return (size + sizeof(short));
  176. }
  177.  
  178. void UI_STORAGE::ObjectSize(const char *name, UI_SEARCH_INFO &search)
  179. {
  180.     search.size = (int)(lseek(file, 0L, SEEK_CUR) + cacheOffset - search.offset);
  181.     if (!name)
  182.         return;
  183.     if (cacheOffset)
  184.     {
  185.         write(file, cache, cacheOffset);
  186.         cacheOffset = 0;
  187.         cacheRemaining = cacheSize;
  188.     }
  189.     UI_STORAGE_ELEMENT *element = (UI_STORAGE_ELEMENT *)UI_LIST::Get(UI_STORAGE::FindName, name);
  190.     if (!element)
  191.         element = (UI_STORAGE_ELEMENT *)UI_LIST::Get(UI_STORAGE::FindName, search.stringID);
  192.     if (element)
  193.         element->search = search;
  194. }
  195.  
  196. long UI_STORAGE::Offset()
  197. {
  198.     return(lseek(file, 0L, SEEK_CUR) + cacheOffset);
  199. }
  200.  
  201. void UI_STORAGE::Save()
  202. {
  203.     if (!FlagSet(access, O_RDWR))
  204.         return;
  205.  
  206.     // Store the signature information.
  207.     int saveFile = open("temp.$$$", O_CREAT | O_TRUNC | O_BINARY | O_RDWR, S_IREAD | S_IWRITE);
  208.     write(saveFile, &_signature, sizeof(_signature));
  209.  
  210.     // Store the number of objects.
  211.     short noOfObjects = Count();
  212.     write(saveFile, &noOfObjects, sizeof(noOfObjects));
  213.  
  214.     // Save room for the search elements.
  215.     lseek(saveFile, noOfObjects * sizeof(UI_SEARCH_INFO), SEEK_CUR);
  216.  
  217.     // Store out the object information.
  218.     for (UI_STORAGE_ELEMENT *element = First(); element; )
  219.         if (element->search.size > 0)
  220.         {
  221.             char *buffer = new char[element->search.size];
  222.             lseek(file, element->search.offset, SEEK_SET);
  223.             read(file, buffer, element->search.size);
  224.             element->search.offset = lseek(saveFile, 0L, SEEK_CUR);
  225.             write(saveFile, buffer, element->search.size);
  226.             delete buffer;
  227.             element = element->Next();
  228.         }
  229.  
  230.     // Write the object offset information.
  231.     lseek(saveFile, sizeof(_signature) + sizeof(noOfObjects), SEEK_SET);
  232.     for (element = First(); element; element = element->Next())
  233.         write(saveFile, &element->search, sizeof(element->search));
  234.  
  235.     // Update to the original file.
  236.     close(file);
  237.     close(saveFile);
  238.  
  239.     UI_STORAGE::ChangeExtension(name, ".DAT");
  240.     remove(name);
  241.     rename("temp.$$$", name);
  242.     file = open(name, access);
  243. }
  244.  
  245. UI_STORAGE_ELEMENT *UI_STORAGE::Seek(const char *objectName, int seekMode)
  246. {
  247.     UI_STORAGE_ELEMENT *element = (UI_STORAGE_ELEMENT *)UI_LIST::Get(UI_STORAGE::FindName, objectName);
  248.     if (!element && seekMode == SEEK_READ)
  249.         return (NULL);
  250.     else if (!element)
  251.     {
  252.         element = new UI_STORAGE_ELEMENT;
  253.         memset(element->search.stringID, 0, sizeof(element->search.stringID));
  254.         strcpy(element->search.stringID, objectName);
  255.         element->search.offset = lseek(file, 0, SEEK_END);
  256.         element->search.size = 0;
  257.         element->search.type = 0;
  258.         element->search.numberID = 0;
  259.         UI_LIST::Add(element);
  260.     }
  261.     else if (seekMode == SEEK_WRITE)
  262.         element->search.offset = lseek(file, 0, SEEK_END);
  263.     else
  264.         lseek(file, element->search.offset, SEEK_SET);
  265.  
  266.     cacheOffset = 0;
  267.     cacheRemaining = (seekMode == SEEK_READ) ? 0 : cacheSize;
  268.     return (element);
  269. }
  270.  
  271. UI_STORAGE_ELEMENT *UI_STORAGE::Seek(USHORT objectNumber, int seekMode)
  272. {
  273.     UI_STORAGE_ELEMENT *element = (UI_STORAGE_ELEMENT *)UI_LIST::Get(UI_STORAGE::FindNumber, &objectNumber);
  274.  
  275.     if (!element)
  276.         return (NULL);
  277.     else if (seekMode == SEEK_WRITE)
  278.         element->search.offset = lseek(file, 0L, SEEK_END);
  279.     else
  280.         lseek(file, element->search.offset, SEEK_SET);
  281.  
  282.     cacheOffset = 0;
  283.     cacheRemaining = (seekMode == SEEK_READ) ? 0 : cacheSize;
  284.     return (element);
  285. }
  286.  
  287. int UI_STORAGE::Store(void *buffer, int length)
  288. {
  289.     // Make sure write is enabled.
  290.     if (!FlagSet(access, O_RDWR))
  291.         return (0);
  292.  
  293.     // See if cache is turned on.
  294.     if (!cache)
  295.         return (write(file, buffer, length));
  296.  
  297.     // See if flushing is requested or if there is enough cached to write.
  298.     if (length > cacheRemaining)
  299.     {
  300.         if (cacheOffset)
  301.             write(file, cache, cacheOffset);
  302.         cacheOffset = 0;
  303.         cacheRemaining = cacheSize;
  304.     }
  305.  
  306.     // Copy the file write buffer to the cached buffer.
  307.     if (length >= cacheSize)
  308.         write(file, buffer, length);
  309.     else
  310.     {
  311.         memmove(&cache[cacheOffset], buffer, length);
  312.         cacheOffset += length;
  313.         cacheRemaining -= length;
  314.     }
  315.     return (length);
  316. }
  317.  
  318. int UI_STORAGE::Store(const char *string)
  319. {
  320.     USHORT size = string ? strlen(string) : 0;
  321.     UI_STORAGE::Store(&size, sizeof(size));
  322.     if (size)
  323.         size = UI_STORAGE::Store(string, size);
  324.     return (size + sizeof(short));
  325. }
  326.  
  327. void UI_STORAGE::StripFullPath(const char *fullPath, char *pathName, char *fileName, char *objectName)
  328. {
  329.     // Determine the path/file split area.
  330.     char *name = strrchr(fullPath, '\\');
  331.     if (!name)
  332.         name = strrchr(fullPath, ':');
  333.  
  334.     // Construct the path name.
  335.     if (pathName)
  336.     {
  337.         if (name)
  338.         {
  339.             strcpy(pathName, fullPath);
  340.             pathName[(int)(name - fullPath)] = '\0';
  341.             strupr(pathName);
  342.         }
  343.         else
  344.             pathName[0] = '\0';
  345.     }
  346.  
  347.     // Construct the file name.
  348.     if (fileName)
  349.     {
  350.         if (name)
  351.             strcpy(fileName, ++name);
  352.         else
  353.             strcpy(fileName, fullPath);
  354.         name = strrchr(fileName, '~');
  355.         if (name)
  356.             fileName[(int)(name - fileName)] = '\0';
  357.         strupr(fileName);
  358.     }
  359.  
  360.     // Construct the object name.
  361.     if (objectName)
  362.     {
  363.         name = strrchr(fullPath, '~');
  364.         if (name)
  365.             strcpy(objectName, ++name);
  366.         else
  367.             objectName[0] = '\0';
  368.         strupr(objectName);
  369.     }
  370. }
  371.  
  372. int UI_STORAGE::ValidName(const char *name, int createStorage)
  373. {
  374.     char path[MAXPATH];
  375.     if (createStorage)
  376.     {
  377.         UI_STORAGE::StripFullPath(name, path);
  378.         strcat(path, "\\*.*");
  379.     }
  380.     else
  381.         strcpy(path, name);
  382.     struct ffblk fileBlock;
  383.     return (!findfirst(path, &fileBlock, FA_DIREC));
  384. }
  385.