1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
|
/*
//
// Copyright 1997-2009 Torsten Rohlfing
//
// Copyright 2004-2013 SRI International
//
// This file is part of the Computational Morphometry Toolkit.
//
// http://www.nitrc.org/projects/cmtk/
//
// The Computational Morphometry Toolkit is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// The Computational Morphometry Toolkit is distributed in the hope that it
// will be useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with the Computational Morphometry Toolkit. If not, see
// <http://www.gnu.org/licenses/>.
//
// $Revision: 5436 $
//
// $LastChangedDate: 2018-12-10 19:01:20 -0800 (Mon, 10 Dec 2018) $
//
// $LastChangedBy: torstenrohlfing $
//
*/
#ifndef __cmtkTypedStream_h_included_
#define __cmtkTypedStream_h_included_
#include <cmtkconfig.h>
#include <Base/cmtkTypes.h>
#include <stack>
#include <stdio.h>
#include <zlib.h>
#ifndef NULL
#define NULL 0
#endif
#include <string>
namespace
cmtk
{
/** \addtogroup IO */
//@{
/**\name TypedStream.h
*/
//@{
/** base class for reading and writing of "typedstream" archives.
*/
class TypedStream
{
public:
/// This class.
typedef TypedStream Self;
/// Condition upon function return.
typedef enum
{
/// There was an error.
CONDITION_ERROR,
/// No error encountered; operation completed successfully.
CONDITION_OK
} Condition;
/// Classes of error conditions
typedef enum
{
/// No error.
ERROR_NONE,
/// Unknown error.
ERROR_UNKNOWN,
/** A call to a system function returned an error condition.
* To find out more details, "errno" may be consulted.
*/
ERROR_SYSTEM,
/** Error in the format of the open archive.
*/
ERROR_FORMAT,
/** Wrong or invalid arguments given to a function.
*/
ERROR_ARG,
/** The requested operation is not available in the current stream mode.
* This usually means that a write access was requested on a read-only
* archive or a Seek() operation on a write-only archive.
*/
ERROR_MODE,
/** Error in a primitive data object.
* A value in the archive does not have the correct syntax for the expected
* type.
*/
ERROR_TYPE,
/** An internal limit was exhausted.
* As we are now using a proper STL stack for keeping track of open levels,
* this condition should not occur any more.
*/
ERROR_LIMIT,
/** Close of a level was requested when none was open.
*/
ERROR_LEVEL,
/** The current stream is invalid.
* This condition is set when an access is tried without opening a file
* first.
*/
ERROR_INVALID,
ERROR_MAX
} Status;
/// Identifiers for supported primitive data types.
typedef enum
{
/// Interger.
TYPE_INT,
/// Boolean (Yes/No).
TYPE_BOOL,
/// Binary boolean (0/1).
TYPE_BINARYBOOL,
/// Single-precision float.
TYPE_FLOAT,
/// Double-precision float
TYPE_DOUBLE,
/// String (char*).
TYPE_STRING
} Type;
/// Identifiers for tokens in archives.
typedef enum
{
/// End-of-file.
TOKEN_EOF,
/// Section beginning "{".
TOKEN_BEGIN,
/// Section end "}".
TOKEN_END,
/// Key (field name).
TOKEN_KEY,
/// Field value.
TOKEN_VALUE,
/// Comment.
TOKEN_COMMENT
} Token;
/// Debug flag values.
typedef enum
{
/// There was an error.
DEBUG_OFF,
/// No error encountered; operation completed successfully.
DEBUG_ON
} DebugFlag;
/// Default constructor.
TypedStream();
/** Return validity of archive.
*\return 1 if an archive is currently open, 0 if not.
*/
int IsValid()
{
return (this->File != NULL) || (this->GzFile != NULL);
}
/** Return status of last operation.
*/
Self::Status GetStatus() const
{
return this->m_Status;
}
/// Set debugging flag.
void SetDebugFlag( const Self::DebugFlag debugFlag = Self::DEBUG_ON /*!< Set the debug flag to this value. */ )
{
this->m_DebugFlag = debugFlag;
}
protected:
/// Internal: Length of the read buffer for one archive line.
static const int LIMIT_BUFFER = 1024;
/// Pointer to the actual file.
FILE *File;
/// Pointer to the compressed file in decompression mode.
gzFile GzFile;
/** Holds the status of the last operation.
*/
Self::Status m_Status;
/** Number of significant digits for "float" fields.
* As all float numbers are written to the archive as strings, part of the
* native resolution is lost. This field determines, how many significant
* digits are preserved when converting single precision float numbers to
* strings.
*/
int PrecisionFloat;
/** Number of significant digits for "double" fields.
* As all float numbers are written to the archive as strings, part of the
* native resolution is lost. This field determines, how many significant
* digits are preserved when converting double precision float numbers to
* strings.
*/
int PrecisionDouble;
/// Buffer for the current line read from the archive.
char Buffer[Self::LIMIT_BUFFER];
/// Pointer to the "key" part of the line currently in Buffer.
char* BufferKey;
/// Pointer to the "value" part of the line currently in Buffer.
char* BufferValue;
/** Stack of open section levels.
* This stack holds the starting positions of all currently open sections.
* The entries are byte positions relative to the beginning of the file.
*/
std::stack<int> LevelStack;
/** Compare two strings.
* Other than the standard library's strcmp() function, this implementation
* ignores upper and lowercase. Also, strings are terminated by either NULL
* characters or any white space or newline.
*\return 0 for identical strings (up to upper-/lowercase), 1 for
* non-identical strings.
*/
static int StringCmp( const char* s1, const char* s2 );
/** Separate next token.
* This function identifies the next token in the given string, sets a NULL
* character to mark its end and returns a pointer to the token's first
* character. The state between calls is saved in the "SplitPosition" field.
* Calling the function with NULL as a parameter resets the internal state.
*/
char* StringSplit( char* s1 /*!< String to split into tokens. */ ) const;
/// Internal position pointer for "StringSplit()".
mutable char* SplitPosition;
/** Return the identifier for the generated archive format (version).
* This is the earliest CMTK version that can read this archive properly.
*/
static const char* GetTypedStreamIdent()
{
return "! TYPEDSTREAM 2.4\n";
}
/// Debug flag.
Self::DebugFlag m_DebugFlag;
/// Output diagnostic message if debug flag is set.
void DebugOutput( const char* format /*!< printf-style format string for the remaining variable number of function arguments.*/, ... );
};
//@}
} // namespace cmtk
//@}
#endif // #ifndef __cmtkTypedstream_h_included_
|