00001 /* $NoKeywords: $ */ 00002 /* 00003 // 00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved. 00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert 00006 // McNeel & Associates. 00007 // 00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. 00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF 00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED. 00011 // 00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>. 00013 // 00015 */ 00016 00017 #if !defined(OPENNURBS_BASE64_INC_) 00018 #define OPENNURBS_BASE64_INC_ 00019 00021 00022 class ON_CLASS ON_Base64EncodeStream 00023 { 00024 public: 00025 ON_Base64EncodeStream(); 00026 virtual ~ON_Base64EncodeStream(); 00027 00028 /* 00029 Description: 00030 ON_Base64EncodeStream delivers the base64 encoded stream by 00031 calling a base64 encoded stream output handler function. 00032 There are two options for specifying the base64 encoded stream 00033 output handler function. 00034 1. Overriding the virtual Out() function. 00035 2. Providing a callback function. 00036 SetCallback() is used to specify a callback function to handle 00037 the base64 encoded stream and to specify a context pointer to be 00038 passed to either option of the handler. 00039 Parameters: 00040 callback_function - [in] 00041 Function to handle sections of the base64 encoded stream. 00042 If callback_function is null, then the virtual Out() 00043 function will be called. When callback_function 00044 is specified, it must return true if the base64 encoding 00045 calculation should continue and false to cancel the 00046 base64 encoding calculation. 00047 callback_context - [in] 00048 This value is passed as the first argument when calling 00049 callback_function or the virutal Out() function. 00050 Returns: 00051 True if successful. 00052 Remarks: 00053 Once base64 encoding has started, it would be unusual to 00054 intentionally change the base64 encoded stream output handler, 00055 but you can do this if you need to. 00056 */ 00057 bool SetCallback( 00058 ON_StreamCallbackFunction callback_function, 00059 void* callback_context 00060 ); 00061 00062 /* 00063 Returns: 00064 Current value of the callback function for handling 00065 the base64 encoded stream. If the callback function is 00066 null, the the virtual Out() function is used to 00067 handle the output stream. 00068 */ 00069 ON_StreamCallbackFunction CallbackFunction() const; 00070 00071 /* 00072 Returns: 00073 Current value of the context pointer passed as the first 00074 argument to the base64 encoded stream output handler function. 00075 */ 00076 void* CallbackContext() const; 00077 00078 /* 00079 Description: 00080 Call Begin() one time to initialize the base64 encoding 00081 calculation. Then call In() one or more times 00082 to submit the unencoded stream to the base64 encoding 00083 calculation. When you reach the end of the unencoded 00084 stream, call End(). 00085 Returns: 00086 true if successful, false if an error occured. 00087 */ 00088 bool Begin(); 00089 00090 00091 /* 00092 Description: 00093 Call In() one or more times to base64 encode a stream of bytes. 00094 After the last call to In(), call End(). Calling In() will 00095 result in at least in_buffer_size/57 and at most 00096 (in_buffer_size+56)/57 calls to to the output stream handler. 00097 Parameters: 00098 in_buffer_size - [in] 00099 number of bytes in in_buffer 00100 in_buffer - [in] 00101 Returns: 00102 true if successful, false if an error occured. 00103 */ 00104 bool In( 00105 ON__UINT64 in_buffer_size, 00106 const void* in_buffer 00107 ); 00108 00109 /* 00110 Description: 00111 If an explicit base 64 encoded stream output handler is not 00112 specified ( CallbackFunction() returns null ), then the 00113 virtual Out() function is called to handle the base 64 encoded 00114 output stream. As the input stream is encoded, one or more 00115 calls to Out() will occur. 00116 00117 With a possible exception of the last call to Out(), when Out() 00118 is called, 57 input bytes have been encoded into 76 output 00119 characters with ASCII codes A-Z, a-z, 0-9, +, /. 00120 Parameters: 00121 callback_context - [in] 00122 context pointer set by calling SetCallback(). Typically 00123 the context pointer is not used by a virtual override 00124 because the context can be added as member variables 00125 of the derived class, but it is available if needed. 00126 out_buffer_size - [in] 00127 number of non-null characters in out_buffer. 00128 out_buffer - [in] 00129 A null terminated ASCII string that is a base 64 encoding. 00130 out_buffer[0...(out_buffer_size-1)] are ASCII characters with 00131 values characters with ASCII codes A-Z, a-z, 0-9, +, / 00132 and out_buffer[out_buffer_size] = 0. 00133 Returns: 00134 True to continue base 64 encodeing and false to cancel the 00135 encoding calculation. 00136 */ 00137 virtual bool Out( 00138 void* callback_context, 00139 ON__UINT32 out_buffer_size, 00140 const char* out_buffer 00141 ); 00142 00143 /* 00144 Description: 00145 After the last call to In(), call End(). Calling End() may 00146 generate one call to the output stream handler with the value 00147 of out_buffer_size = 4 to 76. 00148 Returns: 00149 true if successful, false if an error occured. 00150 */ 00151 bool End(); 00152 00153 /* 00154 Returns: 00155 Then the returned value is the total number bytes in the input 00156 stream. The size is updated every time In() is called before 00157 any calls are made to the output stream handler. If the 00158 calculation is finished ( End() has been called ), then the 00159 returned value is the total number of bytes in the entire 00160 input stream. 00161 */ 00162 ON__UINT64 InSize() const; 00163 00164 /* 00165 Returns: 00166 Then the returned value is the total number characters in the 00167 output stream. The size is incremented immediately after each 00168 call to the output stream handler. If the base64 encoding 00169 calculation is finished ( End() has been called ), then the 00170 returned value is the total number of bytes in the entire 00171 output stream. 00172 */ 00173 ON__UINT64 OutSize() const; 00174 00175 /* 00176 Returns: 00177 Then the returned value is the 32-bit crc of the input stream. 00178 The crc is updated every time In() is called before any calls 00179 are made to the output stream handler. If the base64 encoding 00180 calculation is finished ( End() has been called ), then the 00181 returned value is the 32-bit crc of the entire input stream. 00182 */ 00183 ON__UINT32 InCRC() const; 00184 00185 /* 00186 Returns: 00187 Then the returned value is the 32bit crc of the output stream. 00188 The crc is updated immediately after each call to the output 00189 stream handler. If the calculation is finished ( End() has 00190 been called ), then the returned value is the 32-bit crc of 00191 the entire output stream. 00192 */ 00193 ON__UINT32 OutCRC() const; 00194 00195 private: 00196 ON_StreamCallbackFunction m_out_callback_function; 00197 void* m_out_callback_context; 00198 ON__UINT64 m_in_size; 00199 ON__UINT64 m_out_size; 00200 ON__UINT32 m_in_crc; 00201 ON__UINT32 m_out_crc; 00202 void* m_implementation; 00203 void* m_reserved; 00204 00205 void ErrorHandler(); 00206 00207 private: 00208 // prohibit use - no implementation 00209 ON_Base64EncodeStream(const ON_Base64EncodeStream&); 00210 ON_Base64EncodeStream& operator=(const ON_Base64EncodeStream&); 00211 }; 00212 00214 00215 class ON_CLASS ON_DecodeBase64 00216 { 00217 public: 00218 ON_DecodeBase64(); 00219 virtual ~ON_DecodeBase64(); 00220 00221 void Begin(); 00222 00223 // Decode will generate zero or more callbacks to the 00224 // virtual Output() function. If the base 64 encoded information 00225 // is in pieces, you can call Decode() for each piece. For example, 00226 // if your encoded information is in a text file, you might call 00227 // Decode() for every line in the file. Decode() returns 0 if 00228 // there is nothing in base64str to decode or if it detects an 00229 // error that prevents any further decoding. The function Error() 00230 // can be used to determine if an error occured. Otherwise, 00231 // Decode() returns a pointer to the location in the string where 00232 // it stopped decoding because it detected a character, like a null 00233 // terminator, an end of line character, or any other character 00234 // that could not be part of the base 64 encoded information. 00235 const char* Decode(const char* base64str); 00236 const char* Decode(const char* base64str, size_t base64str_count); 00237 const wchar_t* Decode(const wchar_t* base64str); 00238 const wchar_t* Decode(const wchar_t* base64str, size_t base64str_count); 00239 00240 // You must call End() when Decode() returns 0 or when you have 00241 // reached the end of your encoded information. End() may 00242 // callback to Output() zero or one time. If all the information 00243 // passed to Decode() was successfully decoded, then End() 00244 // returns true. If something was not decoded, then End() 00245 // returns false. 00246 bool End(); 00247 00248 // Override the virtual Output() callback function to process the 00249 // decoded output. Each time Output() is called there are m_output_count 00250 // bytes in the m_output[] array. 00251 // Every call to Decode() can result in zero, one, or many callbacks 00252 // to Output(). Calling End() may result in zero or one callbacks 00253 // to Output(). 00254 virtual void Output(); 00255 00256 // m_decode_count = total number of input base64 characters 00257 // that Decode() has decoded. 00258 unsigned int m_decode_count; 00259 00260 int m_output_count; // 0 to 512 00261 unsigned char m_output[512]; 00262 00263 // Call if your Output() function detects an error and 00264 // wants to stop further decoding. 00265 void SetError(); 00266 00267 // Returns true if an error occured during decoding because 00268 // invalid input was passed to Decode(). 00269 const bool Error() const; 00270 00271 private: 00272 int m_status; // 1: error - decoding stopped 00273 // 2: '=' encountered as 3rd char in Decode() 00274 // 3: successfully parsed "**==" 00275 // 4: successfully parsed "***=" 00276 // 5: End() successfully called. 00277 00278 // cached encoded input from previous call to Decode() 00279 int m_cache_count; 00280 int m_cache[4]; 00281 00282 void DecodeHelper1(); // decodes "**==" quartet into 1 byte 00283 void DecodeHelper2(); // decodes "***=" quartet into 2 bytes 00284 }; 00285 00286 00288 00289 00290 /* 00291 class ON_CLASS ON_EncodeBase64 00292 { 00293 public: 00294 ON_EncodeBase64(); 00295 virtual ~ON_EncodeBase64(); 00296 00297 void Begin(); 00298 00299 // Calling Encode will generate at least 00300 // sizeof_buffer/57 and at most (sizeof_buffer+56)/57 00301 // calls to Output(). Every callback to Output() will 00302 // have m_output_count = 76. 00303 void Encode(const void* buffer, size_t sizeof_buffer); 00304 00305 // Calling End may generate a single call to Output() 00306 // If it does generate a single call to Output(), 00307 // then m_output_count will be between 1 and 76. 00308 void End(); // may generate a single call to Output(). 00309 00310 // With a single exception, when Output() is called, 00311 // 57 input bytes have been encoded into 76 output 00312 // characters with ASCII codes A-Z, a-z, 0-9, +, /. 00313 // m_output_count will be 76 00314 // m_output[0...(m_output_count-1)] will be the base 64 00315 // encoding. 00316 // m_output[m_output_count] = 0. 00317 // The Output() function can modify the values of m_output[] 00318 // and m_output_count anyway it wants. 00319 virtual void Output(); 00320 00321 // Total number of bytes passed to Encode(). 00322 int m_encode_count; 00323 00324 // When the virtual Output() is called, there are m_output_count (1 to 76) 00325 // characters of base64 encoded output in m_output[]. The remainder of 00326 // the m_output[] array is zero. The Output function may modify the 00327 // contents of m_output[] any way it sees fit. 00328 int m_output_count; 00329 char m_output[80]; 00330 00331 private: 00332 // input waiting to be encoded 00333 // At most 56 bytes can be waiting to be processed in m_input[]. 00334 unsigned int m_unused2; // Here for alignment purposes. Never used by opennurbs. 00335 unsigned int m_input_count; 00336 unsigned char m_input[64]; 00337 00338 void EncodeHelper1(const unsigned char*, char*); 00339 void EncodeHelper2(const unsigned char*, char*); 00340 void EncodeHelper3(const unsigned char*, char*); 00341 void EncodeHelper57(const unsigned char*); 00342 }; 00343 */ 00344 00345 #endif