//======================================================================
//
// Do the command in query mode. It only does one thing, print the Stream,
// Channel, Associations, and Structure formats available.
//
MStatus exportMetadataCmd::doQuery()
{
	assert( fSerializer );
	MStatus status = MS::kSuccess;

	std::set<const adsk::Data::StreamSerializer*>::iterator sFmtIt;
	for( sFmtIt = adsk::Data::StreamSerializer::allFormats().begin();
		 sFmtIt != adsk::Data::StreamSerializer::allFormats().end(); sFmtIt++ )
	{
		const adsk::Data::StreamSerializer* fmt = *sFmtIt;
		MString fmtMsg( MStringResource::getString(kExportMetadataFormatType, status) );
		MString fmtType( "Stream" );
		MString fmtName( fmt->formatType() );
		MString msg;
		msg.format( fmtMsg, fmtType, fmtName );
		appendToResult( msg );
	}

	std::set<const adsk::Data::ChannelSerializer*>::iterator cFmtIt;
	for( cFmtIt = adsk::Data::ChannelSerializer::allFormats().begin();
		 cFmtIt != adsk::Data::ChannelSerializer::allFormats().end(); cFmtIt++ )
	{
		const adsk::Data::ChannelSerializer* fmt = *cFmtIt;
		MString fmtMsg( MStringResource::getString(kExportMetadataFormatType, status) );
		MString fmtType( "Channel" );
		MString fmtName( fmt->formatType() );
		MString msg;
		msg.format( fmtMsg, fmtType, fmtName );
		appendToResult( msg );
	}

	std::set<const adsk::Data::AssociationsSerializer*>::iterator aFmtIt;
	for( aFmtIt = adsk::Data::AssociationsSerializer::allFormats().begin();
		 aFmtIt != adsk::Data::AssociationsSerializer::allFormats().end(); aFmtIt++ )
	{
		const adsk::Data::AssociationsSerializer* fmt = *aFmtIt;
		MString fmtMsg( MStringResource::getString(kExportMetadataFormatType, status) );
		MString fmtType( "Associations" );
		MString fmtName( fmt->formatType() );
		MString msg;
		msg.format( fmtMsg, fmtType, fmtName );
		appendToResult( msg );
	}

	std::set<const adsk::Data::StructureSerializer*>::iterator fmtIt;
	for( fmtIt = adsk::Data::StructureSerializer::allFormats().begin();
		 fmtIt != adsk::Data::StructureSerializer::allFormats().end(); fmtIt++ )
	{
		const adsk::Data::StructureSerializer* fmt = *fmtIt;
		MString fmtMsg( MStringResource::getString(kExportMetadataFormatType, status) );
		MString fmtType( "Structure" );
		MString fmtName( fmt->formatType() );
		MString msg;
		msg.format( fmtMsg, fmtType, fmtName );
		appendToResult( msg );
	}

	return status;
}
	ProperClassMethods::ProperClassMethods(shared_ptr<Class> const &clazz)
	{
		for(std::size_t m=0;m<clazz->get_methods_count();++m)
		{
			proper_method pm(clazz->get_method(m));
			if(!m_methods.push_back(pm).second)
			{
				std::size_t n(1);
				do
				{
					format fmtName("%1%_%2%");
					fmtName % clazz->get_method(m)->get_name();
					fmtName % n++;
					pm.m_proper_name=fmtName.str();
				}
				while(!m_methods.push_back(pm).second);
			}
		}
	}
void 
MediaDocument::UpdateTitleAndCharset(const nsACString& aTypeStr,
                                     const char* const* aFormatNames,
                                     int32_t aWidth, int32_t aHeight,
                                     const nsAString& aStatus)
{
  nsXPIDLString fileStr;
  GetFileName(fileStr);

  NS_ConvertASCIItoUTF16 typeStr(aTypeStr);
  nsXPIDLString title;

  if (mStringBundle) {
    // if we got a valid size (not all media have a size)
    if (aWidth != 0 && aHeight != 0) {
      nsAutoString widthStr;
      nsAutoString heightStr;
      widthStr.AppendInt(aWidth);
      heightStr.AppendInt(aHeight);
      // If we got a filename, display it
      if (!fileStr.IsEmpty()) {
        const char16_t *formatStrings[4]  = {fileStr.get(), typeStr.get(), 
          widthStr.get(), heightStr.get()};
        NS_ConvertASCIItoUTF16 fmtName(aFormatNames[eWithDimAndFile]);
        mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 4,
                                            getter_Copies(title));
      } 
      else {
        const char16_t *formatStrings[3]  = {typeStr.get(), widthStr.get(), 
          heightStr.get()};
        NS_ConvertASCIItoUTF16 fmtName(aFormatNames[eWithDim]);
        mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 3,
                                            getter_Copies(title));
      }
    } 
    else {
    // If we got a filename, display it
      if (!fileStr.IsEmpty()) {
        const char16_t *formatStrings[2] = {fileStr.get(), typeStr.get()};
        NS_ConvertASCIItoUTF16 fmtName(aFormatNames[eWithFile]);
        mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 2,
                                            getter_Copies(title));
      }
      else {
        const char16_t *formatStrings[1] = {typeStr.get()};
        NS_ConvertASCIItoUTF16 fmtName(aFormatNames[eWithNoInfo]);
        mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 1,
                                            getter_Copies(title));
      }
    }
  } 

  // set it on the document
  if (aStatus.IsEmpty()) {
    SetTitle(title);
  }
  else {
    nsXPIDLString titleWithStatus;
    const nsPromiseFlatString& status = PromiseFlatString(aStatus);
    const char16_t *formatStrings[2] = {title.get(), status.get()};
    NS_NAMED_LITERAL_STRING(fmtName, "TitleWithStatus");
    mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 2,
                                        getter_Copies(titleWithStatus));
    SetTitle(titleWithStatus);
  }
}
/**
 * Canonize interface name. If attempt is not NULL, pick the interface
 * which has that address.
 * If attempt is NULL, pick interfaces in the following order of preference
 * 1. eth0
 * 2. Anything starting with eth0:
 * 3. Anything starting with eth
 * 4. Anything else
 * 5. localhost
 * 6. zero address
 */
net_if_t *getNetIf(const char *wanted) {
#ifndef __MINGW32__
	struct ifreq *ifrp, *ifend, *chosen;
	struct ifconf ifc;
	int s;
#else /* __MINGW32__ */
	int i;

	int etherNo=-1;
	int wantedEtherNo=-2; /* Wanted ethernet interface */

	MIB_IPADDRTABLE *iptab=NULL;
	MIB_IFTABLE *iftab=NULL;

	MIB_IPADDRROW *iprow, *chosen=NULL;
	MIB_IFROW *chosenIf=NULL;
	WORD wVersionRequested; /* Version of Winsock to load */
	WSADATA wsaData; /* Winsock implementation details */
	ULONG a;

	int r;
#endif /* __MINGW32__ */

	int lastGoodness=0;
	struct in_addr wantedAddress;
	int isAddress=0;
	int wantedLen=0;
	net_if_t *net_if;

	if(wanted == NULL) {
	    wanted = getenv("IFNAME");
	}

	if(wanted && INET_ATON(wanted, &wantedAddress))
	    isAddress=1;
	else
	    wantedAddress.s_addr=0;

	if(wanted)
	    wantedLen=strlen(wanted);

	net_if = MALLOC(net_if_t);
	if(net_if == NULL)
	    udpc_fatal(1, "Out of memory error");

#ifndef __MINGW32__

	s = socket(PF_INET, SOCK_DGRAM, 0);
	if (s < 0) {
	    perror("make socket");
	    exit(1);
	}

	ifc.ifc_len = sizeof(struct ifreq) * 10;
	while(1) {
	    size_t len = ifc.ifc_len;
	    ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len);
	    if(ifc.ifc_buf == NULL) {
		udpc_fatal(1, "Out of memory error");
	    }

	    if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0 ||
		ifc.ifc_len < (signed int)sizeof(struct ifreq)) {
		perror("udpcast: SIOCGIFCONF: ");
		exit(1);
	    }

	    if(len == ifc.ifc_len) {
		ifc.ifc_len += sizeof(struct ifreq) * 10;
		free(ifc.ifc_buf);
	    } else
		break;
	}

	ifend = (struct ifreq *)((char *)ifc.ifc_buf + ifc.ifc_len);
	chosen=NULL;

	for (ifrp = (struct ifreq *) ifc.ifc_buf ; ifrp < ifend;
#ifdef IFREQ_SIZE
	     ifrp = IFREQ_SIZE(*ifrp) + (char *)ifrp
#else
	     ifrp++
#endif
	     ) {
	    unsigned long iaddr = getSinAddr(&ifrp->ifr_addr).s_addr;
	    int goodness;

	    if(ifrp->ifr_addr.sa_family != PF_INET)
		continue;

	    if(wanted) {
		if(isAddress && iaddr == wantedAddress.s_addr) {
		    goodness=8;
		} else if(strcmp(wanted, ifrp->ifr_name) ==0) {
		    /* perfect match on interface name */
		    goodness=12;
		} else if(wanted != NULL &&
			  strncmp(wanted, ifrp->ifr_name, wantedLen) ==0) {
		    /* prefix match on interface name */
		    goodness=7;
		} else {
		    /* no match, try next */
		    continue;
		}
	    } else {
		if(iaddr == 0) {
		    /* disregard interfaces whose address is zero */
		    goodness = 1;
		} else if(iaddr == htonl(0x7f000001)) {
		    /* disregard localhost type devices */
		    goodness = 2;
		} else if(strcmp("eth0", ifrp->ifr_name) == 0 ||
			  strcmp("en0",  ifrp->ifr_name) == 0) {
		    /* prefer first ethernet interface */
		    goodness = 6;
		} else if(strncmp("eth0:", ifrp->ifr_name, 5) == 0) {
		    /* second choice: any secondary addresses of first ethernet */
		    goodness = 5;
		} else if(strncmp("eth", ifrp->ifr_name, 3) == 0 ||
			  strncmp("en",  ifrp->ifr_name, 2) == 0) {
		    /* and, if not available, any other ethernet device */
		    goodness = 4;
		} else {
		    goodness = 3;
		}
	    }

	    if(hasLink(s, ifrp->ifr_name))
	      /* Good or unknown link status privileged over known
	       * disconnected */
	      goodness += 3;

	    /* If all else is the same, prefer interfaces that
	     * have broadcast */
	    goodness = goodness * 2;
	    if(goodness >= lastGoodness) {
		/* Privilege broadcast-enabled interfaces */
		if(ioctl(s,  SIOCGIFBRDADDR, ifrp) < 0)
		    udpc_fatal(-1, "Error getting broadcast address for %s: %s",
			       ifrp->ifr_name, strerror(errno));
		if(getSinAddr(&ifrp->ifr_ifru.ifru_broadaddr).s_addr)
		    goodness++;
	    }

	    if(goodness > lastGoodness) {
		chosen = ifrp;
		lastGoodness = goodness;
		net_if->addr.s_addr = iaddr;
	    }
	}


	if(!chosen) {
	    fprintf(stderr, "No suitable network interface found\n");
	    fprintf(stderr, "The following interfaces are available:\n");

	    for (ifrp = (struct ifreq *) ifc.ifc_buf ; ifrp < ifend;
#ifdef IFREQ_SIZE
		 ifrp = IFREQ_SIZE(*ifrp) + (char *)ifrp
#else
		 ifrp++
#endif
		 ) {
		char buffer[16];

		if(ifrp->ifr_addr.sa_family != PF_INET)
		    continue;

		fprintf(stderr, "\t%s\t%s\n",
			ifrp->ifr_name,
			udpc_getIpString((struct sockaddr_in *)&ifrp->ifr_addr, buffer));
	    }
	    exit(1);
	}

	net_if->name = strdup(chosen->ifr_name);

#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
	/* Index for multicast subscriptions */
	if(ioctl(s,  SIOCGIFINDEX, chosen) < 0)
	    udpc_fatal(-1, "Error getting index for %s: %s", net_if->name,
		       strerror(errno));
	net_if->index = chosen->ifr_ifindex;
#endif

	/* Broadcast */
	if(ioctl(s,  SIOCGIFBRDADDR, chosen) < 0)
	    udpc_fatal(-1, "Error getting broadcast address for %s: %s",
		       net_if->name, strerror(errno));
	net_if->bcast = getSinAddr(&chosen->ifr_ifru.ifru_broadaddr);

	close(s);
	free(ifc.ifc_buf);

#else /* __MINGW32__ */

	/* WINSOCK initialization */
	wVersionRequested = MAKEWORD(2, 0); /* Request Winsock v2.0 */
	if (WSAStartup(wVersionRequested, &wsaData) != 0) /* Load Winsock DLL */ {
	    fprintf(stderr,"WSAStartup() failed");
	    exit(1);
	}
	/* End WINSOCK initialization */


	a=0;
	r=GetIpAddrTable(iptab, &a, TRUE);
	iptab=malloc(a);
	r=GetIpAddrTable(iptab, &a, TRUE);

	a=0;
	r=GetIfTable(iftab, &a, TRUE);
	iftab=malloc(a);
	r=GetIfTable(iftab, &a, TRUE);

	if(wanted && !strncmp(wanted, "eth", 3) && wanted[3]) {
	    char *ptr;
	    int n = strtoul(wanted+3, &ptr, 10);
	    if(!*ptr)
		wantedEtherNo=n;
	}

	for(i=0; i<iptab->dwNumEntries; i++) {
	    int goodness=-1;
	    unsigned long iaddr;
	    int isEther=0;
	    MIB_IFROW *ifrow;

	    iprow = &iptab->table[i];
	    iaddr = iprow->dwAddr;

	    ifrow = getIfRow(iftab, iprow->dwIndex);

	    if(ifrow && ifrow->dwPhysAddrLen == 6 && iprow->dwBCastAddr) {
		isEther=1;
		etherNo++;
	    }

	    if(wanted) {
		if(isAddress && iaddr == wantedAddress.s_addr) {
		    goodness=8;
		} else if(isEther && wantedEtherNo == etherNo) {
			goodness=9;
		} else if(ifrow->dwPhysAddrLen) {
		    int j;
		    const char *ptr=wanted;
		    for(j=0; *ptr && j<ifrow->dwPhysAddrLen; j++) {
			int digit = strtoul(ptr, (char**)&ptr, 16);
			if(digit != ifrow->bPhysAddr[j])
			    break; /* Digit mismatch */
			if(*ptr == '-' || *ptr == ':') {
			    ptr++;
			}
		    }
		    if(!*ptr && j == ifrow->dwPhysAddrLen) {
			goodness=9;
		    }
		}
	    } else {
		if(iaddr == 0) {
		    /* disregard interfaces whose address is zero */
		    goodness = 1;
		} else if(iaddr == htonl(0x7f000001)) {
		    /* disregard localhost type devices */
		    goodness = 2;
		} else if(isEther) {
		    /* prefer ethernet */
		    goodness = 6;
		} else if(ifrow->dwPhysAddrLen) {
		    /* then prefer interfaces which have a physical address */
		    goodness = 4;
		} else {
		    goodness = 3;
		}
	    }

	    goodness = goodness * 2;
	    /* If all else is the same, prefer interfaces that
	     * have broadcast */
	    if(goodness >= lastGoodness) {
		/* Privilege broadcast-enabled interfaces */
		if(iprow->dwBCastAddr)
		    goodness++;
	    }

	    if(goodness > lastGoodness) {
		chosen = iprow;
		chosenIf = ifrow;
		lastGoodness = goodness;
	    }
	}

	if(!chosen) {
	    fprintf(stderr, "No suitable network interface found%s%s\n",
		    wanted ? " for " : "", wanted ? wanted : "");
	    fprintf(stderr, "The following interfaces are available:\n");

	    for(i=0; i<iptab->dwNumEntries; i++) {
		char buffer[16];
		struct sockaddr_in addr;
		MIB_IFROW *ifrow;
		char *name=NULL;
		iprow = &iptab->table[i];
		addr.sin_addr.s_addr = iprow->dwAddr;
		ifrow = getIfRow(iftab, iprow->dwIndex);
		name = fmtName(ifrow);
		fprintf(stderr, " %15s  %s\n",
			udpc_getIpString(&addr, buffer),
			name ? name : "");
		if(name)
		    free(name);
	    }
	    exit(1);
	}

	net_if->bcast.s_addr = net_if->addr.s_addr = chosen->dwAddr;
	if(chosen->dwBCastAddr)
	    net_if->bcast.s_addr |= ~chosen->dwMask;
	if(chosenIf) {
	    net_if->name = fmtName(chosenIf);
	} else {
	    net_if->name = "*";
	}
	free(iftab);
	free(iptab);
#endif /* __MINGW32__ */

	return net_if;
}
void 
nsMediaDocument::UpdateTitleAndCharset(const nsACString& aTypeStr,
                                       const char* const* aFormatNames,
                                       PRInt32 aWidth, PRInt32 aHeight,
                                       const nsAString& aStatus)
{
  nsXPIDLString fileStr;
  if (mDocumentURI) {
    nsCAutoString fileName;
    nsCOMPtr<nsIURL> url = do_QueryInterface(mDocumentURI);
    if (url)
      url->GetFileName(fileName);

    nsCAutoString docCharset;

    // Now that the charset is set in |StartDocumentLoad| to the charset of
    // the document viewer instead of a bogus value ("ISO-8859-1" set in
    // |nsDocument|'s ctor), the priority is given to the current charset. 
    // This is necessary to deal with a media document being opened in a new 
    // window or a new tab, in which case |originCharset| of |nsIURI| is not 
    // reliable.
    if (mCharacterSetSource != kCharsetUninitialized) {  
      docCharset = mCharacterSet;
    }
    else {  
      // resort to |originCharset|
      mDocumentURI->GetOriginCharset(docCharset);
      SetDocumentCharacterSet(docCharset);
    }
    if (!fileName.IsEmpty()) {
      nsresult rv;
      nsCOMPtr<nsITextToSubURI> textToSubURI = 
        do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
      if (NS_SUCCEEDED(rv))
        // UnEscapeURIForUI always succeeds
        textToSubURI->UnEscapeURIForUI(docCharset, fileName, fileStr);
      else 
        CopyUTF8toUTF16(fileName, fileStr);
    }
  }


  NS_ConvertASCIItoUTF16 typeStr(aTypeStr);
  nsXPIDLString title;

  if (mStringBundle) {
    // if we got a valid size (not all media have a size)
    if (aWidth != 0 && aHeight != 0) {
      nsAutoString widthStr;
      nsAutoString heightStr;
      widthStr.AppendInt(aWidth);
      heightStr.AppendInt(aHeight);
      // If we got a filename, display it
      if (!fileStr.IsEmpty()) {
        const PRUnichar *formatStrings[4]  = {fileStr.get(), typeStr.get(), 
          widthStr.get(), heightStr.get()};
        NS_ConvertASCIItoUTF16 fmtName(aFormatNames[eWithDimAndFile]);
        mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 4,
                                            getter_Copies(title));
      } 
      else {
        const PRUnichar *formatStrings[3]  = {typeStr.get(), widthStr.get(), 
          heightStr.get()};
        NS_ConvertASCIItoUTF16 fmtName(aFormatNames[eWithDim]);
        mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 3,
                                            getter_Copies(title));
      }
    } 
    else {
    // If we got a filename, display it
      if (!fileStr.IsEmpty()) {
        const PRUnichar *formatStrings[2] = {fileStr.get(), typeStr.get()};
        NS_ConvertASCIItoUTF16 fmtName(aFormatNames[eWithFile]);
        mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 2,
                                            getter_Copies(title));
      }
      else {
        const PRUnichar *formatStrings[1] = {typeStr.get()};
        NS_ConvertASCIItoUTF16 fmtName(aFormatNames[eWithNoInfo]);
        mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 1,
                                            getter_Copies(title));
      }
    }
  } 

  // set it on the document
  if (aStatus.IsEmpty()) {
    SetTitle(title);
  }
  else {
    nsXPIDLString titleWithStatus;
    const nsPromiseFlatString& status = PromiseFlatString(aStatus);
    const PRUnichar *formatStrings[2] = {title.get(), status.get()};
    NS_NAMED_LITERAL_STRING(fmtName, "TitleWithStatus");
    mStringBundle->FormatStringFromName(fmtName.get(), formatStrings, 2,
                                        getter_Copies(titleWithStatus));
    SetTitle(titleWithStatus);
  }
}