00001
00012 #ifndef __NMEStyleCpp__
00013 #define __NMEStyleCpp__
00014
00015 #if defined(UseNMECppException)
00016
00017 # undef UseNMECppException
00018 # include "NMECpp.h"
00019 # define UseNMECppException
00020
00021 # include "NMEErrorCpp.h"
00022 #else
00023 # include "NMECpp.h"
00024 #endif
00025
00026 #include "NMEStyle.h"
00027
00030 class NMELinkHandler
00031 {
00032 public:
00037 virtual void click(NMEConstText link, NMEInt linkLength) = 0;
00038 };
00039
00051 class NMEStyle: public NME
00052 {
00053 public:
00054
00057 NMEStyle(): NME()
00058 {
00059 styleTable = NULL;
00060 }
00061
00067 NMEStyle(char const *input, int inputLength = -1): NME(input, inputLength)
00068 {
00069 styleTable = NULL;
00070 }
00071
00075 NMEStyle(NMEStyle const &nme): NME(nme)
00076 {
00077 unicodeStyleOffsets = nme.unicodeStyleOffsets;
00078 if (nme.styleTable)
00079 {
00080 format.parHookFun = format.spanHookFun = NMEStyleSpanHook;
00081 styleTableSize = nme.styleTableSize;
00082 styleTable = (NMEStyleTable *) new char[styleTableSize];
00083 NMEStyleInit(styleTable, styleTableSize,
00084 unicodeStyleOffsets);
00085 styleTable->n = nme.styleTable->n;
00086 int i;
00087 for (i = 0; i < styleTable->n; i++)
00088 styleTable->span[i] = nme.styleTable->span[i];
00089 format.hookData = (void *)styleTable;
00090 }
00091 else
00092 styleTable = NULL;
00093 }
00094
00096 ~NMEStyle()
00097 {
00098 if (styleTable)
00099 delete [] (char *)styleTable;
00100 }
00101
00106 NMEStyle NMEStyle::operator = (NMEStyle const &nme)
00107 {
00108 if (this != &nme)
00109 {
00110 NME::operator = (nme);
00111 if (styleTable)
00112 delete [] (char *)styleTable;
00113 if (nme.styleTable)
00114 {
00115 format.parHookFun = format.spanHookFun = NMEStyleSpanHook;
00116 styleTableSize = nme.styleTableSize;
00117 styleTable = (NMEStyleTable *) new char[styleTableSize];
00118 NMEStyleInit(styleTable, styleTableSize,
00119 unicodeStyleOffsets);
00120 styleTable->n = nme.styleTable->n;
00121 int i;
00122 for (i = 0; i < styleTable->n; i++)
00123 styleTable->span[i] = nme.styleTable->span[i];
00124 format.hookData = (void *)styleTable;
00125 }
00126 else
00127 styleTable = NULL;
00128 }
00129 return *this;
00130 }
00131
00136 void setUnicodeStyleOffsets(bool unicodeStyleOffsets = true)
00137 {
00138 this->unicodeStyleOffsets = unicodeStyleOffsets;
00139 }
00140
00146 NMEErr getOutput(NMEConstText *output, NMEInt *outputLength = NULL)
00147 {
00148 if (!styleTable)
00149 {
00150 format.parHookFun = format.spanHookFun = NMEStyleSpanHook;
00151 styleTableSize = sizeof(NMEStyleTable) + inputLength;
00152 styleTable = (NMEStyleTable *) new char[styleTableSize];
00153 NMEStyleInit(styleTable, styleTableSize,
00154 unicodeStyleOffsets);
00155 format.hookData = (void *)styleTable;
00156 }
00157
00158 for (;;)
00159 {
00160 NMEErr err = NME::getOutput(output, outputLength);
00161 if (err == kNMEErrOk)
00162 break;
00163 else if (err == (NMEErr)kNMEErrStyleTableTooSmall)
00164 {
00165 if (styleTableSize >= 65536 + 10 * inputLength)
00166 #if defined(UseNMECppException)
00167 throw NMEError((NMEErr)kNMEErrStyleTableTooSmall);
00168 #else
00169 return (NMEErr)kNMEErrStyleTableTooSmall;
00170 #endif
00171 delete [] (char *)styleTable;
00172 styleTableSize *= 2;
00173 styleTable = (NMEStyleTable *) new char[styleTableSize];
00174 NMEStyleInit(styleTable, styleTableSize,
00175 unicodeStyleOffsets);
00176 format.hookData = (void *)styleTable;
00177 }
00178 else
00179 #if defined(UseNMECppException)
00180 throw NMEError(err);
00181 #else
00182 return err;
00183 #endif
00184 }
00185
00186 return kNMEErrOk;
00187 }
00188
00192 NMEStyleTable const *getStyleTable()
00193 {
00194
00195 if (!output)
00196 if (getOutput(NULL) != kNMEErrOk)
00197 {
00198
00199 NMEStyleInit(styleTable, styleTableSize,
00200 unicodeStyleOffsets);
00201 return NULL;
00202 }
00203 return styleTable;
00204 }
00205
00213 NMEBoolean handleLinkClick(NMEInt offset, NMELinkHandler *handler)
00214 {
00215
00216 if (!styleTable)
00217 (void)getOutput(NULL);
00218 if (styleTable)
00219 {
00220 NMEInt i;
00221
00222 for (i = 0; i < styleTable->n; i++)
00223 if (styleTable->span[i].style == kNMEStyleCharLink
00224 && offset >= styleTable->span[i].begin
00225 && offset < styleTable->span[i].end)
00226 {
00227 if (handler)
00228 handler->click(input + styleTable->span[i].linkOffset,
00229 styleTable->span[i].linkLength);
00230 return TRUE;
00231 }
00232 }
00233
00234 return FALSE;
00235 }
00236
00237 private:
00238
00239 bool unicodeStyleOffsets;
00240 NMEStyleTable *styleTable;
00241 NMEInt styleTableSize;
00242 };
00243
00244 #endif