Skip to content

Commit

Permalink
Support for x64 builds; increased internal precision for floats
Browse files Browse the repository at this point in the history
  • Loading branch information
hedger committed Mar 16, 2014
1 parent e8765a5 commit 87ff1f3
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 51 deletions.
13 changes: 7 additions & 6 deletions BWXML/BW.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ limitations under the License.
#pragma once

#include <cassert>
#include <cstdint>

namespace BigWorld
{
static const int PACKED_SECTION_MAGIC = 0x62a14e45;
static const uint32_t PACKED_SECTION_MAGIC = 0x62a14e45;

enum PackedDataType
{
Expand All @@ -38,23 +39,23 @@ namespace BigWorld
// FIXME: use union?
class DataDescriptor
{
unsigned int __raw;
uint32_t __raw;
public:
DataDescriptor() : __raw(0) {};
DataDescriptor(PackedDataType type, unsigned int offset)
DataDescriptor(PackedDataType type, uint32_t offset)
{
assert(offset < 0x0FFFFFFF);
__raw = ((static_cast<unsigned int>(type) << 28) | offset);
__raw = ((static_cast<uint32_t>(type) << 28) | offset);
}

PackedDataType typeId() const {return static_cast<PackedDataType>(__raw >> 28); };
unsigned int offset() const {return __raw & 0x0FFFFFFF; };
uint32_t offset() const {return __raw & 0x0FFFFFFF; };
};
static_assert(sizeof(DataDescriptor) == 4, "Wrong sizeof DataDescriptor, check your compiler settings!");

struct DataNode
{
unsigned short nameIdx;
uint16_t nameIdx;
DataDescriptor data;
};

Expand Down
31 changes: 16 additions & 15 deletions BWXML/BWCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,29 @@ namespace BWPack
using namespace BigWorld;
using namespace IO;

static std::string serializeF(const std::vector<float>& floatVals)
static std::string serializeF(const std::vector<double>& floatVals)
{
std::stringstream _ret;
StreamBufWriter ret(_ret.rdbuf());
std::for_each(floatVals.begin(), floatVals.end(), [&](float v){ ret.put<float>(v); });
std::for_each(floatVals.begin(), floatVals.end(),
[&](float v){ ret.put<float>(static_cast<float>(v)); });
return _ret.str();
}

static std::string serializeI(const long long& intVal)
static std::string serializeI(const int64_t& intVal)
{
std::stringstream _ret;
StreamBufWriter ret(_ret.rdbuf());

unsigned long long absVal = abs(intVal);
if (absVal > std::numeric_limits<long>::max())
ret.put<long long>(intVal);
else if (absVal > std::numeric_limits<short>::max())
ret.put<int>(static_cast<int>(intVal));
else if (absVal > std::numeric_limits<char>::max())
ret.put<short>(static_cast<short>(intVal));
uint64_t absVal = abs(intVal);
if (absVal > std::numeric_limits<int32_t>::max())
ret.put<int64_t>(intVal);
else if (absVal > std::numeric_limits<int16_t>::max())
ret.put<int32_t>(static_cast<int>(intVal));
else if (absVal > std::numeric_limits<int8_t>::max())
ret.put<int16_t>(static_cast<int16_t>(intVal));
else if (absVal != 0)
ret.put<char>(static_cast<char>(intVal));
ret.put<int8_t>(static_cast<int8_t>(intVal));

return _ret.str();
}
Expand All @@ -59,7 +60,7 @@ namespace BWPack
std::stringstream _ret;
StreamBufWriter ret(_ret.rdbuf());
if (boolVal)
ret.put<unsigned char>(1);
ret.put<uint8_t>(1);
return _ret.str();
}

Expand All @@ -76,8 +77,8 @@ namespace BWPack
if ((strVal.find('.') != std::string::npos)
&& (strVal.find('f') == std::string::npos))
{
std::vector<float> values;
float tmp;
std::vector<double> values;
double tmp;
std::stringstream ss;

ss << strVal;
Expand All @@ -98,7 +99,7 @@ namespace BWPack
{
std::stringstream ss;
ss << strVal;
long long i;
uint64_t i;
ss >> i;
if (!ss.fail() && ss.eof())
return rawDataBlock(BW_Int, serializeI(i));
Expand Down
5 changes: 3 additions & 2 deletions BWXML/BWCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ limitations under the License.

#include "BW.hpp"
#include <string>
#include <cstdint>

namespace BWPack
{
Expand All @@ -35,9 +36,9 @@ namespace BWPack

struct dataBlock
{
short stringId;
uint16_t stringId;
rawDataBlock data;
dataBlock(const short _stringId, rawDataBlock _data)
dataBlock(const uint16_t _stringId, rawDataBlock _data)
: stringId(_stringId), data(_data) {};
};

Expand Down
25 changes: 12 additions & 13 deletions BWXML/BWReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ namespace BWPack

BWXMLReader::BWXMLReader(const std::string& fname) : mStream(fname)
{
int magic = mStream.get<int>();
uint32_t magic = mStream.get<uint32_t>();
if (magic != PACKED_SECTION_MAGIC)
throw std::runtime_error("Wrong header magic");

unsigned char version = mStream.get<unsigned char>();
uint8_t version = mStream.get<uint8_t>();
if (version != 0)
throw std::runtime_error("Unsupported file version");
ReadStringTable();
Expand All @@ -56,11 +56,11 @@ namespace BWPack
//std::cout << "Collected " << mStrings.size() << " strings." << std::endl;
};

void BWXMLReader::readData(DataDescriptor descr, ptree& current_node, int prev_offset)
void BWXMLReader::readData( BigWorld::DataDescriptor descr, boost::property_tree::ptree& current_node, uint32_t prev_offset )
{
current_node.clear();
int startPos = prev_offset, endPos = descr.offset();
int var_size = endPos - startPos;
uint32_t startPos = prev_offset, endPos = descr.offset();
uint32_t var_size = endPos - startPos;
assert(var_size >= 0);

std::stringstream contentBuffer;
Expand All @@ -81,17 +81,16 @@ namespace BWPack
switch (var_size)
{
case 8:
current_node.put_value(mStream.get<long long>());
current_node.put_value(mStream.get<int64_t>());
break;
case 4:
current_node.put_value(mStream.get<int>());
current_node.put_value(mStream.get<int32_t>());
break;
case 2:
current_node.put_value(mStream.get<short>());
current_node.put_value(mStream.get<int16_t>());
break;
case 1:
// static_cast'ing to force ptree interprete our 1-byte value as a number, not a character
current_node.put_value(static_cast<int>(mStream.get<char>()));
current_node.put_value(mStream.get<int8_t>());
break;
case 0:
current_node.put_value(0);
Expand All @@ -106,9 +105,9 @@ namespace BWPack
contentBuffer << std::fixed << std::setfill('\t');
if (var_size / sizeof(float) == BW_MATRIX_SIZE) // we've got a matrix!
{
for (int i=0; i<BW_MATRIX_NROWS; ++i)
for (size_t i=0; i<BW_MATRIX_NROWS; ++i)
{
for (int j=0; j<BW_MATRIX_NCOLS; ++j)
for (size_t j=0; j<BW_MATRIX_NCOLS; ++j)
{
if (!contentBuffer.str().empty())
contentBuffer << " ";
Expand Down Expand Up @@ -152,7 +151,7 @@ namespace BWPack
ptree BWXMLReader::ReadSection()
{
ptree current_node;
int nChildren = mStream.get<short>();
int nChildren = mStream.get<uint16_t>();

DataDescriptor ownData = mStream.get<DataDescriptor>();

Expand Down
2 changes: 1 addition & 1 deletion BWXML/BWReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ namespace BWPack

void ReadStringTable();
boost::property_tree::ptree ReadSection();
void readData(BigWorld::DataDescriptor descr, boost::property_tree::ptree& current_node, int prev_offset);
void readData(BigWorld::DataDescriptor descr, boost::property_tree::ptree& current_node, uint32_t prev_offset);
};
}
27 changes: 18 additions & 9 deletions BWXML/BWWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ namespace BWPack
{
using boost::property_tree::ptree;
using namespace BigWorld;
using namespace BWPack;

BWXMLWriter::BWXMLWriter(const std::string& fname)
{
Expand Down Expand Up @@ -74,12 +73,16 @@ namespace BWPack
}
}

int BWXMLWriter::resolveString(const std::string& str) const
uint16_t BWXMLWriter::resolveString(const std::string& str) const
{
auto pos = std::find(mStrings.begin(), mStrings.end(), str);
if (pos == mStrings.end())
throw std::runtime_error("String key not found!");
return (pos - mStrings.begin());
size_t strIdx = std::distance(mStrings.begin(), pos);
if (strIdx > std::numeric_limits<uint16_t>::max())
throw std::runtime_error("String table overflow!");

return static_cast<uint16_t>(strIdx);
}

// 'simple' indicates that we need the node's exact value, even if it has children
Expand Down Expand Up @@ -118,9 +121,12 @@ namespace BWPack
return PackBuffer(node_value.data());
}

BigWorld::DataDescriptor BWXMLWriter::BuildDescriptor(rawDataBlock block, int prevOffset) const
BigWorld::DataDescriptor BWXMLWriter::BuildDescriptor(rawDataBlock block, uint32_t prevOffset) const
{
return DataDescriptor(block.type, prevOffset + block.data.length());
if (block.data.length() > std::numeric_limits<uint32_t>::max())
throw std::runtime_error("Data block is too large");

return DataDescriptor(block.type, prevOffset + static_cast<uint32_t>(block.data.length()));
}

void BWXMLWriter::saveTo(const std::string& destname)
Expand All @@ -130,10 +136,10 @@ namespace BWPack
std::stringstream outbuf;
IO::StreamBufWriter outstream(outbuf.rdbuf());
outstream.put(BigWorld::PACKED_SECTION_MAGIC);
outstream.put<char>(0);
outstream.put<uint8_t>(0);
for (auto it = mStrings.begin(); it!= mStrings.end(); ++it)
outstream.putString(*it);
outstream.put<char>(0);
outstream.put<uint8_t>(0);

outstream.putString(serializeSection(mTree), false);

Expand Down Expand Up @@ -161,11 +167,14 @@ namespace BWPack
childData.push_back(dataBlock(resolveString(it->first), serializeNode(it->second, false)));
}

if (childData.size() > std::numeric_limits<uint16_t>::max())
throw std::runtime_error("Too many children nodes!");

DataDescriptor ownDescriptor = BuildDescriptor(ownData, 0);
ret.put<short>(childData.size());
ret.put<uint16_t>(static_cast<uint16_t>(childData.size()));
ret.put<DataDescriptor>(ownDescriptor);

int currentOffset = ownDescriptor.offset();
uint32_t currentOffset = ownDescriptor.offset();
for (auto it=childData.begin(); it!=childData.end(); ++it)
{
DataNode bwNode;
Expand Down
4 changes: 2 additions & 2 deletions BWXML/BWWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ namespace BWPack
typedef std::vector<BWPack::dataBlock> dataArray;

void collectStrings();
int resolveString(const std::string& str) const;
uint16_t resolveString(const std::string& str) const;
void treeWalker(const boost::property_tree::ptree& node);

BigWorld::DataDescriptor BuildDescriptor(BWPack::rawDataBlock block, int prevOffset) const;
BigWorld::DataDescriptor BuildDescriptor(BWPack::rawDataBlock block, uint32_t prevOffset) const;
BWPack::rawDataBlock serializeNode(const boost::property_tree::ptree& nodeVal, bool simple) const;
std::string serializeSection(const boost::property_tree::ptree& section) const;
};
Expand Down
2 changes: 1 addition & 1 deletion BWXML/DataStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace BWPack
mInput.close();
}

std::string StreamReader::getString(int len)
std::string StreamReader::getString(size_t len)
{
std::string ret;
if (len)
Expand Down
2 changes: 1 addition & 1 deletion BWXML/DataStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace BWPack
return buf;
}

std::string getString(int len);
std::string getString(size_t len);
std::string getNullTerminatedString();
};

Expand Down
2 changes: 1 addition & 1 deletion BWXML/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ std::string FindCommonPrefix(const std::vector<path>& paths)

int main(int argc, char* argv[])
{
std::cout << "BWXML v1.03 by hedger" << std::endl;
std::cout << "BWXML v1.04 by hedger" << std::endl;

bpo::options_description desc("Allowed options");
desc.add_options()
Expand Down

0 comments on commit 87ff1f3

Please sign in to comment.