00001
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
00057
00058 }
00059
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
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
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
00232 if (ACE_OS::strcmp (this->encoding_, ACE_TEXT ("UTF-8")) == 0)
00233 return this->peekchar_i();
00234
00235
00236
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
00249
00250 #else
00251 #if defined (__HP_aCC)
00252 static int shut_up_aCC = 0;
00253 #endif
00254
00255 #endif