/// // Copyright (C) 2003, 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING /// #include "pfb2pfa.h" #include #include #include "encode.h" #include "util/warning.h" void PS::pfb2pfa(std::istream &in, std::ostream &out, std::vector *lengths) { in.exceptions(std::ios_base::eofbit); // throw exception on eof try { while(in) { // parse header if (in.peek() != 128) throw std::runtime_error("bad magic number for segment"); in.get(); int type = in.get(); switch(type) { case 1: case 2: break; case 3: return; break; // eof signal default: throw std::runtime_error("bad segment type"); break; } long length = 0; for(int i = 0; i < 4; i++) length |= in.get() << (i << 3); std::ostream::pos_type blockstart = out.tellp(); if(blockstart == std::ostream::pos_type(-1)) blockstart = 0; if(type == 1) { // ascii unsigned char c; for(long i = 0; i < length; i++) { c = in.get(); if(c == '\r') c = '\n'; // linefeed instead of carriage return out.put(c); } if(c != '\n') out.put('\n'); // end with linefeed } else { // type == 2 - binary ASCIIHexEncodeFilter filter(false); // don't write eod marker filter.begin(&out); for(long i = 0; i < length; i++) { unsigned char c = in.get(); filter.write(&c, 1); } filter.end(); } if(lengths) lengths->push_back(out.tellp() - blockstart); debug << "Blockstart: " << blockstart << ", end: " << out.tellp() << "\n"; } } catch (std::ios_base::failure) { throw std::runtime_error("unexpected end of file"); } } #ifdef PFB2PFA_STANDALONE int main(int argc, char **argv) { try { PS::pfb2pfa(std::cin, std::cout); } catch(std::runtime_error e) { std::cerr << e.what() << std::endl; return 1; } return 0; } #endif