DataBuf IptcParser::encode(const IptcData& iptcData) { DataBuf buf(iptcData.size()); byte *pWrite = buf.pData_; IptcData::const_iterator iter = iptcData.begin(); IptcData::const_iterator end = iptcData.end(); for ( ; iter != end; ++iter) { // marker, record Id, dataset num *pWrite++ = marker_; *pWrite++ = static_cast<byte>(iter->record()); *pWrite++ = static_cast<byte>(iter->tag()); // extended or standard dataset? long dataSize = iter->size(); if (dataSize > 32767) { // always use 4 bytes for extended length uint16_t sizeOfSize = 4 | 0x8000; us2Data(pWrite, sizeOfSize, bigEndian); pWrite += 2; ul2Data(pWrite, dataSize, bigEndian); pWrite += 4; } else { us2Data(pWrite, static_cast<uint16_t>(dataSize), bigEndian); pWrite += 2; } pWrite += iter->value().copy(pWrite, bigEndian); } return buf; } // IptcParser::encode
void processRemove(const std::string& line, int num, IptcData &iptcData) { std::string::size_type keyStart = line.find_first_not_of(" \t", 1); if (keyStart == std::string::npos) { std::ostringstream os; os << "Invalid \'r\' command at line " << num; throw Error(1, os.str()); } const std::string key( line.substr(keyStart) ); IptcKey iptcKey(key); IptcData::iterator iter = iptcData.findKey(iptcKey); if (iter != iptcData.end()) { iptcData.erase(iter); } }
void processRemove(const std::string& line, int num) { std::string::size_type keyStart = line.find_first_not_of(" \t", 1); if (keyStart == std::string::npos) { std::ostringstream os; os << "Invalid \'r\' command at line " << num; throw Error(os.str()); } const std::string key( line.substr(keyStart) ); std::pair<uint16, uint16> p = IptcDataSets::decomposeKey(key); if (p.first == 0xffff) throw Error("Invalid key" + key); if (p.second == IptcDataSets::invalidRecord) throw Error("Invalid key" + key); IptcData::iterator iter = g_iptcData.findId(p.first, p.second); if (iter != g_iptcData.end()) { g_iptcData.erase(iter); } }
void processModify(const std::string& line, int num) { std::string::size_type keyStart = line.find_first_not_of(" \t", 1); std::string::size_type keyEnd = line.find_first_of(" \t", keyStart+1); std::string::size_type dataStart = line.find_first_not_of(" \t", keyEnd+1); if (keyStart == std::string::npos || keyEnd == std::string::npos || dataStart == std::string::npos) { std::ostringstream os; os << "Invalid \'m\' command at line " << num; throw Error(os.str()); } std::string key(line.substr(keyStart, keyEnd-keyStart)); std::pair<uint16, uint16> p = IptcDataSets::decomposeKey(key); if (p.first == 0xffff) throw Error("Invalid key" + key); if (p.second == IptcDataSets::invalidRecord) throw Error("Invalid key" + key); std::string data(line.substr(dataStart)); // if data starts and ends with quotes, remove them if (data.at(0) == '\"' && data.at(data.size()-1) == '\"') { data = data.substr(1, data.size()-2); } TypeId type = IptcDataSets::dataSetType(p.first, p.second); Value *val = Value::create(type); val->read(data); IptcData::iterator iter = g_iptcData.findId(p.first, p.second); if (iter != g_iptcData.end()) { iter->setValue(val); } else { int rc = g_iptcData.add(IptcKey(key), val); if (rc) { std::string error = IptcData::strError(rc, "Input file"); throw Error(error); } } }
DataBuf IptcParser::encode(const IptcData& iptcData) { DataBuf buf(iptcData.size()); byte *pWrite = buf.pData_; // Copy the iptc data sets and sort them by record but preserve the order of datasets IptcMetadata sortedIptcData; std::copy(iptcData.begin(), iptcData.end(), std::back_inserter(sortedIptcData)); std::stable_sort(sortedIptcData.begin(), sortedIptcData.end(), cmpIptcdataByRecord); IptcData::const_iterator iter = sortedIptcData.begin(); IptcData::const_iterator end = sortedIptcData.end(); for ( ; iter != end; ++iter) { // marker, record Id, dataset num *pWrite++ = marker_; *pWrite++ = static_cast<byte>(iter->record()); *pWrite++ = static_cast<byte>(iter->tag()); // extended or standard dataset? long dataSize = iter->size(); if (dataSize > 32767) { // always use 4 bytes for extended length uint16_t sizeOfSize = 4 | 0x8000; us2Data(pWrite, sizeOfSize, bigEndian); pWrite += 2; ul2Data(pWrite, dataSize, bigEndian); pWrite += 4; } else { us2Data(pWrite, static_cast<uint16_t>(dataSize), bigEndian); pWrite += 2; } pWrite += iter->value().copy(pWrite, bigEndian); } return buf; } // IptcParser::encode
void processModify(const std::string& line, int num, IptcData &iptcData) { std::string::size_type keyStart = line.find_first_not_of(" \t", 1); std::string::size_type keyEnd = line.find_first_of(" \t", keyStart+1); std::string::size_type dataStart = line.find_first_not_of(" \t", keyEnd+1); if (keyStart == std::string::npos || keyEnd == std::string::npos || dataStart == std::string::npos) { std::ostringstream os; os << "Invalid \'m\' command at line " << num; throw Error(1, os.str()); } std::string key(line.substr(keyStart, keyEnd-keyStart)); IptcKey iptcKey(key); std::string data(line.substr(dataStart)); // if data starts and ends with quotes, remove them if (data.at(0) == '\"' && data.at(data.size()-1) == '\"') { data = data.substr(1, data.size()-2); } TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record()); Value::AutoPtr value = Value::create(type); value->read(data); IptcData::iterator iter = iptcData.findKey(iptcKey); if (iter != iptcData.end()) { iter->setValue(value.get()); } else { int rc = iptcData.add(iptcKey, value.get()); if (rc) { throw Error(1, "Iptc dataset already exists and is not repeatable"); } } }