summaryrefslogtreecommitdiff
path: root/Build/source/libs/teckit/TECkit-src/SFconv/sfReader.h
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/teckit/TECkit-src/SFconv/sfReader.h')
-rw-r--r--Build/source/libs/teckit/TECkit-src/SFconv/sfReader.h234
1 files changed, 234 insertions, 0 deletions
diff --git a/Build/source/libs/teckit/TECkit-src/SFconv/sfReader.h b/Build/source/libs/teckit/TECkit-src/SFconv/sfReader.h
new file mode 100644
index 00000000000..9576b2d31b7
--- /dev/null
+++ b/Build/source/libs/teckit/TECkit-src/SFconv/sfReader.h
@@ -0,0 +1,234 @@
+#include <string>
+#include <cstdio>
+
+#include "ushort_chartraits.h"
+
+#define END_OF_FILE -1
+#define BODY_TEXT 0
+#define SFM 1
+#define INLINE_START 2
+#define INLINE_END 3
+#define INLINE_MARKER 4
+
+template<class C>
+class sfReader
+{
+public:
+ typedef std::basic_string<C> stringT;
+ typedef std::char_traits<C> traitsT;
+
+ sfReader(std::FILE* inFile, char inForm = kForm_Bytes);
+ ~sfReader();
+
+ long escapeChar;
+ long inlineEscapeChar;
+ long startInline;
+ long endInline;
+
+ stringT sfmChars;
+ stringT inlineChars;
+
+ int next(bool checkInlineEnd);
+
+ stringT text;
+
+protected:
+ long get();
+ void putback(long c);
+
+ long fSavedChar;
+
+ char inForm;
+
+ std::FILE* inFile;
+};
+
+template<class C>
+sfReader<C>::sfReader(std::FILE* f, char i)
+ : inForm(i)
+ , inFile(f)
+{
+ escapeChar = '\\';
+ inlineEscapeChar = -1;
+ startInline = -1;
+ endInline = -1;
+
+ text.reserve(10000);
+ fSavedChar = -1;
+}
+
+template<class C>
+sfReader<C>::~sfReader()
+{
+}
+
+template<> long
+sfReader<char>::get()
+{
+ long rval = fSavedChar;
+ if (rval == -1)
+ rval = getc(inFile);
+ else
+ fSavedChar = -1;
+ return rval;
+}
+
+static char bytesFromUTF8[256] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5};
+static unsigned long offsetsFromUTF8[6] =
+ {0x00000000UL, 0x00003080UL, 0x000E2080UL,
+ 0x03C82080UL, 0xFA082080UL, 0x82082080UL};
+/*
+const unsigned long kReplacementCharacter = 0x0000FFFDUL;
+const unsigned long kMaximumUCS2 = 0x0000FFFFUL;
+const unsigned long kMaximumUTF16 = 0x0010FFFFUL;
+const unsigned long kMaximumUCS4 = 0x7FFFFFFFUL;
+*/
+const int halfShift = 10;
+const unsigned long halfBase = 0x0010000UL;
+const unsigned long halfMask = 0x3FFUL;
+const unsigned long kSurrogateHighStart = 0xD800UL;
+const unsigned long kSurrogateHighEnd = 0xDBFFUL;
+const unsigned long kSurrogateLowStart = 0xDC00UL;
+const unsigned long kSurrogateLowEnd = 0xDFFFUL;
+
+template<> long
+sfReader<UniChar>::get()
+{
+ if (fSavedChar != -1) {
+ long rval = fSavedChar;
+ fSavedChar = -1;
+ return rval;
+ }
+ long c1 = getc(inFile);
+ if (c1 == -1)
+ return -1;
+ else {
+ if (inForm == kForm_UTF8) {
+ long t1, t2 = -1;
+ unsigned long ch = c1;
+ unsigned short extraBytes = bytesFromUTF8[c1];
+ long c2;
+ switch(extraBytes) { /* note: code falls through cases! */
+ case 5: c2 = getc(inFile); if (c2 == -1) return -1; ch <<= 6; ch += c2;
+ case 4: c2 = getc(inFile); if (c2 == -1) return -1; ch <<= 6; ch += c2;
+ case 3: c2 = getc(inFile); if (c2 == -1) return -1; ch <<= 6; ch += c2;
+ case 2: c2 = getc(inFile); if (c2 == -1) return -1; ch <<= 6; ch += c2;
+ case 1: c2 = getc(inFile); if (c2 == -1) return -1; ch <<= 6; ch += c2;
+ case 0: ;
+ };
+ ch -= offsetsFromUTF8[extraBytes];
+ if (ch <= UNI_MAX_BMP) {
+ t1 = ch;
+ } else if (ch > UNI_MAX_UTF16) {
+ t1 = UNI_REPLACEMENT_CHAR;
+ } else {
+ ch -= halfBase;
+ t1 = (ch >> halfShift) + kSurrogateHighStart;
+ t2 = (ch & halfMask) + kSurrogateLowStart;
+ }
+ fSavedChar = t2;
+ return t1;
+ }
+ else {
+ long c2 = getc(inFile);
+ if (c2 == -1)
+ return -1;
+ if (inForm == kForm_UTF16BE)
+ return (c1 << 8) + c2;
+ else
+ return (c2 << 8) + c1;
+ }
+ }
+}
+
+template<class C>
+void
+sfReader<C>::putback(long c)
+{
+ fSavedChar = c;
+}
+
+template<class C>
+int
+sfReader<C>::next(bool checkInlineEnd)
+{
+ const long eof = traitsT::eof();
+ long c = get();
+ if (c == eof)
+ return END_OF_FILE;
+
+ text.clear();
+
+ if (c == escapeChar) {
+ while (1) {
+ c = get();
+ if (c == eof) {
+ return SFM;
+ }
+ if (sfmChars.find(c, 0) != stringT::npos) {
+ text.append(1, c);
+ }
+ else if (text.length() == 0) {
+ text.append(1, c);
+ return SFM;
+ }
+ else {
+ putback(c);
+ return SFM;
+ }
+ }
+ }
+
+ if (c == inlineEscapeChar) {
+ while (1) {
+ c = get();
+ if (c == eof) {
+ return INLINE_MARKER;
+ }
+ if (inlineChars.find(c, 0) != stringT::npos)
+ text.append(1, c);
+ else if (text.length() == 0) {
+ text.append(1, c);
+ c = get();
+ if (c == startInline)
+ return INLINE_START;
+ else {
+ putback(c);
+ return INLINE_MARKER;
+ }
+ }
+ else {
+ if (c == startInline)
+ return INLINE_START;
+ else {
+ putback(c);
+ return INLINE_MARKER;
+ }
+ }
+ }
+ }
+
+ if (checkInlineEnd && c == endInline) {
+ return INLINE_END;
+ }
+
+ // must be "junk" before the first SFM
+ text.append(1, c);
+
+ while (1) {
+ c = get();
+ if (c == eof || c == escapeChar || c == inlineEscapeChar || (checkInlineEnd && c == endInline)) {
+ putback(c);
+ return BODY_TEXT;
+ }
+ text.append(1, c);
+ }
+}