X-Git-Url: https://deadsoftware.ru/gitweb?p=odcread.git;a=blobdiff_plain;f=textmodel.cc;h=dd982dc490873b612a2377269d35fa3b30e0edac;hp=bc76a32798a9feff7848e7014bc6ca5ece906244;hb=41d9c65ec79728a8771cd2288dfc3458569c6801;hpb=9b0fce2b8ea23e4eb23485421e1d80a774c912b3 diff --git a/textmodel.cc b/textmodel.cc index bc76a32..dd982dc 100644 --- a/textmodel.cc +++ b/textmodel.cc @@ -2,24 +2,17 @@ #include #include +#include namespace odc { const std::string TextModel::TYPENAME("TextModels.Model^"); -const TypeProxy TextModel::PROXY; +const TypeProxy TextModel::PROXY; TextModel::TextModel(INTEGER id) : ContainerModel(id) {} -const std::string &TextModel::getType() { - return TYPENAME; -} - -const std::string *TextModel::getSuper() { - return &ContainerModel::getType(); -} - const std::string &TextModel::getTypeName() const { - return getType(); + return TYPENAME; } void TextModel::internalize(Reader &reader) { @@ -29,20 +22,12 @@ void TextModel::internalize(Reader &reader) { } const std::string StdTextModel::TYPENAME("TextModels.StdModel^"); -const TypeProxy StdTextModel::PROXY; +const TypeProxy StdTextModel::PROXY; -StdTextModel::StdTextModel(INTEGER id) : TextModel(id) {} - -const std::string &StdTextModel::getType() { - return TYPENAME; -} - -const std::string *StdTextModel::getSuper() { - return &TextModel::getType(); -} +StdTextModel::StdTextModel(INTEGER id) : TextModel(id), d_pieces() {} const std::string &StdTextModel::getTypeName() const { - return getType(); + return TYPENAME; } /* @@ -58,81 +43,130 @@ void StdTextModel::internalize(Reader &reader) { reader.readVersion(0, 1); if (reader.isCancelled()) return; - std::vector dict; - INTEGER len = reader.readInt(); + std::vector dict; // attribute dictionary + + // reads the meta-data + INTEGER len = reader.readInt(); // lenght of meta-data section BYTE ano = reader.readByte(); - std::cout << "len " << len << " ano " << (int)ano << std::endl; while (ano != -1) { + // This part reads the piece's attributes. These are ignored for now, + // but may be needed in the future. if (ano == dict.size()) { - Store *attr = reader.readStore(); // readAttributes(); Stores.Join(t, attr) - dict.push_back(attr); + dict.push_back(reader.readStore()); } + Store *attr = dict[ano]; + INTEGER pieceLen = reader.readInt(); if (pieceLen > 0) { // shortchar piece - std::cout << "Found SChar piece" << std::endl; -// NEW(sp); sp.len := len; sp.attr := attr; -// sp.file := rd.rider.Base(); sp.org := org; un := sp; -// INC(org, len) -- increment org by len ? + d_pieces.push_back(new ShortPiece(pieceLen)); } else if (pieceLen < 0) { // longchar piece - std::cout << "Found LChar piece" << std::endl; -// len := -len; ASSERT(~ODD(len), 100); -// NEW(lp); lp.len := len DIV 2; lp.attr := attr; -// lp.file := rd.rider.Base(); lp.org := org; un := lp; -// INC(org, len) -- increment org by len ? + assert(pieceLen % 2 == 0); + d_pieces.push_back(new LongPiece(-pieceLen / 2)); } else { // embedded view - reader.readInt(); reader.readInt(); - Store *view = reader.readStore(); // fixme: save somewhere -// NEW(v); v.len := 1; v.attr := attr; -// rd.ReadInt(v.w); rd.ReadInt(v.h); Views.ReadView(rd, v.view); -// v.view.InitContext(NewContext(v, t)); -// un := v; INC(org) -- increment org by one?? WTH? + reader.readInt(); reader.readInt(); // view width + height: ignore + Store *view = reader.readStore(); + d_pieces.push_back(new ViewPiece(view)); } ano = reader.readByte(); } -// rd.SetPos(org); -} -// PROCEDURE (t: StdModel) Internalize (VAR rd: Stores.Reader); -// VAR u, un: Run; sp: Piece; lp: LPiece; v: ViewRef; -// org, len: INTEGER; ano: BYTE; thisVersion: INTEGER; -// attr: Attributes; dict: AttrDict; -// BEGIN -// ASSERT(t.Domain() = NIL, 20); ASSERT(t.len = 0, 21); -// t.Internalize^(rd); IF rd.cancelled THEN RETURN END; -// rd.ReadVersion(minVersion, maxStdModelVersion, thisVersion); -// IF rd.cancelled THEN RETURN END; -// StdInit(t); -// dict.len := 0; u := t.trailer; -// rd.ReadInt(len); org := rd.Pos() + len; -// rd.ReadByte(ano); -// WHILE ano # -1 DO -// IF ano = dict.len THEN -// ReadAttr(rd, attr); Stores.Join(t, attr); -// IF dict.len < dictSize THEN dict.attr[dict.len] := attr; INC(dict.len) END -// ELSE -// attr := dict.attr[ano] -// END; -// rd.ReadInt(len); -// IF len > 0 THEN (* piece *) -// NEW(sp); sp.len := len; sp.attr := attr; -// sp.file := rd.rider.Base(); sp.org := org; un := sp; -// INC(org, len) -// ELSIF len < 0 THEN (* longchar piece *) -// len := -len; ASSERT(~ODD(len), 100); -// NEW(lp); lp.len := len DIV 2; lp.attr := attr; -// lp.file := rd.rider.Base(); lp.org := org; un := lp; -// INC(org, len) -// ELSE (* len = 0 => embedded view *) -// NEW(v); v.len := 1; v.attr := attr; -// rd.ReadInt(v.w); rd.ReadInt(v.h); Views.ReadView(rd, v.view); -// v.view.InitContext(NewContext(v, t)); -// un := v; INC(org) -// END; -// INC(t.len, un.len); u.next := un; un.prev := u; u := un; -// rd.ReadByte(ano) -// END; -// rd.SetPos(org); -// u.next := t.trailer; t.trailer.prev := u -// END Internalize; -// + + // reads the pieces described in the meta-data + for (int i = 0; i < d_pieces.size(); ++i) { + d_pieces[i]->read(reader); + } + + // free memory from stores in the dictionary + for (int i = 0; i < dict.size(); ++i) { + delete dict[i]; + } +} + +std::string StdTextModel::toString() { + std::string sofar = "StdTextModel { "; + for (int i = 0; i < d_pieces.size(); ++i) { + sofar += d_pieces[i]->toString() + " "; + } + return sofar + "}"; +} + +void StdTextModel::accept(Visitor &visitor) const { + visitor.partStart(); + for (int i = 0; i < d_pieces.size(); ++i) { + d_pieces[i]->accept(visitor); + } + visitor.partEnd(); +} + +TextPiece::TextPiece(size_t len): d_len(len) {} + +LongPiece::LongPiece(size_t len): TextPiece(len * 2) {} + +LongPiece::~LongPiece() { + delete d_buf; +} + +void LongPiece::read(Reader &reader) { + d_buf = new CHAR[d_len / 2 + 1]; + reader.readLChar(d_buf, d_len / 2); + d_buf[d_len / 2] = 0; +} + +std::string LongPiece::toString() const { + return std::string("LongPiece(FIXME)"); +} + +std::wstring LongPiece::getText() const { + return std::wstring((wchar_t*)d_buf); +} + +void LongPiece::accept(Visitor &visitor) const { + visitor.textLongPiece(this); +} + +ShortPiece::ShortPiece(size_t len): TextPiece(len) {} + +ShortPiece::~ShortPiece() { + delete d_buf; +} + +void ShortPiece::read(Reader &reader) { + d_buf = new SHORTCHAR[d_len + 1]; + reader.readSChar(d_buf, d_len); + d_buf[d_len] = 0; +} + +std::string ShortPiece::toString() const { + return std::string("ShortPiece(") + std::string(d_buf) + std::string(")"); +} + +std::string ShortPiece::getText() const { + std::string str(d_buf); + for (std::string::iterator it = str.begin(); it < str.end(); ++it) { + if (*it == '\r') *it = '\n'; + } + return str; +} + +void ShortPiece::accept(Visitor &visitor) const { + visitor.textShortPiece(this); +} + +ViewPiece::ViewPiece(Store *view): TextPiece(1), d_view(view) {} + +ViewPiece::~ViewPiece() { + delete d_view; +} + +void ViewPiece::read(Reader &reader) { + reader.readByte(); +} + +std::string ViewPiece::toString() const { + return std::string("ViewPiece { ") + d_view->toString() + " }"; +} + +void ViewPiece::accept(Visitor &visitor) const { + return d_view->accept(visitor); +} } // namespace odc