ZipCharStream.cpp

Go to the documentation of this file.
00001 // ZipCharStream.cpp,v 1.5 2004/10/26 18:59:25 elliott_c Exp
00002 
00003 #ifdef USE_ZZIP
00004 
00005 #include "ACEXML/common/ZipCharStream.h"
00006 #include "ace/ACE.h"
00007 
00008 
00009 ACEXML_ZipCharStream::ACEXML_ZipCharStream (void)
00010   : filename_ (0), encoding_ (0), size_ (0), infile_ (0), pos_ (0),
00011     limit_ (0)
00012 {
00013 }
00014 
00015 ACEXML_ZipCharStream::~ACEXML_ZipCharStream (void)
00016 {
00017   this->close();
00018 }
00019 
00020 int
00021 ACEXML_ZipCharStream::open (const ACEXML_Char *name)
00022 {
00023   delete[] this->filename_;
00024   this->filename_ = 0;
00025 
00026   delete[] this->encoding_;
00027   this->encoding_ = 0;
00028 
00029   this->infile_ = zzip_fopen (name, ACE_TEXT ("r"));
00030   if (this->infile_ == 0)
00031     return -1;
00032 
00033   this->filename_ = ACE::strnew (ACE::basename (name));
00034   return this->determine_encoding();
00035 }
00036 
00037 int
00038 ACEXML_ZipCharStream::determine_encoding (void)
00039 {
00040   if (this->infile_ == 0)
00041     return -1;
00042   char input[4];
00043   int i = 0;
00044   for (; i < 4 && (input[i] = this->peekchar_i(i)) > 0; ++i)
00045     ;
00046   if (i < 4)
00047     return -1;
00048   const ACEXML_Char* temp = ACEXML_Encoding::get_encoding (input);
00049   if (!temp)
00050     return -1;
00051   else
00052     {
00053       if (this->encoding_)
00054         delete [] this->encoding_;
00055       this->encoding_ = ACE::strnew (temp);
00056   //     ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("File's encoding is %s\n"),
00057 //                   this->encoding_));
00058     }
00059   // Move over the byte-order-mark if present.
00060   char ch;
00061   for (int j = 0; j < 3; ++j)
00062     {
00063       if ((ch = this->peekchar_i()) < 0)
00064         return -1;
00065       if (ch == '\xFF' || ch == '\xFE' || ch == '\xEF' || ch == '\xBB' ||
00066           ch == '\xBF')
00067         this->get(ch);
00068       else
00069         break;
00070     }
00071   return 0;
00072 }
00073 
00074 void
00075 ACEXML_ZipCharStream::rewind()
00076 {
00077   if (this->infile_ == 0)
00078     return;
00079   zzip_rewind (this->infile_);
00080   this->determine_encoding();
00081 }
00082 
00083 int
00084 ACEXML_ZipCharStream::available (void)
00085 {
00086   if (this->infile_ == 0)
00087     return -1;
00088   long curr;
00089   if ((curr = zzip_tell (this->infile_)) < 0)
00090     return -1;
00091   return (this->size_ - curr);
00092 }
00093 
00094 int
00095 ACEXML_ZipCharStream::close (void)
00096 {
00097   if (this->infile_ != 0)
00098     {
00099       zzip_close (this->infile_);
00100       this->infile_ = 0;
00101     }
00102   delete[] this->filename_;
00103   this->filename_ = 0;
00104   delete[] this->encoding_;
00105   this->encoding_ = 0;
00106   this->size_ = 0;
00107   this->pos_ = 0;
00108   this->limit_ = 0;
00109   return 0;
00110 }
00111 
00112 
00113 int
00114 ACEXML_ZipCharStream::getchar_i (char& ch)
00115 {
00116   if (this->infile_ == 0)
00117     return -1;
00118 
00119   if (this->pos_ < this->limit_)
00120     {
00121       ch = this->buf_[this->pos_++];
00122       return 0;
00123     }
00124   this->limit_ = zzip_read (this->infile_, this->buf_, sizeof (this->buf_));
00125   if (this->limit_ == 0)
00126     return -1;
00127   this->pos_ = 0;
00128   ch = this->buf_[this->pos_++];
00129   return 0;
00130 }
00131 
00132 int
00133 ACEXML_ZipCharStream::peekchar_i (off_t offset)
00134 {
00135   if (this->infile_ == 0)
00136     return -1;
00137 
00138   if (offset > (off_t) sizeof (this->buf_))
00139     return -1;
00140   if (this->pos_ + offset < this->limit_)
00141     return this->buf_[this->pos_ + offset];
00142   int i = 0;
00143   for (; this->pos_ < this->limit_; ++this->pos_, ++i)
00144     this->buf_[i] = this->buf_[this->pos_];
00145   this->limit_ = zzip_read (this->infile_, this->buf_ + i,
00146                             sizeof (this->buf_) - i);
00147   this->limit_ += i;
00148   if (this->limit_ == 0)
00149     return -1;
00150   this->pos_ = 0;
00151   return this->buf_[this->pos_ + offset];
00152 }
00153 
00154 int
00155 ACEXML_ZipCharStream::read (ACEXML_Char *str, size_t len)
00156 {
00157   if (this->infile_ == 0)
00158     return -1;
00159 
00160   size_t i = 0;
00161   for (; i < len && this->pos_ < this->limit_; ++i)
00162     str[i] = this->buf_[this->pos_++];
00163   if (i == len)
00164     return len;
00165   len = len - i;
00166   this->pos_ = 0;
00167   this->limit_ = 0;
00168   int bytes = zzip_fread (str + i, sizeof (ACEXML_Char), len, this->infile_);
00169   return (bytes + i);
00170 }
00171 
00172 int
00173 ACEXML_ZipCharStream::get (ACEXML_Char& ch)
00174 {
00175 #if defined (ACE_USES_WCHAR)
00176   return this->get_i (ch);
00177 #else
00178   return this->getchar_i (ch);
00179 #endif /* ACE_USES_WCHAR */
00180 }
00181 
00182 
00183 int
00184 ACEXML_ZipCharStream::peek (void)
00185 {
00186 #if defined (ACE_USES_WCHAR)
00187   return this->peek_i();
00188 #else
00189   return this->peekchar_i();
00190 #endif /* ACE_USES_WCHAR */
00191 }
00192 
00193 const ACEXML_Char*
00194 ACEXML_ZipCharStream::getEncoding (void)
00195 {
00196   return this->encoding_;
00197 }
00198 
00199 const ACEXML_Char*
00200 ACEXML_ZipCharStream::getSystemId (void)
00201 {
00202   return this->filename_;
00203 }
00204 
00205 #if defined (ACE_USES_WCHAR)
00206 int
00207 ACEXML_ZipCharStream::get_i (ACEXML_Char& ch)
00208 {
00209   if (ACE_OS::strcmp (this->encoding_, ACE_TEXT ("UTF-8")) == 0)
00210     return this->getchar_i (ch);
00211 
00212   int BE = (ACE_OS::strcmp (this->encoding_,
00213                             ACE_TEXT ("UTF-16BE")) == 0) ? 1 : 0;
00214   ACEXML_Char input[2];
00215   int i = 0;
00216   for (; i < 2 && (this->getchar_i (input[i]) == 0); ++i)
00217     ;
00218   if (i < 2)
00219     {
00220       ch = 0;
00221       return -1;
00222     }
00223   ch = BE ? input[0] << 8 | input[1] : input[1] << 8 | input[0];
00224   return 0;
00225 }
00226 
00227 int
00228 ACEXML_ZipCharStream::peek_i (void)
00229 {
00230 
00231   // If we are reading a UTF-8 encoded file, just use the plain unget.
00232   if (ACE_OS::strcmp (this->encoding_, ACE_TEXT ("UTF-8")) == 0)
00233     return this->peekchar_i();
00234 
00235   // Peek into the stream. This reads two characters off the stream, keeps
00236   // it in peek_.
00237   int BE = (ACE_OS::strcmp (this->encoding_,
00238                             ACE_TEXT ("UTF-16BE")) == 0) ? 1 : 0;
00239 
00240   ACEXML_Char input[2];
00241   int i = 0;
00242   for (; i < 2 && (input[i] = this->peekchar_i (i)) > 0; ++i)
00243     ;
00244   if (i < 2)
00245     return -1;
00246   return (BE ? input[0] << 8 | input[1] : input[1] << 8 | input[0]);
00247 }
00248 #endif /* ACE_USES_WCHAR */
00249 
00250 #else
00251 #if defined (__HP_aCC)
00252 static int shut_up_aCC = 0;
00253 #endif /* __HP_aCC */
00254 
00255 #endif /* USE_ZZIP */

Generated on Thu Nov 9 11:45:40 2006 for ACEXML by doxygen 1.3.6