home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / ICU / src / icu / source / tools / genrb / ustdio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-19  |  7.0 KB  |  303 lines

  1. /*
  2. *******************************************************************************
  3. *                                                                             *
  4. * COPYRIGHT:                                                                  *
  5. *   (C) Copyright International Business Machines Corporation, 1998           *
  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 ustdio.c
  13. *
  14. * Modification History:
  15. *
  16. *   Date        Name        Description
  17. *   11/18/98    stephen        Creation.
  18. *   03/12/99    stephen     Modified for new C API.
  19. *******************************************************************************
  20. */
  21.  
  22. #include "ustdio.h"
  23. #include "ufile.h"
  24. #include "ucnv.h"
  25. #include "ustring.h"
  26. #include "cmemory.h"
  27.  
  28. static const UChar DELIMITERS [] = { 0x000A, 0x0000 };
  29.  
  30. #define DELIM_CR 0x000D
  31. #define DELIM_LF 0x000A
  32.  
  33. #define IS_STRING_DELIMITER(s)    (bool_t)(    (s) == DELIM_CR || \
  34.                         (s) == DELIM_LF    )
  35.  
  36.  
  37. /* Input/output */
  38.  
  39. int32_t
  40. u_fputs(const UChar *s,
  41.     UFILE *f,
  42.     UErrorCode *status)
  43. {
  44.   int32_t count;
  45.  
  46.   if(U_FAILURE(*status)) return 0;
  47.   
  48.   count = u_file_write(s, u_strlen(s), f, status);
  49.   count += u_file_write(DELIMITERS, u_strlen(DELIMITERS), f, status);
  50.   return count;
  51. }
  52.  
  53. int32_t
  54. u_fputc(UChar uc,
  55.     UFILE *f,
  56.     UErrorCode *status)
  57. {
  58.   if(U_FAILURE(*status)) return U_EOF;
  59.  
  60.   return u_file_write(&uc, 1, f, status) == 1 ? uc : U_EOF;
  61. }
  62.  
  63. int32_t
  64. u_file_write(const UChar *chars, 
  65.          int32_t count, 
  66.          UFILE *f,
  67.          UErrorCode *status)
  68. {
  69.   /* Set up conversion parameters */
  70.   const UChar        *mySource       = chars;
  71.   const UChar        *sourceAlias       = chars;
  72.   const UChar        *mySourceEnd     = chars + count;
  73.   char            *myTarget     = f->fCharBuffer;
  74.   int32_t        bufferSize    = UFILE_CHARBUFFER_SIZE;
  75.   int32_t        written        = 0;
  76.  
  77.   if(U_FAILURE(*status)) return U_EOF;
  78.   
  79.   /* Perform the conversion in a loop */
  80.   do {
  81.     *status     = U_ZERO_ERROR;
  82.     sourceAlias = mySource;
  83.     
  84.     ucnv_fromUnicode(f->fConverter,
  85.              &myTarget, 
  86.              f->fCharBuffer + bufferSize,
  87.              &mySource,
  88.              mySourceEnd,
  89.              NULL,
  90.              TRUE,
  91.              status);
  92.  
  93.     /* write the converted bytes */
  94.     T_FileStream_write(f->fFile, 
  95.                f->fCharBuffer, 
  96.                sizeof(char) * (myTarget - f->fCharBuffer));
  97.     
  98.     written     += (myTarget - f->fCharBuffer);
  99.     myTarget     = f->fCharBuffer;
  100.   }
  101.   while(*status == U_INDEX_OUTOFBOUNDS_ERROR); 
  102.  
  103.   /* return # of chars written */
  104.   return written;
  105. }
  106.  
  107. UChar*
  108. u_fgets(UFILE *f,
  109.     int32_t n,
  110.     UChar *s,
  111.     UErrorCode *status)
  112. {
  113.   int32_t dataSize;
  114.   int32_t read;
  115.   int32_t count;
  116.   UChar *alias;
  117.  
  118.   if(U_FAILURE(*status)) return 0;
  119.  
  120.   /* subtract 1 from n to compensate for the terminator */
  121.   --n;
  122.  
  123.   /* determine the amount of data in the buffer */
  124.   dataSize = f->fUCLimit - f->fUCPos;
  125.  
  126.   /* if the buffer contains more data than requested, operate on the buffer */
  127.   if(dataSize > n) {
  128.  
  129.     /* find the first occurrence of a delimiter character */
  130.     alias = f->fUCPos;
  131.     count = 0;
  132.     while( ! IS_STRING_DELIMITER(*alias) && count < n) {
  133.       ++count;
  134.       ++alias;
  135.     }
  136.  
  137.     /* copy the characters into the target*/
  138.     icu_memcpy(s, f->fUCPos, count * sizeof(UChar));
  139.  
  140.     /* add the terminator */
  141.     s[count] = 0x0000;
  142.  
  143.     /* update the current buffer position */
  144.     f->fUCPos += count;
  145.  
  146.     /* refill the buffer */
  147.     ufile_fill_uchar_buffer(f, status);
  148.     if(U_FAILURE(*status)) return 0;
  149.     
  150.     /* skip over any remaining delimiters */
  151.     while(IS_STRING_DELIMITER(*(f->fUCPos)) && f->fUCPos < f->fUCLimit)
  152.       ++(f->fUCPos);
  153.     
  154.     /* return s */
  155.     return s;
  156.   }
  157.  
  158.   /* otherwise, iteratively fill the buffer and copy */
  159.   read = 0;
  160.   do {
  161.     
  162.     /* refill the buffer */
  163.     ufile_fill_uchar_buffer(f, status);
  164.     if(U_FAILURE(*status)) return 0;
  165.     
  166.     /* determine the amount of data in the buffer */
  167.     dataSize = f->fUCLimit - f->fUCPos;
  168.  
  169.     /* find the first occurrence of a delimiter character, if present */
  170.     alias = f->fUCPos;
  171.     count = 0;
  172.     while( ! IS_STRING_DELIMITER(*alias) && alias < f->fUCLimit && count < n) {
  173.       ++count;
  174.       ++alias;
  175.     }
  176.     
  177.     /* copy the current data in the buffer */
  178.     memcpy(s + read, f->fUCPos, count * sizeof(UChar));
  179.     
  180.     /* update number of items read */
  181.     read += count;
  182.  
  183.     /* update the current buffer position */
  184.     f->fUCPos += count;
  185.  
  186.     /* if we found a delimiter */
  187.     if(alias < f->fUCLimit) {
  188.  
  189.       /* refill the buffer */
  190.       ufile_fill_uchar_buffer(f, status);
  191.       if(U_FAILURE(*status)) return 0;
  192.  
  193.       /* skip over any remaining delimiters */
  194.       while(IS_STRING_DELIMITER(*(f->fUCPos)) && f->fUCPos < f->fUCLimit)
  195.     ++(f->fUCPos);
  196.       
  197.       /* break out */
  198.       break;
  199.     }
  200.  
  201.   } while(dataSize != 0 && read < n);
  202.  
  203.   /* if 0 characters were read, return 0 */
  204.   if(read == 0)
  205.     return 0;
  206.  
  207.   /* add the terminator and return s */
  208.   s[read] = 0x0000;
  209.   return s;
  210. }
  211.  
  212. UChar
  213. u_fgetc(UFILE *f,
  214.     UErrorCode *status)
  215. {
  216.   if(U_FAILURE(*status)) return U_EOF;
  217.  
  218.   /* if we have an available character in the buffer, return it */
  219.   if(f->fUCPos < f->fUCLimit)
  220.     return *(f->fUCPos)++;
  221.   /* otherwise, fill the buffer and return the next character */
  222.   else {
  223.     ufile_fill_uchar_buffer(f, status);
  224.     if(U_FAILURE(*status)) return U_EOF;
  225.     if(f->fUCPos < f->fUCLimit) {
  226.       return *(f->fUCPos)++;
  227.     }
  228.     /* at EOF */
  229.     else {
  230.       return U_EOF;
  231.     }
  232.   }
  233. }
  234.  
  235. UChar
  236. u_fungetc(UChar c,
  237.       UFILE *f,
  238.       UErrorCode *status)
  239. {
  240.   if(U_FAILURE(*status)) return U_EOF;
  241.  
  242.   /* if we're at the beginning of the buffer, sorry! */
  243.   if(f->fUCPos == f->fUCBuffer) {
  244.     *status = U_BUFFER_OVERFLOW_ERROR;
  245.     return U_EOF;
  246.   }
  247.   /* otherwise, put the character back */
  248.   else {
  249.     *--(f->fUCPos) = c;
  250.     return c;
  251.   }
  252. }
  253.  
  254. int32_t
  255. u_file_read(UChar *chars, 
  256.         int32_t count, 
  257.         UFILE *f,
  258.         UErrorCode *status)
  259. {
  260.   int32_t dataSize;
  261.   int32_t read;
  262.  
  263.   if(U_FAILURE(*status)) return 0;
  264.  
  265.   /* determine the amount of data in the buffer */
  266.   dataSize = f->fUCLimit - f->fUCPos;
  267.  
  268.   /* if the buffer contains the amount requested, just copy */
  269.   if(dataSize > count) {
  270.     icu_memcpy(chars, f->fUCPos, count * sizeof(UChar));
  271.  
  272.     /* update the current buffer position */
  273.     f->fUCPos += count;
  274.  
  275.     /* return # of chars read */
  276.     return count;
  277.   }
  278.  
  279.   /* otherwise, iteratively fill the buffer and copy */
  280.   read = 0;
  281.   do {
  282.     
  283.     /* refill the buffer */
  284.     ufile_fill_uchar_buffer(f, status);
  285.     if(U_FAILURE(*status)) return read;
  286.     
  287.     /* determine the amount of data in the buffer */
  288.     dataSize = f->fUCLimit - f->fUCPos;
  289.  
  290.     /* copy the current data in the buffer */
  291.     icu_memcpy(chars + read, f->fUCPos, dataSize * sizeof(UChar));
  292.     
  293.     /* update number of items read */
  294.     read += dataSize;
  295.  
  296.     /* update the current buffer position */
  297.     f->fUCPos += dataSize;
  298.  
  299.   } while(dataSize != 0 && read < count);
  300.   
  301.   return read;
  302. }
  303.