📄 sofp_03.cc
字号:
// file: $isip/class/io/SofParser/sofp_03.cc// version: $Id: sofp_03.cc,v 1.9 2002/12/17 16:35:30 parihar Exp $//// isip include files//#include "SofParser.h"#include <MemoryManager.h>// method: load//// arguments:// Sof& sof: (input) an Sof file// long size: (input) number of bytes to parse within Sof object//// return: a boolean value indicating status//// this method loads the parameters from the Sof object. it assumes// that the Sof file is already positioned correctly to read the// object in question.//boolean SofParser::load(Sof& sof_a, long size_a) { // check argument // if (!sof_a.isOpen()) { return Error::handle(name(), L"load - sof file is not open", Error::READ_CLOSED, __FILE__, __LINE__, Error::WARNING); } // if it's not text, return // if (!sof_a.isText()) { return true; } // initialize the flag to keep track of load errors. note that this // flag will be reset to false before we exit this method. // load_error_d = false; // FULL_OBJECT is a flag to read the whole object // if (size_a == FULL_OBJECT) { // position the Sof object to the beginning of the current object // if (!sof_a.rewind()) { return Error::handle(name(), L"load - cannot position the sof object to the beginning of the current object", Error::SEEK, __FILE__, __LINE__, Error::WARNING); } // get the object size // size_a = sof_a.getObjectSize(); } // now error check the size argument // if (size_a <= 0) { return Error::handle(name(), L"load - number of bytes to parse within Sof object is less than or equal to zero", Error::ARG, __FILE__, __LINE__); } // save the position & size of our file space // base_position_d = sof_a.tell(); full_size_d = size_a; // initialize FSM // state_d = NO_GPI; open_index_d = true; implicit_block_d = false; statement_term_d = -1; block_count_d = 0; is_token_d = false; if (!implicit_object_d) { param_d = SofSymbolTable::NO_SYMB; statement_asgn_d = -1; } long parsed_length = 0; // initialize memory // byte buffer[MAX_BUFFER_SIZE+1]; MemoryManager::memset(buffer, 0, MAX_BUFFER_SIZE+1*sizeof(byte)); unichar ubuf[MAX_BUFFER_SIZE+1]; MemoryManager::memset(ubuf, 0, MAX_BUFFER_SIZE+1*sizeof(unichar)); long read_size = 0; long nchars_pass = 0; // all positions are with respect to the beginning of the entry // long base_pos = 0; // in case there is a partial statement from the last read, use this // as an offset into the current buffer. So available new data // should be read starting at this point into the buffer // long size_left = 0; // compute the number of bytes to read in this pass // if (size_a > (MAX_BUFFER_SIZE - size_left)) { read_size = (MAX_BUFFER_SIZE - size_left); size_a -= read_size; } else { read_size = size_a; size_a = 0; } while (read_size > 0) { // clear out the buffer. note that characters 0-size_left are // preserved from the previous loop run. // MemoryManager::memset(&buffer[size_left], 0, MAX_BUFFER_SIZE - size_left); // read in a buffer of data // nchars_pass = sof_a.read(&buffer[size_left],sizeof(byte),read_size); // make sure we read as many characters as we think we should. we // are in the middle of an Sof file, so we should not hit an EOF. // if (nchars_pass != read_size) { load_error_d = false; return Error::handle(name(), L"load - number of characters read so far is not equal to the amount that must be read", Error::READ, __FILE__, __LINE__, Error::WARNING); } buffer[size_left + read_size] = (byte)NULL; // convert the buffer into unicode characters // SysString str; str.assign(buffer); if (debug_level_d > Integral::DETAILED) { str.debug(L"buffer string"); } str.getBuffer(ubuf, read_size + size_left + 1); // parse this buffer of data // unichar* buffer_pos = ubuf; // increase the number of characters to parse by the number we just read in // size_left += nchars_pass; nchars_pass = size_left; // after calling preParse, // // o parsed_length will return the number of "output" characters // o the buffer pointed to by buffer_pos will be updated in place // with the parser output, characters 0-parsed_length are valid output // o note a maximum of size_left characters will be examined by the parser // o the final argument is an integer index used to obtain // absolute file positions in the indeces // while (preParse(parsed_length, buffer_pos, size_left, base_pos + ((long)buffer_pos - (long)ubuf) / sizeof(unichar))) { if (debug_level_d >= Integral::DETAILED) { // save the last char // unichar tchar = buffer_pos[parsed_length]; buffer_pos[parsed_length] = (unichar)NULL; SysString temp((unichar*)buffer_pos); temp.debug(L"this was parsed"); buffer_pos[parsed_length] = tchar; } // if we hit a param, add it to the table // if (param_d >= 0) { if (!index_d.add(param_d, BASE_TAG, statement_asgn_d, statement_term_d - statement_asgn_d + 1)) { load_error_d = false; return Error::handle(name(), L"load - unable to add the parameter to the table", SofList::ERR, __FILE__, __LINE__, Error::WARNING); } } else { break; } // increment the counters // buffer_pos += (statement_term_d + sizeof(byte) - base_pos - ((long)buffer_pos - (long)ubuf) / sizeof(unichar)); size_left = nchars_pass - ((long)buffer_pos-(long)ubuf)/sizeof(unichar); // reset the state machine // statement_asgn_d = -1; statement_term_d = -1; token_count_d = 0; param_d = -1; state_d = NO_GPI; parsed_length = 0; str.assign(buffer_pos); if (debug_level_d >= Integral::DETAILED) { str.debug(L"remaining buffer string"); } } // check for symbol table error // if ((statement_asgn_d != -1) && (param_d < 0)) { load_error_d = false; return Error::handle(name(), L"load - symbol table error", SofSymbolTable::ERR, __FILE__, __LINE__, Error::WARNING); } // check for a partial parse // if (param_d != SofSymbolTable::NO_SYMB) { // if the param_d is set, then it hit an assignment operator. we // just need to throw more data at it until it hits a terminal. // // statement_asgn_d += base_pos // + ((long)buffer_pos - (long)ubuf) / sizeof(unichar); size_left = 0; } else { // the name might be split across the end of the buffer, so // shift it back to the beginning and reset state machine. note // that we need to place the "output" back onto the char* // buffer, not ubuf. // size_left = parsed_length; SysString leftover; leftover.assign(buffer_pos); leftover.getBuffer(buffer, size_left+1); state_d = NO_GPI; } // compute the size of the next pass // if (size_a > (MAX_BUFFER_SIZE - size_left)) { read_size = (MAX_BUFFER_SIZE - size_left); size_a -= read_size; } else { read_size = size_a; size_a = 0; } // the nchars_pass variable is not corrupted in the loop // base_pos += (nchars_pass - size_left); } // initialize used array // if (table_d.getCount() > used_size_d) { if (used_d != (boolean*)NULL) { delete [] used_d; } used_size_d = table_d.getCount(); used_d = new boolean[used_size_d]; memset(used_d, 0, used_size_d * sizeof(boolean)); } if (debug_level_d >= Integral::DETAILED) { debug(L"after loading"); } if (load_error_d) { load_error_d = false; return Error::handle(name(), L"load", ERR, __FILE__, __LINE__, Error::WARNING); } // exit gracefully // return true;}// method: read//// arguments:// SysString& value: (output) data read from file// Sof& sof: (input) sof object from which to read// long size: (input) maximum amount of data to return//// return: a boolean value indicating status//// this function reads text data from the file//boolean SofParser::read(SysString& value_a, Sof& sof_a, long size_a) { // if it's not text, return // if (!sof_a.isText()) { return Error::handle(name(), L"read - attempting to read non-text data from file", Error::ARG, __FILE__, __LINE__); } // seek to the begining of the current object // // sof_a.seek(index_d.getPosition(), File::POS); // range check size // if (size_a == FULL_OBJECT) { size_a = full_size_d; } if (debug_level_d >= Integral::BRIEF) { SysString output; SysString numeric; output.assign(L"reading from "); numeric.assign(sof_a.tell()); output.concat(numeric); output.concat(L" to "); numeric.assign((long)(size_a + sof_a.tell())); output.concat(numeric); Console::put(output); } // read in the data // byte buffer[size_a + 1]; if (sof_a.read(buffer, sizeof(byte), size_a) != size_a) { return Error::handle(name(), L"read - unable to read buffer form sof object", Error::READ, __FILE__, __LINE__, Error::WARNING); } buffer[size_a] = (byte)NULL; // we need to deal with the data as unichar characters // unichar ubuf[size_a + 1]; MemoryManager::memset(ubuf, 0, sizeof(unichar) * (size_a + 1)); SysString str; str.assign((byte*)buffer, size_a + 1); if (debug_level_d >= Integral::BRIEF) { str.debug(L"reading this string"); } str.getBuffer(ubuf, size_a + 1); long length = -1; // pre-parse the data // state_d = NO_GPI; // reset the state machine statement_asgn_d = 1; // prevent us picking up any more '=' chars open_index_d = false; // don't add to the index if (!preParse(length, (unichar*)ubuf, size_a, 0)) { return Error::handle(name(), L"read - error parsing rvalue", ERR_RVALUE, __FILE__, __LINE__, Error::WARNING); } ubuf[length] = (unichar)NULL; // reset the machine // state_d = NO_GPI; statement_asgn_d = -1; statement_term_d = -1; value_a.assign(ubuf); if (debug_level_d >= Integral::BRIEF) { value_a.debug(L"after read, parsed this string"); } // make sure we are returning a valid string. the delimiter // character or the terminator character can be terminated in the // preParse function. so, both length and (length-1) are valid. // if ((value_a.length() < (length-1)) || (value_a.length() > length)) { return Error::handle(name(), L"read - error parsing rvalue", ERR_RVALUE, __FILE__, __LINE__, Error::WARNING); } if (debug_level_d >= Integral::BRIEF) { value_a.debug(L"returning this string"); } // exit gracefully // return true;}// method: reset//// arguments: none//// return: a boolean value indicating status//// this method resets the class for a new parse.//boolean SofParser::reset() { // reset the list and symbol table // index_d.clear(); table_d.clear(); // initialize all variables // state_d = NO_GPI; param_d = SofSymbolTable::NO_SYMB; block_count_d = 0; token_count_d = 0; statement_asgn_d = -1; statement_term_d = -1; statement_last_token_d = -1; base_position_d = 0; full_size_d = FULL_OBJECT; open_index_d = false; implicit_object_d = false; implicit_block_d = false; is_token_d = false; // exit gracefully // return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -