| 80 | } |
| 81 | |
| 82 | void IfcLoader::SaveFile(const std::function<void(char *, size_t)> &outputData, bool orderLinesByExpressID) const |
| 83 | { |
| 84 | std::ostringstream output; |
| 85 | output << "ISO-10303-21;"<<std::endl<<"HEADER;"<<std::endl; |
| 86 | output << "/******************************************************" << std::endl; |
| 87 | output << "* STEP Physical File produced by: That Open Engine WebIfc " << WEB_IFC_VERSION_NUMBER << std::endl; |
| 88 | output << "* Module: web-ifc/IfcLoader" << std::endl; |
| 89 | output << "* Version: " << WEB_IFC_VERSION_NUMBER << std::endl; |
| 90 | output << "* Source: https://github.com/ThatOpen/engine_web-ifc" << std::endl; |
| 91 | output << "* Issues: https://github.com/ThatOpen/engine_web-ifc/issues" << std::endl; |
| 92 | output << "******************************************************/" << std::endl; |
| 93 | |
| 94 | uint32_t linesWritten = 0; |
| 95 | for (uint8_t z=0; z < 2; z++) |
| 96 | { |
| 97 | std::vector<IfcLine*>* currentLines; |
| 98 | if(z==0) currentLines= (std::vector<IfcLine*>*) &_headerLines; |
| 99 | else { |
| 100 | currentLines = new std::vector<IfcLine*>(); |
| 101 | std::transform( _lines.begin(), _lines.end(), std::back_inserter( *currentLines ), [](auto &kv){ return kv.second;} ); |
| 102 | } |
| 103 | if (orderLinesByExpressID) { |
| 104 | // Sort based on tapeOffset, which preserves the order by which the lines have been pushed |
| 105 | std::sort(currentLines->begin(), currentLines->end(), [](const IfcLine* a, const IfcLine* b) { return a->tapeOffset < b->tapeOffset; }); |
| 106 | } |
| 107 | for(uint32_t i=0; i < currentLines->size();i++) |
| 108 | { |
| 109 | |
| 110 | IfcLine * line = (*currentLines)[i]; |
| 111 | |
| 112 | if (line->ifcType == 0) continue; |
| 113 | _tokenStream->MoveTo(line->tapeOffset); |
| 114 | bool newLine = true; |
| 115 | bool insideSet = false; |
| 116 | IfcTokenType prev = IfcTokenType::EMPTY; |
| 117 | while (!_tokenStream->IsAtEnd()) |
| 118 | { |
| 119 | IfcTokenType t = static_cast<IfcTokenType>(_tokenStream->Read<char>()); |
| 120 | |
| 121 | if (t != IfcTokenType::SET_END && t != IfcTokenType::LINE_END) |
| 122 | { |
| 123 | if (insideSet && prev != IfcTokenType::SET_BEGIN && prev != IfcTokenType::LABEL && prev != IfcTokenType::LINE_END) |
| 124 | { |
| 125 | output << ","; |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | if (t == IfcTokenType::LINE_END) |
| 130 | { |
| 131 | output << ";" << std::endl; |
| 132 | break; |
| 133 | } |
| 134 | |
| 135 | switch (t) |
| 136 | { |
| 137 | case IfcTokenType::UNKNOWN: |
| 138 | { |
| 139 | output << "*"; |