summaryrefslogtreecommitdiff
path: root/ACEXML/common/ZipCharStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACEXML/common/ZipCharStream.cpp')
-rw-r--r--ACEXML/common/ZipCharStream.cpp213
1 files changed, 213 insertions, 0 deletions
diff --git a/ACEXML/common/ZipCharStream.cpp b/ACEXML/common/ZipCharStream.cpp
new file mode 100644
index 00000000000..f16bc77f463
--- /dev/null
+++ b/ACEXML/common/ZipCharStream.cpp
@@ -0,0 +1,213 @@
+// $Id$
+
+#include "ACEXML/common/ZipCharStream.h"
+#include "ace/ACE.h"
+
+
+ACEXML_ZipCharStream::ACEXML_ZipCharStream (void)
+ : filename_ (0), encoding_ (0), size_ (0), infile_ (NULL), pos_ (0),
+ limit_ (0)
+{
+}
+
+ACEXML_ZipCharStream::~ACEXML_ZipCharStream (void)
+{
+ this->close();
+}
+
+int
+ACEXML_ZipCharStream::open (const ACEXML_Char *name)
+{
+ delete[] this->filename_;
+ this->filename_ = 0;
+
+ delete[] this->encoding_;
+ this->encoding_ = 0;
+
+ this->infile_ = zzip_fopen (name, ACE_TEXT ("r"));
+ if (this->infile_ == NULL)
+ return -1;
+
+ this->filename_ = ACE::strnew (ACE::basename (name));
+ if (this->determine_encoding() == -1)
+ return -1;
+ return 0;
+}
+
+int
+ACEXML_ZipCharStream::determine_encoding (void)
+{
+ char input[4];
+ int retval = 0;
+ int i = 0;
+ for (; i < 4 && (input[i] = this->peekchar_i(i)); ++i)
+ ;
+ if (i < 4)
+ return -1;
+ const ACEXML_Char* temp = ACEXML_Encoding::get_encoding (input);
+ if (!temp)
+ return -1;
+ else
+ {
+ this->encoding_ = ACE::strnew (temp);
+ // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("File's encoding is %s\n"),
+// this->encoding_));
+ }
+ // Move over the byte-order-mark if present.
+ char ch;
+ for (int j = 0; j < 3; ++j)
+ {
+ if ((ch = this->peekchar_i()) < 0)
+ return -1;
+ if (ch == '\xFF' || ch == '\xFE' || ch == '\xEF' || ch == '\xBB' ||
+ ch == '\xBF')
+ this->get(ch);
+ else
+ break;
+ }
+ return 0;
+}
+
+void
+ACEXML_ZipCharStream::rewind()
+{
+ zzip_rewind (this->infile_);
+}
+
+int
+ACEXML_ZipCharStream::available (void)
+{
+ long curr;
+ if ((curr = zzip_tell (this->infile_)) < 0)
+ return -1;
+ return (this->size_ - curr);
+}
+
+int
+ACEXML_ZipCharStream::close (void)
+{
+ if (this->infile_ != NULL)
+ zzip_close (this->infile_);
+ delete[] this->filename_;
+ delete[] this->encoding_;
+ this->size_ = 0;
+ return 0;
+}
+
+
+int
+ACEXML_ZipCharStream::getchar_i (char& ch)
+{
+ if (this->pos_ < this->limit_)
+ {
+ ch = this->buf_[this->pos_++];
+ return 0;
+ }
+ this->limit_ = zzip_read (this->infile_, this->buf_, sizeof (this->buf_));
+ if (this->limit_ == 0)
+ return -1;
+ this->pos_ = 0;
+ ch = this->buf_[this->pos_++];
+ return 0;
+}
+
+int
+ACEXML_ZipCharStream::peekchar_i (int offset)
+{
+ if (offset > sizeof (this->buf_))
+ return -1;
+ if (this->pos_ + offset < this->limit_)
+ return this->buf_[this->pos_ + offset];
+ int i = 0;
+ for (; this->pos_ < this->limit_; ++this->pos_, ++i)
+ this->buf_[i] = this->buf_[this->pos_];
+ this->limit_ = zzip_read (this->infile_, this->buf_ + i,
+ sizeof (this->buf_) - i);
+ this->limit_ += i;
+ if (this->limit_ == 0)
+ return -1;
+ this->pos_ = 0;
+ return this->buf_[this->pos_ + offset];
+}
+
+int
+ACEXML_ZipCharStream::read (ACEXML_Char *str, size_t len)
+{
+ for (size_t i = 0; i < len && this->pos_ < this->limit_; ++i)
+ str[i] = this->buf_[this->pos_++];
+ if (i == len)
+ return len;
+ len = len - i;
+ return zzip_fread (str + i, sizeof (ACEXML_Char), len, this->infile_);
+}
+
+int
+ACEXML_ZipCharStream::get (ACEXML_Char& ch)
+{
+#if defined (ACE_USES_WCHAR)
+ return this->get_i (ch);
+#else
+ return this->getchar_i (ch);
+#endif /* ACE_USES_WCHAR */
+}
+
+
+int
+ACEXML_ZipCharStream::peek (void)
+{
+#if defined (ACE_USES_WCHAR)
+ return this->peek_i();
+#else
+ return this->peekchar_i();
+#endif /* ACE_USES_WCHAR */
+}
+
+const ACEXML_Char*
+ACEXML_ZipCharStream::getEncoding (void)
+{
+ return this->encoding_;
+}
+
+#if defined (ACE_USES_WCHAR)
+int
+ACEXML_ZipCharStream::get_i (ACEXML_Char& ch)
+{
+ if (ACE_OS::strcmp (this->encoding_, ACE_TEXT ("UTF-8")) == 0)
+ return this->getchar_i (ch);
+
+ int BE = (ACE_OS::strcmp (this->encoding_,
+ ACE_TEXT ("UTF-16BE")) == 0) ? 1 : 0;
+ ACEXML_Char input[2];
+ int i = 0;
+ for (; i < 2 && (this->getchar_i (input[i]) == 0); ++i)
+ ;
+ if (i < 2)
+ {
+ ch = 0;
+ return -1;
+ }
+ ch = BE ? input[0] << 8 | input[1] : input[1] << 8 | input[0];
+ return 0;
+}
+
+int
+ACEXML_ZipCharStream::peek_i (void)
+{
+ // If we are reading a UTF-8 encoded file, just use the plain unget.
+ if (ACE_OS::strcmp (this->encoding_, ACE_TEXT ("UTF-8")) == 0)
+ return this->peekchar_i();
+
+ // Peek into the stream. This reads two characters off the stream, keeps
+ // it in peek_.
+ int BE = (ACE_OS::strcmp (this->encoding_,
+ ACE_TEXT ("UTF-16BE")) == 0) ? 1 : 0;
+
+ ACEXML_Char input[2];
+ int i = 0;
+ for (; i < 2 && (input[i] = this->peekchar_i (i)); ++i)
+ ;
+ if (i < 2)
+ return -1;
+ return (BE ? input[0] << 8 | input[1] : input[1] << 8 | input[0]);
+}
+#endif /* ACE_USES_WCHAR */