GP-4285 Compressed SLEIGH

This commit is contained in:
caheckman 2024-01-10 22:53:12 +00:00
parent b380fd5fa6
commit 8fbd171cdf
207 changed files with 15233 additions and 6055 deletions

View file

@ -24,6 +24,9 @@ unordered_map<string,uint4> AttributeId::lookupAttributeId;
const int4 PackedDecode::BUFFER_SIZE = 1024;
const char XmlEncode::spaces[] = "\n ";
const int4 XmlEncode::MAX_SPACES = 24+1;
/// Access static vector of AttributeId objects that are registered during static initialization
/// The list itself is created once on the first call to this method.
/// \return a reference to the vector
@ -38,11 +41,13 @@ vector<AttributeId *> &AttributeId::getList(void)
/// in the global hashtable.
/// \param nm is the name of the attribute
/// \param i is an id to associate with the attribute
AttributeId::AttributeId(const string &nm,uint4 i)
/// \param scope is an id for the scope of this attribute
AttributeId::AttributeId(const string &nm,uint4 i,int4 scope)
: name(nm)
{
id = i;
getList().push_back(this);
if (scope == 0)
getList().push_back(this);
}
/// Fill the hashtable mapping attribute names to their id, from registered attribute objects
@ -78,11 +83,13 @@ vector<ElementId *> &ElementId::getList(void)
/// in the global hashtable.
/// \param nm is the name of the element
/// \param i is an id to associate with the element
ElementId::ElementId(const string &nm,uint4 i)
/// \param scope is an id for the scope of this element
ElementId::ElementId(const string &nm,uint4 i,int4 scope)
: name(nm)
{
id = i;
getList().push_back(this);
if (scope == 0)
getList().push_back(this);
}
/// Fill the hashtable mapping element names to their id, from registered element objects
@ -132,7 +139,7 @@ uint4 XmlDecode::peekElement(void)
return 0;
el = *iter;
}
return ElementId::find(el->getName());
return ElementId::find(el->getName(),scope);
}
uint4 XmlDecode::openElement(void)
@ -156,7 +163,7 @@ uint4 XmlDecode::openElement(void)
elStack.push_back(el);
iterStack.push_back(el->getChildren().begin());
attributeIndex = -1;
return ElementId::find(el->getName());
return ElementId::find(el->getName(),scope);
}
uint4 XmlDecode::openElement(const ElementId &elemId)
@ -194,7 +201,7 @@ void XmlDecode::closeElement(uint4 id)
const Element *el = elStack.back();
if (iterStack.back() != el->getChildren().end())
throw DecoderError("Closing element <" + el->getName() + "> with additional children");
if (ElementId::find(el->getName()) != id)
if (ElementId::find(el->getName(), scope) != id)
throw DecoderError("Trying to close <" + el->getName() + "> with mismatching id");
#endif
elStack.pop_back();
@ -207,7 +214,7 @@ void XmlDecode::closeElementSkipping(uint4 id)
{
#ifdef CPUI_DEBUG
const Element *el = elStack.back();
if (ElementId::find(el->getName()) != id)
if (ElementId::find(el->getName(), scope) != id)
throw DecoderError("Trying to close <" + el->getName() + "> with mismatching id");
#endif
elStack.pop_back();
@ -228,7 +235,7 @@ uint4 XmlDecode::getNextAttributeId(void)
int4 nextIndex = attributeIndex + 1;
if (nextIndex < el->getNumAttributes()) {
attributeIndex = nextIndex;
return AttributeId::find(el->getAttributeName(attributeIndex));
return AttributeId::find(el->getAttributeName(attributeIndex),scope);
}
return 0;
}
@ -419,40 +426,89 @@ AddrSpace *XmlDecode::readSpace(const AttributeId &attribId)
return res;
}
OpCode XmlDecode::readOpcode(void)
{
const Element *el = elStack.back();
string nm = el->getAttributeValue(attributeIndex);
OpCode opc = get_opcode(nm);
if (opc == (OpCode)0)
throw DecoderError("Bad encoded OpCode");
return opc;
}
OpCode XmlDecode::readOpcode(AttributeId &attribId)
{
const Element *el = elStack.back();
string nm;
if (attribId == ATTRIB_CONTENT) {
nm = el->getContent();
}
else {
int4 index = findMatchingAttribute(el, attribId.getName());
nm = el->getAttributeValue(index);
}
OpCode opc = get_opcode(nm);
if (opc == (OpCode)0)
throw DecoderError("Bad encoded OpCode");
return opc;
}
void XmlEncode::newLine(void)
{
if (!doFormatting)
return;
int numSpaces = depth * 2 + 1;
if (numSpaces > MAX_SPACES) {
numSpaces = MAX_SPACES;
}
outStream.write(spaces,numSpaces);
}
void XmlEncode::openElement(const ElementId &elemId)
{
if (elementTagIsOpen)
if (tagStatus == tag_start)
outStream << '>';
else
elementTagIsOpen = true;
tagStatus = tag_start;
newLine();
outStream << '<' << elemId.getName();
depth += 1;
}
void XmlEncode::closeElement(const ElementId &elemId)
{
if (elementTagIsOpen) {
depth -= 1;
if (tagStatus == tag_start) {
outStream << "/>";
elementTagIsOpen = false;
}
else {
outStream << "</" << elemId.getName() << '>';
tagStatus = tag_stop;
return;
}
if (tagStatus != tag_content)
newLine();
else
tagStatus = tag_stop;
outStream << "</" << elemId.getName() << '>';
}
void XmlEncode::writeBool(const AttributeId &attribId,bool val)
{
if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
if (tagStatus == tag_start) {
outStream << '>';
elementTagIsOpen = false;
}
if (val)
outStream << "true";
else
outStream << "false";
tagStatus = tag_content;
return;
}
a_v_b(outStream, attribId.getName(), val);
@ -462,11 +518,11 @@ void XmlEncode::writeSignedInteger(const AttributeId &attribId,intb val)
{
if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
if (tagStatus == tag_start) {
outStream << '>';
elementTagIsOpen = false;
}
outStream << dec << val;
tagStatus = tag_content;
return;
}
a_v_i(outStream, attribId.getName(), val);
@ -476,11 +532,11 @@ void XmlEncode::writeUnsignedInteger(const AttributeId &attribId,uintb val)
{
if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
if (tagStatus == tag_start) {
outStream << '>';
elementTagIsOpen = false;
}
outStream << hex << "0x" << val;
tagStatus = tag_content;
return;
}
a_v_u(outStream, attribId.getName(), val);
@ -490,11 +546,11 @@ void XmlEncode::writeString(const AttributeId &attribId,const string &val)
{
if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
if (tagStatus == tag_start) {
outStream << '>';
elementTagIsOpen = false;
}
xml_escape(outStream, val.c_str());
tagStatus = tag_content;
return;
}
a_v(outStream,attribId.getName(),val);
@ -514,16 +570,33 @@ void XmlEncode::writeSpace(const AttributeId &attribId,const AddrSpace *spc)
{
if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
if (tagStatus == tag_start) {
outStream << '>';
elementTagIsOpen = false;
}
xml_escape(outStream, spc->getName().c_str());
tagStatus = tag_content;
return;
}
a_v(outStream,attribId.getName(),spc->getName());
}
void XmlEncode::writeOpcode(const AttributeId &attribId,OpCode opc)
{
const char *name = get_opname(opc);
if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value
if (tagStatus == tag_start) {
outStream << '>';
}
outStream << name;
tagStatus = tag_content;
return;
}
outStream << ' ' << attribId.getName() << "=\"";
outStream << name;
outStream << "\"";
}
/// The integer is encoded, 7-bits per byte, starting with the most significant 7-bits.
/// The integer is decode from the \e current position, and the position is advanced.
/// \param len is the number of bytes to extract
@ -598,6 +671,27 @@ void PackedDecode::skipAttributeRemaining(uint1 typeByte)
advancePosition(curPos, length); // Skip -length- data
}
/// Set decoder to beginning of the stream. Add padding to end of the stream.
/// \param bufPos is the number of bytes used by the last input buffer
void PackedDecode::endIngest(int4 bufPos)
{
endPos.seqIter = inStream.begin(); // Set position to beginning of stream
if (endPos.seqIter != inStream.end()) {
endPos.current = (*endPos.seqIter).start;
endPos.end = (*endPos.seqIter).end;
// Make sure there is at least one character after ingested buffer
if (bufPos == BUFFER_SIZE) {
// Last buffer was entirely filled
uint1 *endbuf = new uint1[1]; // Add one more buffer
inStream.emplace_back(endbuf,endbuf + 1);
bufPos = 0;
}
uint1 *buf = inStream.back().start;
buf[bufPos] = ELEMENT_END;
}
}
PackedDecode::~PackedDecode(void)
{
@ -612,25 +706,11 @@ void PackedDecode::ingestStream(istream &s)
{
int4 gcount = 0;
while(s.peek() > 0) {
uint1 *buf = new uint1[BUFFER_SIZE + 1];
inStream.emplace_back(buf,buf+BUFFER_SIZE);
uint1 *buf = allocateNextInputBuffer(1);
s.get((char *)buf,BUFFER_SIZE+1,'\0');
gcount = s.gcount();
}
endPos.seqIter = inStream.begin();
if (endPos.seqIter != inStream.end()) {
endPos.current = (*endPos.seqIter).start;
endPos.end = (*endPos.seqIter).end;
// Make sure there is at least one character after ingested buffer
if (gcount == BUFFER_SIZE) {
// Last buffer was entirely filled
uint1 *endbuf = new uint1[1]; // Add one more buffer
inStream.emplace_back(endbuf,endbuf + 1);
gcount = 0;
}
uint1 *buf = inStream.back().start;
buf[gcount] = ELEMENT_END;
}
endIngest(gcount);
}
uint4 PackedDecode::peekElement(void)
@ -959,6 +1039,24 @@ AddrSpace *PackedDecode::readSpace(const AttributeId &attribId)
return res;
}
OpCode PackedDecode::readOpcode(void)
{
int4 val = (int4)readSignedInteger();
if (val < 0 || val >= CPUI_MAX)
throw DecoderError("Bad encoded OpCode");
return (OpCode)val;
}
OpCode PackedDecode::readOpcode(AttributeId &attribId)
{
findMatchingAttribute(attribId);
OpCode opc = readOpcode();
curPos = startPos;
return opc;
}
/// The value is either an unsigned integer, an address space index, or (the absolute value of) a signed integer.
/// A type header is passed in with the particular type code for the value already filled in.
/// This method then fills in the length code, outputs the full type header and the encoded bytes of the integer.
@ -973,7 +1071,7 @@ void PackedEncode::writeInteger(uint1 typeByte,uint8 val)
lenCode = 0;
sa = -1;
}
if (val < 0x800000000) {
else if (val < 0x800000000) {
if (val < 0x200000) {
if (val < 0x80) {
lenCode = 1; // 7-bits
@ -1119,6 +1217,13 @@ void PackedEncode::writeSpace(const AttributeId &attribId,const AddrSpace *spc)
}
}
void PackedEncode::writeOpcode(const AttributeId &attribId,OpCode opc)
{
writeHeader(ATTRIBUTE, attribId.getId());
writeInteger((TYPECODE_SIGNEDINT_POSITIVE << TYPECODE_SHIFT), opc);
}
// Common attributes. Attributes with multiple uses
AttributeId ATTRIB_CONTENT = AttributeId("XMLcontent",1);
AttributeId ATTRIB_ALIGN = AttributeId("align",2);