📄 sof_05.cc
字号:
// file: $isip/class/io/Sof/sof_05.cc// version: $Id: sof_05.cc,v 1.4 2000/11/21 19:50:11 duncan Exp $//// isip include files//#include "Sof.h"#include <Console.h>#include <MemoryManager.h>// method: readIndex//// arguments: none//// return: a boolean value indicating status//// this method reads the index// note: this needs to be able to compress the symbol table if necessary//boolean Sof::readIndex() { // read all the objects to the file in binary form // // the format: // 1 byte offset to the next entry // 4 byte position // 4 byte tag number // 4 byte size // 4 byte name index // // note that the size of 4 bytes is hardcoded for integers. This is // to facilitate the possibility of different word-length // architectures that will grow into the environment. // // for now we just read and write the information, upgrade this to // a true read/write of 4 byte info in the future. // byte entry_buffer[BUFFER_SIZE]; long buf_size = (long)-1; byte size = (byte)0; long ptr = (long)0; int32 object_tag = (int32)-1; int32 object_pos = (int32)-1; int32 object_size = (int32)-1; int32 object_name = (int32)-1; // use the lowest level read, since we decode things by hand // while((buf_size = fp_d.read(entry_buffer, sizeof(byte), BUFFER_SIZE)) > 0) { // increment position // cur_pos_d += buf_size * sizeof(byte); ptr = 0; // while we have the minimum number of bytes for an entry // while ((buf_size - ptr) >= INDEX_SIZE) { // the first byte of each entry is the size // size = entry_buffer[ptr + INDEX_OFFSET_NEXT]; // sanity check on the size // if (size < INDEX_SIZE) { return Error::handle(name(), L"readIndex", ERR_STRUCT, __FILE__, __LINE__, Error::WARNING); } // read the fields from the binary index // MemoryManager::memcpy(&object_pos, &entry_buffer[ptr+INDEX_OFFSET_POS], sizeof(int32)); MemoryManager::memcpy(&object_tag, &entry_buffer[ptr+INDEX_OFFSET_TAG], sizeof(int32)); MemoryManager::memcpy(&object_size,&entry_buffer[ptr+INDEX_OFFSET_SIZE], sizeof(int32)); MemoryManager::memcpy(&object_name,&entry_buffer[ptr+INDEX_OFFSET_NAME], sizeof(int32)); // determine the checksum of the entry // cksm_d.compute(&entry_buffer[ptr + INDEX_OFFSET_POS], 4 * sizeof(int32)); // set the fields in the index array // index_d.add((long)fp_d.decode(object_name), (long)fp_d.decode(object_tag), (long)fp_d.decode(object_pos), (long)fp_d.decode(object_size)); // increment the pointer // ptr += size; } } // exit gracefully // return true;}// method: writeIndex//// arguments: none//// return: a boolean value indicating status//// this method writes the index//boolean Sof::writeIndex() { // write all the objects to the file in binary form // // the format: // 1 byte offset to the next entry // 4 byte position // 4 byte tag number // 4 byte size // 4 byte name index // // note that the size of 4 bytes is hardcoded for integers. This is // to facilitate the possibility of different word-length // architectures that will grow into the environment. // // for now we just read and write the information, upgrade this to // a true read/write of 4 byte info in the future. // byte entry_buffer[BUFFER_SIZE]; MemoryManager::memset(entry_buffer, 0, BUFFER_SIZE); byte size = (byte)INDEX_SIZE; long ptr = (long)0; byte *last_size = &entry_buffer[INDEX_OFFSET_NEXT]; // loop through all classes // for (long cname = getNameCount() - 1; cname >= 0; cname--) { // loop through all instances of this class // for (long tag = index_d.first(cname); tag != NO_TAG; tag = index_d.next(cname, tag)) { // if we have a full buffer, write it // if ((ptr + INDEX_SIZE) > BUFFER_SIZE) { // increase last_size so that read will skip over empty pad // (*last_size) += (BUFFER_SIZE - ptr); // write the buffer (we don't want byte swapping, use lowest // level write). // if (fp_d.write(entry_buffer,sizeof(byte),BUFFER_SIZE) != BUFFER_SIZE) { return Error::handle(name(), L"writeIndex", Error::WRITE, __FILE__, __LINE__); } cur_pos_d += BUFFER_SIZE * sizeof(byte); // clear out the buffer and initialize pointer // MemoryManager::memset(entry_buffer, 0, BUFFER_SIZE); ptr = 0; } // encode values for this entry // int32 object_name = fp_d.encode((int32)cname); int32 object_tag = fp_d.encode((int32)tag); int32 object_pos = fp_d.encode((int32)index_d.getPosition()); int32 object_size = fp_d.encode((int32)index_d.getSize()); // build the binary index entry // MemoryManager::memcpy(&entry_buffer[ptr + INDEX_OFFSET_POS], &object_pos, sizeof(int32)); MemoryManager::memcpy(&entry_buffer[ptr + INDEX_OFFSET_TAG], &object_tag, sizeof(int32)); MemoryManager::memcpy(&entry_buffer[ptr + INDEX_OFFSET_SIZE], &object_size, sizeof(int32)); MemoryManager::memcpy(&entry_buffer[ptr + INDEX_OFFSET_NAME], &object_name, sizeof(int32)); entry_buffer[ptr + INDEX_OFFSET_NEXT] = (byte)size; // compute the checksum for this entry // cksm_d.compute(&entry_buffer[ptr+INDEX_OFFSET_POS], 4 * sizeof(int32)); // set the last size pointer for the next time around // last_size = &entry_buffer[ptr + INDEX_OFFSET_NEXT]; // increment pointer // ptr += INDEX_SIZE; } } // if there are entries left over, write them out // if (ptr > 0) { if (fp_d.write(entry_buffer, sizeof(byte), ptr) != ptr) { return Error::handle(name(), L"writeIndex", Error::WRITE, __FILE__, __LINE__); } cur_pos_d += ptr * sizeof(byte); } // exit gracefully // return true;}// method: readTable//// arguments: none//// return: a boolean value indicating status//// this method reads the symbol table. note how nasty such functions// are, dealing with low level byte ordering and such. This is why all// code people use is written ABOVE Sof.//boolean Sof::readTable() { // read all the objects to the file in binary form // // the format: // 1 byte offset to the next entry // 4 byte position // 4 byte tag number // <246 byte null terminated string for the name // // note that the size of 4 bytes is hardcoded for integers. This is // to facilitate the possibility of different word-length // architectures that will grow into the environment. // // for now we just read and write the information, upgrade this to // a true read/write of 4 byte info in the future. // byte entry_buffer[BUFFER_SIZE]; byte size = (byte)0; long ptr = (long)sizeof(int32); int32 buf_size; int32 num_classes = (int32)-1; int32 num = (int32)0; int32 object_index; int32 object_refs; byte* object_name; SysString name_str; int16 encoding_int; // this is unicode encoding, not byte order SysChar::ENCODE encoding; MemoryManager::memset(entry_buffer, 0, BUFFER_SIZE); // keep track of file position for error messages // long file_pos = ftell(); // the number of classes is the first thing in the table's binary space // cur_pos_d updated inside the do/while loop // buf_size = fp_d.read(entry_buffer, sizeof(byte), BUFFER_SIZE); MemoryManager::memcpy(&num_classes, entry_buffer, sizeof(int32)); // read what encoding we should read // MemoryManager::memcpy(&encoding_int, &entry_buffer[ptr], sizeof(int16)); ptr += sizeof(int16); // decode the values // num_classes = fp_d.decode(num_classes); encoding_int = fp_d.decode(encoding_int); encoding = (SysChar::ENCODE)encoding_int; if ((buf_size < ptr) || (num_classes < 0)) { return Error::handle(name(), L"readTable", ERR_STRUCT, __FILE__, __LINE__, Error::WARNING); } if (debug_level_d > Integral::BRIEF) { SysString output; output.assign((long)num_classes); output.insert(L"<Sof::readTable> Reading ", 0); output.concat(L" table entries"); Console::put(output); } // since we needed that first 4 bytes for the table size, we need to // use a do loop for the rest of the data. // do { // increment cur_pos // cur_pos_d += buf_size * sizeof(byte); while (((buf_size - ptr) >= SYMBOL_BASE) && (num < num_classes)) { // the first byte of each entry is the size // size = entry_buffer[ptr + SYMBOL_OFFSET_NEXT]; // sanity check on the size // if (size < SYMBOL_BASE) { return Error::handle(name(), L"readTable", ERR_STRUCT, __FILE__, __LINE__, Error::WARNING); } // read the fields from the binary index // MemoryManager::memcpy(&object_index, &entry_buffer[ptr + SYMBOL_OFFSET_IND], sizeof(int32)); MemoryManager::memcpy(&object_refs, &entry_buffer[ptr + SYMBOL_OFFSET_REFS], sizeof(int32)); object_name = &entry_buffer[ptr + SYMBOL_OFFSET_NAME]; // assign the name string // name_str.assign(object_name, SysString::BIG_BUFFER_LENGTH, encoding); // note that this is NOT UNICODE SAFE // long slen = name_str.length(); // compute the checksum // cksm_d.compute(&entry_buffer[ptr + SYMBOL_OFFSET_IND], 2 * sizeof(int32) + slen); // add the entry into the symbol table // table_d.add((long)fp_d.decode(object_index), (long)fp_d.decode(object_refs), name_str); // increment pointers and counters // ptr += size; num++; } // once we have the last entry, reset pointer // if (num < num_classes) { ptr = 0; } // keep reading data until we have all the classes read in // } while ((num < num_classes) && ((buf_size = fp_d.read(entry_buffer, sizeof(byte), BUFFER_SIZE)) > 0) && (file_pos = ftell())); // seek back to the end of the table // if (!fseek(ptr - buf_size, File::POS_PLUS_CUR)) { return Error::handle(name(), L"readTable", Error::SEEK, __FILE__, __LINE__, Error::WARNING); } // exit gracefully // return true;}// method: writeTable//// arguments: none//// return: a boolean value indicating status//// this method writes the symbol table. note how nasty such functions// are, dealing with low level byte ordering and such. This is why all// code people use is written ABOVE Sof.//boolean Sof::writeTable() { // write the symbol table to the file // // the format: // 1 byte offset to the next entry // 4 byte index // 4 byte reference count // <246 byte null terminated string for the name // // note that the size of 4 bytes is hardcoded for integers. This is // to facilitate the possibility of different word-length // architectures that will grow into the environment. // // for now we just read and write the information, upgrade this to // a true read/write of 4 byte info in the future. // byte entry_buffer[BUFFER_SIZE]; MemoryManager::memset(entry_buffer, 0, BUFFER_SIZE); byte size = (byte)0; long ptr = (long)sizeof(int32); // the first thing written is the size of the table // int32 num_classes = fp_d.encode((int32)table_d.getCount()); MemoryManager::memcpy(entry_buffer, &num_classes, sizeof(int32)); // write the encoding we will use (use ASCII until we support UTF8) // SysChar::ENCODE encoding = SysChar::ENCODE_ASCII; int16 encoding_int = (int16)encoding; int16 val = fp_d.encode(encoding_int); MemoryManager::memcpy(&entry_buffer[ptr], &val, sizeof(int16)); ptr += sizeof(int16); // pointer to the last size entry // byte *last_size = &entry_buffer[ptr + SYMBOL_OFFSET_NEXT]; // handle converting names from the symbol table to utf8 encoding // SysString name_str; long slen = 0; // we call this the max name length. it should allow ample room for // any utf8 characters to be expanded to full length // const long max_name_length = SofSymbolTable::MAX_SYM_LENGTH * 6; static byte name_buf[max_name_length]; long count = 0; int32 refs = 0; int32 ind = 0; // loop through integers until all names are written // for (long i = 0; count < table_d.getCount(); i++) { // is this index a name? // if (table_d.getSymbol(name_str, i)) { // encode the values // refs = fp_d.encode((int32)table_d.getRefCount(name_str)); ind = fp_d.encode((int32)i); count++; // encode the name_str // slen = name_str.getBuffer((byte*)name_buf, max_name_length, encoding); size = SYMBOL_BASE + slen + 1; // if we have a full buffer, write it // if (ptr + size > BUFFER_SIZE) { // increase last_size so that read will skip over empty pad // (*last_size) += (BUFFER_SIZE - ptr); // write the buffer (we don't want byte swapping, use lowest // level write). // if (fp_d.write(entry_buffer,sizeof(byte),BUFFER_SIZE) != BUFFER_SIZE) { return Error::handle(name(), L"writeTable", Error::WRITE, __FILE__, __LINE__);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -