DOMNode* DeltaReverse( DOMNode *deltaElement, DOMDocument *reversedDoc ) { vddprintf((" reversing time-version header\n")); DOMNode* reversedElement = reversedDoc->importNode( deltaElement, false ); //DOMString from = deltaElement.getAttributes().getNamedItem("from").getNodeValue() ; //DOMString to = deltaElement.getAttributes().getNamedItem("to" ).getNodeValue() ; const XMLCh* from = deltaElement->getAttributes()->getNamedItem(XMLString::transcode("from"))->getNodeValue() ; const XMLCh* to = deltaElement->getAttributes()->getNamedItem(XMLString::transcode("to"))->getNodeValue() ; reversedElement->getAttributes()->getNamedItem(XMLString::transcode("to"))->setNodeValue( from ); reversedElement->getAttributes()->getNamedItem(XMLString::transcode("from"))->setNodeValue( to ); DOMNode* fromXidMap = deltaElement->getAttributes()->getNamedItem(XMLString::transcode("fromXidMap")); DOMNode* toXidMap = deltaElement->getAttributes()->getNamedItem(XMLString::transcode("toXidMap")); if (fromXidMap!=NULL) { //DOMString from = fromXidMap.getNodeValue(); reversedElement->getAttributes()->getNamedItem(XMLString::transcode("toXidMap"))->setNodeValue( fromXidMap->getNodeValue() ); } if (toXidMap!=NULL) { //DOMString to = toXidMap.getNodeValue(); reversedElement->getAttributes()->getNamedItem(XMLString::transcode("fromXidMap"))->setNodeValue( toXidMap->getNodeValue() ); } // No chanhges in the delta -> ok if (!deltaElement->hasChildNodes()) return( reversedElement ); // Input : read Elementary Operation DOMNode* child = deltaElement->getFirstChild() ; // Output : precedent will be used to write Elementary Operation in reverse order DOMNode* precedent = NULL; // =NULL by default while (child != NULL) { if (child->getNodeType()!=DOMNode::ELEMENT_NODE) THROW_AWAY(("Bad type (%d) for Delta Operation Node", (int)child->getNodeType())); DOMElement* operationNode = (DOMElement*) child ; XyLatinStr operation(child->getLocalName()); // Reverse DELETE into INSERT if (strcmp(operation, "d")==0) { vddprintf((" reversing delete into insert\n")); DOMElement* iElement = reversedDoc->createElementNS(XYDIFF_XYDELTA_NS, XMLString::transcode("xy:i")) ; CopyAttr(iElement, operationNode, XMLString::transcode("par"), true); CopyAttr(iElement, operationNode, XMLString::transcode("pos"), true); CopyAttr(iElement, operationNode, XMLString::transcode("xm"), true); CopyAttr(iElement, operationNode, XMLString::transcode("move"), false); CopyAttr(iElement, operationNode, XMLString::transcode("update"), false); CopyContent(iElement, operationNode); reversedElement->insertBefore( iElement, precedent ) ; precedent = iElement ; } // Reverse INSERT into DELETE else if (strcmp(operation, "i")==0) { vddprintf((" reversing insert into delete\n")); DOMElement *iElement = reversedDoc->createElementNS(XYDIFF_XYDELTA_NS, XMLString::transcode("xy:d")) ; CopyAttr(iElement, operationNode, XMLString::transcode("par"), true); CopyAttr(iElement, operationNode, XMLString::transcode("pos"), true); CopyAttr(iElement, operationNode, XMLString::transcode("xm"), true); CopyAttr(iElement, operationNode, XMLString::transcode("move"), false); CopyAttr(iElement, operationNode, XMLString::transcode("update"), false); CopyContent(iElement, operationNode); reversedElement->insertBefore( iElement, precedent ) ; precedent = iElement ; } // Attribute Update else if (strcmp(operation, "au")==0) { vddprintf((" reversing attribute update\n")); //DOMString xidElem = operationNode.getAttributes().getNamedItem("xid").getNodeValue(); //DOMString attrName = operationNode.getAttributes().getNamedItem("a").getNodeValue(); //DOMString oldValue = operationNode.getAttributes().getNamedItem("ov").getNodeValue(); //DOMString newValue = operationNode.getAttributes().getNamedItem("nv").getNodeValue(); const XMLCh* xidElem = operationNode->getAttributes()->getNamedItem(XMLString::transcode("xid"))->getNodeValue(); const XMLCh* attrName = operationNode->getAttributes()->getNamedItem(XMLString::transcode("a"))->getNodeValue(); const XMLCh* oldValue = operationNode->getAttributes()->getNamedItem(XMLString::transcode("ov"))->getNodeValue(); const XMLCh* newValue = operationNode->getAttributes()->getNamedItem(XMLString::transcode("nv"))->getNodeValue(); DOMElement* auElement = reversedDoc->createElementNS(XYDIFF_XYDELTA_NS, XMLString::transcode("xy:au")); auElement->setAttribute(XMLString::transcode("xid"), xidElem); auElement->setAttribute(XMLString::transcode("a"), attrName); auElement->setAttribute(XMLString::transcode("nv"), oldValue); auElement->setAttribute(XMLString::transcode("ov"), newValue); reversedElement->insertBefore(auElement, precedent); precedent = auElement ; } // Attribute Delete else if (strcmp(operation, "ad")==0) { vddprintf((" reversing attribute insert into attribute delete\n")); //DOMString xidElem = operationNode.getAttributes().getNamedItem("xid").getNodeValue(); //DOMString attrName = operationNode.getAttributes().getNamedItem("a").getNodeValue(); //DOMString attrVal = operationNode.getAttributes().getNamedItem("v").getNodeValue(); const XMLCh* xidElem = operationNode->getAttributes()->getNamedItem(XMLString::transcode("xid"))->getNodeValue(); const XMLCh* attrName = operationNode->getAttributes()->getNamedItem(XMLString::transcode("a"))->getNodeValue(); const XMLCh* attrVal = operationNode->getAttributes()->getNamedItem(XMLString::transcode("v"))->getNodeValue(); DOMElement* aiElement = reversedDoc->createElementNS(XYDIFF_XYDELTA_NS, XMLString::transcode("xy:ai")); aiElement->setAttribute(XMLString::transcode("xid"), xidElem); aiElement->setAttribute(XMLString::transcode("a"), attrName); aiElement->setAttribute(XMLString::transcode("v"), attrVal); reversedElement->insertBefore(aiElement, precedent); precedent = aiElement ; } // Attribute Insert else if (strcmp(operation, "ai")==0) { vddprintf((" reversing attribute delete into attribute insert\n")); //DOMString xidElem = operationNode.getAttributes().getNamedItem("xid").getNodeValue(); //DOMString attrName = operationNode.getAttributes().getNamedItem("a").getNodeValue(); //DOMString attrVal = operationNode.getAttributes().getNamedItem("v").getNodeValue(); const XMLCh* xidElem = operationNode->getAttributes()->getNamedItem(XMLString::transcode("xid"))->getNodeValue(); const XMLCh* attrName = operationNode->getAttributes()->getNamedItem(XMLString::transcode("a"))->getNodeValue(); const XMLCh* attrVal = operationNode->getAttributes()->getNamedItem(XMLString::transcode("v"))->getNodeValue(); DOMElement* adElement = reversedDoc->createElementNS(XYDIFF_XYDELTA_NS, XMLString::transcode("xy:ad")); adElement->setAttribute(XMLString::transcode("xid"), xidElem); adElement->setAttribute(XMLString::transcode("a"), attrName); adElement->setAttribute(XMLString::transcode("v"), attrVal); reversedElement->insertBefore(adElement, precedent); precedent = adElement ; } // Reverse UPDATE to UPDATE else if (strcmp(operation, "u")==0) { vddprintf((" reversing update\n")); DOMNode* oldValue = child->getFirstChild() ; if ( oldValue==NULL ) throw ReverseUpdateException("<update> has no child!"); DOMNode* newValue = oldValue->getNextSibling() ; if ( newValue==NULL ) throw ReverseUpdateException("<update> has only one child!"); //DOMString xid= child.getAttributes().getNamedItem("xid").getNodeValue() ; const XMLCh* xid= child->getAttributes()->getNamedItem(XMLString::transcode("xid"))->getNodeValue() ; DOMElement *uElement = reversedDoc->createElementNS(XYDIFF_XYDELTA_NS, XMLString::transcode("xy:u")) ; uElement->setAttribute(XMLString::transcode("xid"), xid); DOMElement* uOld = reversedDoc->createElementNS(XYDIFF_XYDELTA_NS, XMLString::transcode("xy:ov")); DOMNode* uOldText = reversedDoc->importNode( newValue->getFirstChild(), true ); uOld->appendChild( uOldText ); DOMElement* uNew = reversedDoc->createElementNS(XYDIFF_XYDELTA_NS, XMLString::transcode("xy:nv")); DOMNode* uNewText = reversedDoc->importNode( oldValue->getFirstChild(), true ); uNew->appendChild( uNewText ); uElement->appendChild( uOld ) ; uElement->appendChild( uNew ) ; reversedElement->insertBefore( uElement, precedent ) ; precedent = uElement ; } else if (strcmp(operation, "renameRoot")==0) { vddprintf((" reversing renameRoot operation\n")); const XMLCh* rFrom = operationNode->getAttributes()->getNamedItem(XMLString::transcode("from"))->getNodeValue(); const XMLCh* rTo = operationNode->getAttributes()->getNamedItem(XMLString::transcode("to"))->getNodeValue(); DOMElement *rrElement = reversedDoc->createElementNS(XYDIFF_XYDELTA_NS, XMLString::transcode("xy:renameRoot")); rrElement->setAttribute(XMLString::transcode("from"), rTo); rrElement->setAttribute(XMLString::transcode("to"), rFrom); reversedElement->insertBefore(rrElement, precedent); precedent = rrElement ; } else { throw DeltaReverseException("Invalid Data", "main", "Unknown operation <" + std::string(operation) + ">") ; } child = child->getNextSibling(); } return ( reversedElement ) ; }
// the formatter's core, wraps the line and justifies it if needed int TextFormatter::WrapLine(CFDC& dc, Paragraph& pp, FilePos& pos, LineArray& la, int top, int maxh) { if (maxh <= 0) return 0; // process images separately if (pp.flags&Paragraph::image) return WrapImage(dc, pp, pos, la, top, maxh); if (pp.len == 0 || (pp.len == 1 && pp.str[0] == L' ')) { dc.SelectFont(0, 0); int fh, fa; dc.GetFontSize(fh, fa); if (fh > maxh) return -1; Line l; l.pos = pos; l.flags = Line::first | Line::last | Line::defstyle; l.height = fh; l.base = fa; la.Add(l); pos.off = pp.len; return l.height; } if (m_hyphenate) pp.Hyphenate(); const wchar_t *str = pp.str; int len = pp.len; Buffer<int> dx(len + 1); int toth = 0; while (toth < maxh && pos.off < len) { // 1. get text size int nch = len; int curwidth = m_width; int ispace = 0; if (pos.off == 0 && (pp.flags&(Paragraph::center | Paragraph::right)) == 0) AdjustIndent(curwidth, ispace, pp.lindent, pp.rindent, pp.findent, dc.GetLPX()); else AdjustIndent(curwidth, ispace, pp.lindent, pp.rindent, 0, dc.GetLPX()); dx[0] = 0; int lh = 1, lbase = 1; GetTextExtent(dc, pp, pos.off, curwidth, nch, dx + 1, lh, lbase); if (toth + lh > maxh) return -1; if (nch == 0) nch = 1; // 2. do word wrap bool addhyp = false; if (nch + pos.off < pp.str.size()) { int i; for (i = nch; i > 0 && str[pos.off + i] != L' '; --i) { // wrap at existing dashes if (i < nch && (str[pos.off + i] == L'-' || str[pos.off + i] == 0x2013 || str[pos.off + i] == 0x2014) && i < len - 1 && (str[pos.off + i + 1] == L' ' || iswalpha(str[pos.off + i + 1]))) { ++i; break; } // or at possible hyphenation points if (m_hyphenate && pp.cflags[pos.off + i].hyphen && dx[i] + dc.GetHypWidth() <= curwidth) { addhyp = true; break; } } if (i > 0) nch = i; else addhyp = false; } // insert it into line list if (pos.off == 0 && nch == pp.str.size()) { // got full line Line l(str, len, false); l.pos = pos; l.flags = Line::first | Line::last; l.ispace = ispace; l.height = lh; l.base = lbase; if (dx[nch] < curwidth) { if (pp.flags&Paragraph::center) l.ispace += (curwidth - dx[nch]) / 2; else if (pp.flags&Paragraph::right) l.ispace += curwidth - dx[nch]; } CopyAttr(l.attr, pp.cflags, len); for (int j = 0; j < len; ++j) l.dx[j] = dx[j + 1] - dx[j]; la.Add(l); pos.off = len; } else { Line l(str + pos.off, nch, addhyp); if (addhyp) l.str[nch] = L'-'; l.pos = pos; l.ispace = ispace; l.height = lh; l.base = lbase; l.flags = 0; if (pos.off == 0) l.flags |= Line::first; if (pos.off + nch == pp.str.size()) l.flags |= Line::last; for (int j = 0; j < nch; ++j) l.dx[j] = dx[j + 1] - dx[j]; int extra_width = 0; if (addhyp) l.dx[nch] = extra_width = dc.GetHypWidth(); // 3. justify/center text if needed if (dx[nch] < curwidth) { if (addhyp) curwidth -= extra_width; if (pp.flags&Paragraph::center) { l.ispace += (curwidth - dx[nch]) / 2; } else if (pp.flags&Paragraph::right) { l.ispace += curwidth - dx[nch]; } else if ((m_justified || pp.flags&Paragraph::justify) && !(l.flags&Line::last)) { // count spaces in string int nspc = 0, i; for (i = 0; i < nch; ++i) if (L' ' == str[pos.off + i]) ++nspc; // and distribute extra width to them if (nspc > 0) { int addw = (curwidth - dx[nch]) / nspc; int extraddw = curwidth - dx[nch] - addw*nspc; for (i = 0; i < nch; ++i) { if (str[pos.off + i] == L' ') { l.dx[i] += addw; if (extraddw) { ++l.dx[i]; --extraddw; } } } } } } CopyAttr(l.attr, pp.cflags + pos.off, nch); if (addhyp) l.attr[nch] = l.attr[nch - 1]; la.Add(l); pos.off += nch; while (pos.off < len && str[pos.off] == L' ') ++pos.off; } toth += lh; } return toth; }
void GenesisCopyWindow::CopyDirectory(const char *dirname, const char *destination, const char *destdirname) //////////////////////////////////////////////////////////////////////// { BEntry srcentry(dirname); BEntry dstentry; char name[B_FILE_NAME_LENGTH]; BString fulldestdir; if (srcentry.InitCheck()!=B_OK) return; if (!srcentry.Exists()) return; srcentry.GetName(name); fulldestdir.SetTo(destination); if (destdirname) fulldestdir << "/" << destdirname; else fulldestdir << "/" << name; dstentry.SetTo(fulldestdir.String()); if (dstentry.InitCheck()!=B_OK) return; if (!dstentry.Exists()) { if (create_directory(fulldestdir.String(), 0777)!=B_OK) // TODO: jo a 0777? return; } BDirectory dir; dir.SetTo(dirname); if (dir.InitCheck()==B_OK) { BEntry entry; if (dir.GetEntry(&entry)==B_OK) { while (dir.GetNextEntry(&entry)==B_OK) { entry.GetName(name); if (entry.IsDirectory()) { BString fullname; fullname.SetTo(dirname); fullname << "/" << name; CopyDirectory(fullname.String(), fulldestdir.String()); } else if (entry.IsSymLink()) { BString fullname; fullname.SetTo(dirname); fullname << "/" << name; CopyLink(fullname.String(), fulldestdir.String()); } else { BString fullname; fullname.SetTo(dirname); fullname << "/" << name; CopyFile(fullname.String(), fulldestdir.String()); } } } } // Copy attributes... CopyAttr(dirname, fulldestdir.String()); }
bool GenesisCopyWindow::CopyLink(const char *linkname, const char *destination, const char *destfilename) //////////////////////////////////////////////////////////////////////// { BSymLink srclink; BSymLink dstlink; BDirectory dstdir; BEntry srcentry; BEntry symlinkentry; BPath LinkPath; char name[B_FILE_NAME_LENGTH]; struct stat statbuf; entry_ref ref; srcentry.SetTo(linkname); srcentry.GetName(name); srcentry.GetRef(&ref); symlinkentry.SetTo(&ref, true); symlinkentry.GetPath(&LinkPath); if (destfilename) sprintf(name,"%s",destfilename); if (srcentry.GetStat(&statbuf)!=B_OK) return false; dstdir.SetTo(destination); if (dstdir.InitCheck()!=B_OK) return false; Lock(); m_FileBar->Update(-m_FileBar->CurrentValue()); // Reset to 0.0 m_FileBar->SetMaxValue(1); m_FileBar->SetTrailingText(name); Unlock(); if (dstdir.CreateSymLink(name, LinkPath.Path(), &dstlink)!=B_OK && !m_SkipSymLinkCreationError) { BString text; text << "Cannot create '" << name << "' symbolic link in '" << LinkPath.Path() << "'"; BAlert *myAlert = new BAlert("Copy",text.String(),"Abort","Skip all","Skip",B_WIDTH_AS_USUAL,B_OFFSET_SPACING,B_WARNING_ALERT); myAlert->SetShortcut(0, B_ESCAPE); switch (myAlert->Go()) { case 0: Close(); kill_thread(m_CopyThread); break; case 1: m_SkipSymLinkCreationError = true; break; } return false; } Lock(); m_FileBar->Update(1); Unlock(); dstlink.SetPermissions(statbuf.st_mode); dstlink.SetOwner(statbuf.st_uid); dstlink.SetGroup(statbuf.st_gid); dstlink.SetModificationTime(statbuf.st_mtime); dstlink.SetCreationTime(statbuf.st_crtime); // Copy attributes... BString destlinkname; destlinkname.SetTo(""); destlinkname << destination << "/" << name; CopyAttr(linkname, destlinkname.String()); return true; }
bool GenesisCopyWindow::CopyFile(const char *filename, const char *destination, const char *destfilename) //////////////////////////////////////////////////////////////////////// { char name[B_FILE_NAME_LENGTH]; BString destname; BEntry srcentry(filename); BEntry dstentry(destination); struct stat statbuf; ssize_t len; srcentry.GetName(name); destname.SetTo(destination); destname += "/"; if (destfilename) destname += destfilename; else destname += name; BEntry dstfileentry(destname.String()); if (dstfileentry.InitCheck()!=B_OK) return false; if (dstfileentry.Exists() && !m_OverwriteAll) { BString text; text << "File '" << name << "' already exists. Do you want to overwrite it?"; BAlert *myAlert = new BAlert("Copy",text.String(),"Abort","Overwrite all","Overwrite",B_WIDTH_AS_USUAL,B_OFFSET_SPACING,B_WARNING_ALERT); myAlert->SetShortcut(0, B_ESCAPE); switch (myAlert->Go()) { case 0: Close(); kill_thread(m_CopyThread); break; case 1: m_OverwriteAll = true; break; } } BFile srcfile(filename, B_READ_ONLY); BFile dstfile(destname.String(), B_WRITE_ONLY | B_CREATE_FILE); if (srcentry.InitCheck()!=B_OK) return false; if (dstentry.InitCheck()!=B_OK) return false; if (!srcentry.Exists()) return false; if (!dstentry.Exists()) { return false; } if (srcentry.GetStat(&statbuf)!=B_OK) { return false; } unsigned char *buf = new unsigned char[statbuf.st_blksize]; if (!buf) { return false; } Lock(); m_FileBar->Update(-m_FileBar->CurrentValue()); // Reset to 0.0 m_FileBar->SetMaxValue(statbuf.st_size); m_FileBar->SetTrailingText(name); Unlock(); while (true) { len = srcfile.Read(buf, statbuf.st_blksize); if (len>0) { dstfile.Write(buf, len); Lock(); m_FileBar->Update(len); Unlock(); } else if (len<0) // error { delete [] buf; return false; } else // No more bytes to copy, we are done... break; } dstfile.SetPermissions(statbuf.st_mode); dstfile.SetOwner(statbuf.st_uid); dstfile.SetGroup(statbuf.st_gid); dstfile.SetModificationTime(statbuf.st_mtime); dstfile.SetCreationTime(statbuf.st_crtime); delete [] buf; // Copy attributes... CopyAttr(filename, destname.String()); return true; }