home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0040 - 0049 / ibm0040-0049 / ibm0040.tar / ibm0040 / ZINC_5.ZIP / WINSRC.ZIP / STORE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-01  |  9.3 KB  |  368 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    0
  16. #define MINOR_VERSION    90
  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 0.9\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.         memmove(cache, &cache[cacheOffset], cacheRemaining);
  139.         read(file, &cache[cacheRemaining], cacheSize - cacheRemaining);
  140.         cacheRemaining = cacheSize;
  141.         cacheOffset = 0;
  142.     }
  143.  
  144.     // Copy the cached buffer to the specified read buffer.
  145.     memmove(buffer, &cache[cacheOffset], length);
  146.     cacheOffset += length;
  147.     cacheRemaining -= length;
  148.     return (length);
  149. }
  150.  
  151. int UI_STORAGE::Load(char **string)
  152. {
  153.     USHORT size;
  154.     UI_STORAGE::Load(&size, sizeof(short));
  155.     if (size)
  156.     {
  157.         char *readString = new char[size + 1];
  158.         UI_STORAGE::Load(readString, size);
  159.         readString[size] = '\0';
  160.         *string = readString;
  161.     }
  162.     else
  163.         *string = NULL;
  164.     return (size + sizeof(short));
  165. }
  166.  
  167. void UI_STORAGE::ObjectSize(const char *name, UI_SEARCH_INFO &search)
  168. {
  169.     search.size = (int)(lseek(file, 0L, SEEK_CUR) + cacheOffset - search.offset);
  170.     if (!name)
  171.         return;
  172.     if (cacheOffset)
  173.     {
  174.         write(file, cache, cacheOffset);
  175.         cacheOffset = 0;
  176.         cacheRemaining = cacheSize;
  177.     }
  178.     UI_STORAGE_ELEMENT *element = (UI_STORAGE_ELEMENT *)UI_LIST::Get(UI_STORAGE::FindName, name);
  179.     if (!element)
  180.         element = (UI_STORAGE_ELEMENT *)UI_LIST::Get(UI_STORAGE::FindName, search.stringID);
  181.     if (element)
  182.         element->search = search;
  183. }
  184.  
  185. long UI_STORAGE::Offset()
  186. {
  187.     return(lseek(file, 0L, SEEK_CUR) + cacheOffset);
  188. }
  189.  
  190. void UI_STORAGE::Save()
  191. {
  192.     if (!FlagSet(access, O_RDWR))
  193.         return;
  194.  
  195.     // Store the signature information.
  196.     int saveFile = open("temp.$$$", O_CREAT | O_TRUNC | O_BINARY | O_RDWR, S_IREAD | S_IWRITE);
  197.     write(saveFile, &_signature, sizeof(_signature));
  198.  
  199.     // Store the number of objects.
  200.     short noOfObjects = Count();
  201.     write(saveFile, &noOfObjects, sizeof(noOfObjects));
  202.  
  203.     // Save room for the search elements.
  204.     lseek(saveFile, noOfObjects * sizeof(UI_SEARCH_INFO), SEEK_CUR);
  205.  
  206.     // Store out the object information.
  207.     for (UI_STORAGE_ELEMENT *element = First(); element; )
  208.         if (element->search.size > 0)
  209.         {
  210.             char *buffer = new char[element->search.size];
  211.             lseek(file, element->search.offset, SEEK_SET);
  212.             read(file, buffer, element->search.size);
  213.             element->search.offset = lseek(saveFile, 0L, SEEK_CUR);
  214.             write(saveFile, buffer, element->search.size);
  215.             delete buffer;
  216.             element = element->Next();
  217.         }
  218.  
  219.     // Write the object offset information.
  220.     lseek(saveFile, sizeof(_signature) + sizeof(noOfObjects), SEEK_SET);
  221.     for (element = First(); element; element = element->Next())
  222.         write(saveFile, &element->search, sizeof(element->search));
  223.  
  224.     // Update to the original file.
  225.     close(file);
  226.     close(saveFile);
  227.  
  228.     UI_STORAGE::ChangeExtension(name, ".DAT");
  229.     remove(name);
  230.     rename("temp.$$$", name);
  231.     file = open(name, access);
  232. }
  233.  
  234. UI_STORAGE_ELEMENT *UI_STORAGE::Seek(const char *objectName, int seekMode)
  235. {
  236.     UI_STORAGE_ELEMENT *element = (UI_STORAGE_ELEMENT *)UI_LIST::Get(UI_STORAGE::FindName, objectName);
  237.     if (!element && seekMode == SEEK_READ)
  238.         return (NULL);
  239.     else if (!element)
  240.     {
  241.         element = new UI_STORAGE_ELEMENT;
  242.         memset(element->search.stringID, 0, sizeof(element->search.stringID));
  243.         strcpy(element->search.stringID, objectName);
  244.         element->search.offset = lseek(file, 0, SEEK_END);
  245.         element->search.size = 0;
  246.         element->search.type = 0;
  247.         element->search.numberID = 0;
  248.         UI_LIST::Add(element);
  249.     }
  250.     else if (seekMode == SEEK_WRITE)
  251.         element->search.offset = lseek(file, 0, SEEK_END);
  252.     else
  253.         lseek(file, element->search.offset, SEEK_SET);
  254.  
  255.     cacheOffset = 0;
  256.     cacheRemaining = (seekMode == SEEK_READ) ? 0 : cacheSize;
  257.     return (element);
  258. }
  259.  
  260. UI_STORAGE_ELEMENT *UI_STORAGE::Seek(USHORT objectNumber, int seekMode)
  261. {
  262.     UI_STORAGE_ELEMENT *element = (UI_STORAGE_ELEMENT *)UI_LIST::Get(UI_STORAGE::FindNumber, &objectNumber);
  263.  
  264.     if (!element)
  265.         return (NULL);
  266.     else if (seekMode == SEEK_WRITE)
  267.         element->search.offset = lseek(file, 0L, SEEK_END);
  268.     else
  269.         lseek(file, element->search.offset, SEEK_SET);
  270.  
  271.     cacheOffset = 0;
  272.     cacheRemaining = (seekMode == SEEK_READ) ? 0 : cacheSize;
  273.     return (element);
  274. }
  275.  
  276. int UI_STORAGE::Store(void *buffer, int length)
  277. {
  278.     // Make sure write is enabled.
  279.     if (!FlagSet(access, O_RDWR))
  280.         return (0);
  281.  
  282.     // See if cache is turned on.
  283.     if (!cache)
  284.         return (write(file, buffer, length));
  285.  
  286.     // See if flushing is requested or if there is enough cached to write.
  287.     if (length > cacheRemaining)
  288.     {
  289.         write(file, cache, cacheOffset);
  290.         cacheOffset = 0;
  291.         cacheRemaining = cacheSize;
  292.     }
  293.  
  294.     // Copy the file write buffer to the cached buffer.
  295.     memmove(&cache[cacheOffset], buffer, length);
  296.     cacheOffset += length;
  297.     cacheRemaining -= length;
  298.     return (length);
  299. }
  300.  
  301. int UI_STORAGE::Store(const char *string)
  302. {
  303.     USHORT size = string ? strlen(string) : 0;
  304.     UI_STORAGE::Store(&size, sizeof(size));
  305.     if (size)
  306.         size = UI_STORAGE::Store(string, size);
  307.     return (size + sizeof(short));
  308. }
  309.  
  310. void UI_STORAGE::StripFullPath(const char *fullPath, char *pathName, char *fileName, char *objectName)
  311. {
  312.     // Determine the path/file split area.
  313.     char *name = strrchr(fullPath, '\\');
  314.     if (!name)
  315.         name = strrchr(fullPath, ':');
  316.  
  317.     // Construct the path name.
  318.     if (pathName)
  319.     {
  320.         if (name)
  321.         {
  322.             strcpy(pathName, fullPath);
  323.             pathName[(int)(name - fullPath)] = '\0';
  324.             strupr(pathName);
  325.         }
  326.         else
  327.             pathName[0] = '\0';
  328.     }
  329.  
  330.     // Construct the file name.
  331.     if (fileName)
  332.     {
  333.         if (name)
  334.             strcpy(fileName, ++name);
  335.         else
  336.             strcpy(fileName, fullPath);
  337.         name = strrchr(fileName, '~');
  338.         if (name)
  339.             fileName[(int)(name - fileName)] = '\0';
  340.         strupr(fileName);
  341.     }
  342.  
  343.     // Construct the object name.
  344.     if (objectName)
  345.     {
  346.         name = strrchr(fullPath, '~');
  347.         if (name)
  348.             strcpy(objectName, ++name);
  349.         else
  350.             objectName[0] = '\0';
  351.         strupr(objectName);
  352.     }
  353. }
  354.  
  355. int UI_STORAGE::ValidName(const char *name, int createStorage)
  356. {
  357.     char path[MAXPATH];
  358.     if (createStorage)
  359.     {
  360.         UI_STORAGE::StripFullPath(name, path);
  361.         strcat(path, "\\*.*");
  362.     }
  363.     else
  364.         strcpy(path, name);
  365.     struct ffblk fileBlock;
  366.     return (!findfirst(path, &fileBlock, FA_DIREC));
  367. }
  368.