trpage_writebuf.cpp

来自「最新osg包」· C++ 代码 · 共 461 行

CPP
461
字号
/* ************************   Copyright Terrain Experts Inc.   Terrain Experts Inc (TERREX) reserves all rights to this source code   unless otherwise specified in writing by the President of TERREX.   This copyright may be updated in the future, in which case that version   supercedes this one.   -------------------   Terrex Experts Inc.   4400 East Broadway #314   Tucson, AZ  85711   info@terrex.com   Tel: (520) 323-7990   ************************   */#include <osgDB/FileUtils>#include <stdlib.h>#include <stdio.h>#include <string.h>/* trpage_writebuf.cpp    This source file contains the implementation of trpgMemWriteBuffer.    That is a subclass of trpgWriteBuffer, which implements an interface    definition for an object which can accept data to be written.    The Mem version is used to write (for example) a tile's worth of data.    That data can then be written to a file (or sent over the network).    You should not need to change this implementation.  Simply sublcass    trpgWriteBuffer and implement all of the required methods.  The    resulting class can then be used in all the places a trpgWriteBuffer    is required.    */#include <trpage_io.h>#include <trpage_swap.h>/* **********************   Memory Write Buffer functions   **********************   */// ConstructortrpgMemWriteBuffer::trpgMemWriteBuffer(trpgEndian in_ness){    ness = in_ness;    cpuNess = trpg_cpu_byte_order();    data = NULL;    curLen = totLen = 0;}// DestructortrpgMemWriteBuffer::~trpgMemWriteBuffer(){    if (data)        delete [] data;    data = NULL;}/* Length()    Return the length of the given buffer.    */int trpgMemWriteBuffer::length() const{    return curLen;}/* getData()    Return a pointer to the memory buffer.    */const char *trpgMemWriteBuffer::getData() const{    return data;}/* Length()    Set the maximum buffer length.    */void trpgMemWriteBuffer::setLength(unsigned int len){    if ((int)len > totLen) {        char *old_data = data;        int oldLen = totLen;        totLen = 2*len;        data = new char[totLen];        if (old_data) {            memcpy(data,old_data,oldLen);            delete [] old_data;        }    }}/* append()    Append the given data to our buffer.    */void trpgMemWriteBuffer::append(unsigned int len,const char *val){    if (len == 0)  return;    setLength(curLen+len);    memcpy(&data[curLen],val,len);    curLen += len;}/* set()    Set a specific portion of the buffer to a given value.    */void trpgMemWriteBuffer::set(unsigned int pos,unsigned int len,const char *val){    if (len == 0) return;    if (pos+len > (unsigned int)curLen) return;    memcpy(&data[pos],val,len);}/* --- replacement virtual functions --- *//* Reset()    Drop whatever's being stored.    */void trpgMemWriteBuffer::Reset(){    curLen = 0;}// Add(Int32)void trpgMemWriteBuffer::Add(int32 val){    if (ness != cpuNess)        val = trpg_byteswap_int(val);    append(sizeof(int32),(const char *)&val);}// Add(int64)void trpgMemWriteBuffer::Add(int64 val){    if (ness != cpuNess)        val = trpg_byteswap_llong(val);    append(sizeof(int64),(const char *)&val);}// Add(string)// [len] [value...]void trpgMemWriteBuffer::Add(const char *val){    int32 len = (val ? strlen(val) : 0),vlen = len;    if (ness != cpuNess)        vlen = trpg_byteswap_int(vlen);    append(sizeof(int32),(const char *)&vlen);    append(len,val);}// Add(std::string)void trpgMemWriteBuffer::Add(std::string &val){    Add(val.c_str());}// Add(float32)void trpgMemWriteBuffer::Add(float32 val){    char cval[4];    if (ness != cpuNess)        trpg_byteswap_float_to_4bytes(val,cval);    else        memcpy(cval,&val,4);    append(sizeof(float32),cval);}// Add(float64)void trpgMemWriteBuffer::Add(float64 val){    char cval[8];    if (ness != cpuNess)        trpg_byteswap_double_to_8bytes(val,cval);    else        memcpy(cval,&val,8);    append(sizeof(float64),cval);}// Add(int8)void trpgMemWriteBuffer::Add(uint8 val){    // No byte swapping needed    append(sizeof(uint8),(const char *)&val);}//#if (bool != int32)// Add(bool)void trpgMemWriteBuffer::Add(bool val){    uint8 ival;    ival = (val ? 1 : 0);    Add(ival);}//#endif#if (trpgDiskRef != int64)// Add(trpgDiskRef)void trpgMemWriteBuffer::Add(trpgDiskRef val){    if (ness != cpuNess)        val = trpg_byteswap_llong(val);    append(sizeof(trpgDiskRef),(const char *)&val);}#endif// Add(trpgToken)void trpgMemWriteBuffer::Add(trpgToken val){    if (ness != cpuNess)        val = trpg_byteswap_short(val);    append(sizeof(trpgToken),(const char *)&val);}// Add(tx2iPoint)void trpgWriteBuffer::Add(const trpg2iPoint &val){    Add((int32)val.x);    Add((int32)val.y);}// Add(tx2dPoint)void trpgWriteBuffer::Add(const trpg2dPoint &val){    Add((float64)val.x);    Add((float64)val.y);}// Add(trpg3dPoint)void trpgWriteBuffer::Add(const trpg3dPoint &val){    Add((float64)val.x);    Add((float64)val.y);    Add((float64)val.z);}// Add(trpgColor)void trpgWriteBuffer::Add(const trpgColor &val){    Add(val.red);    Add(val.green);    Add(val.blue);}// Add(std::string)void trpgWriteBuffer::Add(const std::string &val){    Add(val.c_str());}/* Push()    Starts defining a new object.    Need to keep track of where length goes.    */void trpgMemWriteBuffer::Begin(trpgToken tok){    Add(tok);    lengths.push_back(curLen);    Add((int32)0);}/* Push()    Pushes a level on the stack.  For defining children.    */void trpgMemWriteBuffer::Push(){    Add((trpgToken)TRPG_PUSH);}/* Pop()    Pops a level off the "stack".    */void trpgMemWriteBuffer::Pop(){    Add((trpgToken)TRPG_POP);}/* Will take out a pop from the end of the  buffer, if there is one */bool trpgMemWriteBuffer::UnPop(){   //Check to see if there is a pop token ant the end   trpgToken tk;   memcpy(&tk, &data[curLen - sizeof(trpgToken)], sizeof(trpgToken));   if(tk == TRPG_POP)   {      curLen -= sizeof(trpgToken);      return true;   }   else      return false;}/* Will take out a push from the end of the  buffer, if there is one */bool trpgMemWriteBuffer::UnPush(){   //Check to see if there is a push token ant the end   trpgToken tk;   memcpy(&tk, &data[curLen - sizeof(trpgToken)], sizeof(trpgToken));   if(tk == TRPG_PUSH)   {      curLen -= sizeof(trpgToken);      return true;   }   else      return false;}/* End()    Finished defining an object.    Write the length out where appropriate.    */void trpgMemWriteBuffer::End(){    if (lengths.size() == 0)        // Note: say something clever here        return;    int id = lengths.size()-1;    int32 len = curLen - lengths[id];    int32 rlen = len-sizeof(int32);    if (ness != cpuNess)        rlen = trpg_byteswap_int(rlen);    set(curLen - len,sizeof(int32),(const char *)&rlen);    lengths.resize(id);}/* Appendable File    This class is used as a simple appendable file.  It's used    for dumping tile and texture (or most anything) into. */trpgwAppFile::trpgwAppFile(trpgEndian inNess,const char *fileName,bool reuse){    Init(inNess,fileName,reuse);}void trpgwAppFile::Init(trpgEndian inNess,const char *fileName,bool reuse){    valid = false;    ness = inNess;    cpuNess = trpg_cpu_byte_order();    if (reuse==false) {        if (!(fp = osgDB::fopen(fileName,"wb")))            return;        lengthSoFar = 0;        valid = true;    } else {        if (!(fp = osgDB::fopen(fileName,"ab")))            return;        // ftell is still zero, dammit.  Arg.        fseek(fp,0,SEEK_END);        lengthSoFar = ftell(fp);        valid = true;    }    }trpgwAppFile::~trpgwAppFile(){    if (fp)        fclose(fp);    valid = false;}// Return the amount of data written so far (in total)int trpgwAppFile::GetLengthWritten(){    return lengthSoFar;}// Append the given buffer to our appendable filebool trpgwAppFile::Append(const trpgMemWriteBuffer *buf1,const trpgMemWriteBuffer *buf2){    if (!isValid()) return false;    // Get the total length    int totLen = buf1->length() + (buf2 ? buf2->length() : 0);    // Write the length out    if (fwrite(&totLen,sizeof(int32),1,fp) != 1) {        valid = false;        return false;    }    // Write the data out    const char *data = buf1->getData();    unsigned int len = buf1->length();    if (fwrite(data,sizeof(char),len,fp) != len) {        valid = false;        return false;    }    if (buf2) {        data = buf2->getData();        len = buf2->length();        if (fwrite(data,sizeof(char),len,fp) != len) {            valid = false;            return false;        }    }    lengthSoFar += totLen;    return true;}// Append the given raw data to our appendable filebool trpgwAppFile::Append(const char *data,int size){    if (!isValid()) return false;    if (!data)        return false;    // Write the length out    if (fwrite(&size,sizeof(int32),1,fp) != 1) {        valid = false;        return false;    }    // Write the data out    if (fwrite(data,sizeof(char),size,fp) != (size_t)size) {        valid = false;        return false;    }    lengthSoFar += size;    return true;}// Flushes the current tile filebool trpgwAppFile::Flush(){    // Flush the File *    if (fp)        fflush(fp);    return true;}// Return the current file positionint64 trpgwAppFile::Pos() const{    if (!isValid())        return 0;        // Note: This means an appendable file is capped at 2GB    long pos = ftell(fp);    return pos;}// Validity checkbool trpgwAppFile::isValid() const{    return valid;}

⌨️ 快捷键说明

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