home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / ICU / src / icu / source / common / rbread.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-19  |  8.2 KB  |  354 lines

  1. /*
  2. *******************************************************************************
  3. *                                                                             *
  4. * COPYRIGHT:                                                                  *
  5. *   (C) Copyright International Business Machines Corporation, 1998, 1999     *
  6. *   Licensed Material - Program-Property of IBM - All Rights Reserved.        *
  7. *   US Government Users Restricted Rights - Use, duplication, or disclosure   *
  8. *   restricted by GSA ADP Schedule Contract with IBM Corp.                    *
  9. *                                                                             *
  10. *******************************************************************************
  11. *
  12. * File rbread.cpp
  13. *
  14. * Modification History:
  15. *
  16. *   Date        Name        Description
  17. *   06/11/99    stephen     Creation.
  18. *******************************************************************************
  19. */
  20.  
  21. #include <stdio.h>
  22.  
  23. #include "rbread.h"
  24. #include "cmemory.h"
  25. #include "cstring.h"
  26. #include "filestrm.h"
  27. #include "ustring.h"
  28. #include "rbdata.h"
  29.  
  30. #include "unistr.h"
  31. #include "rbdata.h"
  32.  
  33.  
  34. /* Protos */
  35. static void read_ustring(FileStream *rb, UnicodeString& val, 
  36.              UErrorCode& status);
  37. static StringList* read_strlist(FileStream *rb, UnicodeString& listname, 
  38.                 UErrorCode& status);
  39. static String2dList* read_strlist2d(FileStream *rb, UnicodeString& listname,
  40.                     UErrorCode& status);
  41. static TaggedList* read_taglist(FileStream *rb, UnicodeString& listname,
  42.                 UErrorCode& status);
  43. static void RBHashtable_valueDeleter(void *value);
  44.  
  45.  
  46. /* Read a string from a compiled resource file */
  47. #define BUF_SIZE 128
  48. void
  49. read_ustring(FileStream *rb, 
  50.          UnicodeString& val,
  51.          UErrorCode& status)
  52. {
  53.   int32_t len = 0, readLen = 0, remain = 0;
  54.   UChar buf [BUF_SIZE];
  55.  
  56.   if(U_FAILURE(status)) return;
  57.  
  58.   /* Read the string's length */
  59.   T_FileStream_read(rb, &len, sizeof(len));
  60.  
  61.   /* Truncate the output string */
  62.   val.remove();
  63.  
  64.   remain = len;
  65.  
  66.   /* Successively read the string's data from the file */
  67.   while(remain != 0) {
  68.  
  69.     /* Read the next chunk of data */
  70.     readLen = icu_min(BUF_SIZE, remain);
  71.     icu_memset(buf, 0, readLen*sizeof(UChar));
  72.     T_FileStream_read(rb, buf, sizeof(UChar) * readLen);
  73.  
  74.     /* Append the chunk to the string */
  75.     val.append(buf, readLen);
  76.     
  77.     remain -= readLen;
  78.   }
  79.  
  80. }
  81.  
  82. /* Read a string list */
  83. StringList*
  84. read_strlist(FileStream *rb,
  85.          UnicodeString& listname,
  86.          UErrorCode& status)
  87. {
  88.   int32_t i, count = 0;
  89.   StringList *retval;
  90.  
  91.   if(U_FAILURE(status)) return 0;
  92.  
  93.   /* Setup the string list */
  94.   retval = new StringList();
  95.   if(retval == 0) {
  96.     status = U_MEMORY_ALLOCATION_ERROR;
  97.     return 0;
  98.   }
  99.  
  100.   /* Read the name of this string list */
  101.   read_ustring(rb, listname, status);
  102.   if(U_FAILURE(status)) {
  103.     delete retval;
  104.     return 0;
  105.   }
  106.  
  107.   /* Read the number of items in this string list */
  108.   T_FileStream_read(rb, &count, sizeof(count));
  109.   retval->fCount = count;
  110.  
  111.   /* Allocate space for the array of strings */
  112.   retval->fStrings = new UnicodeString [ retval->fCount ];
  113.   if(retval->fStrings == 0) {
  114.     status = U_MEMORY_ALLOCATION_ERROR;
  115.     delete retval;
  116.     return 0;
  117.   }
  118.  
  119.   /* Successively read strings in the list */
  120.   for(i = 0; i < count; ++i) {
  121.     read_ustring(rb, retval->fStrings[i], status);
  122.  
  123.     /* handle error */
  124.     if(U_FAILURE(status)) {
  125.       delete [] retval->fStrings;
  126.       delete retval;
  127.       return 0;
  128.     }
  129.   }
  130.   
  131.   return retval;
  132. }
  133.  
  134. /* Read a 2-d string list */
  135. String2dList*
  136. read_strlist2d(FileStream *rb,
  137.            UnicodeString& listname,
  138.            UErrorCode& status)
  139. {
  140.   int32_t i, j;
  141.   int32_t rows, itemcount;
  142.   String2dList *retval;
  143.  
  144.   if(U_FAILURE(status)) return 0;
  145.   
  146.   /* Setup the 2-d string list */
  147.   retval = new String2dList();
  148.   if(retval == 0) {
  149.     status = U_MEMORY_ALLOCATION_ERROR;
  150.     return 0;
  151.   }
  152.  
  153.   /* Read the name of this 2-d string list */
  154.   read_ustring(rb, listname, status);
  155.   if(U_FAILURE(status)) {
  156.     delete retval;
  157.     return 0;
  158.   }
  159.  
  160.   /* Read the number of rows in this 2-d string list */
  161.   T_FileStream_read(rb, &rows, sizeof(rows));
  162.   retval->fRowCount = rows;
  163.  
  164.   /* Allocate space for the array of strings */
  165.   retval->fStrings = new UnicodeString* [ retval->fRowCount ];
  166.   if(retval->fStrings == 0) {
  167.     status = U_MEMORY_ALLOCATION_ERROR;
  168.     delete retval;
  169.     return 0;
  170.   }
  171.  
  172.   /* Read each row */
  173.   for(i = 0; i < rows; ++i) {
  174.  
  175.     /* Read the number of items in this row */
  176.     T_FileStream_read(rb, &itemcount, sizeof(itemcount));
  177.  
  178.     /* Hack for now - assume all rows are the same length */
  179.     retval->fColCount = itemcount;
  180.  
  181.     /* Allocate enough space for each item */
  182.     retval->fStrings[i] = new UnicodeString[itemcount];
  183.     if(retval->fStrings[i] == 0) {
  184.       status = U_MEMORY_ALLOCATION_ERROR;
  185.       /* Complicated cleanup later */
  186.       delete retval;
  187.       return 0;
  188.     }
  189.  
  190.     /* Read each item */
  191.     for(j = 0; j < itemcount; ++j) {
  192.       read_ustring(rb, retval->fStrings[i][j], status);
  193.       
  194.       /* handle error */
  195.       if(U_FAILURE(status)) {
  196.     /* Complicated cleanup later */
  197.     delete retval;
  198.     return 0;
  199.       }
  200.     }
  201.   }
  202.  
  203.   return retval;
  204. }
  205.  
  206. /* Read a tagged list */
  207. TaggedList*
  208. read_taglist(FileStream *rb, 
  209.          UnicodeString& listname,
  210.          UErrorCode& status)
  211. {
  212.   TaggedList *retval;
  213.   int32_t i, count = 0;
  214.   UnicodeString tag, value;
  215.  
  216.   if(U_FAILURE(status)) return 0;
  217.  
  218.   /* Setup the tagged list */
  219.   retval = new TaggedList();
  220.   if(retval == 0) {
  221.     status = U_MEMORY_ALLOCATION_ERROR;
  222.     return 0;
  223.   }
  224.  
  225.   /* Read the name of this tagged list */
  226.   read_ustring(rb, listname, status);
  227.   if(U_FAILURE(status)) {
  228.     delete retval;
  229.     return 0;
  230.   }
  231.  
  232.   /* Read the number of items in this tagged list */
  233.   T_FileStream_read(rb, &count, sizeof(count));
  234.  
  235.   /* Successively read strings in the list */
  236.   for(i = 0; i < count; ++i) {
  237.     read_ustring(rb, tag, status);
  238.     read_ustring(rb, value, status);
  239.     
  240.     /* handle error */
  241.     if(U_FAILURE(status)) {
  242.       delete retval;
  243.       return 0;
  244.     }
  245.  
  246.     /* put the tag/value in the list */
  247.     retval->put(tag, value);
  248.   }
  249.  
  250.   return retval;
  251. }
  252.  
  253. /* Parse a compiled rb file */
  254. UHashtable*
  255. rb_parse(FileStream *f, 
  256.      UnicodeString& localename,
  257.      UErrorCode& status)
  258. {
  259.   UHashtable *retval;
  260.   int32_t bom;
  261.   int32_t itemtype;
  262.   UnicodeString listname;
  263.   StringList *strlist;
  264.   String2dList *strlist2d;
  265.   TaggedList *taglist;
  266.  
  267.   if(U_FAILURE(status)) return 0;
  268.  
  269.   /* Open the hashtable for saving data */
  270.   retval = uhash_open((UHashFunction)uhash_hashUString, &status);
  271.   if(retval == 0 || U_FAILURE(status)) {
  272.     status = U_MEMORY_ALLOCATION_ERROR;
  273.     return 0;
  274.   }
  275.   uhash_setValueDeleter(retval, RBHashtable_valueDeleter);
  276.  
  277.   /* Read the byte order mark from the file */
  278.   T_FileStream_read(f, &bom, sizeof(bom));
  279.   
  280.   /* Verify the byte ordering matches */
  281.   if(bom != sBOM) {
  282.     uhash_close(retval);
  283.     status = U_INVALID_FORMAT_ERROR;
  284.     return 0;
  285.   }
  286.  
  287.   /* Read the locale name from the file */
  288.   read_ustring(f, localename, status);
  289.   if(U_FAILURE(status)) {
  290.     uhash_close(retval);
  291.     return 0;
  292.   }
  293.  
  294.   /* Successively read each list item */
  295.   for(;;) {
  296.  
  297.     /* Read the next item type */
  298.     T_FileStream_read(f, &itemtype, sizeof(itemtype));
  299.  
  300.     /* If we're at EOF, break */
  301.     if(itemtype == sEOF) {
  302.       break;
  303.     }
  304.    
  305.     /* Parse each item and add it to the hashtable */
  306.     switch(itemtype) {
  307.     case sSTRINGLIST:
  308.       strlist = read_strlist(f, listname, status);
  309.       uhash_putKey(retval, listname.hashCode() & 0x7FFFFFFF, 
  310.            strlist, &status);
  311.       if(U_FAILURE(status)) {
  312.     uhash_close(retval);
  313.     return 0;
  314.       }
  315.       break;
  316.  
  317.     case sSTRINGLIST2D:
  318.       strlist2d = read_strlist2d(f, listname, status);
  319.       uhash_putKey(retval, listname.hashCode() & 0x7FFFFFFF, 
  320.            strlist2d, &status);
  321.       if(U_FAILURE(status)) {
  322.     uhash_close(retval);
  323.     return 0;
  324.       }
  325.       break;
  326.  
  327.     case sTAGGEDLIST:
  328.       taglist = read_taglist(f, listname, status);
  329.       uhash_putKey(retval, listname.hashCode() & 0x7FFFFFFF, 
  330.            taglist, &status);
  331.       if(U_FAILURE(status)) {
  332.     uhash_close(retval);
  333.     return 0;
  334.       }
  335.       break;
  336.     }
  337.   }
  338.  
  339.   /* Check if any errors occurred during reading */
  340.   if(T_FileStream_error(f) != 0) {
  341.     status = U_FILE_ACCESS_ERROR;
  342.     delete retval;
  343.     return 0;
  344.   }
  345.  
  346.   return retval;
  347. }
  348.  
  349. void 
  350. RBHashtable_valueDeleter(void *value)
  351. {
  352.   delete (ResourceBundleData*)value;
  353. }
  354.