⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xref.cc

📁 swf文件查看工具,能够看flash文件的格式
💻 CC
📖 第 1 页 / 共 2 页
字号:
//========================================================================//// XRef.cc//// Copyright 1996-2003 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <stdlib.h>#include <stddef.h>#include <string.h>#include <ctype.h>#include "gmem.h"#include "Object.h"#include "Stream.h"#include "Lexer.h"#include "Parser.h"#include "Dict.h"#include "Error.h"#include "ErrorCodes.h"#include "XRef.h"//------------------------------------------------------------------------#define xrefSearchSize 1024	// read this many bytes at end of file				//   to look for 'startxref'//------------------------------------------------------------------------// Permission bits//------------------------------------------------------------------------#define permPrint    (1<<2)#define permChange   (1<<3)#define permCopy     (1<<4)#define permNotes    (1<<5)#define defPermFlags 0xfffc//------------------------------------------------------------------------// ObjectStream//------------------------------------------------------------------------class ObjectStream {public:  // Create an object stream, using object number <objStrNum>,  // generation 0.  ObjectStream(XRef *xref, int objStrNumA);  ~ObjectStream();  // Return the object number of this object stream.  int getObjStrNum() { return objStrNum; }  // Get the <objIdx>th object from this stream, which should be  // object number <objNum>, generation 0.  Object *getObject(int objIdx, int objNum, Object *obj);private:  int objStrNum;		// object number of the object stream  int nObjects;			// number of objects in the stream  Object *objs;			// the objects (length = nObjects)  int *objNums;			// the object numbers (length = nObjects)};ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {  Stream *str;  Parser *parser;  int *offsets;  Object objStr, obj1, obj2;  int first, i;  objStrNum = objStrNumA;  nObjects = 0;  objs = NULL;  objNums = NULL;  if (!xref->fetch(objStrNum, 0, &objStr)->isStream()) {    goto err1;  }  if (!objStr.streamGetDict()->lookup("N", &obj1)->isInt()) {    obj1.free();    goto err1;  }  nObjects = obj1.getInt();  obj1.free();  if (nObjects <= 0) {    goto err1;  }  if (!objStr.streamGetDict()->lookup("First", &obj1)->isInt()) {    obj1.free();    goto err1;  }  first = obj1.getInt();  obj1.free();  if (first < 0) {    goto err1;  }  objs = new Object[nObjects];  objNums = (int *)gmallocn(nObjects, sizeof(int));  offsets = (int *)gmallocn(nObjects, sizeof(int));  // parse the header: object numbers and offsets  objStr.streamReset();  obj1.initNull();  str = new EmbedStream(objStr.getStream(), &obj1, gTrue, first);  parser = new Parser(xref, new Lexer(xref, str), gFalse);  for (i = 0; i < nObjects; ++i) {    parser->getObj(&obj1);    parser->getObj(&obj2);    if (!obj1.isInt() || !obj2.isInt()) {      obj1.free();      obj2.free();      delete parser;      gfree(offsets);      goto err1;    }    objNums[i] = obj1.getInt();    offsets[i] = obj2.getInt();    obj1.free();    obj2.free();    if (objNums[i] < 0 || offsets[i] < 0 ||	(i > 0 && offsets[i] < offsets[i-1])) {      delete parser;      gfree(offsets);      goto err1;    }  }  while (str->getChar() != EOF) ;  delete parser;  // skip to the first object - this shouldn't be necessary because  // the First key is supposed to be equal to offsets[0], but just in  // case...  for (i = first; i < offsets[0]; ++i) {    objStr.getStream()->getChar();  }  // parse the objects  for (i = 0; i < nObjects; ++i) {    obj1.initNull();    if (i == nObjects - 1) {      str = new EmbedStream(objStr.getStream(), &obj1, gFalse, 0);    } else {      str = new EmbedStream(objStr.getStream(), &obj1, gTrue,			    offsets[i+1] - offsets[i]);    }    parser = new Parser(xref, new Lexer(xref, str), gFalse);    parser->getObj(&objs[i]);    while (str->getChar() != EOF) ;    delete parser;  }  gfree(offsets); err1:  objStr.free();  return;}ObjectStream::~ObjectStream() {  int i;  if (objs) {    for (i = 0; i < nObjects; ++i) {      objs[i].free();    }    delete[] objs;  }  gfree(objNums);}Object *ObjectStream::getObject(int objIdx, int objNum, Object *obj) {  if (objIdx < 0 || objIdx >= nObjects || objNum != objNums[objIdx]) {    return obj->initNull();  }  return objs[objIdx].copy(obj);}//------------------------------------------------------------------------// XRef//------------------------------------------------------------------------XRef::XRef(BaseStream *strA) {  Guint pos;  Object obj;  ok = gTrue;  errCode = errNone;  size = 0;  entries = NULL;  streamEnds = NULL;  streamEndsLen = 0;  objStr = NULL;  encrypted = gFalse;  permFlags = defPermFlags;  ownerPasswordOk = gFalse;  // read the trailer  str = strA;  start = str->getStart();  pos = getStartXref();  // if there was a problem with the 'startxref' position, try to  // reconstruct the xref table  if (pos == 0) {    if (!(ok = constructXRef())) {      errCode = errDamaged;      return;    }  // read the xref table  } else {    while (readXRef(&pos)) ;    // if there was a problem with the xref table,    // try to reconstruct it    if (!ok) {      if (!(ok = constructXRef())) {	errCode = errDamaged;	return;      }    }  }  // get the root dictionary (catalog) object  trailerDict.dictLookupNF("Root", &obj);  if (obj.isRef()) {    rootNum = obj.getRefNum();    rootGen = obj.getRefGen();    obj.free();  } else {    obj.free();    if (!(ok = constructXRef())) {      errCode = errDamaged;      return;    }  }  // now set the trailer dictionary's xref pointer so we can fetch  // indirect objects from it  trailerDict.getDict()->setXRef(this);}XRef::~XRef() {  gfree(entries);  trailerDict.free();  if (streamEnds) {    gfree(streamEnds);  }  if (objStr) {    delete objStr;  }}// Read the 'startxref' position.Guint XRef::getStartXref() {  char buf[xrefSearchSize+1];  char *p;  int c, n, i;  // read last xrefSearchSize bytes  str->setPos(xrefSearchSize, -1);  for (n = 0; n < xrefSearchSize; ++n) {    if ((c = str->getChar()) == EOF) {      break;    }    buf[n] = c;  }  buf[n] = '\0';  // find startxref  for (i = n - 9; i >= 0; --i) {    if (!strncmp(&buf[i], "startxref", 9)) {      break;    }  }  if (i < 0) {    return 0;  }  for (p = &buf[i+9]; isspace(*p); ++p) ;  lastXRefPos = strToUnsigned(p);  return lastXRefPos;}// Read one xref table section.  Also reads the associated trailer// dictionary, and returns the prev pointer (if any).GBool XRef::readXRef(Guint *pos) {  Parser *parser;  Object obj;  GBool more;  // start up a parser, parse one token  obj.initNull();  parser = new Parser(NULL,	     new Lexer(NULL,	       str->makeSubStream(start + *pos, gFalse, 0, &obj)),	     gTrue);  parser->getObj(&obj);  // parse an old-style xref table  if (obj.isCmd("xref")) {    obj.free();    more = readXRefTable(parser, pos);  // parse an xref stream  } else if (obj.isInt()) {    obj.free();    if (!parser->getObj(&obj)->isInt()) {      goto err1;    }    obj.free();    if (!parser->getObj(&obj)->isCmd("obj")) {      goto err1;    }    obj.free();    if (!parser->getObj(&obj)->isStream()) {      goto err1;    }    more = readXRefStream(obj.getStream(), pos);    obj.free();  } else {    goto err1;  }  delete parser;  return more; err1:  obj.free();  delete parser;  ok = gFalse;  return gFalse;}GBool XRef::readXRefTable(Parser *parser, Guint *pos) {  XRefEntry entry;  GBool more;  Object obj, obj2;  Guint pos2;  int first, n, newSize, i;  while (1) {    parser->getObj(&obj);    if (obj.isCmd("trailer")) {      obj.free();      break;    }    if (!obj.isInt()) {      goto err1;    }    first = obj.getInt();    obj.free();    if (!parser->getObj(&obj)->isInt()) {      goto err1;    }    n = obj.getInt();    obj.free();    if (first < 0 || n < 0 || first + n < 0) {      goto err1;    }    if (first + n > size) {      for (newSize = size ? 2 * size : 1024;	   first + n > newSize && newSize > 0;	   newSize <<= 1) ;      if (newSize < 0) {	goto err1;      }      entries = (XRefEntry *)greallocn(entries, newSize, sizeof(XRefEntry));      for (i = size; i < newSize; ++i) {	entries[i].offset = 0xffffffff;	entries[i].type = xrefEntryFree;      }      size = newSize;    }    for (i = first; i < first + n; ++i) {      if (!parser->getObj(&obj)->isInt()) {	goto err1;      }      entry.offset = (Guint)obj.getInt();      obj.free();      if (!parser->getObj(&obj)->isInt()) {	goto err1;      }      entry.gen = obj.getInt();      obj.free();      parser->getObj(&obj);      if (obj.isCmd("n")) {	entry.type = xrefEntryUncompressed;      } else if (obj.isCmd("f")) {	entry.type = xrefEntryFree;      } else {	goto err1;      }      obj.free();      if (entries[i].offset == 0xffffffff) {	entries[i] = entry;	// PDF files of patents from the IBM Intellectual Property	// Network have a bug: the xref table claims to start at 1	// instead of 0.	if (i == 1 && first == 1 &&	    entries[1].offset == 0 && entries[1].gen == 65535 &&	    entries[1].type == xrefEntryFree) {	  i = first = 0;	  entries[0] = entries[1];	  entries[1].offset = 0xffffffff;	}      }    }  }  // read the trailer dictionary  if (!parser->getObj(&obj)->isDict()) {    goto err1;  }  // get the 'Prev' pointer  obj.getDict()->lookupNF("Prev", &obj2);  if (obj2.isInt()) {    *pos = (Guint)obj2.getInt();    more = gTrue;  } else if (obj2.isRef()) {    // certain buggy PDF generators generate "/Prev NNN 0 R" instead    // of "/Prev NNN"    *pos = (Guint)obj2.getRefNum();    more = gTrue;  } else {    more = gFalse;  }  obj2.free();  // save the first trailer dictionary  if (trailerDict.isNone()) {    obj.copy(&trailerDict);  }  // check for an 'XRefStm' key

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -