Compare commits

..

7 Commits

Author SHA1 Message Date
ruslan%netscape.com
b6a9a31b18 Minor cleanup
git-svn-id: svn://10.0.0.236/branches/linkclickfix_tmp_branch@65590 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-11 03:03:28 +00:00
ruslan%netscape.com
528acf4c90 Now this fixes everything
git-svn-id: svn://10.0.0.236/branches/linkclickfix_tmp_branch@65586 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-11 02:21:59 +00:00
ruslan%netscape.com
4dcb15068c Merge in GetSecurityInfo fix from the main branch
git-svn-id: svn://10.0.0.236/branches/linkclickfix_tmp_branch@65572 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-10 22:24:54 +00:00
ruslan%netscape.com
04353776b2 A better fix for link-click problem
git-svn-id: svn://10.0.0.236/branches/linkclickfix_tmp_branch@65557 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-10 19:36:56 +00:00
ruslan%netscape.com
3d8808b91f Add more logging
git-svn-id: svn://10.0.0.236/branches/linkclickfix_tmp_branch@65532 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-08 04:03:20 +00:00
ruslan%netscape.com
0e08e3e2ee Fix for link-click problem
git-svn-id: svn://10.0.0.236/branches/linkclickfix_tmp_branch@65508 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-07 21:54:37 +00:00
(no author)
953c538a6a This commit was manufactured by cvs2svn to create branch
'linkclickfix_tmp_branch'.

git-svn-id: svn://10.0.0.236/branches/linkclickfix_tmp_branch@65467 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-07 00:31:05 +00:00
512 changed files with 75897 additions and 9122 deletions

View File

@@ -1,80 +0,0 @@
#!perl
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Simon Fraser <sfraser@netscape.com>
#
require 5.004;
use strict;
use Cwd;
use Moz::BuildUtils;
use Moz::BuildCore;
#-------------------------------------------------------------
# Where have the build options gone?
#
# The various build flags have been centralized into one place.
# The master list of options is in MozBuildFlags.txt. However,
# you should never need to edit that file, or this one.
#
# To customize what gets built, or where to start the build,
# edit the $prefs_file_name file in
# System Folder:Preferences:Mozilla build prefs:
# Documentation is provided in that file.
#-------------------------------------------------------------
my($prefs_file_name) = "Mozilla opt build prefs";
my($config_header_file_name) = ":mozilla:config:mac:DefinesOptions.h";
#-------------------------------------------------------------
# hashes to hold build options
#-------------------------------------------------------------
my(%build);
my(%options);
my(%filepaths);
my(%optiondefines);
# Hash of input files for this build. Eventually, there will be
# input files for manifests, and projects too.
my(%inputfiles) = (
"buildflags", "MozillaBuildFlags.txt",
"checkoutdata", "MozillaCheckoutList.txt",
"buildprogress", "¥ Mozilla opt progress",
"buildmodule", "MozillaBuildList.pm",
"checkouttime", "Mozilla last checkout"
);
#-------------------------------------------------------------
# end build hashes
#-------------------------------------------------------------
# set the build root directory, which is the the dir above mozilla
SetupBuildRootDir(":mozilla:build:mac:build_scripts");
# Set up all the flags on $main::, like DEBUG, CARBON etc.
# Override the defaults using the preferences files.
SetupDefaultBuildOptions(0, ":mozilla:dist:viewer:", $config_header_file_name);
my($do_checkout) = 0;
my($do_build) = 1;
RunBuild($do_checkout, $do_build, \%inputfiles, $prefs_file_name);

View File

@@ -1,80 +0,0 @@
#!perl
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Simon Fraser <sfraser@netscape.com>
#
require 5.004;
use strict;
use Cwd;
use Moz::BuildUtils;
use Moz::BuildCore;
#-------------------------------------------------------------
# Where have the build options gone?
#
# The various build flags have been centralized into one place.
# The master list of options is in MozBuildFlags.txt. However,
# you should never need to edit that file, or this one.
#
# To customize what gets built, or where to start the build,
# edit the $prefs_file_name file in
# System Folder:Preferences:Mozilla build prefs:
# Documentation is provided in that file.
#-------------------------------------------------------------
my($prefs_file_name) = "Mozilla debug build prefs";
my($config_header_file_name) = ":mozilla:config:mac:DefinesOptionsDebug.h";
#-------------------------------------------------------------
# hashes to hold build options
#-------------------------------------------------------------
my(%build);
my(%options);
my(%filepaths);
my(%optiondefines);
# Hash of input files for this build. Eventually, there will be
# input files for manifests, and projects too.
my(%inputfiles) = (
"buildflags", "MozillaBuildFlags.txt",
"checkoutdata", "MozillaCheckoutList.txt",
"buildprogress", "¥ Mozilla debug progress",
"buildmodule", "MozillaBuildList.pm",
"checkouttime", "Mozilla last checkout"
);
#-------------------------------------------------------------
# end build hashes
#-------------------------------------------------------------
# set the build root directory, which is the the dir above mozilla
SetupBuildRootDir(":mozilla:build:mac:build_scripts");
# Set up all the flags on $main::, like DEBUG, CARBON etc.
# Override the defaults using the preferences files.
SetupDefaultBuildOptions(1, ":mozilla:dist:viewer_debug:", $config_header_file_name);
my($do_pull) = 0; # overridden by flags and prefs
my($do_build) = 1;
RunBuild($do_pull, $do_build, \%inputfiles, $prefs_file_name);

View File

@@ -1,595 +0,0 @@
#!perl -w
package Moz::BuildCore;
require 5.004;
require Exporter;
use strict;
use vars qw( @ISA @EXPORT );
# perl includes
use Cwd;
use POSIX;
use Time::Local;
use File::Basename;
use LWP::Simple;
# homegrown
use Moz::Moz;
use Moz::Jar;
use Moz::BuildFlags;
use Moz::BuildUtils;
use Moz::CodeWarriorLib;
# use MozillaBuildList; # eventually, this should go away, and be replaced by data input
@ISA = qw(Exporter);
@EXPORT = qw(
RunBuild
);
#//--------------------------------------------------------------------------------------------------
#// DoPrebuildCheck
#//
#// Check the build tools etc before running the build.
#//--------------------------------------------------------------------------------------------------
sub DoPrebuildCheck()
{
SanityCheckBuildOptions();
# launch codewarrior and persist its location. Have to call this before first
# call to getCodeWarriorPath().
my($ide_path_file) = $main::filepaths{"idepath"};
$ide_path_file = full_path_to($ide_path_file);
LaunchCodeWarrior($ide_path_file);
}
#//--------------------------------------------------------------------------------------------------
#// SanityCheckBuildOptions
#//--------------------------------------------------------------------------------------------------
sub SanityCheckBuildOptions()
{
my($bad_options) = 0;
# Jar options
if (!$main::options{chrome_jars} && !$main::options{chrome_files})
{
print "Warning: Both \$options{chrome_jars} and \$options{chrome_files} are off. You won't get any chrome.\n";
$bad_options = 1;
}
if (!$main::options{chrome_jars} && $main::options{use_jars})
{
print "Warning: \$options{chrome_jars} is off but \$options{use_jars} is on. Your build won't run (expects jars, got files).\n";
$bad_options = 1;
}
if (!$main::options{chrome_files} && !$main::options{use_jars})
{
print "Warning: \$options{chrome_jars} is off but \$options{chrome_files} is on. Your build won't run (expects files, got jars).\n";
$bad_options = 1;
}
if ($main::options{ldap_experimental} && !$main::options{ldap})
{
print "Warning: \$options{ldap_experimental} is on but \$options{ldap} is off. LDAP experimental features will not be built.\n";
$bad_options = 1;
}
if ($main::options{wsp} && !$main::options{xmlextras})
{
print "Warning: \$options{wsp} is on but \$options{xmlextras} is off. wsp will not be built.\n";
$bad_options = 1;
}
if ($bad_options) {
print "Build will start in 5 seconds. Press command-. to stop\n";
DelayFor(5);
}
}
#//--------------------------------------------------------------------------------------------------
#// GenBuildSystemInfo
#//--------------------------------------------------------------------------------------------------
sub GenBuildSystemInfo()
{
# always rebuild the configuration program.
BuildProjectClean(":mozilla:build:mac:tools:BuildSystemInfo:BuildSystemInfo.mcp", "BuildSystemInfo");
# delete the configuration file.
unlink(":mozilla:build:mac:BuildSystemInfo.pm");
# run the program.
system(":mozilla:build:mac:BuildSystemInfo");
# wait for the file to be created.
while (!(-e ":mozilla:build:mac:BuildSystemInfo.pm")) { WaitNextEvent(); }
# wait for BuildSystemInfo to finish, so that we see correct results.
while (IsProcessRunning("BuildSystemInfo")) { WaitNextEvent(); }
# now, evaluate the contents of the file.
open(F, ":mozilla:build:mac:BuildSystemInfo.pm");
while (<F>) { eval; }
close(F);
}
#//--------------------------------------------------------------------------------------------------
#// Make library aliases
#//--------------------------------------------------------------------------------------------------
sub MakeLibAliases()
{
my($dist_dir) = GetBinDirectory();
#// ProfilerLib
if ($main::PROFILE)
{
my($profilerlibpath) = Moz::CodeWarriorLib::getCodeWarriorPath("MacOS Support:Profiler:Profiler Common:ProfilerLib");
MakeAlias("$profilerlibpath", "$dist_dir"."Essential Files:");
}
}
#//--------------------------------------------------------------------------------------------------
#// ConfigureBuildSystem
#//
#// defines some build-system configuration variables.
#//--------------------------------------------------------------------------------------------------
sub ConfigureBuildSystem()
{
#// In the future, we may want to do configurations based on the actual build system itself.
#// GenBuildSystemInfo();
#// For now, if we discover a newer header file than existed in Universal Interfaces 3.2,
#// we'll assume that 3.3 or later is in use.
my($universal_interfaces) = Moz::CodeWarriorLib::getCodeWarriorPath("MacOS Support:Universal:Interfaces:CIncludes:");
if (-e ($universal_interfaces . "ControlDefinitions.h")) {
$main::UNIVERSAL_INTERFACES_VERSION = 0x0330;
}
#// Rename IC SDK folder in the Mac OS Support folder
my($ic_sdk_folder) = Moz::CodeWarriorLib::getCodeWarriorPath("MacOS Support:ICProgKit2.0.2");
if( -e $ic_sdk_folder)
{
my($new_ic_folder_name) = Moz::CodeWarriorLib::getCodeWarriorPath("MacOS Support:(ICProgKit2.0.2)");
rename ($ic_sdk_folder, $new_ic_folder_name);
# note that CodeWarrior doesn't descend into folders with () the name
print "Mozilla no longer needs the Internet Config SDK to build:\n Renaming the 'ICProgKit2.0.2' folder to '(ICProgKit2.0.2)'\n";
}
printf("UNIVERSAL_INTERFACES_VERSION = 0x%04X\n", $main::UNIVERSAL_INTERFACES_VERSION);
# alias required CodeWarrior libs into the Essential Files folder (only the Profiler lib now)
MakeLibAliases();
}
#//--------------------------------------------------------------------------------------------------
#// CheckOutModule. Takes variable number of args; first two are required
#//--------------------------------------------------------------------------------------------------
sub CheckOutModule($$$$)
{
my($session, $module, $revision, $date) = @_;
my($result) = $session->checkout($module, $revision, $date);
# result of 1 is success
if ($result) { return; }
my($checkout_err) = $session->getLastError();
if ($checkout_err == 708) {
die "Error: Checkout was cancelled.\n";
} elsif ($checkout_err == 911) {
die "Error: CVS session settings are incorrect. Check your password, and the CVS root settings.\n";
} elsif ($checkout_err == 703) {
die "Error: CVS checkout failed. Unknown module, unknown tag, bad username, or other CVS error.\n";
} elsif ($checkout_err == 711) {
print "Checkout of '$module' failed.\n";
}
}
#//--------------------------------------------------------------------------------------------------
#// getScriptFolder
#//--------------------------------------------------------------------------------------------------
sub getScriptFolder()
{
return dirname($0);
}
#//--------------------------------------------------------------------------------------------------
#// getScriptFolder
#//--------------------------------------------------------------------------------------------------
sub get_url_contents($)
{
my($url) = @_;
my($url_contents) = LWP::Simple::get($url);
$url_contents =~ s/\r\n/\n/g; # normalize linebreaks
$url_contents =~ s/\r/\n/g; # normalize linebreaks
return $url_contents;
}
#//--------------------------------------------------------------------------------------------------
#// get_files_from_content
#//--------------------------------------------------------------------------------------------------
sub uniq
{
my $lastval;
grep(($_ ne $lastval, $lastval = $_)[$[], @_);
}
#//--------------------------------------------------------------------------------------------------
#// get_files_from_content
#//--------------------------------------------------------------------------------------------------
sub get_files_from_content($)
{
my($content) = @_;
my(@jscalls) = grep (/return js_file_menu[^{]*/, split(/\n/, $content));
my $i;
for ($i = 0; $i < @jscalls ; $i++)
{
$jscalls[$i] =~ s/.*\(|\).*//g;
my(@callparams) = split(/,/, $jscalls[$i]);
my ($repos, $dir, $file, $rev) = grep(s/['\s]//g, @callparams);
$jscalls[$i] = "$dir/$file";
}
&uniq(sort(@jscalls));
}
#//--------------------------------------------------------------------------------------------------
#// getLastUpdateTime
#//
#// Get the last time we updated. Return 0 on failure
#//--------------------------------------------------------------------------------------------------
sub getLastUpdateTime($)
{
my($timestamp_file) = @_;
my($time_string);
local(*TIMESTAMP_FILE);
unless (open(TIMESTAMP_FILE, "< $timestamp_file")) { return 0; }
while (<TIMESTAMP_FILE>)
{
my($line) = $_;
chomp($line);
# ignore comments and empty lines
if ($line =~ /^\#/ || $line =~ /^\s*$/) {
next;
}
$time_string = $line;
}
# get the epoch seconds
my($last_update_secs) = $time_string;
$last_update_secs =~ s/\s#.+$//;
print "FAST_UPDATE found that you last updated at ".localtime($last_update_secs)."\n";
# how long ago was this, in hours?
my($gm_now) = time();
my($update_hours) = 1 + ceil(($gm_now - $last_update_secs) / (60 * 60));
return $update_hours;
}
#//--------------------------------------------------------------------------------------------------
#// saveCheckoutTimestamp
#//
#// Create a file on disk containing the current time. Param is time(), which is an Epoch seconds
#// (and therefore in GMT).
#//
#//--------------------------------------------------------------------------------------------------
sub saveCheckoutTimestamp($$)
{
my($gm_secs, $timestamp_file) = @_;
local(*TIMESTAMP_FILE);
open(TIMESTAMP_FILE, ">$timestamp_file") || die "Failed to open $timestamp_file\n";
print(TIMESTAMP_FILE "# time of last checkout or update, in GMT. Used by FAST_UPDATE\n");
print(TIMESTAMP_FILE "$gm_secs \# around ".localtime()." local time\n");
close(TIMESTAMP_FILE);
}
#//--------------------------------------------------------------------------------------------------
#// FastUpdate
#//
#// Use Bonsai url data to update only those dirs which have new files
#//
#//--------------------------------------------------------------------------------------------------
sub FastUpdate($$)
{
my($modules, $timestamp_file) = @_; # list of modules to check out
my($num_hours) = getLastUpdateTime($timestamp_file);
if ($num_hours == 0 || $num_hours > 170) {
print "Can't fast_update; last update was too long ago, or never. Doing normal checkout.\n";
return 0;
}
print "Doing fast update, pulling files changed in the last $num_hours hours\n";
my($cvsfile) = AskAndPersistFile($main::filepaths{"sessionpath"});
my($session) = Moz::MacCVS->new( $cvsfile );
unless (defined($session)) { die "Error: Checkout aborted. Cannot create session file: $session" }
# activate MacCVS
ActivateApplication('Mcvs');
my($checkout_start_time) = time();
#print "Time now is $checkout_start_time ($checkout_start_time + 0)\n";
my($this_co);
foreach $this_co (@$modules)
{
my($module, $revision, $date) = ($this_co->[0], $this_co->[1], $this_co->[2]);
# assume that things pulled by date wont change
if ($date ne "") {
print "$module is pulled by date, so ignoring in FastUpdate.\n";
next;
}
my($search_type) = "hours";
my($min_date) = "";
my($max_date) = "";
my($url) = "http://bonsai.mozilla.org/cvsquery.cgi?treeid=default&module=${module}&branch=${revision}&branchtype=match&dir=&file=&filetype=match&who=&whotype=match&sortby=Date&hours=${num_hours}&date=${search_type}&mindate=${min_date}&maxdate=${max_date}&cvsroot=%2Fcvsroot";
if ($revision eq "") {
print "Getting list of checkins to $module from Bonsai...\n";
} else {
print "Getting list of checkins to $module on branch $revision from Bonsai...\n";
}
my(@files) = &get_files_from_content(&get_url_contents($url));
if ($#files > 0)
{
my(@cvs_co_list);
my($co_file);
foreach $co_file (@files)
{
print "Updating $co_file\n";
push(@cvs_co_list, $co_file);
}
my($result) = $session->update($revision, \@cvs_co_list);
# result of 1 is success
if (!$result) { die "Error: Fast update failed\n"; }
} else {
print "No files in this module changed\n";
}
}
saveCheckoutTimestamp($checkout_start_time, $timestamp_file);
return 1;
}
#//--------------------------------------------------------------------------------------------------
#// Checkout
#//--------------------------------------------------------------------------------------------------
sub CheckoutModules($$$)
{
my($modules, $pull_date, $timestamp_file) = @_; # list of modules to check out
my($start_time) = TimeStart();
# assertRightDirectory();
my($cvsfile) = AskAndPersistFile($main::filepaths{"sessionpath"});
my($session) = Moz::MacCVS->new( $cvsfile );
unless (defined($session)) { die "Error: Checkout aborted. Cannot create session file: $session" }
my($checkout_start_time) = time();
# activate MacCVS
ActivateApplication('Mcvs');
my($this_co);
foreach $this_co (@$modules)
{
my($module, $revision, $date) = ($this_co->[0], $this_co->[1], $this_co->[2]);
if ($date eq "") {
$date = $pull_date;
}
CheckOutModule($session, $module, $revision, $date);
# print "Checking out $module with ref $revision, date $date\n";
}
saveCheckoutTimestamp($checkout_start_time, $timestamp_file);
TimeEnd($start_time, "Checkout");
}
#//--------------------------------------------------------------------------------------------------
#// ReadCheckoutModulesFile
#//--------------------------------------------------------------------------------------------------
sub ReadCheckoutModulesFile($$)
{
my($modules_file, $co_list) = @_;
my($checkout_file) = getScriptFolder().":".$modules_file;
local(*CHECKOUT_FILE);
open(CHECKOUT_FILE, "< $checkout_file") || die "Error: failed to open checkout list $checkout_file\n";
while (<CHECKOUT_FILE>)
{
my($line) = $_;
chomp($line);
# ignore comments and empty lines
if ($line =~ /^\#/ || $line =~ /^\s*$/) {
next;
}
my(@cvs_co) = ["", "", ""];
my($module, $revision, $date) = (0, 1, 2);
if ($line =~ /\s*([^#,\s]+)\s*\,\s*([^#,\s]+)\s*\,\s*([^#]+)/)
{
@cvs_co[$module] = $1;
@cvs_co[$revision] = $2;
@cvs_co[$date] = $3;
}
elsif ($line =~ /\s*([^#,\s]+)\s*\,\s*([^#,\s]+)\s*(#.+)?/)
{
@cvs_co[$module] = $1;
@cvs_co[$revision] = $2;
}
elsif ($line =~ /\s*([^#,\s]+)\s*\,\s*,\s*([^#,]+)/)
{
@cvs_co[$module] = $1;
@cvs_co[$date] = $2;
}
elsif ($line =~ /\s*([^#,\s]+)/)
{
@cvs_co[$module] = $1;
}
else
{
die "Error: unrecognized line '$line' in $modules_file\n";
}
# strip surrounding space from date
@cvs_co[$date] =~ s/^\s*|\s*$//g;
# print "Going to check out '@cvs_co[$module]', '@cvs_co[$revision]', '@cvs_co[$date]'\n";
push(@$co_list, \@cvs_co);
}
close(CHECKOUT_FILE);
}
#//--------------------------------------------------------------------------------------------------
#// PullFromCVS
#//--------------------------------------------------------------------------------------------------
sub PullFromCVS($$)
{
unless ( $main::build{pull} ) { return; }
my($modules_file, $timestamp_file) = @_;
StartBuildModule("pull");
my(@cvs_co_list);
ReadCheckoutModulesFile($modules_file, \@cvs_co_list);
if ($main::FAST_UPDATE && $main::options{pull_by_date})
{
die "Error: you can't use FAST_UPDATE if you are pulling by date.\n";
}
my($did_fast_update) = $main::FAST_UPDATE && FastUpdate(\@cvs_co_list, $timestamp_file);
if (!$did_fast_update)
{
my($pull_date) = "";
if ($main::options{pull_by_date})
{
# acceptable CVS date formats are (in local time):
# ISO8601 (e.g. "1972-09-24 20:05") and Internet (e.g. "24 Sep 1972 20:05").
# Perl's localtime() string format also seems to work.
$pull_date = localtime().""; # force string interp.
print "Pulling by date $pull_date\n";
}
CheckoutModules(\@cvs_co_list, $pull_date, $timestamp_file);
}
EndBuildModule("pull");
}
#//--------------------------------------------------------------------------------------------------
#// RunBuild
#//--------------------------------------------------------------------------------------------------
sub RunBuild($$$$)
{
my($do_pull, $do_build, $input_files, $build_prefs) = @_;
InitBuildProgress($input_files->{"buildprogress"});
# if we are pulling, we probably want to do a full build, so clear the build progress
if ($do_pull) {
ClearBuildProgress();
}
# read local prefs, and the build progress file, and set flags to say what to build
SetupBuildParams(\%main::build,
\%main::options,
\%main::optiondefines,
\%main::filepaths,
$input_files->{"buildflags"},
$build_prefs);
# If we were told to pull, make sure we do, overriding prefs etc.
if ($do_pull)
{
$main::build{"pull"} = 1;
}
# transfer this flag
$CodeWarriorLib::CLOSE_PROJECTS_FIRST = $main::CLOSE_PROJECTS_FIRST;
# setup the build log
SetupBuildLog($main::filepaths{"buildlogfilepath"}, $main::USE_TIMESTAMPED_LOGS);
StopForErrors();
if ($main::LOG_TO_FILE) {
RedirectOutputToFile($main::filepaths{"scriptlogfilepath"});
}
# run a pre-build check to see that the tools etc are in order
DoPrebuildCheck();
# do the pull
PullFromCVS($input_files->{"checkoutdata"}, $input_files->{"checkouttime"});
unless ($do_build) { return; }
my($build_start) = TimeStart();
# check the build environment
ConfigureBuildSystem();
# here we load and call methods in the build module indirectly.
# we have to use indirection because the build module can be named
# differently for different builds.
chdir(dirname($0)); # change to the script dir
my($build_module) = $input_files->{"buildmodule"};
# load the build module
require $build_module;
{ # scope for no strict 'refs'
no strict 'refs';
my($package_name) = $build_module;
$package_name =~ s/\.pm$//;
chdir($main::MOZ_SRC);
&{$package_name."::BuildDist"}();
chdir($main::MOZ_SRC);
&{$package_name."::BuildProjects"}();
}
# the build finished, so clear the build progress state
ClearBuildProgress();
TimeEnd($build_start, "Build");
print "Build complete\n";
}
1;

View File

@@ -1,425 +0,0 @@
#!perl -w
package Moz::BuildFlags;
require 5.004;
require Exporter;
# Package that attempts to read a file from the Preferences folder,
# and get build settings out of it
use strict;
use Exporter;
use Cwd;
use File::Basename;
use Moz::Moz;
use Moz::Prefs;
use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(
SetupBuildParams
InitBuildProgress
WriteBuildProgress
ClearBuildProgress
ReadBuildProgress
);
my(@build_flags);
my(@options_flags);
my(@filepath_flags);
my(%arrays_list) = (
"build_flags", \@build_flags,
"options_flags", \@options_flags,
"filepath_flags", \@filepath_flags
);
my($progress_file) = "¥ÊBuild progress";
#-------------------------------------------------------------------------------
# appendArrayFlag
#
# Set a flag in the array
#-------------------------------------------------------------------------------
sub appendArrayFlag(@)
{
my($array_name) = shift;
my($setting) = shift;
my($value) = shift;
my(@optional_values);
foreach (@_) {
push(@optional_values, $_);
}
my(@this_flag) = [$setting, $value, @optional_values];
my($flags_array) = $arrays_list{$array_name};
if ($flags_array)
{
push(@{$flags_array}, @this_flag) || die "Failed to append\n";
}
else
{
die "Error: unknown build flags array $array_name\n";
}
}
#-------------------------------------------------------------------------------
# readFlagsFile
#
# Read the file of build flags from disk. File path is relative to the
# script directory.
#-------------------------------------------------------------------------------
sub readFlagsFile($)
{
my($flags_file) = @_;
my($file_path) = $0;
$file_path =~ s/[^:]+$/$flags_file/;
print "Reading build flags from '$file_path'\n";
local(*FLAGS_FILE);
open(FLAGS_FILE, "< $file_path") || die "Error: failed to open flags file $file_path\n";
my($cur_array) = "";
while(<FLAGS_FILE>)
{
my($line) = $_;
chomp($line);
# ignore comments and empty lines
if ($line =~ /^\#/ || $line =~ /^\s*$/) {
next;
}
# 1-word line, probably array name
if ($line =~ /^([^#\s]+)\s*$/)
{
$cur_array = $1;
next;
}
elsif ($line =~ /^([^#\s]+)\s+\"(.+)\"(\s+#.+)?$/) # quoted option, possible comment
{
my($flag) = $1;
my($setting) = $2;
appendArrayFlag($cur_array, $flag, $setting);
}
elsif ($line =~ /^([^#\s]+)((\s+[^#\s]+)+)(\s+#.+)?$/) # multiple word line, possible comment
{
my($flag) = $1;
appendArrayFlag($cur_array, $flag, split(' ', $2));
}
else
{
die "Error: unknown build flag at '$line'\n";
}
}
close(FLAGS_FILE);
}
#-------------------------------------------------------------------------------
# flagsArrayToHash
#
# Utility routine to migrate flag from a 2D array to a hash, where
# item[n][0] is the hash entry name, and item[n][1] is the hash entry value.
#-------------------------------------------------------------------------------
sub flagsArrayToHash($$)
{
my($src_array, $dest_hash) = @_;
my($item);
foreach $item (@$src_array)
{
$dest_hash->{$item->[0]} = $item->[1];
}
}
#-----------------------------------------------
# printHash
#
# Utility routine to print a hash
#-----------------------------------------------
sub printHash($)
{
my($hash_ref) = @_;
print "Printing hash:\n";
my($key, $value);
while (($key, $value) = each (%$hash_ref))
{
print " $key $value\n";
}
}
#-----------------------------------------------
# printBuildArray
#
# Utility routine to print a 2D array
#-----------------------------------------------
sub printBuildArray($)
{
my($build_array) = @_;
my($entry);
foreach $entry (@$build_array)
{
print "$entry->[0] = $entry->[1]\n";
}
}
#-------------------------------------------------------------------------------
# SetBuildFlags
#-------------------------------------------------------------------------------
sub SetBuildFlags($)
{
my($build) = @_;
flagsArrayToHash(\@build_flags, $build);
}
#-------------------------------------------------------------------------------
# SetBuildOptions
#-------------------------------------------------------------------------------
sub SetBuildOptions($)
{
my($options) = @_;
flagsArrayToHash(\@options_flags, $options);
}
#-------------------------------------------------------------------------------
# SetFilepathFlags
#-------------------------------------------------------------------------------
sub SetFilepathFlags($)
{
my($filepath) = @_;
flagsArrayToHash(\@filepath_flags, $filepath);
}
#-------------------------------------------------------------------------------
# SetOptionDefines
#-------------------------------------------------------------------------------
sub SetOptionDefines($)
{
my($optiondefines) = @_;
foreach my $entry (@options_flags)
{
if (defined($entry->[2])) {
$optiondefines->{$entry->[0]}{$entry->[2]} = 1;
}
}
}
#-------------------------------------------------------------------------------
# PropagateAllFlags
#-------------------------------------------------------------------------------
sub PropagateAllFlags($)
{
my($build_array) = @_;
# if "all" is set, set all the flags to 1
unless ($build_array->[0][0] eq "all") { die "Error: 'all' must come first in the flags array\n"; }
if ($build_array->[0][1] == 1)
{
my($index);
foreach $index (@$build_array)
{
$index->[1] = 1;
}
}
}
#//--------------------------------------------------------------------------------------------------
#// _getBuildProgressFile
#//--------------------------------------------------------------------------------------------------
sub _getBuildProgressFile()
{
return $progress_file;
}
#//--------------------------------------------------------------------------------------------------
#// setBuildProgressStart
#//
#// This automagically sets $build{"all"} to 0
#//--------------------------------------------------------------------------------------------------
sub setBuildProgressStart($$)
{
my($build_array, $name) = @_;
my($index);
foreach $index (@$build_array)
{
$index->[1] = 0;
if ($index->[0] eq $name) {
last;
}
}
print "Building from module after $name, as specified by build progress\n";
}
#//--------------------------------------------------------------------------------------------------
#// InitBuildProgress
#//--------------------------------------------------------------------------------------------------
sub InitBuildProgress($)
{
my($prog_file) = @_;
if ($prog_file ne "") {
$progress_file = full_path_to($prog_file);
print "Writing build progress to $progress_file\n";
}
}
#//--------------------------------------------------------------------------------------------------
#// WriteBuildProgress
#//--------------------------------------------------------------------------------------------------
sub WriteBuildProgress($)
{
my($module_built) = @_;
my($progress_file) = _getBuildProgressFile();
if ($progress_file ne "")
{
open(PROGRESS_FILE, ">>$progress_file") || die "Failed to open $progress_file\n";
print(PROGRESS_FILE "$module_built\n");
close(PROGRESS_FILE);
}
}
#//--------------------------------------------------------------------------------------------------
#// ClearBuildProgress
#//--------------------------------------------------------------------------------------------------
sub ClearBuildProgress()
{
my($progress_file) = _getBuildProgressFile();
if ($progress_file ne "") {
unlink $progress_file;
}
}
#//--------------------------------------------------------------------------------------------------
#// WipeBuildProgress
#//--------------------------------------------------------------------------------------------------
sub WipeBuildProgress()
{
print "Ignoring build progress\n";
ClearBuildProgress();
$progress_file = "";
}
#//--------------------------------------------------------------------------------------------------
#// ReadBuildProgress
#//--------------------------------------------------------------------------------------------------
sub ReadBuildProgress($)
{
my($build_array) = @_;
my($progress_file) = _getBuildProgressFile();
my($last_module);
if (open(PROGRESS_FILE, "< $progress_file"))
{
print "Getting build progress from $progress_file\n";
while (<PROGRESS_FILE>)
{
my($line) = $_;
chomp($line);
$last_module = $line;
}
close(PROGRESS_FILE);
}
if ($last_module)
{
setBuildProgressStart($build_array, $last_module);
}
}
#-------------------------------------------------------------------------------
# clearOldBuildSettings
#-------------------------------------------------------------------------------
sub clearOldBuildSettings($$$$)
{
my($build, $options, $optiondefines, $filepaths) = @_;
# empty the arrays in case we're being called twice
@build_flags = ();
@options_flags = ();
@filepath_flags = ();
# and empty the hashes
%$build = ();
%$options = ();
%$optiondefines = ();
%$filepaths = ();
}
#-------------------------------------------------------------------------------
# SetupBuildParams
#-------------------------------------------------------------------------------
sub SetupBuildParams($$$$$$)
{
my($build, $options, $optiondefines, $filepaths, $flags_file, $prefs_file) = @_;
# Empty the hashes and arrays, to wipe out any stale data.
# Needed because these structures persist across two build scripts
# called using 'do' from a parent script.
clearOldBuildSettings($build, $options, $optiondefines, $filepaths);
# Read from the flags file, which sets up the various arrays
readFlagsFile($flags_file);
# If 'all' is set in the build array, propagate that to all entries
PropagateAllFlags(\@build_flags);
# read the user pref file, that can change values in the array
ReadMozUserPrefs($prefs_file, \@build_flags, \@options_flags, \@filepath_flags);
# If build progress exists, this clears flags in the array up to a certain point
if ($main::USE_BUILD_PROGRESS) {
ReadBuildProgress(\@build_flags);
} else {
WipeBuildProgress();
}
# printBuildArray(\@build_flags);
# printBuildArray(\@options_flags);
SetBuildFlags($build);
SetBuildOptions($options);
SetOptionDefines($optiondefines);
SetFilepathFlags($filepaths);
# printHash($build);
# printHash($options);
}
1;

View File

@@ -1,786 +0,0 @@
package Moz::BuildUtils;
require 5.004;
require Exporter;
# Package that contains build util functions specific to the Mozilla build
# process.
use strict;
use Exporter;
use Cwd;
use File::Path;
use File::Basename;
use Mac::Events;
use Mac::StandardFile;
use Moz::Moz;
use Moz::BuildFlags;
use Moz::MacCVS;
#use Moz::ProjectXML; #optional; required for static build only
use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(
SetupDefaultBuildOptions
SetupBuildRootDir
StartBuildModule
EndBuildModule
GetBinDirectory
BuildOneProjectWithOutput
BuildOneProject
BuildProject
BuildProjectClean
BuildIDLProject
BuildFolderResourceAliases
AskAndPersistFile
DelayFor
TimeStart
TimeEnd
EmptyTree
SetupBuildLog
SetBuildNumber
SetTimeBomb
UpdateConfigHeader
);
#//--------------------------------------------------------------------------------------------------
#// SetupDefaultBuildOptions
#//--------------------------------------------------------------------------------------------------
sub SetupDefaultBuildOptions($$$)
{
my($debug, $bin_dir, $config_header_file_name) = @_;
# Here we set up defaults for the various build flags.
# If you want to override any of these, it's best to do
# so via the relevant preferences file, which lives in
# System Folder:Preferences:Mozilla build prefs:{build prefs file}.
# For the name of the prefs file, see the .pl script that you
# run to start this build. The prefs files are created when
# you run the build, and contain some documentation.
#-------------------------------------------------------------
# configuration variables that globally affect what is built
#-------------------------------------------------------------
$main::DEBUG = $debug;
$main::PROFILE = 0;
$main::RUNTIME = 0; # turn on to just build runtime support and NSPR projects
$main::GC_LEAK_DETECTOR = 0; # turn on to use GC leak detection
$main::MOZILLA_OFFICIAL = 0; # generate build number
$main::LOG_TO_FILE = 0; # write perl output to a file
#-------------------------------------------------------------
# configuration variables that affect the manner of building,
# but possibly affecting the outcome.
#-------------------------------------------------------------
$main::ALIAS_SYM_FILES = $main::DEBUG;
$main::CLOBBER_LIBS = 1; # turn on to clobber existing libs and .xSYM files before
# building each project
# The following two options will delete all dist files (if you have $main::build{dist} turned on),
# but leave the directory structure intact.
$main::CLOBBER_DIST_ALL = 1; # turn on to clobber all aliases/files inside dist (headers/xsym/libs)
$main::CLOBBER_DIST_LIBS = 0; # turn on to clobber only aliases/files for libraries/sym files in dist
$main::CLOBBER_IDL_PROJECTS = 0; # turn on to clobber all IDL projects.
$main::CLOBBER_PROJECTS = 0; # turn on to remove object code from each project before building it
$main::UNIVERSAL_INTERFACES_VERSION = 0x0320;
#-------------------------------------------------------------
# configuration variables that are preferences for the build,
# style and do not affect what is built.
#-------------------------------------------------------------
$main::CLOSE_PROJECTS_FIRST = 0;
# 1 = close then make (for development),
# 0 = make then close (for tinderbox).
$main::USE_TIMESTAMPED_LOGS = 0;
$main::USE_BUILD_PROGRESS = 1; # track build progress for restartable builds
#-------------------------------------------------------------
# END OF CONFIG SWITCHES
#-------------------------------------------------------------
$main::BIN_DIRECTORY = $bin_dir;
$main::DEFINESOPTIONS_FILE = $config_header_file_name;
}
#//--------------------------------------------------------------------------------------------------
#// SetupBuildRootDir
#//--------------------------------------------------------------------------------------------------
sub SetupBuildRootDir($)
{
my($rel_path_to_script) = @_;
my($cur_dir) = cwd();
$cur_dir =~ s/$rel_path_to_script$//;
chdir($cur_dir) || die "Error: failed to set build root directory to '$cur_dir'.\nYou probably need to put 'mozilla' one level down (in a folder).\n";
$main::MOZ_SRC = cwd();
}
#//--------------------------------------------------------------------------------------------------
#// StartBuildModule
#//--------------------------------------------------------------------------------------------------
sub StartBuildModule($)
{
my($module) = @_;
print("---- Start of $module ----\n");
}
#//--------------------------------------------------------------------------------------------------
#// EndBuildModule
#//--------------------------------------------------------------------------------------------------
sub EndBuildModule($)
{
my($module) = @_;
WriteBuildProgress($module);
print("---- End of $module ----\n");
}
#--------------------------------------------------------------------------------------------------
# GetBinDirectory
#--------------------------------------------------------------------------------------------------
sub GetBinDirectory()
{
if ($main::BIN_DIRECTORY eq "") { die "Dist directory not set\n"; }
return $main::BIN_DIRECTORY;
}
#--------------------------------------------------------------------------------------------------
# AskAndPersistFile stores the information about the user pick inside
# the file $session_storage
#--------------------------------------------------------------------------------------------------
sub AskAndPersistFile($)
{
my ($sessionStorage) = @_;
my $cvsfile;
if (( -e $sessionStorage) &&
open( SESSIONFILE, $sessionStorage ))
{
# Read in the path if available
$cvsfile = <SESSIONFILE>;
chomp $cvsfile;
close SESSIONFILE;
if ( ! -e $cvsfile )
{
print STDERR "$cvsfile has disappeared\n";
undef $cvsfile;
}
}
unless (defined ($cvsfile))
{
# make sure that MacPerl is a front process
ActivateApplication('McPL');
MacPerl::Answer("Could not find your MacCVS session file. Please choose one", "OK");
# prompt user for the file name, and store it
my $macFile = StandardGetFile( 0, "McvD");
if ( $macFile->sfGood() )
{
$cvsfile = $macFile->sfFile();
# save the choice if we can
if ( open (SESSIONFILE, ">" . $sessionStorage))
{
printf SESSIONFILE $cvsfile, "\n";
close SESSIONFILE;
}
else
{
print STDERR "Could not open storage file $sessionStorage for saving $cvsfile\n";
}
}
}
return $cvsfile;
}
#--------------------------------------------------------------------------------------------------
# BuildIDLProject
#
#--------------------------------------------------------------------------------------------------
sub BuildIDLProject($$)
{
my ($project_path, $module_name) = @_;
if ($main::CLOBBER_IDL_PROJECTS)
{
my (@suffix_list) = (".mcp", ".xml");
my ($project_name, $project_dir, $suffix) = fileparse($project_path, @suffix_list);
if ($suffix eq "") { die "Error: Project, $project_path must end in .xml or .mcp\n"; }
my($datafolder_path);
if ($suffix eq ".xml")
{
$datafolder_path = $project_dir . "_" . $project_name . " Data:";
}
else {
$datafolder_path = $project_dir . $project_name . " Data:";
}
print STDERR "Deleting IDL data folder: $datafolder_path\n";
EmptyTree($datafolder_path);
}
BuildOneProject($project_path, "headers", 0, 0, 0);
BuildOneProject($project_path, $module_name.".xpt", 1, 0, 1);
}
#--------------------------------------------------------------------------------------------------
# CreateStaticLibTargets
#
#--------------------------------------------------------------------------------------------------
sub CreateXMLStaticLibTargets($)
{
my($xml_path) = @_;
my (@suffix_list) = (".xml");
my ($project_name, $project_dir, $suffix) = fileparse($xml_path, @suffix_list);
if ($suffix eq "") { die "XML munging: $xml_path must end in .xml\n"; }
#sniff the file to see if we need to fix up broken Pro5-exported XML
print "Parsing $xml_path\n";
my $ide_version = Moz::ProjectXML::SniffProjectXMLIDEVersion($xml_path);
if ($ide_version eq "4.0")
{
my $new_file = $project_dir.$project_name."2.xml";
print "Cleaning up Pro 5 xml to $new_file\n";
Moz::ProjectXML::CleanupPro5XML($xml_path, $new_file);
unlink $xml_path;
rename ($new_file, $xml_path);
}
my $doc = Moz::ProjectXML::ParseXMLDocument($xml_path);
my @target_list = Moz::ProjectXML::GetTargetsList($doc);
my $target;
my %target_hash; # for easy lookups below
foreach $target (@target_list) { $target_hash{$target} = 1; }
foreach $target (@target_list)
{
if ($target =~ /(.+).shlb$/) # if this is a shared lib target
{
my $target_base = $1;
my $static_target = $target_base.".o";
# ensure that this does not exist already
if ($target_hash{$static_target}) {
print "Static target $static_target already exists in project. Not making\n";
next;
}
print "Making static target '$static_target' from target '$target'\n";
Moz::ProjectXML::CloneTarget($doc, $target, $static_target);
Moz::ProjectXML::SetAsStaticLibraryTarget($doc, $static_target, $static_target);
}
}
print "Writing XML file to $xml_path\n";
my $temp_path = $project_dir."_".$project_name.".xml";
Moz::ProjectXML::WriteXMLDocument($doc, $temp_path, $ide_version);
Moz::ProjectXML::DisposeXMLDocument($doc);
if (-e $temp_path)
{
unlink $xml_path;
rename ($temp_path, $xml_path);
}
else
{
die "Error: Failed to add new targets to XML project\n";
}
}
#//--------------------------------------------------------------------------------------------------
#// ProcessProjectXML
#//
#// Helper routine to allow for XML pre-processing. This should read in the XML, process it,
#// and replace the original file with the processed version.
#//--------------------------------------------------------------------------------------------------
sub ProcessProjectXML($)
{
my($xml_path) = @_;
# we need to manually load Moz::ProjectXML, becaues not everyone will have the
# required perl modules in their distro.
my($cur_dir) = cwd();
chdir(dirname($0)); # change to the script dir
eval "require Moz::ProjectXML";
if ($@) { die "Error: could not do Project XML munging because you do not have the correct XML modules installed. Error is:\n################\n $@################"; }
chdir($cur_dir);
CreateXMLStaticLibTargets($xml_path);
}
#//--------------------------------------------------------------------------------------------------
#// Build one project, and make the alias. Parameters are project path, target name, shared library
#// name, make shlb alias (boolean), make xSYM alias (boolean), and is component (boolean).
#//--------------------------------------------------------------------------------------------------
sub BuildOneProjectWithOutput($$$$$$)
{
my ($project_path, $target_name, $output_name, $alias_lib, $alias_xSYM, $component) = @_;
unless ($project_path =~ m/^$main::BUILD_ROOT.+/) { return; }
my (@suffix_list) = (".mcp", ".xml");
my ($project_name, $project_dir, $suffix) = fileparse($project_path, @suffix_list);
if ($suffix eq "") { die "Error: Project, $project_path must end in .xml or .mcp\n"; }
my($dist_dir) = GetBinDirectory();
# Put libraries in "Essential Files" folder, Components in "Components" folder
my($output_dir) = $component ? "Components:" : "Essential Files:";
my($output_path) = $dist_dir.$output_dir;
if ($main::options{static_build})
{
if ($output_name =~ /\.o$/ || $output_name =~ /\.[Ll]ib$/)
{
$alias_xSYM = 0;
$alias_lib = 1;
$output_path = $main::DEBUG ? ":mozilla:dist:static_libs_debug:" : ":mozilla:dist:static_libs:";
}
}
# if the flag is on to export projects to XML, export and munge them
if ($main::EXPORT_PROJECTS && !($project_path =~ /IDL\.mcp$/))
{
my $xml_out_path = $project_path;
$xml_out_path =~ s/\.mcp$/\.xml/;
# only do this if project is newer?
if (! -e $xml_out_path)
{
ExportProjectToXML(full_path_to($project_path), full_path_to($xml_out_path));
ProcessProjectXML($xml_out_path);
}
}
# if the flag is set to use XML projects, default to XML if the file
# is present.
if ($main::USE_XML_PROJECTS && !($project_path =~ /IDL\.mcp$/))
{
my $xml_project_path = $project_dir.$project_name.".xml";
if (-e $xml_project_path)
{
$project_path = $xml_project_path;
$suffix = ".xml";
}
}
if ($suffix eq ".xml")
{
my($xml_path) = $project_path;
# Prepend an "_" onto the name of the generated project file so it doesn't conflict
$project_path = $project_dir . "_" . $project_name . ".mcp";
my($project_modtime) = (-e $project_path ? GetFileModDate($project_path) : 0);
my($xml_modtime) = (-e $xml_path ? GetFileModDate($xml_path) : 0);
if ($xml_modtime > $project_modtime)
{
print("Importing $project_path from $project_name.xml.\n");
unlink($project_path);
# Might want to delete the "xxx.mcp Data" dir ???
ImportXMLProject(full_path_to($xml_path), full_path_to($project_path));
}
}
if ($main::CLOBBER_LIBS)
{
unlink "$project_dir$output_name"; # it's OK if these fail
unlink "$project_dir$output_name.xSYM";
}
DoBuildProject($project_path, $target_name, $main::CLOBBER_PROJECTS);
$alias_lib ? MakeAlias("$project_dir$output_name", "$output_path") : 0;
$alias_xSYM ? MakeAlias("$project_dir$output_name.xSYM", "$output_path") : 0;
}
#//--------------------------------------------------------------------------------------------------
#// For compatiblity with existing scripts, BuildOneProject now just calls
#// BuildOneProjectWithOutput, with the output name and target name identical.
#// Note that this routine assumes that the target name and the shared libary name
#// are the same.
#//--------------------------------------------------------------------------------------------------
sub BuildOneProject($$$$$)
{
my ($project_path, $target_name, $alias_lib, $alias_xSYM, $component) = @_;
BuildOneProjectWithOutput($project_path, $target_name, $target_name,
$alias_lib, $alias_xSYM, $component);
}
#//--------------------------------------------------------------------------------------------------
#// For compatiblity with existing scripts, BuildProject now just calls
#// BuildOneProjectWithOutput, with the output name and target name identical.
#// Note that this routine assumes that the target name and the shared libary name
#// are the same. No aliases of the output are made.
#//--------------------------------------------------------------------------------------------------
sub BuildProject($$)
{
my ($project_path, $target_name) = @_;
BuildOneProjectWithOutput($project_path, $target_name, $target_name, 0, 0, 0);
}
#//--------------------------------------------------------------------------------------------------
#// Identical to BuildProject but clobbers the project before building it.
#//--------------------------------------------------------------------------------------------------
sub BuildProjectClean($$)
{
my ($project_path, $target_name) = @_;
my ($save_clobber_flag) = $main::CLOBBER_PROJECTS;
$main::CLOBBER_PROJECTS = 1;
BuildOneProjectWithOutput($project_path, $target_name, $target_name, 0, 0, 0);
$main::CLOBBER_PROJECTS = $save_clobber_flag;
}
#//--------------------------------------------------------------------------------------------------
#// Make resource aliases for one directory
#//--------------------------------------------------------------------------------------------------
sub BuildFolderResourceAliases($$)
{
my($src_dir, $dest_dir) = @_;
# get a list of all the resource files
opendir(SRCDIR, $src_dir) || die("can't open $src_dir");
my(@resource_files) = readdir(SRCDIR);
closedir(SRCDIR);
# make aliases for each one into the dest directory
print("Placing aliases to all files from $src_dir in $dest_dir\n");
for ( @resource_files )
{
next if $_ eq "CVS";
#print(" Doing $_\n");
if (-l $src_dir.$_)
{
print(" $_ is an alias\n");
next;
}
my($file_name) = $src_dir . $_;
MakeAlias($file_name, $dest_dir);
}
}
#//--------------------------------------------------------------------------------------------------
#// DelayFor
#//
#// Delay for the given number of seconds, allowing the script to be cancelled
#//--------------------------------------------------------------------------------------------------
sub DelayFor($)
{
my($delay_secs) = @_;
STDOUT->autoflush(1);
my($end_time) = time() + $delay_secs;
my($last_time) = 0;
my($cur_time) = time();
while ($cur_time < $end_time)
{
$cur_time = time();
if ($cur_time > $last_time)
{
print ".";
$last_time = $cur_time;
}
WaitNextEvent();
}
print "\n";
STDOUT->autoflush(0);
}
#//--------------------------------------------------------------------------------------------------
#// TimeStart
#//--------------------------------------------------------------------------------------------------
sub TimeStart()
{
return time();
}
#//--------------------------------------------------------------------------------------------------
#// TimeEnd
#//--------------------------------------------------------------------------------------------------
sub TimeEnd($$)
{
use integer;
my($start_time, $operation_name) = @_;
my($end_time) = time();
my($tot_sec) = $end_time - $start_time;
my($seconds) = $tot_sec;
my($hours) = $seconds / (60 * 60);
$seconds -= $hours * (60 * 60);
my($minutes) = $seconds / 60;
$seconds -= $minutes * 60;
print "$operation_name took $hours hours $minutes minutes and $seconds seconds\n";
}
#//--------------------------------------------------------------------------------------------------
#// Remove all files from a tree, leaving directories intact (except "CVS").
#//--------------------------------------------------------------------------------------------------
sub EmptyTree($)
{
my ($root) = @_;
#print "EmptyTree($root)\n";
opendir(DIR, $root);
my $sub;
foreach $sub (readdir(DIR))
{
my $fullpathname = $root.$sub; # -f, -d only work on full paths
# Don't call empty tree for the alias of a directory.
# -d returns true for the alias of a directory, false for a broken alias)
if (-d $fullpathname)
{
if (-l $fullpathname) # delete aliases
{
unlink $fullpathname;
next;
}
EmptyTree($fullpathname.":");
if ($sub eq "CVS")
{
#print "rmdir $fullpathname\n";
rmdir $fullpathname;
}
}
else
{
unless (unlink $fullpathname) { die "Failed to delete $fullpathname\n"; }
}
}
closedir(DIR);
}
#//--------------------------------------------------------------------------------------------------
#// Recurse through a directory hierarchy, looking for MANIFEST files.
#// Currently unused.
#//--------------------------------------------------------------------------------------------------
sub ScanForManifestFiles($$$$)
{
my($dir, $theme_root, $theme_name, $dist_dir) = @_;
opendir(DIR, $dir) or die "Cannot open dir $dir\n";
my @files = readdir(DIR);
closedir DIR;
my $file;
foreach $file (@files)
{
my $filepath = $dir.":".$file;
if (-d $filepath)
{
# print "Looking for MANIFEST files in $filepath\n";
ScanForManifestFiles($filepath, $theme_root, $theme_name, $dist_dir);
}
elsif ($file eq "MANIFEST")
{
# print "Doing manifest file $filepath\n";
# Get the dest path from the first line of the file
open(MANIFEST, $filepath) || die "Could not open file $file";
# Read in the path if available
my($dest_line) = <MANIFEST>;
chomp $dest_line;
close MANIFEST;
$dest_line =~ s|^#!dest[\t ]+|| || die "No destination line found in $filepath\n";
my($dest_path) = $dist_dir."chrome:skins:$theme_name:$dest_line";
# print " Destination is $dest_path\n";
InstallResources($filepath, "$dest_path", 0);
}
}
}
#-----------------------------------------------
# SetupBuildLog
#-----------------------------------------------
sub SetupBuildLog($$)
{
my($logfile_path, $timestamped_log) = @_;
my($logdir) = "";
my($logfile) = $logfile_path;
if ($logfile_path =~ /(.+?:)([^:]+)$/) # ? for non-greedy match
{
$logdir = $1;
$logfile = $2;
mkpath($logdir);
}
if ($timestamped_log)
{
#Use time-stamped names so that you don't clobber your previous log file!
my $now = localtime();
while ($now =~ s@:@.@) {} # replace all colons by periods
OpenErrorLog("${logdir}${now}");
}
else
{
OpenErrorLog("${logdir}${logfile}");
}
}
#-----------------------------------------------
# SetBuildNumber
#-----------------------------------------------
sub SetBuildNumber($$)
{
my($build_num_file, $files_to_touch) = @_;
# Make sure we add the config dir to search, to pick up mozBDate.pm
# Need to do this dynamically, because this module can be used before
# mozilla/config has been checked out.
my ($inc_path) = $0; # $0 is the path to the parent script
$inc_path =~ s/:build:mac:build_scripts:.+$/:config/;
push(@INC, $inc_path);
require mozBDate;
mozBDate::UpdateBuildNumber($build_num_file, $main::MOZILLA_OFFICIAL);
my($file);
foreach $file (@$files_to_touch)
{
print "Writing build number to $file from ${file}.in\n";
mozBDate::SubstituteBuildNumber($file, $build_num_file, "${file}.in");
}
}
#-----------------------------------------------
# SetTimeBomb
#-----------------------------------------------
sub SetTimeBomb($$)
{
my ($warn_days, $bomb_days) = @_;
system("perl :mozilla:config:mac-set-timebomb.pl $warn_days $bomb_days");
}
#//--------------------------------------------------------------------------------------------------
#// Regenerate a configuration header file if necessary
#//--------------------------------------------------------------------------------------------------
sub UpdateConfigHeader($)
{
my($config_path) = @_;
my($config, $oldconfig) = ("", "");
my($define, $definevalue, $defines);
my($k, $l,);
foreach $k (keys(%main::options))
{
if ($main::options{$k})
{
foreach $l (keys(%{$main::optiondefines{$k}}))
{
$my::defines{$l} = $main::optiondefines{$k}{$l};
print "Setting up my::defines{$l}\n";
}
}
}
my $config_headerfile = current_directory().$config_path;
if (-e $config_headerfile)
{
open(CONFIG_HEADER, "< $config_headerfile") || die "$config_headerfile: $!\n";
my($line);
while ($line = <CONFIG_HEADER>)
{
if ($line =~ m/#define\s+([^\s]*)\s+([^\s]*)\s*\n/)
{
$define = $1;
$definevalue = $2;
#canonicalize so that whitespace changes are not significant
my $canon_value = "#define " . $define . " " . $definevalue . "\n";
$oldconfig .= $canon_value;
if (exists ($my::defines{$define}) and ($my::defines{$define} == $definevalue))
{
delete $my::defines{$define};
$config .= $canon_value;
}
}
}
close(CONFIG_HEADER);
}
if (%my::defines)
{
foreach $k (keys(%my::defines))
{
$config .= "#define " . $k . " " . $my::defines{$k} . "\n";
}
}
my $file_name = basename($config_headerfile);
if (($config ne $oldconfig) || (!-e $config_headerfile))
{
printf("Writing new configuration header $file_name\n");
open(CONFIG_HEADER, "> $config_headerfile") || die "$config_headerfile: $!\n";
print(CONFIG_HEADER "/* This file is auto-generated based on build options. Do not edit. */\n");
print CONFIG_HEADER ($config);
close(CONFIG_HEADER);
MacPerl::SetFileInfo("CWIE", "TEXT", $config_headerfile);
}
else
{
printf("Configuration header $file_name is up-to-date\n");
}
}
1;

View File

@@ -1,660 +0,0 @@
#!perl
package Moz::CodeWarriorLib;
=pod
=head1 NAME
CodeWarriorLib - supply interface to CodeWarrior
=head1 SYNOPSIS
#!perl
use CodeWarriorLib;
CodeWarriorLib::activate();
$had_errors = CodeWarriorLib::build_project(
$project_path, $target_name, $recent_errors_file, $clean_build
);
=head1 DESCRIPTION
Replaces the AppleScript library I<CodeWarriorLib>.
=over 4
=cut
use strict;
use Cwd;
use File::Basename;
use Mac::Types;
use Mac::Events;
use Mac::AppleEvents;
use Mac::AppleEvents::Simple;
use Mac::Processes;
use Mac::MoreFiles;
use Mac::StandardFile;
use vars qw($VERSION);
$VERSION = '1.02';
my($app) = 'CWIE';
my($scriptDir) = cwd(); # could use $0 for this
my($ide_loc_file) = "";
# 0 == don't switch CWIE to front app in do_event(), 1 == do switch
# note: activate() still switches when called
$Mac::AppleEvents::Simple::SWITCH = 0;
# $Mac::AppleEvents::Simple::WARN = 1;
# supply your own path to the source here
#_test('PowerPudgeIV:mozilla:mozilla:');
# If you want to understand the gobbldeygook that's used to build Apple Events,
# you should start by reading the AEGizmos documentation.
=pod
=item _get_project($full_path)
A private routine returning a reference to the open project with the given name,
or else the empty string (when that project is not open)
full_path is a string identifying the project to be built and is of the form,
e.g., "HD:ProjectFolder:MyProject.mcp". It must be supplied.
=cut
sub _get_project ($) {
my(
$full_path, $candidate_projects
) = @_;
$candidate_projects = _doc_named(basename($full_path, '*'));
if ($candidate_projects) {
my($cps) = _get_dobj($candidate_projects);
my($num) = AECountItems($cps);
if ($num) { # is a list
foreach (1 .. AECountItems($cps)) {
my($cp) = AEGetNthDesc($cps, $_);
if (lc $full_path eq lc _full_path($cp)) {
return($cp);
}
}
} else { # is only one, not a list
if (lc $full_path eq lc _full_path($cps)) {
return($cps);
}
}
}
return;
}
=pod
=item build_project
Build a selected target of a project, saving any errors to a file, if supplied.
full_path is a string identifying the project to be built and is of the form,
e.g., "HD:ProjectFolder:MyProject.mcp". It must be supplied.
If target_name is the empty string, the current target of the selected project
will be built, else, target_name should be a string matching a target name in
the selected project.
If error_path is the empty string, errors will not be saved to a file,
else, error_path should be the full path of a file to save error messages into.
=cut
$CodeWarriorLib::CLOSE_PROJECTS_FIRST = 0; # If true we close then make. If false, make then close.
my $last_project_built = "";
my $last_project_was_closed = 0;
sub build_project ($;$$$) {
my(
$full_path, $target_name, $error_path,
$remove_object, $p, $project_was_closed, $had_errors
) = @_;
_close_errors_window();
if ($CodeWarriorLib::CLOSE_PROJECTS_FIRST && ($last_project_built ne $full_path))
{
# If we're in "close first" mode, we don't close if the current project
# is the same as the previous one.
if ($last_project_was_closed) {
$p = _get_project($last_project_built);
_close($p);
}
$last_project_built = $full_path;
$last_project_was_closed = 0; # now refers to the new project
}
$project_was_closed = 0;
while (1) {
$p = _get_project($full_path);
if (!$p) {
if ($project_was_closed) {
print "### Error - request for project document failed after opening\n";
die "### possibly CW Pro 4 bug: be sure to close your Find window\n";
}
$project_was_closed = 1;
$last_project_was_closed = 1;
_open_file($full_path);
} else {
last;
}
}
$had_errors = 0;
if ($target_name eq '') {
if ($remove_object) {_remove_object($p)}
_build($p);
} else {
if ($remove_object) {_remove_object($p, $target_name)}
_build($p, $target_name);
}
if ($error_path ne '') {
_save_errors_window($error_path);
}
$had_errors = _close_errors_window();
if (!$CodeWarriorLib::CLOSE_PROJECTS_FIRST)
{
if ($project_was_closed) {
$p = _get_project($full_path);
_close($p);
}
}
return($had_errors);
}
=pod
=item appIsRunning()
=cut
sub _appIsRunning($)
{
my ($appSignature) = @_;
my ($psi);
my ($found) = 0;
my ($appPSN);
foreach $psi (values(%Process))
{
if ($psi->processSignature() eq $appSignature)
{
$appPSN = $psi->processNumber();
$found = 1;
last;
}
}
return $found;
}
=pod
=item appIsFrontmost()
=cut
sub _appIsFrontmost($)
{
my ($appSignature) = @_;
my ($psi);
my ($found) = 0;
my ($appPSN);
foreach $psi (values(%Process))
{
if ($psi->processSignature() eq $appSignature)
{
$appPSN = $psi->processNumber();
$found = 1;
last;
}
}
return (GetFrontProcess() == $appPSN);
}
=pod
=item activate()
Launches CodeWarrior and brings it to the front.
Once found, path will be saved in $idepath_file for future reference.
Edit or delete this file to change the location of the IDE. If app is
moved, C<activate()> will prompt for a new location.
First looks for an open CodeWarrior app. Second, tries to open previously
saved location in ':idepath.txt'. Third, tries to find it and allow user
to choose it with Navigation Services (if present). Fourth, uses good old
GUSI routines built-in to MacPerl for a Choose Directory dialog box.
=cut
sub activate ($) {
$ide_loc_file = $_[0]; # save in global
my($filepath, $appath, $psi) = ($ide_loc_file);
foreach $psi (values(%Process)) {
if ($psi->processSignature() eq $app) {
$appath = $psi->processAppSpec();
_save_appath($filepath, $appath);
last;
}
}
if (!$appath || !-x $appath) {
$appath = _read_appath($filepath);
}
if (!$appath || ! -x $appath)
{
# make sure that MacPerl is a front process
#ActivateApplication('McPL');
MacPerl::Answer("Please locate the CodeWarrior application.", "OK");
# prompt user for the file name, and store it
my $macFile = StandardGetFile( 0, "APPL");
if ( $macFile->sfGood() )
{
$appath = $macFile->sfFile();
}
else
{
die "Operation canceled\n";
}
# if (eval {require Mac::Navigation}) {
# my($options, $nav);
# Mac::Navigation->import();
# $options = NavGetDefaultDialogOptions();
# $options->message('Where is CodeWarrior IDE?');
# $options->windowTitle('Find CodeWarrior IDE');
# $nav = NavChooseObject($Application{$app}, $options);
# die "CodeWarrior IDE not found.\n" if (!$nav || !$nav->file(1));
# $appath = $nav->file(1);
# } else {
# local(*D);
# my $cwd = `pwd`;
# $appath = _get_folder(
# 'Where is the CW IDE folder?',
# dirname($Application{$app})
# );
# die "CodeWarrior IDE not found.\n" if !$appath;
# opendir(D, $appath) or die $!;
# chdir($appath);
# foreach my $file (sort readdir (D)) {
# my(@app) = MacPerl::GetFileInfo($file);
# if ($app[0] && $app[1] &&
# $app[1] eq 'APPL' && $app[0] eq $app
# ) {
# $appath .= $file;
# last;
# }
# }
# chomp($cwd);
# chdir($cwd);
# }
_save_appath($filepath, $appath);
}
my($lp) = LaunchParam->new(
launchAppSpec => $appath,
launchControlFlags => launchContinue() + launchNoFileFlags()
);
unless (LaunchApplication($lp)) {
unlink($filepath);
die $^E;
}
# wait for CodeWarrior to show up in the list of processes
while (!_appIsRunning('CWIE'))
{
WaitNextEvent();
}
# wait for CodeWarrior to come to the front
while (!_appIsFrontmost('CWIE'))
{
WaitNextEvent();
}
}
=pod
=item getCodeWarriorPath()
Returns a file path relative to the CodeWarrior folder
=cut
sub getCodeWarriorPath($)
{
my($subfolder)=@_;
my($app_path) = _read_appath($ide_loc_file);
if ($app_path eq "") { die "Error: Failed to get CodeWarrior IDE path\n"; }
my($codewarrior_root) = $app_path;
$codewarrior_root =~ s/[^:]*$//;
return ($codewarrior_root . $subfolder);
}
=pod
=item getCodeWarriorIDEName()
Returns the name of the CodeWarrior application
=cut
sub getCodeWarriorIDEName()
{
my($subfolder)=@_;
my($app_path) = _read_appath($ide_loc_file);
if ($app_path eq "") { die "Error: Failed to get CodeWarrior IDE path\n"; }
my(@codewarrior_path) = split(/:/, $app_path);
return pop(@codewarrior_path);
}
=pod
=item quit()
Quits CodeWarrior.
=cut
sub quit() {
$last_project_built = "";
$last_project_was_closed = 0;
my($evt) = do_event(qw/aevt quit/, $app);
}
sub _build ($;$) {
my($evt);
if ($_[1]) {
my($prm) =
q"'----':obj {form:name, want:type(TRGT), seld:TEXT(@), from:" .
AEPrint($_[0]) . '}';
$evt = do_event(qw/CWIE MAKE/, $app, $prm, $_[1]);
} else {
my($prm) = q"'----':" . AEPrint($_[0]);
$evt = do_event(qw/CWIE MAKE/, $app, $prm);
}
}
sub _remove_object ($;$) {
my($evt);
if ($_[1]) {
my($prm) =
q"'----':obj {form:name, want:type(TRGT), seld:TEXT(@), from:" .
AEPrint($_[0]) . '}';
$evt = do_event(qw/CWIE RMOB/, $app, $prm, $_[1]);
} else {
my($prm) = q"'----':" . AEPrint($_[0]);
$evt = do_event(qw/CWIE RMOB/, $app, $prm);
}
}
sub _open_file ($) {
my($prm) =
q"'----':obj {form:name, want:type(alis), " .
q"seld:TEXT(@), from:'null'()}";
do_event(qw/aevt odoc/, $app, $prm, $_[0]);
}
sub import_project ($$) {
my($xml_file, $project_path) = @_;
my($prm) = "kocl:type(PRJD), rtyp:TEXT(@), data:TEXT(@), &subj:'null'()";
my($evt) = do_event(qw/core crel/, $app, $prm, $project_path, $xml_file);
my($result) = _get_event_result($evt);
if ($result eq "") {
_close(_get_project($project_path));
}
return $result;
}
sub export_project ($$) {
my($project_path, $xml_out_path) = @_;
my($p, $project_was_closed);
$project_was_closed = 0;
while (1) {
$p = _get_project($project_path);
if (!$p) {
if ($project_was_closed) {
print "### Error - request for project document failed after opening\n";
die "### possibly CW bug: be sure to close your Find window\n";
}
$project_was_closed = 1;
_open_file($project_path);
} else {
last;
}
}
# avoid problems with the Project Messages window
_close_named_window("Project Messages");
my($prm) =
q"'----':obj {form:indx, want:type(PRJD), " .
q"seld:1, from:'null'()}, kfil:TEXT(@)";
my($evt) = do_event(qw/CWIE EXPT/, $app, $prm, $xml_out_path);
if ($project_was_closed) {
$p = _get_project($project_path);
_close($p);
}
return _get_event_result($evt);
}
sub _doc_named ($) {
my($prm) =
q"'----':obj {form:test, want:type(docu), from:'null'(), " .
q"seld:cmpd{relo:'= ', 'obj1':obj {form:prop, want:type" .
q"(prop), seld:type(pnam), from:'exmn'()}, 'obj2':TEXT(@)}}";
my($evt) = do_event(qw/core getd/, $app, $prm, $_[0]);
return($evt->{REPLY} eq 'aevt\ansr{}' ? undef : $evt);
}
sub _full_path ($) {
my($obj) = $_[0];
my($prm) =
q"'----':obj {form:prop, want:type(prop), seld:type(FILE), " .
q"from:" . AEPrint($_[0]) . q"}, rtyp:type(TEXT)";
my($evt) = do_event(qw/core getd/, $app, $prm);
return MacPerl::MakePath(
MacUnpack('fss ', (
AEGetParamDesc($evt->{REP}, keyDirectObject()))->data()->get()
)
);
}
sub _save_errors_window ($) {
my($prm) =
q"'----':obj {form:name, want:type(alis), seld:TEXT(@), from:'null'()}";
do_event(qw/MMPR SvMs/, $app, $prm, $_[0]);
}
sub _close_errors_window () {
return _close_named_window('Errors & Warnings');
}
sub _close_named_window ($) {
my($window_name) = @_;
my($prm) =
q"'----':obj {form:name, want:type(cwin), " .
q"seld:TEXT(@), from:'null'()}";
my($evt) = do_event(qw/core clos/, $app, $prm, $window_name);
return($evt->{REPLY} eq 'aevt\ansr{}' ? 1 : 0);
}
sub _close () {
my($prm) = q"'----':" . AEPrint($_[0]);
do_event(qw/core clos/, $app, $prm);
}
sub _get_dobj ($) {
return(AEGetParamDesc($_[0]->{REP}, keyDirectObject()));
}
sub _get_folder ($$) {
require 'GUSI.ph';
my($prompt, $default) = @_;
MacPerl::Choose(
GUSI::AF_FILE(), 0, $prompt, '',
GUSI::CHOOSE_DIR() + ($default ? &GUSI::CHOOSE_DEFAULT : 0),
$default
);
}
sub _get_event_result ($)
{
my($evt) = @_;
my($result) = $evt->{ERROR};
if ( $result eq "" && $evt->{ERRNO} != 0 )
{
$result = "unknown error (".$evt->{ERRNO}.")";
}
return $result;
}
sub _save_appath ($$) {
my($cwd) = cwd(); # remember the current working dir
chdir($scriptDir); # change dir to the script dir
local(*F);
open(F, '>' . $_[0]) or die $!;
print F $_[1];
close(F);
chdir($cwd); # restore the cwd
}
sub _read_appath ($) {
my($filepath) = @_;
my($cwd) = cwd(); # remember the current working dir
chdir($scriptDir); # change dir to the script dir
if (! -e $filepath) {
return "";
}
local(*F);
open(F, $filepath);
my($appath) = <F>;
close(F);
chdir($cwd); # restore the cwd
return($appath);
}
sub _test ($) {
activate($ide_loc_file);
my($path) = $_[0];
build_project(
"${path}modules:xml:macbuild:XML.mcp", '',
"${path}build:mac:Mozilla.BuildLog.part"
);
}
1;
=pod
=back
=head1 HISTORY
=over 4
=item v1.02, September 23, 1998
Made fixes in finding and saving location of CodeWarrior IDE.
=item v1.01, June 1, 1998
Made fixes to C<chdir()> in C<activate()>, made C<activate()> more robust
in finding CodeWarrior IDE, added global variable to NOT switch to IDE
for each sent event, a few other fixes.
=item v1.00, May 30, 1998
First shot
=back
=head1 AUTHORS
Chris Nandor F<E<lt>pudge@pobox.comE<gt>>, and the author of the
original I<CodeWarriorLib>, Scott Collins F<E<lt>scc@netscape.comE<gt>>.
=head1 SEE ALSO
BuildProject L<Moz>.
=head1 COPYRIGHT
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
=cut

View File

@@ -1,573 +0,0 @@
#!perl -w
package Moz::Jar;
#
# Module for creating jar files, either using a jar manifest, or
# simply jarring up folders on disk.
#
require 5.004;
require Exporter;
use strict;
use Archive::Zip;
use File::Path;
use Mac::Files;
use Moz::Moz;
use vars qw( @ISA @EXPORT );
@ISA = qw(Exporter);
@EXPORT = qw(
CreateJarFileFromDirectory
CreateJarFromManifest
WriteOutJarFiles
SanityCheckJarOptions
);
#-------------------------------------------------------------------------------
# Add the contents of a directory to the zip file
#
#-------------------------------------------------------------------------------
sub _addDirToJar($$$$)
{
my($dir, $jar_root, $zip, $compress) = @_;
opendir(DIR, $dir) or die "Error: Cannot open dir $dir\n";
my @files = readdir(DIR);
closedir DIR;
my $unix_jar_root = $jar_root;
$unix_jar_root =~ s|:|/|g; # colon to slash conversion
my $file;
foreach $file (@files)
{
my $filepath = $dir.":".$file;
if (-d $filepath)
{
print "Adding files to jar from $filepath\n";
_addDirToJar($filepath, $jar_root, $zip, $compress);
}
else
{
my $member = Archive::Zip::Member->newFromFile($filepath);
die "Error: Failed to create zip file member $filepath\n" unless $member;
my $unixName = $filepath;
$unixName =~ s|:|/|g; # colon to slash conversion
$unixName =~ s|^$unix_jar_root||; # relativise
$member->fileName($unixName);
# print "Adding $file as $unixName\n";
if ($compress) {
$member->desiredCompressionMethod(Archive::Zip::COMPRESSION_DEFLATED);
} else {
$member->desiredCompressionMethod(Archive::Zip::COMPRESSION_STORED);
}
$zip->addMember($member);
}
}
}
#-------------------------------------------------------------------------------
# Add the contents of a directory to the zip file
#
#-------------------------------------------------------------------------------
sub CreateJarFileFromDirectory($$$)
{
my($srcdir, $jarpath, $compress) = @_;
my $zip = Archive::Zip->new();
_addDirToJar($srcdir, $srcdir, $zip, $compress);
print "Saving zip file...\n";
my $status = $zip->writeToFileNamed($jarpath);
if ($status == 0) {
print "Zipping completed successfully\n";
} else {
print "Error saving zip file\n";
}
# set the file type/creator to something reasonable
MacPerl::SetFileInfo("ZIP ", "ZIP ", $jarpath);
}
#-------------------------------------------------------------------------------
# printZipContents
#
#-------------------------------------------------------------------------------
sub printZipContents($)
{
my($zip) = @_;
my(@members) = $zip->memberNames();
print "Zip contains:\n";
my($member);
foreach $member (@members)
{
print " $member\n";
}
}
#-------------------------------------------------------------------------------
# safeSaveJarFile
#
# Archive::Zip has a problem where you cannot save a zip file on top of
# an existing zip file that it has open, because it holds references
# into that zip. So we have to save to a temp file, then do a swap.
#
# Note that the zip will become invalid after this operation.
# If you want to do further operations on it, you'll have to reread it.
#-------------------------------------------------------------------------------
sub safeSaveJarFile($$)
{
my($zip, $full_dest_path) = @_;
my($temp_file_name) = $full_dest_path."_temp";
($zip->writeToFileNamed($temp_file_name) == Archive::Zip::AZ_OK) || die "Error: died writing jar to temp file $temp_file_name\n";
unlink $full_dest_path;
(rename $temp_file_name, $full_dest_path) || die "Error: Failed to rename $temp_file_name\n";
MacPerl::SetFileInfo("ZIP ", "ZIP ", $full_dest_path);
}
#-------------------------------------------------------------------------------
# addToJarFile
#
# Add a file to a jar file
#
# Parameters:
# 1. Jar ID. Unix path of jar file inside chrome.
# 2. Abs path to jar.mn file (i.e. source) (mac breaks)
# 3. File source, relative to jar.mn path (mac breaks)
# 4. Abs path to the resulting .jar file (mac breaks)
# 5. Relative file path within the jar (unix breaks)
# 6. Reference to hash of jar files
#
#-------------------------------------------------------------------------------
sub addToJarFile($$$$$$$)
{
my($jar_id, $jar_man_dir, $file_src, $jar_path, $file_jar_path, $override, $jars) = @_;
# print "addToJarFile with:\n $jar_man_dir\n $file_src\n $jar_path\n $file_jar_path\n";
unless ($jar_path =~ m/(.+:)([^:]+)$/) { die "Error: Bad jar path $jar_path\n"; }
my($target_dir) = $1;
my($jar_name) = $2;
$target_dir =~ s/[^:]+$//;
# print "¥ $target_dir $jar_name\n";
# find the source file
my($src) = $jar_man_dir.":".$file_src;
if ((!-e $src) && ($file_src =~ m/.+:([^:]+)$/)) # src does not exist. Fall back to looking for src in jar.mn dir
{
$file_src = $1;
$src = $jar_man_dir.":".$file_src;
if (!-e $src) {
die "Error: Can't find chrome file $src\n";
}
}
if ($main::options{chrome_jars})
{
my($zip) = $jars->{$jar_id};
unless ($zip) { die "Error: Can't find Zip entry for $jar_id\n"; }
# print "Adding $file_src to jar file $jar_path at $file_jar_path\n";
my($member) = Archive::Zip::Member->newFromFile($src);
unless ($member) { die "Error: Failed to create zip file member $src\n"; }
$member->fileName($file_jar_path);
my($compress) = 1;
if ($compress) {
$member->desiredCompressionMethod(Archive::Zip::COMPRESSION_DEFLATED);
$member->desiredCompressionLevel(Archive::Zip::COMPRESSION_LEVEL_DEFAULT); # defaults to 6
} else {
$member->desiredCompressionMethod(Archive::Zip::COMPRESSION_STORED);
}
my($old_member) = $zip->memberNamed($file_jar_path);
if ($override)
{
if ($old_member)
{
# print "Overriding $file_jar_path in jar file $jar_id\n";
# need to compare mod dates or use the + here
$zip->removeMember($old_member);
}
$zip->addMember($member);
}
else
{
if ($old_member)
{
#compare dates here
my($member_moddate) = $old_member->lastModTime();
my($file_moddate) = GetFileModDate($src);
if ($file_moddate > $member_moddate)
{
print "Updating older file $file_jar_path in $jar_id\n";
$zip->removeMember($old_member);
$zip->addMember($member);
}
else
{
print "File $file_jar_path in $jar_id is more recent. Not updating.\n";
}
}
else
{
$zip->addMember($member);
}
}
}
if ($main::options{chrome_files}) # we install raw files too
{
my($rel_path) = $file_jar_path;
$rel_path =~ s|/|:|g; # slash to colons
my($dir_name) = $jar_name;
$dir_name =~ s/\.jar$//;
my($dst) = $target_dir.$dir_name.":".$rel_path;
# print "Aliassing $src\n to\n$dst\n";
if ($override)
{
unlink $dst;
MakeAlias($src, $dst); # don't check errors, otherwise we fail on replacement
}
else
{
if (-e $dst)
{
#compare dates here
my($dst_moddate) = GetFileModDate($dst);
my($file_moddate) = GetFileModDate($src);
if ($file_moddate > $dst_moddate)
{
print "Updating older file $rel_path in $dir_name\n";
unlink $dst;
MakeAlias($src, $dst);
}
else
{
print "File $file_jar_path in $jar_id is more recent. Not updating.\n";
}
}
else
{
MakeAlias($src, $dst);
}
}
}
}
#-------------------------------------------------------------------------------
# setupJarFile
#
# setup a zip for writing
#-------------------------------------------------------------------------------
sub setupJarFile($$$)
{
my($jar_id, $dest_path, $jar_hash) = @_;
# print "Creating jar file $jar_id at $jar_path\n";
my($jar_file) = $jar_id;
$jar_file =~ s|/|:|g; # slash to colons
my($full_jar_path) = full_path_to($dest_path.":".$jar_file);
if ($main::options{chrome_jars})
{
my($zip) = $jar_hash->{$jar_id};
if (!$zip) # if we haven't made it already, do so
{
my($zip) = Archive::Zip->new();
$jar_hash->{$jar_id} = $zip;
# does the jar file exist already? If so, read it in
if (-e $full_jar_path)
{
print "Reading in jar file $jar_id\n";
if ($zip->read($full_jar_path) != Archive::Zip::AZ_OK) { die "Error: Failed to re-read $full_jar_path\n"; }
# printZipContents($zip);
}
}
}
else
{
# installing files.
# nothing to do. MakeAlias creates dirs as needed.
# add this jar to the list
$jar_hash->{$jar_id} = 1;
}
}
#-------------------------------------------------------------------------------
# closeJarFile
#
# We're done with this jar file _for this jar.mn_. We may add more entries
# to it later, so keep it open in the hash.
#-------------------------------------------------------------------------------
sub closeJarFile($$)
{
my($jar_path, $jar_hash) = @_;
# print "Closing jar file $jar_path\n";
if ($main::options{chrome_jars})
{
}
else
{
# installing files.
# nothing to do
}
}
#-------------------------------------------------------------------------------
# WriteOutJarFiles
#
# Now we dump out the jars
#-------------------------------------------------------------------------------
sub WriteOutJarFiles($$)
{
my($chrome_dir, $jars) = @_;
unless ($main::options{chrome_jars}) { return; }
my($full_chrome_path) = full_path_to($chrome_dir);
my($key);
foreach $key (keys %$jars)
{
my($zip) = $jars->{$key};
my($rel_path) = $key;
$rel_path =~ s/\//:/g;
my($output_path) = $full_chrome_path.":".$rel_path;
print "Writing zip file $key to $output_path\n";
# ensure the target dirs exist
my($path) = $output_path;
$path =~ s/[^:]+$//;
mkpath($path);
# unlink $output_path; # remove any existing jar
safeSaveJarFile($zip, $output_path);
# $zip is invalid after this operation, so nuke it here
$jars->{$key} = 0;
}
}
#-------------------------------------------------------------------------------
# registerChromePackage
#
# Enter a chrome package into the installed-chrome.txt file
#-------------------------------------------------------------------------------
sub registerChromePackage($$$$$$)
{
my($jar_file, $file_path, $chrome_dir, $jar_hash, $chrome_type, $pkg_name) = @_;
my($manifest_subdir) = $jar_file;
$manifest_subdir =~ s/:/\//g;
my($chrome_entry);
if ($main::options{use_jars}) {
$chrome_entry = "$chrome_type,install,url,jar:resource:/chrome/$manifest_subdir!/$chrome_type/$pkg_name";
} else {
$manifest_subdir =~ s/\.jar$//;
$chrome_entry = "$chrome_type,install,url,resource:/chrome/$manifest_subdir/$chrome_type/$pkg_name";
}
# print "Entering $chrome_entry in installed-chrome.txt\n";
# ensure chrome_dir exists
mkpath($chrome_dir);
my($inst_chrome) = ${chrome_dir}.":installed-chrome.txt";
if (open(CHROMEFILE, "<$inst_chrome")) {
while (<CHROMEFILE>) {
chomp;
if ($_ eq $chrome_entry) {
# $chrome_entry already appears in installed-chrome.txt file
# just update the mod date
my $now = time;
utime($now, $now, $inst_chrome) || die "Error: Couldn't touch $inst_chrome";
print "+++ updating chrome $inst_chrome\n+++\t\t$chrome_entry\n";
close(CHROMEFILE) || die "Error: can't close $inst_chrome: $!";
return 0;
}
}
close(CHROMEFILE) || die "Error: can't close $inst_chrome: $!";
}
open(CHROMEFILE, ">>${inst_chrome}") || die "Error: Failed to open $inst_chrome\n";
print(CHROMEFILE "${chrome_entry}\n");
close(CHROMEFILE) || die "Error: Failed to close $inst_chrome\n";
print "+++ adding chrome $inst_chrome\n+++\t\t$chrome_entry\n";
}
#-------------------------------------------------------------------------------
# Create or add to a jar file from a jar.mn file.
# Both arguments are relative to the mozilla root dir.
#
#
#-------------------------------------------------------------------------------
sub CreateJarFromManifest($$$)
{
my($jar_man_path, $dest_path, $jars) = @_;
if ($main::options{chrome_jars}) {
print "Jarring from $jar_man_path\n";
}
if ($main::options{chrome_files}) {
print "Installing files from $jar_man_path\n";
}
$jar_man_path = full_path_to($jar_man_path);
$dest_path = full_path_to($dest_path);
# if the jars hash is empty, nuke installed-chrome.txt
if (! scalar(%$jars))
{
print "Nuking installed-chrome.txt\n";
my($installed_chrome) = $dest_path.":installed-chrome.txt";
# unlink $installed_chrome;
}
my $jar_man_dir = "";
my $jar_man_file = "";
if ($jar_man_path =~ /(.+):([^:]+)$/)
{
$jar_man_dir = $1; # no trailing :
$jar_man_file = $2;
}
# Keep a hash of jar files, keyed on relative jar path (e.g. "packages/core.jar")
# Entries are open Archive::Zips (if zipping), and installed-chrome entries.
my($jar_id) = ""; # Current foo/bar.jar from jar.mn file
my($jar_file) = ""; # relative path to jar file (from $dest_path), with mac separators
my($full_jar_path);
open(FILE, "<$jar_man_path") || die "Error: could not open \"$jar_man_path\": $!";
while (<FILE>)
{
my($line) = $_;
chomp($line);
# print "$line\n";
if ($line =~ /^\s*\#.*$/) { # skip comments
next;
}
if ($line =~/^([\w\d.\-\_\\\/]+)\:\s*$/) # line start jar file entries
{
$jar_id = $1;
$jar_file = $jar_id;
$jar_file =~ s|/|:|g; # slash to colons
$full_jar_path = $dest_path.":".$jar_file;
setupJarFile($jar_id, $dest_path, $jars);
}
elsif ($line =~ /^(\+?)\s+([\w\d.\-\_\\\/]+)\s*(\([\w\d.\-\_\\\/]+\))?$\s*/) # jar file entry
{
my($override) = ($1 eq "+");
my($file_dest) = $2;
my($file_src) = $3;
if ($file_src) {
$file_src = substr($file_src, 1, -1); #strip the ()
} else {
$file_src = $file_dest;
}
$file_src =~ s|/|:|g;
if ($jar_file ne "") # if jar is open, add to jar
{
if ($file_dest =~ /([\w\d.\-\_]+)\/([\w\d.\-\_\\\/]+)contents.rdf/)
{
my $chrome_type = $1;
my $pkg_name = $2;
registerChromePackage($jar_file, $file_dest, $dest_path, $jars, $chrome_type, $pkg_name);
}
addToJarFile($jar_id, $jar_man_dir, $file_src, $full_jar_path, $file_dest, $override, $jars);
}
else
{
die "Error: bad jar.mn format at $line\n";
}
}
elsif ($line =~ /^\s*$/ ) # blank line
{
if ($jar_file ne "") #if a jar file is open, close it
{
closeJarFile($full_jar_path, $jars);
$jar_file = "";
$full_jar_path = "";
}
}
}
close(FILE);
if ($jar_file ne "") #if a jar file is open, close it
{
closeJarFile($full_jar_path, $jars);
}
}
1;

View File

@@ -1,228 +0,0 @@
#!perl -w
package Moz::MacCVS;
# package Mac::Apps::MacCVS; this should really be the name of the package
# but due to our directory hierarchy in mozilla, I am not doing it
require 5.004;
require Exporter;
use strict;
use Exporter;
use vars qw($VERSION @ISA @EXPORT);
use Cwd;
use File::Basename;
use Mac::StandardFile;
use Mac::AppleEvents;
use Mac::AppleEvents::Simple;
@ISA = qw(Exporter);
@EXPORT = qw(new describe checkout update);
$VERSION = "1.00";
# If you want to understand the gobbldeygook that's used to build Apple Events,
# you should start by reading the AEGizmos documentation.
# Architecture:
# cvs session object:
# name - session name
# session_file - session file
#
#
my($last_error) = 0;
my($gAppSig) = 'Mcvs'; # MacCVS Pro
#
# utility routines
#
sub _checkForEventError($)
{
my($evt) = @_;
if ($evt->{ERRNO} != 0)
{
print STDERR "Error. Script returned '$evt->{ERROR} (error $evt->{ERRNO})\n";
$last_error = $evt->{ERRNO};
return 0;
}
return 1; # success
}
#
# Session object methods
#
sub new
{
my ( $proto, $session_file) = @_;
my $class = ref($proto) || $proto;
my $self = {};
if ( defined($session_file) && ( -e $session_file) )
{
$self->{"name"} = basename( $session_file );
$self->{"session_file"} = $session_file;
bless $self, $class;
return $self;
}
else
{
print STDERR "MacCVS->new cvs file < $session_file > does not exist\n";
return;
}
}
# makes sure that the session is open
# assertSessionOpen()
# returns 1 on success
sub assertSessionOpen()
{
my ($self) = shift;
$last_error = 0;
my($prm) =
q"'----':obj {form:name, want:type(alis), seld:TEXT(@), from:'null'()}";
my($evt) = do_event(qw/aevt odoc/, $gAppSig, $prm, $self->{session_file});
return _checkForEventError($evt);
}
# prints the cvs object, used mostly for debugging
sub describe
{
my($self) = shift;
$last_error = 0;
print "MacCVS:: name: ", $self->{name}, " session file: ", $self->{session_file}, "\n";
}
# checkout( self, module, revision, date)
# MacCVS checkout command
# returns 1 on success.
sub checkout()
{
my($self, $module, $revision, $date ) = @_;
unless( defined ($module) ) { $module = ""; } # get rid of the pesky undefined warnings
unless( defined ($revision) ) { $revision = ""; }
unless( defined ($date) ) { $date = ""; }
$last_error = 0;
$self->assertSessionOpen() || die "Error: failed to open MacCVS session file at $self->{session_file}\n";
my($revstring) = ($revision ne "") ? $revision : "(none)";
my($datestring) = ($date ne "") ? $date : "(none)";
print "Checking out $module with revision $revstring, date $datestring\n";
my($prm) =
q"'----':obj {form:name, want:type(docu), seld:TEXT(@), from:'null'()}, ".
q"modl:'TEXT'(@), tagr:'TEXT'(@), tagd:'TEXT'(@) ";
my($evt) = do_event(qw/MCvs cout/, $gAppSig, $prm, $self->{name}, $module, $revision, $date);
return _checkForEventError($evt);
}
# update( self, branch tag, list of paths)
# MacCVS udate command
# returns 1 on success.
# NOTE: MacCVS Pro does not correctly support this stuff yet (as of version 2.7d5).
sub update()
{
my($self, $branch, $paths ) = @_;
$last_error = 0;
$self->assertSessionOpen() || die "Error: failed to open MacCVS session file at $self->{session_file}\n";
if ($branch eq "HEAD") {
$branch = "";
}
my($paths_list) = "";
my($path);
foreach $path (@$paths)
{
if ($paths_list ne "") {
$paths_list = $paths_list.", ";
}
$paths_list = $paths_list."Ò".$path."Ó";
}
my($prm) =
q"'----':obj {form:name, want:type(docu), seld:TEXT(@), from:'null'()}, ".
q"tagr:'TEXT'(@), tFls:[";
$prm = $prm.$paths_list."]";
my($evt) = do_event(qw/MCvs updt/, $gAppSig, $prm, $self->{name}, $branch);
return _checkForEventError($evt);
};
sub getLastError()
{
return $last_error;
}
1;
=pod
=head1 NAME
MacCVS - Interface to MacCVS
=head1 SYNOPSIS
use MacCVS;
$session = MacCVS->new( <session_file_path>) || die "cannot create session";
$session->checkout([module] [revision] [date]) || die "Could not check out";
=head1 DESCRIPTION
This is a MacCVS interface for talking to MacCVS Pro client.
MacCVSSession is the class used to manipulate the session
=item new
MacCVS->new( <cvs session file path>);
Creates a new session. Returns undef on failure.
=item checkout( <module> [revision] [date] )
cvs checkout command. Revision and date are optional
returns 0 on failure
=cut
=head1 SEE ALSO
=over
=item MacCVS Home Page
http://www.maccvs.org/
=back
=head1 AUTHORS
Aleks Totic atotic@netscape.com
Simon Fraser sfraser@netscape.com
=cut
__END__

View File

@@ -1,603 +0,0 @@
=head1 NAME
B<Moz> - routines for automating CodeWarrior builds, and some extra-curricular
activities related to building Mozilla
=head1 SYNOPSIS
use Moz;
OpenErrorLog(":::BuildLog");
StopForErrors();
$Moz::QUIET = 1;
InstallFromManifest(":projects:MANIFEST", $dist_dir);
BuildProjectClean(":projects:SomeProject.mcp", "SomeTarget");
MakeAlias(":projects:SomeProject.shlb", $dist_dir);
DontStopForErrors();
BuildProject(":projects:SomeOtherProject.mcp", "SomeTarget");
=head1 DESCRIPTION
B<Moz> comprises the routines needed to slap CodeWarrior around, force it
to build a sequence of projects, report the results, and a few other things.
This module should only contain functions that are generic to any build,
not just the Mozilla build.
=cut
package Moz::Moz;
require Exporter;
use Cwd;
use File::Copy;
use File::Path;
use File::Basename;
use Mac::Types;
use Mac::Events;
use Mac::Processes;
use ExtUtils::Manifest 'maniread';
use Moz::CodeWarriorLib;
@ISA = qw(Exporter);
@EXPORT = qw( LaunchCodeWarrior
GetCodeWarriorRelativePath
current_directory
full_path_to
DoBuildProject
ImportXMLProject
ExportProjectToXML
OpenErrorLog
MakeAlias
GetFileModDate
StopForErrors
DontStopForErrors
InstallFromManifest
InstallResources
RedirectOutputToFile
Delay
ActivateApplication
IsProcessRunning);
@EXPORT_OK = qw(CloseErrorLog QUIET);
sub current_directory()
{
my $current_directory = cwd();
chop($current_directory) if ( $current_directory =~ m/:$/ );
return $current_directory;
}
sub full_path_to($)
{
my ($path) = @_;
if ( $path =~ m/^[^:]+$/ )
{
$path = ":" . $path;
}
if ( $path =~ m/^:/ )
{
$path = current_directory() . $path;
}
return $path;
}
$logging = 0;
$recent_errors_file = "";
$stop_on_1st_error = 1;
$QUIET = 0;
=head2 Logging all the errors and warnings - C<OpenErrorLog($log_file)>, C<CloseErrorLog()>
The warnings and errors generated in the course of building projects can be logged to a file.
Tinderbox uses this facility to show why a remote build failed.
Logging is off by default.
Start logging at any point in your build process with C<OpenErrorLog($log_file)>.
Stop with C<CloseErrorLog()>.
You never need to close the log explicitly, unless you want to just log a couple of projects in the middle of a big list.
C<CloseErrorLog()> is not exported by default.
=cut
sub CloseErrorLog()
{
if ( $logging )
{
close(ERROR_LOG);
$logging = 0;
StopForErrors() if $stop_on_1st_error;
}
}
sub OpenErrorLog($)
{
my ($log_file) = @_;
CloseErrorLog();
if ( $log_file )
{
$log_file = full_path_to($log_file);
open(ERROR_LOG, ">$log_file") || die "Error: Can't open $log_file\n";
MacPerl::SetFileInfo("CWIE", "TEXT", $log_file);
$log_file =~ m/.+:(.+)/;
$recent_errors_file = full_path_to("$1.part");
$logging = 1;
}
}
=head2 Stopping before it's too late - C<StopForErrors()>, C<DontStopForErrors()>
When building a long list of projects, you decide whether to continue building subsequent projects when one fails.
By default, your build script will C<die> after the first project that generates an error while building.
Change this behavior with C<DontStopForErrors()>.
Re-enable it with C<StopForErrors()>.
=cut
sub StopForErrors()
{
$stop_on_1st_error = 1;
# Can't stop for errors unless we notice them.
# Can't notice them unless we are logging.
# If the user didn't explicitly request logging, log to a temporary file.
if ( ! $recent_errors_file )
{
OpenErrorLog("${TMPDIR}BuildResults");
}
}
sub DontStopForErrors()
{
$stop_on_1st_error = 0;
}
sub log_message($)
{
if ( $logging )
{
my ($message) = @_;
print ERROR_LOG $message;
}
}
sub log_message_with_time($)
{
if ( $logging )
{
my ($message) = @_;
my $time_stamp = localtime();
log_message("$message ($time_stamp)\n");
}
}
sub log_recent_errors($)
{
my ($project_name) = @_;
my $found_errors = 0;
if ( $logging )
{
open(RECENT_ERRORS, "<$recent_errors_file");
while( <RECENT_ERRORS> )
{
if ( /^Error/ || /^CouldnÕt find project file/ || /^Link Error/ )
{
# if (!$found_errors)
# print $_;
$found_errors = 1;
}
print ERROR_LOG $_;
}
close(RECENT_ERRORS);
unlink("$recent_errors_file");
}
if ( $stop_on_1st_error && $found_errors )
{
print ERROR_LOG "### Build failed.\n";
die "### Errors encountered building \"$project_name\".\n";
}
}
sub DoBuildProject($$$)
{
my ($project_path, $target_name, $clean_build) = @_;
$project_path = full_path_to($project_path);
# $project_path =~ m/.+:(.+)/;
# my $project_name = $1;
log_message_with_time("### Building \"$project_path\"");
# Check that the given project exists
if (! -e $project_path)
{
print ERROR_LOG "### Build failed.\n";
die "### Can't find project file \"$project_path\".\n";
}
print "Building \"$project_path\[$target_name\]\"\n";
$had_errors = Moz::CodeWarriorLib::build_project(
$project_path, $target_name, $recent_errors_file, $clean_build
);
WaitNextEvent();
# $had_errors =
#MacPerl::DoAppleScript(<<END_OF_APPLESCRIPT);
# tell (load script file "$CodeWarriorLib") to BuildProject("$project_path", "$project_name", "$target_name", "$recent_errors_file", $clean_build)
#END_OF_APPLESCRIPT
# Append any errors to the globally accumulated log file
# if ( $had_errors ) # Removed this test, because we want warnings, too. -- jrm
{
log_recent_errors($project_path);
}
}
sub ImportXMLProject($$)
{
my ($xml_path, $project_path) = @_;
# my ($codewarrior_ide_name) = Moz::CodeWarriorLib::getCodeWarriorIDEName();
# my $ascript = <<EOS;
# tell application "$codewarrior_ide_name"
# make new (project document) as ("$project_path") with data ("$xml_path")
# end tell
#EOS
# print $ascript."\n";
# my($result) = MacPerl::DoAppleScript($ascript);
# unless ($result) { die "Error: ImportXMLProject AppleScript failed $^E $result\n"; }
#
my($import_error) = Moz::CodeWarriorLib::import_project($xml_path, $project_path);
if ($import_error ne "") {
die "Error: ImportXMLProject failed with error $import_error\n";
}
}
sub ExportProjectToXML($$)
{
my ($project_path, $xml_path) = @_;
my (@suffix_list) = (".mcp");
my ($project_name, $project_dir, $suffix) = fileparse($project_path, @suffix_list);
if ($suffix eq "") { die "Project: $project_path doesn't look like a project file.\n"; }
if (-e $xml_path) {
print "$xml_path exists - not exporting $project_path\n";
}
else {
print "Exporting $project_path to $xml_path\n";
my($export_error) = Moz::CodeWarriorLib::export_project($project_path, $xml_path);
if ($export_error ne "") {
die "Error: export_project failed with error '$export_error'\n";
}
if (! -e $xml_path) {
die "Error: XML export to $xml_path failed\n";
}
}
}
=head2 Miscellaneous
C<MakeAlias($old_file, $new_file)> functions like C<symlink()>, except with better argument defaulting and more explicit error messages.
=cut
sub MakeAlias($$)
{
my ($old_file, $new_file) = @_;
# if the directory to hold $new_file doesn't exist, create it
if ( ($new_file =~ m/(.+:)/) && !-d $1 )
{
mkpath($1);
}
# if a leaf name wasn't specified for $new_file, use the leaf from $old_file
if ( ($new_file =~ m/:$/) && ($old_file =~ m/.+:(.+)/) )
{
$new_file .= $1;
}
my $message = "Can't create a Finder alias (at \"$new_file\")\n for \"$old_file\"; because ";
die "Error: $message \"$old_file\" doesn't exist.\n" unless -e $old_file;
die "Error: $message I won't replace an existing (non-alias) file with an alias.\n" if ( -e $new_file && ! -l $new_file );
# now: $old_file exists; $new_file doesn't (or else, is an alias already)
if ( -l $new_file )
{
# ...then see if it already points to $old_file
my $current_target = full_path_to(readlink($new_file));
my $new_target = full_path_to($old_file);
return if ( $current_target eq $new_target );
# if the desired alias already exists and points to the right thing, then we're done
unlink $new_file;
}
symlink($old_file, $new_file) || die "Error: $message symlink returned an unexpected error.\n";
}
=pod
C<InstallFromManifest()>
=cut
sub InstallFromManifest($;$$)
{
my ($manifest_file, $dest_dir, $flat) = @_;
$flat = 0 unless defined($flat); # if $flat, all rel. paths in MANIFEST get aliased to the root of $dest_dir
$dest_dir ||= ":";
$manifest_file =~ m/(.+):/;
my $source_dir = $1;
chop($dest_dir) if $dest_dir =~ m/:$/;
#Mac::Events->import();
WaitNextEvent();
if ($flat)
{
print "Doing manifest on \"$manifest_file\" FLAT\n" unless $QUIET;
}
else
{
print "Doing manifest on \"$manifest_file\"\n" unless $QUIET;
}
my $read = maniread(full_path_to($manifest_file));
foreach $file (keys %$read)
{
next unless $file;
$subdir = ":";
if (!$flat && ($file =~ /:.+:/ ))
{
$subdir = $&;
}
$file = ":$file" unless $file =~ m/^:/;
MakeAlias("$source_dir$file", "$dest_dir$subdir");
}
}
=pod
C<InstallResources()>
=cut
# parameters are path to MANIFEST file, destination dir, true (to make copies) or false (to make aliases)
sub InstallResources($;$;$)
{
my ($manifest_file, $dest_dir, $copy_files) = @_;
$dest_dir ||= ":";
mkpath($dest_dir) if !-d $dest_dir;
$manifest_file =~ m/(.+):/;
my $source_dir = $1;
chop($dest_dir) if $dest_dir =~ m/:$/;
WaitNextEvent();
print "Installing resources from \"$manifest_file\"\n" unless $QUIET;
my $read = maniread(full_path_to($manifest_file));
foreach $file (keys %$read)
{
next unless $file;
if ($copy_files)
{
copy("$source_dir:$file", "$dest_dir:$file");
}
else
{
MakeAlias("$source_dir:$file", "$dest_dir:$file");
}
}
}
#//--------------------------------------------------------------------------------------------------
#// Delay
#//--------------------------------------------------------------------------------------------------
sub Delay($)
{
my ($delay_seconds) = @_;
$now = time;
$exit_time = $now + $delay_seconds;
while ($exit_time > $now) {
$now = time;
}
}
#//--------------------------------------------------------------------------------------------------
#// GetFileModDate
#//--------------------------------------------------------------------------------------------------
sub GetFileModDate($)
{
my($filePath)=@_;
my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks) = stat($filePath);
return $mtime;
}
#//--------------------------------------------------------------------------------------------------
#// LaunchCodeWarrior
#//--------------------------------------------------------------------------------------------------
sub LaunchCodeWarrior($)
{
my($idepath_file) = @_; # full path to IDE location file
my($cur_dir) = cwd();
# this both launches and writes the IDE path file
Moz::CodeWarriorLib::activate($idepath_file);
chdir($cur_dir);
}
#//--------------------------------------------------------------------------------------------------
#// GetCodeWarriorRelativePath
#//--------------------------------------------------------------------------------------------------
sub GetCodeWarriorRelativePath($)
{
my($rel_path) = @_;
return Moz::CodeWarriorLib::getCodeWarriorPath($rel_path);
}
#//--------------------------------------------------------------------------------------------------
#// RedirectOutputToFile
#//--------------------------------------------------------------------------------------------------
sub RedirectOutputToFile($)
{
my($log_file) = @_;
# ensure that folders in the path exist
my($logdir) = "";
my($logfile) = $log_file;
if ($log_file =~ /(.+?:)([^:]+)$/) # ? for non-greedy match
{
$logdir = $1;
$logfile = $2;
mkpath($logdir);
}
print "Output is now being redirected to the file '$log_file'\n";
open(STDOUT, "> $log_file") || die "Can't redirect stdout";
open(STDERR, ">&STDOUT") || die "Can't dup stdout";
select(STDERR); $| = 1; # make unbuffered
select(STDOUT); $| = 1; # make unbuffered
MacPerl::SetFileInfo("CWIE", "TEXT", $log_file);
}
#//--------------------------------------------------------------------------------------------------
#// ActivateApplication
#//--------------------------------------------------------------------------------------------------
sub ActivateApplication($)
{
my ($appSignature) = @_;
my ($psi, $found);
my ($appPSN);
$found = 0;
foreach $psi (values(%Process))
{
if ($psi->processSignature() eq $appSignature)
{
$appPSN = $psi->processNumber();
$found = 1;
last;
}
}
if ($found == 0 || SameProcess($appPSN, GetFrontProcess()))
{
return;
}
SetFrontProcess($appPSN);
while (GetFrontProcess() != $appPSN)
{
WaitNextEvent();
}
}
#//--------------------------------------------------------------------------------------------------
#// IsProcessRunning
#//--------------------------------------------------------------------------------------------------
sub IsProcessRunning($)
{
my($processName, $psn, $psi) = @_;
while ( ($psn, $psi) = each(%Process) ) {
if ($psi->processName eq $processName) { return 1; }
}
return 0;
}
1;
=head1 AUTHORS
Scott Collins <scc@netscape.com>, Simon Fraser <sfraser@netscape.com>, Chris Yeh <cyeh@netscape.com>
=head1 SEE ALSO
BuildMozillaDebug.pl (et al), BuildList.pm, CodeWarriorLib (an AppleScript library)
=head1 COPYRIGHT
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
=cut

View File

@@ -1,272 +0,0 @@
package Moz::Prefs;
require 5.004;
require Exporter;
# Package that attempts to read a file from the Preferences folder,
# and get build settings out of it
use strict;
use Exporter;
use File::Path;
use Mac::Files;
use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(ReadMozUserPrefs);
#-------------------------------------------------------------------------------
#
# GetPrefsFolder
#
#-------------------------------------------------------------------------------
sub GetPrefsFolder()
{
my($prefs_folder) = FindFolder(kOnSystemDisk, kPreferencesFolderType, 1);
return $prefs_folder.":Mozilla build prefs";
}
#-------------------------------------------------------------------------------
#
# SetArrayValue
#
#-------------------------------------------------------------------------------
sub SetArrayValue($$$)
{
my($array_ref, $index1, $index2) = @_;
my($index);
foreach $index (@$array_ref)
{
if ($index->[0] eq $index1)
{
$index->[1] = $index2;
return 1;
}
}
return 0;
}
#-------------------------------------------------------------------------------
#
# WriteDefaultPrefsFile
#
#-------------------------------------------------------------------------------
sub WriteDefaultPrefsFile($)
{
my($file_path) = @_;
my($file_contents);
$file_contents = <<'EOS';
% You can use this file to customize the Mozilla build system.
% The following kinds of lines are allowable:
% Comment lines, which start with a '%' in the first column
% Lines which modify the default build settings. For the list of flags,
% see MozBuildFlags.pm. Examples are:
%
% build pull 0 % don't pull
% options mng 1 % turn mng on
%
% Line containing the special 'buildfrom' flag, which specifies
% where to start the build. Example:
%
% buildfrom nglayout % where to start the build
%
% Lines which specify the location of the files used to store paths
% to the CodeWarrior IDE, and the MacCVS Pro session file. Note quoting
% of paths containing whitespace. Examples:
%
% filepath idepath ::codewarrior.txt
% filepath sessionpath ":Some folder:MacCVS session path.txt"
%
% Lines which modify the build settings like %main::DEBUG.
% Any lines which do not match either of the above are assumed
% to set variables on $main::. Examples:
%
% MOZILLA_OFFICIAL 1
%
EOS
$file_contents =~ s/%/#/g;
local(*PREFS_FILE);
open(PREFS_FILE, "> $file_path") || die "Could not write default prefs file\n";
print PREFS_FILE ($file_contents);
close(PREFS_FILE);
MacPerl::SetFileInfo("McPL", "TEXT", $file_path);
}
#-------------------------------------------------------------------------------
#
# HandlePrefSet
#
#-------------------------------------------------------------------------------
sub HandlePrefSet($$$$)
{
my($flags, $name, $value, $desc) = @_;
if (SetArrayValue($flags, $name, $value)) {
print "Prefs set $desc flag '$name' to '$value'\n";
} else {
die "$desc setting '$name' is not a valid option\n";
}
}
#-------------------------------------------------------------------------------
#
# HandleBuildFromPref
#
#-------------------------------------------------------------------------------
sub HandleBuildFromPref($$)
{
my($build_array, $name) = @_;
my($setting) = 0;
my($index);
foreach $index (@$build_array)
{
if ($index->[0] eq $name) {
$setting = 1;
}
$index->[1] = $setting;
}
if ($setting == 1) {
print "Building from $name onwards, as specified by prefs\n";
} else {
printf "Failed to find buildfrom setting '$name'\n";
}
}
#-------------------------------------------------------------------------------
#
# ReadPrefsFile
#
#-------------------------------------------------------------------------------
sub ReadPrefsFile($$$$$)
{
my($file_path, $build_flags, $options_flags, $filepath_flags, $create_if_missing) = @_;
local(*PREFS_FILE);
if (open(PREFS_FILE, "< $file_path"))
{
print "Reading build prefs from '$file_path'\n";
while (<PREFS_FILE>)
{
my($line) = $_;
chomp($line);
if ($line =~ /^\#/ || $line =~ /^\s*$/) { # ignore comments and empty lines
next;
}
if (($line =~ /^\s*([^#\s]+)\s+([^#\s]+)\s+\"(.+)\"(\s+#.+)?/) ||
($line =~ /^\s*([^#\s]+)\s+([^#\s]+)\s+\'(.+)\'(\s+#.+)?/) ||
($line =~ /^\s*([^#\s]+)\s+([^#\s]+)\s+([^#\s]+)(\s+#.+)?/))
{
my($array_name) = $1;
my($option_name) = $2;
my($option_value) = $3;
# print "Read '$array_name' '$option_name' '$option_value'\n";
if ($array_name eq "build")
{
HandlePrefSet($build_flags, $option_name, $option_value, "Build");
}
elsif ($array_name eq "options")
{
HandlePrefSet($options_flags, $option_name, $option_value, "Options");
}
elsif ($array_name eq "filepath" && $option_name && $option_value)
{
HandlePrefSet($filepath_flags, $option_name, $option_value, "Filepath");
}
else
{
print "Unknown pref option at $line\n";
}
}
elsif ($line =~ /^\s*buildfrom\s+([^#\s]+)(\s+#.+)?/)
{
my($build_start) = $1;
HandleBuildFromPref($build_flags, $build_start);
}
elsif ($line =~ /^\s*([^#\s]+)\s+([^#\s]+)(\s+#.+)?/)
{
my($build_var) = $1;
my($var_setting) = $2;
print "Setting \$main::$build_var to $var_setting\n";
eval "\$main::$build_var = \"$var_setting\"";
}
else
{
print "Unrecognized input line at $line\n";
}
}
close(PREFS_FILE);
}
elsif ($create_if_missing)
{
print "No prefs file found at $file_path; using defaults\n";
my($folder_path) = $file_path;
$folder_path =~ s/[^:]+$//;
mkpath($folder_path);
WriteDefaultPrefsFile($file_path);
}
}
#-------------------------------------------------------------------------------
#
# ReadMozUserPrefs
#
#-------------------------------------------------------------------------------
sub ReadMozUserPrefs($$$$)
{
my($prefs_file_name, $build_flags, $options_flags, $filepath_flags) = @_;
if ($prefs_file_name eq "") { return; }
# if local prefs exist, just use those. Othewise, look in the prefs folder
if (-e $prefs_file_name)
{
# read local prefs
ReadPrefsFile($prefs_file_name, $build_flags, $options_flags, $filepath_flags, 0);
}
else
{
# first read prefs folder prefs
my($prefs_path) = GetPrefsFolder();
$prefs_path .= ":$prefs_file_name";
ReadPrefsFile($prefs_path, $build_flags, $options_flags, $filepath_flags, 1);
}
}
1;

View File

@@ -1,932 +0,0 @@
#!/usr/bin/perl
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Simon Fraser <sfraser@netscape.com>
#
package Moz::ProjectXML;
require 5.004;
require Exporter;
use strict;
use Exporter;
use Cwd;
use XML::DOM;
use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(
ParseXMLDocument
DisposeXMLDocument
WriteXMLDocument
CleanupPro5XML
GetTargetsList
CloneTarget
SetAsSharedLibraryTarget
SetAsStaticLibraryTarget
AddTarget
RemoveTarget
GetTargetSetting
SetTargetSetting
getChildElementTextContents
);
#--------------------------------------------------------------------------------------------------
# A module for reading, manipulating, and writing XML-format CodeWarrior project files.
#
# Sample usage:
#
# use ProjectXML;
#
# my $doc = ProjectXML::ParseXMLDocument("Test.mcp.xml");
# ProjectXML::CloneTarget($doc, "Test.shlb", "Test.lib");
# ProjectXML::SetAsStaticLibraryTarget($doc, "Test.lib", "TestOutput.lib");
# ProjectXML::WriteXMLDocument($doc, "Test_out.xml");
# ProjectXML::DisposeXMLDocument($doc);
#
#--------------------------------------------------------------------------------------------------
#//--------------------------------------------------------------------------------------------------
#// ParseXMLDocument
#// Note that the caller must call DisposeXMLDocument on the returned doc
#//--------------------------------------------------------------------------------------------------
sub ParseXMLDocument($)
{
my($doc_path) = @_;
my $parser = new XML::DOM::Parser(ErrorContext => 2);
my $doc = $parser->parsefile($doc_path);
return $doc;
}
#//--------------------------------------------------------------------------------------------------
#// DisposeXMLDocument
#// Needed to avoid memory leaks - cleanup circular references for garbage collection
#//--------------------------------------------------------------------------------------------------
sub DisposeXMLDocument($)
{
my($doc) = @_;
$doc->dispose();
}
#//--------------------------------------------------------------------------------------------------
#// WriteXMLDocument
#//--------------------------------------------------------------------------------------------------
sub _pro5_tag_compression($$)
{
return 1; # Pro 5 is broken and can't import XML with <foo/> style tags
}
sub _pro6plus_tag_compression($$)
{
return 0; # Pro 6 can deal with empty XML tags like <foo/>
}
sub WriteXMLDocument($$$)
{
my($doc, $file_path, $ide_version) = @_;
if ($ide_version eq "4.0")
{
XML::DOM::setTagCompression(\&_pro5_tag_compression);
}
else
{
XML::DOM::setTagCompression(\&_pro6plus_tag_compression);
}
$doc->printToFile($file_path);
}
#//--------------------------------------------------------------------------------------------------
#// CleanupPro5XML
#// XML Projects exported by Pro 5 contain garbage data under the MWMerge_MacOS_skipResources
#// setting. This routine cleans this up, saving the result to a new file
#//--------------------------------------------------------------------------------------------------
sub CleanupPro5XML($$)
{
my($xml_path, $out_path) = @_;
local(*XML_FILE);
open(XML_FILE, "< $xml_path") || die "Error: failed to open file $xml_path\n";
local(*CLEANED_FILE);
open(CLEANED_FILE, "> $out_path") || die "Error: failed to open file $out_path for writing\n";
my $in_skip_resources_settings = 0;
while(<XML_FILE>)
{
my($line) = $_;
if ($line =~ /^<\?codewarrior/) # is processing inst line
{
my $test_line = $line;
chomp($test_line);
my $out_line = $test_line;
if ($test_line =~ /^<\?codewarrior\s+exportversion=\"(.+)\"\s+ideversion=\"(.+)\"\s*\?>$/)
{
my $export_version = $1;
my $ide_version = $2;
$ide_version = "4.0_mozilla"; # pseudo IDE version so we know we touched it
$out_line = "<?codewarrior exportversion=\"".$export_version."\" ideversion=\"".$ide_version."\"?>";
}
print CLEANED_FILE "$out_line\n";
next;
}
if ($line =~ /MWMerge_MacOS_skipResources/)
{
$in_skip_resources_settings = 1;
print CLEANED_FILE "$line";
}
elsif($in_skip_resources_settings && $line =~ /<!-- Settings for/)
{
# leaving bad settings lines. Write closing tag
print CLEANED_FILE " <!-- Corrupted setting entries removed by script -->\n";
print CLEANED_FILE " </SETTING>\n\n";
print CLEANED_FILE "$line";
$in_skip_resources_settings = 0;
}
elsif (!$in_skip_resources_settings)
{
print CLEANED_FILE "$line";
}
}
close(XML_FILE);
close(CLEANED_FILE);
}
#--------------------------------------------------------------------------------------------------
# SniffProjectXMLIDEVersion
#
#--------------------------------------------------------------------------------------------------
sub SniffProjectXMLIDEVersion($)
{
my($xml_path) = @_;
my $found_version = "";
local(*XML_FILE);
open(XML_FILE, "< $xml_path") || die "Error: failed to open file $xml_path\n";
while(<XML_FILE>)
{
my($line) = $_;
chomp($line);
if ($line =~ /^<\?codewarrior/) # is processing inst line
{
unless ($line =~ /^<\?codewarrior\s+exportversion=\"(.+)\"\s+ideversion=\"(.+)\"\s*\?>$/)
{
die "Error: Failed to find ideversion in $xml_path in line $line\n";
}
my $export_version = $1;
my $ide_version = $2;
$found_version = $ide_version;
last;
}
}
close(XML_FILE);
return $found_version;
}
#//--------------------------------------------------------------------------------------------------
#// GetTargetsList
#// Returns an array of target names
#//--------------------------------------------------------------------------------------------------
sub GetTargetsList($)
{
my($doc) = @_;
my $nodes = $doc->getElementsByTagName("TARGET");
my $n = $nodes->getLength;
my @target_names;
for (my $i = 0; $i < $n; $i++)
{
my ($node) = $nodes->item($i);
my($target_name) = getChildElementTextContents($node, "NAME");
push(@target_names, $target_name);
}
return @target_names;
}
#//--------------------------------------------------------------------------------------------------
#// CloneTarget
#// Clone the named target, renaming it to 'new_name'
#//--------------------------------------------------------------------------------------------------
sub CloneTarget($$$)
{
my($doc, $target_name, $new_name) = @_;
my $target_node = getTargetNode($doc, $target_name);
# clone here
my $target_clone = $target_node->cloneNode(1); # deep clone
# -- munge target settings --
# set the target name field
setChildElementTextContents($doc, $target_clone, "NAME", $new_name);
# set the targetname pref
setTargetNodeSetting($doc, $target_clone, "Targetname", $new_name);
# -- insert new target subtree --
my $target_list = $target_node->getParentNode();
$target_list->appendChild($target_clone);
# -- now add to targetorder --
my (@target_order_nodes) = getChildOfDocument($doc, "TARGETORDER");
my $target_order = @target_order_nodes[0];
my $new_order = $doc->createElement("ORDEREDTARGET");
my $order_name = $doc->createElement("NAME");
$new_order->appendChild($order_name);
setChildElementTextContents($doc, $new_order, "NAME", $new_name);
$target_order->appendChild($new_order);
}
#//--------------------------------------------------------------------------------------------------
#// SetAsSharedLibraryTarget
#//
#//--------------------------------------------------------------------------------------------------
sub SetAsSharedLibraryTarget($$$)
{
my($doc, $target_name, $output_name) = @_;
my $target_node = getTargetNode($doc, $target_name);
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_type", "SharedLibrary");
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_filetype", "1936223330"); #'shlb'
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_outfile", $output_name);
}
#//--------------------------------------------------------------------------------------------------
#// AddFileToTarget
#//
#// Add a file to the specified target(s).
#//
#//--------------------------------------------------------------------------------------------------
sub AddFileToTarget($$$)
{
my($doc, $target_list, $file_name) = @_;
# the file must be added in 3 places:
# 1. in <TARGET><FILELIST><FILE> (with linkage flags if necessary)
# 2. in <TARGET><LINKORDER><FILEREF>
# 3. in <GROUPLIST><GROUP><FILEREF>
die "Write me\n";
}
#//--------------------------------------------------------------------------------------------------
#// RemoveFileFromTarget
#//
#// Remove a file from the specified target, removing it from the entire project
#// if no other targets reference it.
#//
#//--------------------------------------------------------------------------------------------------
sub RemoveFileFromTarget($$$)
{
my($doc, $target_node, $file_name) = @_;
# the file must be removed in 3 places:
# 1. in <TARGET><FILELIST><FILE>
# 2. in <TARGET><LINKORDER><FILEREF>
# 3. in <GROUPLIST><GROUP><FILEREF>
# first, remove from <FILELIST>
my $filelist_node = getFirstChildElement($target_node, "FILELIST");
unless ($filelist_node) { die "Error: failed to find FILELIST node\n"; }
my $file_node = getChildNodeByGrandchildContents($doc, $filelist_node, "FILE", "PATH", $file_name);
unless ($file_node) { return; }
$filelist_node->removeChild($file_node);
# next, remove from <LINKORDER>
my $linkorder_node = getFirstChildElement($target_node, "LINKORDER");
unless ($linkorder_node) { die "Error: failed to find LINKORDER node\n"; }
my $fileref_node = getChildNodeByGrandchildContents($doc, $linkorder_node, "FILEREF", "PATH", $file_name);
unless ($fileref_node) { die "Error: link order node for file $file_name not found\n"; }
$linkorder_node->removeChild($fileref_node);
# last, remove from <GROUPLIST>
# <GROUPLIST> is cross-target, so we have to be careful here.
my $grouplist_node = getChildOfDocument($doc, "GROUPLIST");
unless ($grouplist_node) { die "Error: failed to find GROUPLIST node\n"; }
# if the file isn't in any other targets, remove it from the groups
if (!GetFileInUse($doc, $file_name))
{
print "File $file_name is in no other targest. Removing from project\n";
my @group_nodes;
getChildElementsOfType($doc, $grouplist_node, "GROUP", \@group_nodes);
my $group_node;
foreach $group_node (@group_nodes)
{
my @fileref_nodes;
getChildElementsOfType($doc, $group_node, "FILEREF", \@fileref_nodes);
my $fileref_node;
foreach $fileref_node (@fileref_nodes)
{
my $path_name = getChildElementTextContents($fileref_node, "PATH");
if ($path_name eq $file_name)
{
print "Removing $file_name from project group list\n";
$group_node->removeChild($fileref_node);
last;
}
}
# can a file appear in more than one group?
}
}
}
#//--------------------------------------------------------------------------------------------------
#// SetAsStaticLibraryTarget
#//
#//--------------------------------------------------------------------------------------------------
sub SetAsStaticLibraryTarget($$$)
{
my($doc, $target_name, $output_name) = @_;
my $target_node = getTargetNode($doc, $target_name);
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_type", "Library");
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_filetype", "1061109567"); #'????'
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_outfile", $output_name);
# static targets don't need any library linkage, so we can remove linkage
# with all .shlb and .Lib files.
my(@obsolete_files) = ("NSStdLibStubs", "InterfacesStubs", "InterfaceLib", "InternetConfigLib");
print " Removing libraries etc. from target\n";
# get all files in target
my @target_files = GetTargetFilesList($doc, $target_name);
my $target_file;
foreach $target_file (@target_files)
{
if ($target_file =~ /(\.shlb|\.lib|\.Lib|\.o|\.exp)$/)
{
RemoveFileFromTarget($doc, $target_node, $target_file);
}
}
print " Removing stub libraries from target\n";
# then remove files with known names
my $obs_file;
foreach $obs_file (@obsolete_files)
{
RemoveFileFromTarget($doc, $target_node, $obs_file);
}
}
#//--------------------------------------------------------------------------------------------------
#// AddTarget
#//
#//--------------------------------------------------------------------------------------------------
sub AddTarget($$)
{
my($doc, $target_name) = @_;
die "Write me\n";
}
#//--------------------------------------------------------------------------------------------------
#// RemoveTarget
#//
#//--------------------------------------------------------------------------------------------------
sub RemoveTarget($$)
{
my($doc, $target_name) = @_;
die "Write me\n";
}
#//--------------------------------------------------------------------------------------------------
#// GetTargetSetting
#// Get the value for the specified setting in the specified target
#//--------------------------------------------------------------------------------------------------
sub GetTargetSetting($$$)
{
my($doc, $target_name, $setting_name) = @_;
my $target_node = getTargetNode($doc, $target_name);
return getTargetNodeSetting($target_node, "VALUE");
}
#//--------------------------------------------------------------------------------------------------
#// SetTargetSetting
#// Set the value for the specified setting in the specified target
#//--------------------------------------------------------------------------------------------------
sub SetTargetSetting($$$$)
{
my($doc, $target_name, $setting_name, $new_value) = @_;
my $target_node = getTargetNode($doc, $target_name);
setTargetNodeSetting($doc, $target_node, "VALUE", $new_value);
}
#//--------------------------------------------------------------------------------------------------
#// GetTargetFilesList
#// Return an array of the files in the target (in filelist order)
#//--------------------------------------------------------------------------------------------------
sub GetTargetFilesList($$)
{
my($doc, $target_name) = @_;
my $target_node = getTargetNode($doc, $target_name);
my @files_list;
my $filelist_node = getFirstChildElement($target_node, "FILELIST");
unless ($filelist_node) { die "Error: failed to find FILELIST node\n"; }
my @file_nodes;
getChildElementsOfType($doc, $filelist_node, "FILE", \@file_nodes);
my $node;
foreach $node (@file_nodes)
{
my $file_name = getChildElementTextContents($node, "PATH");
push(@files_list, $file_name);
}
return @files_list;
}
#//--------------------------------------------------------------------------------------------------
#// FileIsInTarget
#//
#//--------------------------------------------------------------------------------------------------
sub FileIsInTarget($$$)
{
my($doc, $file_name, $target_name) = @_;
my $target_node = getTargetNode($doc, $target_name);
unless ($target_node) { die "Error: no target found called $target_name\n"; }
my $file_node = GetTargetFileNode($doc, $target_node, $file_name);
if ($file_node) {
return 1;
}
return 0;
}
#//--------------------------------------------------------------------------------------------------
#// GetFileTargetsList
#// Return an array of the targets that a file is in (expensive)
#//--------------------------------------------------------------------------------------------------
sub GetFileTargetsList($$)
{
my ($doc, $file_name) = @_;
my @target_list;
my @targets = GetTargetsList($doc);
my $target;
foreach $target (@targets)
{
if (FileIsInTarget($doc, $file_name, $target))
{
push(@target_list, $target);
}
}
return @target_list;
}
#//--------------------------------------------------------------------------------------------------
#// GetTargetFileNode
#//
#//--------------------------------------------------------------------------------------------------
sub GetTargetFileNode($$$)
{
my($doc, $target_node, $file_name) = @_;
my $filelist_node = getFirstChildElement($target_node, "FILELIST");
unless ($filelist_node) { die "Error: failed to find FILELIST node\n"; }
my $file_node = getChildNodeByGrandchildContents($doc, $filelist_node, "FILE", "PATH", $file_name);
return $file_node;
}
#//--------------------------------------------------------------------------------------------------
#// GetFileInUse
#// Return true if the file is used by any target
#//--------------------------------------------------------------------------------------------------
sub GetFileInUse($$)
{
my($doc, $file_name) = @_;
my $targetlist_node = getChildOfDocument($doc, "TARGETLIST");
my $target_node = $targetlist_node->getFirstChild();
while ($target_node)
{
if ($target_node->getNodeTypeName eq "ELEMENT_NODE" &&
$target_node->getTagName() eq "TARGET")
{
# if this is a target node
my $file_node = GetTargetFileNode($doc, $target_node, $file_name);
if ($file_node) {
return 1; # found it
}
}
$target_node = $target_node->getNextSibling();
}
# not found
return 0;
}
#//--------------------------------------------------------------------------------------------------
#// getChildOfDocument
#//--------------------------------------------------------------------------------------------------
sub getChildOfDocument($$)
{
my($doc, $child_type) = @_;
return getFirstChildElement($doc->getDocumentElement(), $child_type);
}
#//--------------------------------------------------------------------------------------------------
#// getFirstChildElement
#//--------------------------------------------------------------------------------------------------
sub getFirstChildElement($$)
{
my($node, $element_name) = @_;
my $found_node;
unless ($node) { die "getFirstChildElement called with empty node\n"; }
#look for the first "element_name" child
my $child_node = $node->getFirstChild();
while ($child_node)
{
if ($child_node->getNodeTypeName eq "ELEMENT_NODE" &&
$child_node->getTagName() eq $element_name)
{
$found_node = $child_node;
last;
}
$child_node = $child_node->getNextSibling();
}
return $found_node;
}
#//--------------------------------------------------------------------------------------------------
#// getChildElementsOfType
#//
#// Return an array of refs to child nodes of the given type
#//--------------------------------------------------------------------------------------------------
sub getChildElementsOfType($$$$)
{
my($doc, $node, $child_type, $array_ref) = @_;
my $child_node = $node->getFirstChild();
while ($child_node)
{
if ($child_node->getNodeTypeName eq "ELEMENT_NODE" &&
$child_node->getTagName() eq $child_type)
{
push(@$array_ref, $child_node);
}
$child_node = $child_node->getNextSibling();
}
}
#//--------------------------------------------------------------------------------------------------
#// getChildElementTextContents
#//--------------------------------------------------------------------------------------------------
#
# Given <FOOPY><NERD>Hi!</NERD></FOOPY>, where $node is <FOOPY>,
# returns "Hi!". If > 1 <NERD> node, returns the contents of the first.
#
sub getChildElementTextContents($$)
{
my($node, $tag_name) = @_;
my $first_element = getFirstChildElement($node, $tag_name);
my $text_node = $first_element->getFirstChild();
my $text_contents = "";
# concat adjacent text nodes
while ($text_node)
{
if ($text_node->getNodeTypeName() ne "TEXT_NODE")
{
last;
}
$text_contents = $text_contents.$text_node->getData();
$text_node = $text_node->getNextSibling();
}
return $text_contents;
}
#//--------------------------------------------------------------------------------------------------
#// setChildElementTextContents
#//--------------------------------------------------------------------------------------------------
sub setChildElementTextContents($$$$)
{
my($doc, $node, $tag_name, $contents_text) = @_;
my $first_element = getFirstChildElement($node, $tag_name);
my $new_text_node = $doc->createTextNode($contents_text);
# replace all child elements with a text element
removeAllChildren($first_element);
$first_element->appendChild($new_text_node);
}
#//--------------------------------------------------------------------------------------------------
#// getChildNodeByContents
#//
#// Consider <foo><bar><baz>Foopy</baz></bar><bar><baz>Loopy</baz></bar></foo>
#// This function, when called with getChildNodeByContents($foonode, "bar", "baz", "Loopy")
#// returns the second <bar> node.
#//--------------------------------------------------------------------------------------------------
sub getChildNodeByGrandchildContents($$$$$)
{
my($doc, $node, $child_type, $gc_type, $gc_contents) = @_; # gc = grandchild
my $found_node;
my $child_node = $node->getFirstChild();
while ($child_node)
{
if ($child_node->getNodeTypeName eq "ELEMENT_NODE" &&
$child_node->getTagName() eq $child_type)
{
# check for a child of this node of type
my $child_contents = getChildElementTextContents($child_node, $gc_type);
if ($child_contents eq $gc_contents)
{
$found_node = $child_node;
last;
}
}
$child_node = $child_node->getNextSibling();
}
return $found_node;
}
#//--------------------------------------------------------------------------------------------------
#// getTargetNode
#//--------------------------------------------------------------------------------------------------
sub getTargetNode($$)
{
my($doc, $target_name) = @_;
my $targetlist_node = getChildOfDocument($doc, "TARGETLIST");
return getChildNodeByGrandchildContents($doc, $targetlist_node, "TARGET", "NAME", $target_name);
}
#//--------------------------------------------------------------------------------------------------
#// getTargetNamedSettingNode
#//--------------------------------------------------------------------------------------------------
sub getTargetNamedSettingNode($$)
{
my($target_node, $setting_name) = @_;
my $setting_node;
my $settinglist_node = getFirstChildElement($target_node, "SETTINGLIST");
my $child_node = $settinglist_node->getFirstChild();
while ($child_node)
{
if ($child_node->getNodeTypeName ne "ELEMENT_NODE")
{
$child_node = $child_node->getNextSibling();
next;
}
if ($child_node->getTagName() eq "SETTING")
{
my $set_name = getChildElementTextContents($child_node, "NAME");
if ($set_name eq $setting_name)
{
$setting_node = $child_node;
last;
}
}
$child_node = $child_node->getNextSibling();
}
return $setting_node;
}
#//--------------------------------------------------------------------------------------------------
#// getTargetNodeSetting
#//--------------------------------------------------------------------------------------------------
sub getTargetNodeSetting($$)
{
my($target_node, $setting_name) = @_;
my $setting_node = getTargetNamedSettingNode($target_node, $setting_name);
return getChildElementTextContents($setting_node, "VALUE");
}
#//--------------------------------------------------------------------------------------------------
#// setTargetNodeSetting
#//--------------------------------------------------------------------------------------------------
sub setTargetNodeSetting($$$$)
{
my($doc, $target_node, $setting_name, $new_value) = @_;
my $setting_node = getTargetNamedSettingNode($target_node, $setting_name);
setChildElementTextContents($doc, $setting_node, "VALUE", $new_value);
}
#//--------------------------------------------------------------------------------------------------
#// elementInArray
#//--------------------------------------------------------------------------------------------------
sub elementInArray($$)
{
my($element, $array) = @_;
my $test;
foreach $test (@$array)
{
if ($test eq $element) {
return 1;
}
}
return 0;
}
#//--------------------------------------------------------------------------------------------------
#// removeAllChildren
#//--------------------------------------------------------------------------------------------------
sub removeAllChildren($)
{
my($node) = @_;
my $child_node = $node->getFirstChild();
while ($child_node)
{
$node->removeChild($child_node);
$child_node = $node->getFirstChild();
}
}
#//--------------------------------------------------------------------------------------------------
#// dumpNodeData
#//--------------------------------------------------------------------------------------------------
sub dumpNodeData($)
{
my($node) = @_;
unless ($node) { die "Null node passed to dumpNodeData\n"; }
print "Dumping node $node\n";
my($node_type) = $node->getNodeTypeName();
if ($node_type eq "ELEMENT_NODE")
{
my($node_name) = $node->getTagName();
print "Element $node_name\n";
}
elsif ($node_type eq "TEXT_NODE")
{
my($node_data) = $node->getData;
# my(@node_vals) = unpack("C*", $node_data);
print "Text '$node_data'\n"; # may contain LF chars
}
else
{
print "Node $node_type\n";
}
}
#//--------------------------------------------------------------------------------------------------
#// dumpNodeTree
#//--------------------------------------------------------------------------------------------------
sub dumpNodeTree($)
{
my($node) = @_;
my($child_node) = $node->getFirstChild();
unless ($child_node) { return; }
# recurse
dumpNodeData($child_node);
# then go through child nodes
while ($child_node)
{
dumpNodeTree($child_node);
$child_node = $child_node->getNextSibling();
}
}
1;

View File

@@ -1,90 +0,0 @@
#-------------------------------------------------------------------------------
# These 3 lists are the 'master lists' to control what gets built.
#
# Ordering in these arrays is important; it has to reflect the order in
# which the build occurs.
#
# Setting containing spaces must be quoted with double quotes.
#-------------------------------------------------------------------------------
build_flags
all 1
pull 0
dist 0
config 0
xpidl 0
idl 0
stubs 0
runtime 0
common 0
imglib 0
libimg2 0
necko 0
security 0
browserutils 0
intl 0
nglayout 0
accessiblity 0
editor 0
embedding 0
viewer 0
xpapp 0
extensions 0
plugins 0
mailnews 0
apprunner 0
resources 0
options_flags
pull_by_date 0
chrome_jars 1
chrome_files 0
use_jars 1
transformiix 1
mathml 0 MOZ_MATHML
svg 0 MOZ_SVG
# svg requires libart, which is an lgpl library. You need to pull it
# explicitly.
libart_lgpl 0
mng 1
ldap 1 MOZ_LDAP_XPCOM
ldap_experimental 0 MOZ_LDAP_XPCOM_EXPERIMENTAL
xmlextras 1
wsp 0 MOZ_WSP
inspector 1
mailextras 1
xptlink 0
psm 0 MOZ_PSM
embedding_test 1
embedding_chrome 0
embedding_xulprefs 0
embedding_xulsecurity 0
carbon 0 TARGET_CARBON
useimg2 1 USE_IMG2
lowmem 0 MOZ_MAC_LOWMEM
accessible 1 ACCESSIBILITY
bidi 1 IBMBIDI
p3p 0
jsd 1
venkman 1
moz_logging 1 MOZ_LOGGING
chatzilla 1
content_packs 1
xml_rpc 1
cview 1
help 1
timeline 0 MOZ_TIMELINE
static_build 0 MOZ_STATIC_COMPONENT_LIBS
string_debug 0 DEBUG_STRING
string_stats 0 DEBUG_STRING_STATS
xpctools 0 XPC_TOOLS_SUPPORT
smime 1
mdn 1
print_preview 1 NS_PRINT_PREVIEW
moz_xul 1 MOZ_XUL
filepath_flags
idepath ":CodeWarrior IDE Path.txt"
sessionpath ":Mozilla session path.txt"
buildlogfilepath ":Build Logs:Mozilla build log.txt" # this is a path
scriptlogfilepath ":Build Logs:Mozilla script log.txt"

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +0,0 @@
# List of modules to check out. Format is
# module, (tag), (date)
# where tag and date are optional (non-trailing commas are required)
#
# Examples:
# mozilla/nsprpub, NSPRPUB_CLIENT_TAG
# mozilla/gc, , 10/25/2000 12:00:00
#
mozilla/nsprpub, NETSCAPE_7_0_RTM
mozilla/security/nss, NETSCAPE_7_0_RTM
mozilla/security/manager, NETSCAPE_7_0_RTM
mozilla/accessible, NETSCAPE_7_0_RTM
mozilla/directory/c-sdk, NETSCAPE_7_0_RTM
mozilla/lib/mac/Instrumentation, NETSCAPE_7_0_RTM
mozilla/gfx2, NETSCAPE_7_0_RTM
mozilla/modules/libpr0n, NETSCAPE_7_0_RTM
SeaMonkeyAll, NETSCAPE_7_0_RTM
## You need this if you want to be able to use SVG
## Note that this library is under the LGPL, not the MPL
#mozilla/other-licenses/libart_lgpl

View File

@@ -1,79 +0,0 @@
#!perl
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Simon Fraser <sfraser@netscape.com>
#
require 5.004;
use strict;
use Cwd;
use Moz::BuildUtils;
use Moz::BuildCore;
#-------------------------------------------------------------
# Where have the build options gone?
#
# The various build flags have been centralized into one place.
# The master list of options is in MozBuildFlags.txt. However,
# you should never need to edit that file, or this one.
#
# To customize what gets built, or where to start the build,
# edit the $prefs_file_name file in
# System Folder:Preferences:Mozilla build prefs:
# Documentation is provided in that file.
#-------------------------------------------------------------
my($prefs_file_name) = "Mozilla pull prefs";
#-------------------------------------------------------------
# hashes to hold build options
#-------------------------------------------------------------
my(%build);
my(%options);
my(%filepaths);
my(%optiondefines);
# Hash of input files for this build. Eventually, there will be
# input files for manifests, and projects too.
my(%inputfiles) = (
"buildflags", "MozillaBuildFlags.txt",
"checkoutdata", "MozillaCheckoutList.txt",
"buildprogress", "",
"buildmodule", "MozillaBuildList.pm",
"checkouttime", "Mozilla last checkout"
);
#-------------------------------------------------------------
# end build hashes
#-------------------------------------------------------------
# set the build root directory, which is the the dir above mozilla
SetupBuildRootDir(":mozilla:build:mac:build_scripts");
# Set up all the flags on $main::, like DEBUG, CARBON etc.
# Override the defaults using the preferences files.
SetupDefaultBuildOptions(0, ":mozilla:dist:viewer:", "");
my($do_checkout) = 1;
my($do_build) = 0;
RunBuild($do_checkout, $do_build, \%inputfiles, $prefs_file_name);

View File

@@ -1,511 +0,0 @@
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=.
!if !defined(MOZ_TOP)
#enable builds from changed top level directories
MOZ_TOP=mozilla
!endif
MOZ_SRC_FLIPPED = $(MOZ_SRC:\=/)
MOZ_DIST_FLIPPED = $(MOZ_SRC_FLIPPED)/mozilla/dist
!ifdef MOZ_DEBUG
MOZ_OBJDIR = WIN32_D.OBJ
!else
MOZ_OBJDIR = WIN32_O.OBJ
!endif
#
# Command macro defines
#
#//------------------------------------------------------------------------
#// Figure out how to do the pull.
#//------------------------------------------------------------------------
# uncomment these, modify branch tag, and check in to branch for milestones
MOZ_BRANCH=NETSCAPE_7_0_RTM
NSPR_CO_TAG=NETSCAPE_7_0_RTM
PSM_CO_TAG=NETSCAPE_7_0_RTM
NSS_CO_TAG=NETSCAPE_7_0_RTM
LDAPCSDK_CO_TAG=NETSCAPE_7_0_RTM
ACCESSIBLE_CO_TAG=NETSCAPE_7_0_RTM
IMGLIB2_CO_TAG=NETSCAPE_7_0_RTM
GFX2_CO_TAG=NETSCAPE_7_0_RTM
!ifdef MOZ_BRANCH
CVS_BRANCH=-r $(MOZ_BRANCH)
!endif
!ifdef MOZ_DATE
CVS_BRANCH=$(CVS_BRANCH) -D "$(MOZ_DATE)"
!endif
# default pull is "quiet" but it can be overridden with MOZ_CVS_VERBOSE
!ifndef MOZ_CVS_VERBOSE
CVS_FLAGS=-q
!endif
# honor any user-defined CVS flags
!ifdef MOZ_CVS_FLAGS
CVS_FLAGS=$(CVS_FLAGS) $(MOZ_CVS_FLAGS)
!endif
# let's be explicit about CVSROOT... some windows cvs clients
# are too stupid to correctly work without the -d option
#
# if they are too stupid, they should fail. I am
# commenting this out because this does not work
# under 4nt. (%'s are evaluted differently)
#
# If it breaks you, mail dougt@netscape.com
# and leaf@mozilla.org
#
!if 0
!if defined(CVSROOT)
CVS_FLAGS=$(CVS_FLAGS) -d "$(CVSROOT)"
!endif
!endif
!ifndef MOZ_CO_FLAGS
MOZ_CO_FLAGS = -P
!endif
CVSCO = cvs $(CVS_FLAGS) co $(MOZ_CO_FLAGS) $(CVS_BRANCH)
#//------------------------------------------------------------------------
#// Figure out how to pull NSPR.
#// If no NSPR_CO_TAG is specified, use the default static tag
#//------------------------------------------------------------------------
!ifndef NSPR_CO_FLAGS
NSPR_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
NSPR_CO_FLAGS=$(NSPR_CO_FLAGS) $(CVS_BRANCH)
CVSCO_NSPR = cvs $(CVS_FLAGS) co $(NSPR_CO_FLAGS)
#//------------------------------------------------------------------------
#// Figure out how to pull NSS and PSM libs.
#// If no NSS_CO_TAG or PSM_CO_TAG is specified, use the default static tag
#//------------------------------------------------------------------------
!ifndef NSS_CO_FLAGS
NSS_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
NSS_CO_FLAGS=$(NSS_CO_FLAGS) $(CVS_BRANCH)
CVSCO_NSS = cvs $(CVS_FLAGS) co $(NSS_CO_FLAGS)
!ifndef PSM_CO_FLAGS
PSM_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
PSM_CO_FLAGS=$(PSM_CO_FLAGS) $(CVS_BRANCH)
CVSCO_PSM = cvs $(CVS_FLAGS) co $(PSM_CO_FLAGS)
#//------------------------------------------------------------------------
#// Figure out how to pull LDAP C SDK client libs.
#// If no LDAPCSDK_CO_TAG is specified, use the default tag
#//------------------------------------------------------------------------
!ifndef LDAPCSDK_CO_FLAGS
LDAPCSDK_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
LDAPCSDK_CO_FLAGS=$(LDAPCSDK_CO_FLAGS) $(CVS_BRANCH)
CVSCO_LDAPCSDK = cvs $(CVS_FLAGS) co $(LDAPCSDK_CO_FLAGS)
#//------------------------------------------------------------------------
#// Figure out how to pull accessibility libs.
#// If no ACCESSIBLE_CO_TAG is specified, use the default tag
#//------------------------------------------------------------------------
!ifndef ACCESSIBLE_CO_FLAGS
ACCESSIBLE_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
ACCESSIBLE_CO_FLAGS=$(ACCESSIBLE_CO_FLAGS) $(CVS_BRANCH)
CVSCO_ACCESSIBLE = cvs $(CVS_FLAGS) co $(ACCESSIBLE_CO_FLAGS)
#//------------------------------------------------------------------------
#// Figure out how to pull new image library.
#// If no IMGLIB2_CO_TAG is specified, use the default tag
#//------------------------------------------------------------------------
!ifndef IMGLIB2_CO_FLAGS
IMGLIB2_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
IMGLIB2_CO_FLAGS=$(IMGLIB2_CO_FLAGS) $(CVS_BRANCH)
CVSCO_IMGLIB2 = cvs $(CVS_FLAGS) co $(IMGLIB2_CO_FLAGS)
#//------------------------------------------------------------------------
#// Figure out how to pull new image library.
#// If no GFX2_CO_TAG is specified, use the default tag
#//------------------------------------------------------------------------
!ifndef GFX2_CO_FLAGS
GFX2_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
GFX2_CO_FLAGS=$(GFX2_CO_FLAGS) $(CVS_BRANCH)
CVSCO_GFX2 = cvs $(CVS_FLAGS) co $(GFX2_CO_FLAGS)
#//------------------------------------------------------------------------
#// Figure out how to pull the internal libart
#// (only pulled and built if MOZ_INTERNAL_LIBART_LGPL is set)
#// If no MOZ_INTERNAL_LIBART_CO_TAG is specified, use the default tag
#//------------------------------------------------------------------------
!if defined(MOZ_SVG) && !defined(MOZ_INTERNAL_LIBART_LGPL)
ERR_MESSAGE = ^
You are trying to build Mozilla with SVG support (MOZ_SVG=1), but you ^
haven not specified that mozilla/other-licenses/libart_lgpl should be ^
pulled and built. At the moment Mozilla SVG builds need this patched ^
version of libart. You either need to disable SVG support (unset MOZ_SVG) ^
or enable pulling and building by setting MOZ_INTERNAL_LIBART_LGPL=1.^
^
If you choose to pull and build libart, note that it is only licensed^
under the terms of the LGPL, not the MPL. (Which is why you have to opt^
in explicitly.)
!endif
!if defined(MOZ_INTERNAL_LIBART_LGPL)
!ifndef MOZ_INTERNAL_LIBART_CO_FLAGS
MOZ_INTERNAL_LIBART_CO_FLAGS=$(MOZ_CO_FLAGS)
!endif
!if "$(MOZ_INTERNAL_LIBART_CO_TAG)" != ""
MOZ_INTERNAL_LIBART_CO_FLAGS=$(MOZ_INTERNAL_LIBART_CO_FLAGS) -r $(MOZ_INTERNAL_LIBART_CO_TAG)
!else
MOZ_INTERNAL_LIBART_CO_FLAGS=$(MOZ_INTERNAL_LIBART_CO_FLAGS) $(CVS_BRANCH)
!endif
CVSCO_MOZ_INTERNAL_LIBART = cvs $(CVS_FLAGS) co $(MOZ_INTERNAL_LIBART_CO_FLAGS)
!endif
## The master target
############################################################
pull_and_build_all: pull_all build_all_dep
## Rules for pulling the source from the cvs repository
############################################################
pull_clobber_and_build_all: pull_all clobber_all build_all
!if !defined(MOZ_INTERNAL_LIBART_LGPL)
pull_all: pull_nspr pull_psm pull_ldapcsdk pull_accessible pull_gfx2 pull_imglib2 pull_seamonkey
!else
pull_all: pull_nspr pull_psm pull_ldapcsdk pull_accessible pull_gfx2 pull_imglib2 pull_moz_internal_libart pull_seamonkey
!endif
pull_nspr: pull_clientmak
cd $(MOZ_SRC)\.
$(CVSCO_NSPR) mozilla/nsprpub
pull_nss:
cd $(MOZ_SRC)\.
$(CVSCO_NSS) mozilla/security/coreconf
$(CVSCO_NSS) mozilla/security/nss
pull_psm: pull_nss
cd $(MOZ_SRC)\.
$(CVSCO_PSM) mozilla/security/manager
$(CVSCO_PSM) mozilla/security/makefile.win
pull_ldapcsdk:
cd $(MOZ_SRC)\.
$(CVSCO_LDAPCSDK) mozilla/directory/c-sdk
pull_accessible:
cd $(MOZ_SRC)\.
$(CVSCO_ACCESSIBLE) mozilla/accessible
pull_gfx2:
cd $(MOZ_SRC)\.
$(CVSCO_GFX2) mozilla/gfx2
pull_imglib2:
cd $(MOZ_SRC)\.
$(CVSCO_IMGLIB2) mozilla/modules/libpr0n
!if defined(MOZ_INTERNAL_LIBART_LGPL)
pull_moz_internal_libart:
cd $(MOZ_SRC)\.
$(CVSCO_MOZ_INTERNAL_LIBART) mozilla/other-licenses/libart_lgpl
!endif
pull_xpconnect: pull_nspr
cd $(MOZ_SRC)\.
$(CVSCO) mozilla/include
$(CVSCO) mozilla/config
$(CVSCO) -l mozilla/js
$(CVSCO) -l mozilla/js/src
$(CVSCO) mozilla/js/src/fdlibm
$(CVSCO) mozilla/js/src/xpconnect
$(CVSCO) mozilla/modules/libreg
$(CVSCO) mozilla/xpcom
$(CVSCO) mozilla/string
# pull either layout only or seamonkey the browser
pull_layout:
cd $(MOZ_SRC)\.
$(CVSCO) RaptorWin
pull_seamonkey: pull_clientmak
cd $(MOZ_SRC)\.
$(CVSCO) SeaMonkeyAll
pull_clientmak:
cd $(MOZ_SRC)\.
$(CVSCO) mozilla/client.mak
############################################################
# nmake has to be hardcoded, or we have to depend on mozilla/config
# being pulled already to figure out what $(NMAKE) should be.
clobber_all: clobber_nspr clobber_ldapcsdk clobber_psm clobber_seamonkey
build_all: build_nspr build_ldapcsdk build_seamonkey
build_all_dep: depend libs
distclean:
@cd $(MOZ_SRC)\$(MOZ_TOP)\directory\c-sdk
gmake -f gmakefile.win distclean MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
@cd $(MOZ_SRC)\$(MOZ_TOP)\nsprpub
gmake -f gmakefile.win distclean MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
@cd $(MOZ_SRC)\$(MOZ_TOP)
nmake /f client.mak clobber_psm
nmake /f client.mak clobber_seamonkey
clobber_ldapcsdk:
@cd $(MOZ_SRC)\$(MOZ_TOP)\directory\c-sdk
gmake -f gmakefile.win clobber_all MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED) \
SHELL=sh
clobber_nspr:
@cd $(MOZ_SRC)\$(MOZ_TOP)\nsprpub
gmake -f gmakefile.win clobber_all MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
clobber_psm:
@cd $(MOZ_SRC)\$(MOZ_TOP)\security
nmake -f makefile.win clobber_all
clobber_xpconnect:
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
-rd /s /q dist
@cd $(MOZ_SRC)\$(MOZ_TOP)\nsprpub
gmake -f gmakefile.win clobber_all MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
@cd $(MOZ_SRC)\$(MOZ_TOP)\include
nmake -f makefile.win clobber_all
@cd $(MOZ_SRC)\$(MOZ_TOP)\modules\libreg
nmake -f makefile.win clobber_all
@cd $(MOZ_SRC)\$(MOZ_TOP)\string
nmake -f makefile.win clobber_all
@cd $(MOZ_SRC)\$(MOZ_TOP)\xpcom
nmake -f makefile.win clobber_all
@cd $(MOZ_SRC)\$(MOZ_TOP)\js
nmake -f makefile.win clobber_all
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src\xpconnect
nmake -f makefile.win clobber_all
clobber_seamonkey:
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
-rd /s /q dist
nmake -f makefile.win clobber_all
depend: export
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
nmake -f makefile.win depend
depend_xpconnect:
@cd $(MOZ_SRC)\$(MOZ_TOP)\include
nmake -f makefile.win depend
@cd $(MOZ_SRC)\$(MOZ_TOP)\modules\libreg
nmake -f makefile.win depend
@cd $(MOZ_SRC)\$(MOZ_TOP)\string
nmake -f makefile.win depend
@cd $(MOZ_SRC)\$(MOZ_TOP)\xpcom
nmake -f makefile.win depend
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src
nmake -f makefile.win depend
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src\xpconnect
nmake -f makefile.win depend
build_nspr:
@cd $(MOZ_SRC)\$(MOZ_TOP)\nsprpub
gmake -f gmakefile.win MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
build_ldapcsdk:
@cd $(MOZ_SRC)\$(MOZ_TOP)\directory\c-sdk
gmake -f gmakefile.win MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED) SHELL=sh
build_psm:
@cd $(MOZ_SRC)\$(MOZ_TOP)\security
nmake -f makefile.win
build_xpconnect: build_nspr
@cd $(MOZ_SRC)\$(MOZ_TOP)\include
nmake -f makefile.win all
@cd $(MOZ_SRC)\$(MOZ_TOP)\modules\libreg
nmake -f makefile.win all
@cd $(MOZ_SRC)\$(MOZ_TOP)\xpcom
nmake -f makefile.win export
@cd $(MOZ_SRC)\$(MOZ_TOP)\string
nmake -f makefile.win all
@cd $(MOZ_SRC)\$(MOZ_TOP)\xpcom
nmake -f makefile.win libs
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src
nmake -f makefile.win all
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src\xpconnect
nmake -f makefile.win all
build_seamonkey:
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
nmake -f makefile.win all
build_client:
@cd $(MOZ_SRC)\mozilla\.
nmake -f makefile.win all
build_layout:
@cd $(MOZ_SRC)\mozilla\.
nmake -f makefile.win all
build_dist:
@cd $(MOZ_SRC)\mozilla\.
nmake -f makefile.win all
libs:
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
nmake -f makefile.win libs
export: build_nspr build_ldapcsdk
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
nmake -f makefile.win export
clobber_dist:
@cd $(MOZ_SRC)\mozilla\.
nmake -f makefile.win clobber_all
clobber_client:
@cd $(MOZ_SRC)\mozilla\.
nmake -f makefile.win clobber_all
clobber_layout:
@cd $(MOZ_SRC)\mozilla\.
nmake -f makefile.win clobber_all
browse_info::
cd $(MOZ_SRC)\$(MOZ_TOP)
-dir /s /b *.sbr > sbrlist.tmp
-bscmake /Es /o mozilla.bsc @sbrlist.tmp
-rm sbrlist.tmp
regchrome::
@cd $(MOZ_SRC)\mozilla\.
nmake /f makefile.win regchrome
deliver::
@cd $(MOZ_SRC)\mozilla\.
nmake /f makefile.win splitsymbols
#//------------------------------------------------------------------------
#// Utility stuff...
#//------------------------------------------------------------------------
#//------------------------------------------------------------------------
# Verify that MOZ_SRC is set correctly
#//------------------------------------------------------------------------
# Check to see if it is set at all
!if "$(MOZ_SRC)"==""
MOZ_SRC = $(MAKEDIR)\..
!endif
#
# create a temp file at the root and make sure it is visible from MOZ_SRC
#
!if [copy $(MAKEDIR)\client.mak $(MAKEDIR)\xyzzy.tmp > NUL] == 0
!endif
!if !EXIST( $(MOZ_SRC)\mozilla\xyzzy.tmp )
ERR_MESSAGE=$(ERR_MESSAGE)^
MOZ_SRC isn't set correctly: [$(MOZ_SRC)\mozilla]!=[$(MAKEDIR)]
!endif
!if [del $(MAKEDIR)\xyzzy.tmp]
!endif
#//------------------------------------------------------------------------
# Verify that MOZ_BITS is set
#//------------------------------------------------------------------------
!if !defined(MOZ_BITS)
ERR_MESSAGE=$(ERR_MESSAGE)^
Environment variable MOZ_BITS isn't set.
!endif
!if !defined(MOZ_TOOLS)
ERR_MESSAGE=$(ERR_MESSAGE)^
Environment variable MOZ_TOOLS isn't set.
!endif
#//------------------------------------------------------------------------
#// Display error
#//------------------------------------------------------------------------
!if "$(ERR_MESSAGE)" != ""
ERR_MESSAGE = ^
client.mak: ^
$(ERR_MESSAGE) ^
^
client.mak: usage^
^
nmake -f client.mak [MOZ_BRANCH=<cvs_branch_name>] ^
[MOZ_DATE=<cvs_date>]^
[pull_and_build_all]^
[pull_all]^
[build_all]^
^
Environment variables:^
^
MOZ_BITS set to 32^
MOZ_TOOLS set to the directory containing the needed tools ^
!ERROR $(ERR_MESSAGE)
!endif

View File

@@ -1,650 +0,0 @@
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Stephen Lamm
# Build the Mozilla client.
#
# This needs CVSROOT set to work, e.g.,
# setenv CVSROOT :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
# or
# setenv CVSROOT :pserver:username%somedomain.org@cvs.mozilla.org:/cvsroot
#
# To checkout and build a tree,
# 1. cvs co mozilla/client.mk
# 2. cd mozilla
# 3. gmake -f client.mk
#
# Other targets (gmake -f client.mk [targets...]),
# checkout
# build
# clean (realclean is now the same as clean)
# distclean
#
# See http://www.mozilla.org/build/unix.html for more information.
#
# Options:
# MOZ_OBJDIR - Destination object directory
# MOZ_CO_DATE - Date tag to use for checkout (default: none)
# MOZ_CO_MODULE - Module to checkout (default: SeaMonkeyAll)
# MOZ_CVS_FLAGS - Flags to pass cvs (default: -q -z3)
# MOZ_CO_FLAGS - Flags to pass after 'cvs co' (default: -P)
# MOZ_MAKE_FLAGS - Flags to pass to $(MAKE)
# MOZ_CO_BRANCH - Branch tag (Deprecated. Use MOZ_CO_TAG below.)
#
#######################################################################
# Checkout Tags
#
# For branches, uncomment the MOZ_CO_TAG line with the proper tag,
# and commit this file on that tag.
MOZ_CO_TAG = NETSCAPE_7_0_RTM
NSPR_CO_TAG = NETSCAPE_7_0_RTM
PSM_CO_TAG = NETSCAPE_7_0_RTM
NSS_CO_TAG = NETSCAPE_7_0_RTM
LDAPCSDK_CO_TAG = NETSCAPE_7_0_RTM
ACCESSIBLE_CO_TAG = NETSCAPE_7_0_RTM
GFX2_CO_TAG = NETSCAPE_7_0_RTM
IMGLIB2_CO_TAG = NETSCAPE_7_0_RTM
BUILD_MODULES = all
#######################################################################
# Defines
#
CVS = cvs
CWD := $(shell pwd)
ifeq "$(CWD)" "/"
CWD := /.
endif
ifneq (, $(wildcard client.mk))
# Ran from mozilla directory
ROOTDIR := $(shell dirname $(CWD))
TOPSRCDIR := $(CWD)
else
# Ran from mozilla/.. directory (?)
ROOTDIR := $(CWD)
TOPSRCDIR := $(CWD)/mozilla
endif
# on os2, TOPSRCDIR may have two forward slashes in a row, which doesn't
# work; replace first instance with one forward slash
TOPSRCDIR := $(shell echo "$(TOPSRCDIR)" | sed -e 's%//%/%')
ifndef TOPSRCDIR_MOZ
TOPSRCDIR_MOZ=$(TOPSRCDIR)
endif
# if ROOTDIR equals only drive letter (i.e. "C:"), set to "/"
DIRNAME := $(shell echo "$(ROOTDIR)" | sed -e 's/^.://')
ifeq ($(DIRNAME),)
ROOTDIR := /.
endif
AUTOCONF := autoconf
MKDIR := mkdir
SH := /bin/sh
ifndef MAKE
MAKE := gmake
endif
CONFIG_GUESS_SCRIPT := $(wildcard $(TOPSRCDIR)/build/autoconf/config.guess)
ifdef CONFIG_GUESS_SCRIPT
CONFIG_GUESS = $(shell $(CONFIG_GUESS_SCRIPT))
else
_IS_FIRST_CHECKOUT := 1
endif
####################################
# CVS
# Add the CVS root to CVS_FLAGS if needed
CVS_ROOT_IN_TREE := $(shell cat $(TOPSRCDIR)/CVS/Root 2>/dev/null)
ifneq ($(CVS_ROOT_IN_TREE),)
ifneq ($(CVS_ROOT_IN_TREE),$(CVSROOT))
CVS_FLAGS := -d $(CVS_ROOT_IN_TREE)
endif
endif
CVSCO = $(strip $(CVS) $(CVS_FLAGS) co $(CVS_CO_FLAGS))
CVSCO_LOGFILE := $(ROOTDIR)/cvsco.log
CVSCO_LOGFILE := $(shell echo $(CVSCO_LOGFILE) | sed s%//%/%)
ifdef MOZ_CO_TAG
CVS_CO_FLAGS := -r $(MOZ_CO_TAG)
endif
####################################
# Load mozconfig Options
# See build pages, http://www.mozilla.org/build/unix.html,
# for how to set up mozconfig.
MOZCONFIG_LOADER := mozilla/build/autoconf/mozconfig2client-mk
MOZCONFIG_FINDER := mozilla/build/autoconf/mozconfig-find
MOZCONFIG_MODULES := mozilla/build/unix/modules.mk
run_for_side_effects := \
$(shell cd $(ROOTDIR); \
if test "$(_IS_FIRST_CHECKOUT)"; then \
$(CVSCO) $(MOZCONFIG_FINDER) $(MOZCONFIG_LOADER) $(MOZCONFIG_MODULES); \
else true; \
fi; \
$(MOZCONFIG_LOADER) $(TOPSRCDIR) mozilla/.mozconfig.mk > mozilla/.mozconfig.out)
include $(TOPSRCDIR)/.mozconfig.mk
include $(TOPSRCDIR)/build/unix/modules.mk
####################################
# Options that may come from mozconfig
# Change CVS flags if anonymous root is requested
ifdef MOZ_CO_USE_MIRROR
CVS_FLAGS := -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
endif
# MOZ_CVS_FLAGS - Basic CVS flags
ifeq "$(origin MOZ_CVS_FLAGS)" "undefined"
CVS_FLAGS := $(CVS_FLAGS) -q -z 3
else
CVS_FLAGS := $(MOZ_CVS_FLAGS)
endif
# This option is deprecated. The best way to have client.mk pull a tag
# is to set MOZ_CO_TAG (see above) and commit that change on the tag.
ifdef MOZ_CO_BRANCH
$(warning Use MOZ_CO_TAG instead of MOZ_CO_BRANCH)
CVS_CO_FLAGS := -r $(MOZ_CO_BRANCH)
endif
# MOZ_CO_FLAGS - Anything that we should use on all checkouts
ifeq "$(origin MOZ_CO_FLAGS)" "undefined"
CVS_CO_FLAGS := $(CVS_CO_FLAGS) -P
else
CVS_CO_FLAGS := $(CVS_CO_FLAGS) $(MOZ_CO_FLAGS)
endif
ifdef MOZ_CO_DATE
CVS_CO_DATE_FLAGS := -D "$(MOZ_CO_DATE)"
endif
ifdef MOZ_OBJDIR
OBJDIR := $(MOZ_OBJDIR)
MOZ_MAKE := $(MAKE) $(MOZ_MAKE_FLAGS) -C $(OBJDIR)
else
OBJDIR := $(TOPSRCDIR)
MOZ_MAKE := $(MAKE) $(MOZ_MAKE_FLAGS)
endif
####################################
# CVS defines for PSM
#
PSM_CO_MODULE= mozilla/security/manager
PSM_CO_FLAGS := -P -A
ifdef MOZ_CO_FLAGS
PSM_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef PSM_CO_TAG
PSM_CO_FLAGS := $(PSM_CO_FLAGS) -r $(PSM_CO_TAG)
endif
CVSCO_PSM = $(CVS) $(CVS_FLAGS) co $(PSM_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(PSM_CO_MODULE)
####################################
# CVS defines for NSS
#
NSS_CO_MODULE = mozilla/security/nss \
mozilla/security/coreconf \
$(NULL)
NSS_CO_FLAGS := -P
ifdef MOZ_CO_FLAGS
NSS_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef NSS_CO_TAG
NSS_CO_FLAGS := $(NSS_CO_FLAGS) -r $(NSS_CO_TAG)
endif
# Cannot pull static tags by date
ifeq ($(NSS_CO_TAG),NSS_CLIENT_TAG)
CVSCO_NSS = $(CVS) $(CVS_FLAGS) co $(NSS_CO_FLAGS) $(NSS_CO_MODULE)
else
CVSCO_NSS = $(CVS) $(CVS_FLAGS) co $(NSS_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(NSS_CO_MODULE)
endif
####################################
# CVS defines for NSPR
#
NSPR_CO_MODULE = mozilla/nsprpub
NSPR_CO_FLAGS := -P
ifdef MOZ_CO_FLAGS
NSPR_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef NSPR_CO_TAG
NSPR_CO_FLAGS := $(NSPR_CO_FLAGS) -r $(NSPR_CO_TAG)
endif
# Cannot pull static tags by date
ifeq ($(NSPR_CO_TAG),NSPRPUB_CLIENT_TAG)
CVSCO_NSPR = $(CVS) $(CVS_FLAGS) co $(NSPR_CO_FLAGS) $(NSPR_CO_MODULE)
else
CVSCO_NSPR = $(CVS) $(CVS_FLAGS) co $(NSPR_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(NSPR_CO_MODULE)
endif
####################################
# CVS defines for the C LDAP SDK
#
LDAPCSDK_CO_MODULE = mozilla/directory/c-sdk
LDAPCSDK_CO_FLAGS := -P
ifdef MOZ_CO_FLAGS
LDAPCSDK_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef LDAPCSDK_CO_TAG
LDAPCSDK_CO_FLAGS := $(LDAPCSDK_CO_FLAGS) -r $(LDAPCSDK_CO_TAG)
endif
CVSCO_LDAPCSDK = $(CVS) $(CVS_FLAGS) co $(LDAPCSDK_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(LDAPCSDK_CO_MODULE)
####################################
# CVS defines for the C LDAP SDK
#
ACCESSIBLE_CO_MODULE = mozilla/accessible
ACCESSIBLE_CO_FLAGS := -P
ifdef MOZ_CO_FLAGS
ACCESSIBLE_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef ACCESSIBLE_CO_TAG
ACCESSIBLE_CO_FLAGS := $(ACCESSIBLE_CO_FLAGS) -r $(ACCESSIBLE_CO_TAG)
endif
CVSCO_ACCESSIBLE = $(CVS) $(CVS_FLAGS) co $(ACCESSIBLE_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(ACCESSIBLE_CO_MODULE)
####################################
# CVS defines for gfx2
#
GFX2_CO_MODULE = mozilla/gfx2
GFX2_CO_FLAGS := -P
ifdef MOZ_CO_FLAGS
GFX2_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef GFX2_CO_TAG
GFX2_CO_FLAGS := $(GFX2_CO_FLAGS) -r $(GFX2_CO_TAG)
endif
CVSCO_GFX2 = $(CVS) $(CVS_FLAGS) co $(GFX2_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(GFX2_CO_MODULE)
####################################
# CVS defines for new image library
#
IMGLIB2_CO_MODULE = mozilla/modules/libpr0n
IMGLIB2_CO_FLAGS := -P
ifdef MOZ_CO_FLAGS
IMGLIB2_CO_FLAGS := $(MOZ_CO_FLAGS)
endif
ifdef IMGLIB2_CO_TAG
IMGLIB2_CO_FLAGS := $(IMGLIB2_CO_FLAGS) -r $(IMGLIB2_CO_TAG)
endif
CVSCO_IMGLIB2 = $(CVS) $(CVS_FLAGS) co $(IMGLIB2_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(IMGLIB2_CO_MODULE)
####################################
# CVS defines for standalone modules
#
ifneq ($(BUILD_MODULES),all)
MOZ_CO_MODULE := $(filter-out $(NSPRPUB_DIR) security directory/c-sdk, $(BUILD_MODULE_CVS))
MOZ_CO_MODULE += allmakefiles.sh client.mk aclocal.m4 configure configure.in
MOZ_CO_MODULE += Makefile.in
MOZ_CO_MODULE := $(addprefix mozilla/, $(MOZ_CO_MODULE))
NOSUBDIRS_MODULE := $(addprefix mozilla/, $(BUILD_MODULE_CVS_NS))
ifneq ($(NOSUBDIRS_MODULE),)
CVSCO_NOSUBDIRS := $(CVSCO) -l $(CVS_CO_DATE_FLAGS) $(NOSUBDIRS_MODULE)
endif
ifeq (,$(filter $(NSPRPUB_DIR), $(BUILD_MODULE_CVS)))
CVSCO_NSPR :=
endif
ifeq (,$(filter security security/manager, $(BUILD_MODULE_CVS)))
CVSCO_PSM :=
CVSCO_NSS :=
endif
ifeq (,$(filter directory/c-sdk, $(BUILD_MODULE_CVS)))
CVSCO_LDAPCSDK :=
endif
ifeq (,$(filter accessible, $(BUILD_MODULE_CVS)))
CVSCO_ACCESSIBLE :=
endif
ifeq (,$(filter gfx2, $(BUILD_MODULE_CVS)))
CVSCO_GFX2 :=
endif
ifeq (,$(filter modules/libpr0n, $(BUILD_MODULE_CVS)))
CVSCO_IMGLIB2 :=
endif
endif
####################################
# CVS defines for SeaMonkey
#
ifeq ($(MOZ_CO_MODULE),)
MOZ_CO_MODULE := SeaMonkeyAll
endif
CVSCO_SEAMONKEY := $(CVSCO) $(CVS_CO_DATE_FLAGS) $(MOZ_CO_MODULE)
####################################
# CVS defined for libart (pulled and built if MOZ_INTERNAL_LIBART_LGPL is set)
#
CVSCO_LIBART := $(CVSCO) $(CVS_CO_DATE_FLAGS) mozilla/other-licenses/libart_lgpl
ifdef MOZ_INTERNAL_LIBART_LGPL
FASTUPDATE_LIBART := fast_update $(CVSCO_LIBART)
CHECKOUT_LIBART := cvs_co $(CVSCO_LIBART)
else
CHECKOUT_LIBART := true
FASTUPDATE_LIBART := true
endif
####################################
# CVS defines for Calendar (pulled and built if MOZ_CALENDAR is set)
#
CVSCO_CALENDAR := $(CVSCO) $(CVS_CO_DATE_FLAGS) mozilla/calendar
ifdef MOZ_CALENDAR
FASTUPDATE_CALENDAR := fast_update $(CVSCO_CALENDAR)
CHECKOUT_CALENDAR := cvs_co $(CVSCO_CALENDAR)
else
CHECKOUT_CALENDAR := true
FASTUPDATE_CALENDAR := true
endif
# because some cygwin tools can't handle native dos-drive paths & vice-versa
# force configure to use a relative path for --srcdir
# need a better check for win32
# and we need to get OBJDIR earlier
ifdef MOZ_TOOLS
_tmpobjdir := $(shell cygpath -u $(OBJDIR))
_abs2rel := $(shell cygpath -w $(TOPSRCDIR)/build/unix/abs2rel.pl | sed -e 's|\\|/|g')
_OBJ2SRCPATH := $(shell $(_abs2rel) $(TOPSRCDIR) $(_tmpobjdir))
endif
#######################################################################
# Rules
#
# Print out any options loaded from mozconfig.
all build checkout clean depend distclean export libs install realclean::
@if test -f .mozconfig.out; then \
cat .mozconfig.out; \
rm -f .mozconfig.out; \
else true; \
fi
ifdef _IS_FIRST_CHECKOUT
all:: checkout build
else
all:: checkout alldep
endif
# Windows equivalents
pull_all: checkout
build_all: build
build_all_dep: alldep
build_all_depend: alldep
clobber clobber_all: clean
pull_and_build_all: checkout alldep
# Do everything from scratch
everything: checkout clean build
####################################
# CVS checkout
#
checkout::
# @: Backup the last checkout log.
@if test -f $(CVSCO_LOGFILE) ; then \
mv $(CVSCO_LOGFILE) $(CVSCO_LOGFILE).old; \
else true; \
fi
ifdef RUN_AUTOCONF_LOCALLY
@echo "Removing local configures" ; \
cd $(ROOTDIR) && \
$(RM) -f mozilla/configure mozilla/nsprpub/configure \
mozilla/directory/c-sdk/configure
endif
@echo "checkout start: "`date` | tee $(CVSCO_LOGFILE)
@echo '$(CVSCO) mozilla/client.mk mozilla/build/unix/modules.mk'; \
cd $(ROOTDIR) && \
$(CVSCO) mozilla/client.mk mozilla/build/unix/modules.mk
@cd $(ROOTDIR) && $(MAKE) -f mozilla/client.mk real_checkout
real_checkout:
# @: Start the checkout. Split the output to the tty and a log file. \
# : If it fails, touch an error file because "tee" hides the error.
@failed=.cvs-failed.tmp; rm -f $$failed*; \
cvs_co() { echo "$$@" ; \
("$$@" || touch $$failed) 2>&1 | tee -a $(CVSCO_LOGFILE) && \
if test -f $$failed; then false; else true; fi; }; \
cvs_co $(CVSCO_NSPR) && \
cvs_co $(CVSCO_NSS) && \
cvs_co $(CVSCO_PSM) && \
cvs_co $(CVSCO_LDAPCSDK) && \
cvs_co $(CVSCO_ACCESSIBLE) && \
cvs_co $(CVSCO_GFX2) && \
cvs_co $(CVSCO_IMGLIB2) && \
$(CHECKOUT_CALENDAR) && \
$(CHECKOUT_LIBART) && \
cvs_co $(CVSCO_SEAMONKEY) && \
cvs_co $(CVSCO_NOSUBDIRS)
@echo "checkout finish: "`date` | tee -a $(CVSCO_LOGFILE)
# @: Check the log for conflicts. ;
@conflicts=`egrep "^C " $(CVSCO_LOGFILE)` ;\
if test "$$conflicts" ; then \
echo "$(MAKE): *** Conflicts during checkout." ;\
echo "$$conflicts" ;\
echo "$(MAKE): Refer to $(CVSCO_LOGFILE) for full log." ;\
false; \
else true; \
fi
ifdef RUN_AUTOCONF_LOCALLY
@echo Generating configures using $(AUTOCONF) ; \
cd $(TOPSRCDIR) && $(AUTOCONF) && \
cd $(TOPSRCDIR)/nsprpub && $(AUTOCONF) && \
cd $(TOPSRCDIR)/directory/c-sdk && $(AUTOCONF)
endif
fast-update:
# @: Backup the last checkout log.
@if test -f $(CVSCO_LOGFILE) ; then \
mv $(CVSCO_LOGFILE) $(CVSCO_LOGFILE).old; \
else true; \
fi
ifdef RUN_AUTOCONF_LOCALLY
@echo "Removing local configures" ; \
cd $(ROOTDIR) && \
$(RM) -f mozilla/configure mozilla/nsprpub/configure \
mozilla/directory/c-sdk/configure
endif
@echo "checkout start: "`date` | tee $(CVSCO_LOGFILE)
@echo '$(CVSCO) mozilla/client.mk mozilla/build/unix/modules.mk'; \
cd $(ROOTDIR) && \
$(CVSCO) mozilla/client.mk mozilla/build/unix/modules.mk
@cd $(TOPSRCDIR) && \
$(MAKE) -f client.mk real_fast-update
real_fast-update:
# @: Start the update. Split the output to the tty and a log file. \
# : If it fails, touch an error file because "tee" hides the error.
@failed=.fast_update-failed.tmp; rm -f $$failed*; \
fast_update() { (config/cvsco-fast-update.pl $$@ || touch $$failed) 2>&1 | tee -a $(CVSCO_LOGFILE) && \
if test -f $$failed; then false; else true; fi; }; \
cvs_co() { echo "$$@" ; \
("$$@" || touch $$failed) 2>&1 | tee -a $(CVSCO_LOGFILE) && \
if test -f $$failed; then false; else true; fi; }; \
fast_update $(CVSCO_NSPR) && \
cd $(ROOTDIR) && \
failed=mozilla/.fast_update-failed.tmp && \
cvs_co $(CVSCO_NSS) && \
failed=.fast_update-failed.tmp && \
cd mozilla && \
fast_update $(CVSCO_PSM) && \
fast_update $(CVSCO_LDAPCSDK) && \
fast_update $(CVSCO_ACCESSIBLE) && \
fast_update $(CVSCO_GFX2) && \
fast_update $(CVSCO_IMGLIB2) && \
$(FASTUPDATE_CALENDAR) && \
$(FASTUPDATE_LIBART) && \
fast_update $(CVSCO_SEAMONKEY) && \
fast_update $(CVSCO_NOSUBDIRS)
@echo "fast_update finish: "`date` | tee -a $(CVSCO_LOGFILE)
# @: Check the log for conflicts. ;
@conflicts=`egrep "^C " $(CVSCO_LOGFILE)` ;\
if test "$$conflicts" ; then \
echo "$(MAKE): *** Conflicts during fast-update." ;\
echo "$$conflicts" ;\
echo "$(MAKE): Refer to $(CVSCO_LOGFILE) for full log." ;\
false; \
else true; \
fi
ifdef RUN_AUTOCONF_LOCALLY
@echo Generating configures using $(AUTOCONF) ; \
cd $(TOPSRCDIR) && $(AUTOCONF) && \
cd $(TOPSRCDIR)/nsprpub && $(AUTOCONF) && \
cd $(TOPSRCDIR)/directory/c-sdk && $(AUTOCONF)
endif
####################################
# Web configure
WEBCONFIG_FILE := $(HOME)/.mozconfig
MOZCONFIG2CONFIGURATOR := build/autoconf/mozconfig2configurator
webconfig:
@cd $(TOPSRCDIR); \
url=`$(MOZCONFIG2CONFIGURATOR) $(TOPSRCDIR)`; \
echo Running mozilla with the following url: ;\
echo ;\
echo $$url ;\
mozilla -remote "openURL($$url)" || \
netscape -remote "openURL($$url)" || \
mozilla $$url || \
netscape $$url ;\
echo ;\
echo 1. Fill out the form on the browser. ;\
echo 2. Save the results to $(WEBCONFIG_FILE)
#####################################################
# First Checkout
ifdef _IS_FIRST_CHECKOUT
# First time, do build target in a new process to pick up new files.
build::
$(MAKE) -f $(TOPSRCDIR)/client.mk build
else
#####################################################
# After First Checkout
####################################
# Configure
CONFIG_STATUS := $(wildcard $(OBJDIR)/config.status)
CONFIG_CACHE := $(wildcard $(OBJDIR)/config.cache)
ifdef RUN_AUTOCONF_LOCALLY
EXTRA_CONFIG_DEPS := \
$(TOPSRCDIR)/aclocal.m4 \
$(wildcard $(TOPSRCDIR)/build/autoconf/*.m4) \
$(NULL)
$(TOPSRCDIR)/configure: $(TOPSRCDIR)/configure.in $(EXTRA_CONFIG_DEPS)
@echo Generating $@ using autoconf
cd $(TOPSRCDIR); $(AUTOCONF)
endif
CONFIG_STATUS_DEPS_L10N := $(wildcard $(TOPSRCDIR)/l10n/makefiles.all)
CONFIG_STATUS_DEPS := \
$(TOPSRCDIR)/configure \
$(TOPSRCDIR)/allmakefiles.sh \
$(TOPSRCDIR)/.mozconfig.mk \
$(wildcard $(TOPSRCDIR)/nsprpub/configure) \
$(wildcard $(TOPSRCDIR)/directory/c-sdk/configure) \
$(wildcard $(TOPSRCDIR)/mailnews/makefiles) \
$(CONFIG_STATUS_DEPS_L10N) \
$(wildcard $(TOPSRCDIR)/themes/makefiles) \
$(NULL)
# configure uses the program name to determine @srcdir@. Calling it without
# $(TOPSRCDIR) will set @srcdir@ to "."; otherwise, it is set to the full
# path of $(TOPSRCDIR).
ifeq ($(TOPSRCDIR),$(OBJDIR))
CONFIGURE := ./configure
else
CONFIGURE := $(TOPSRCDIR)/configure
endif
ifdef _OBJ2SRCPATH
CONFIGURE_ARGS := --srcdir=$(_OBJ2SRCPATH) $(CONFIGURE_ARGS)
endif
$(OBJDIR)/Makefile $(OBJDIR)/config.status: $(CONFIG_STATUS_DEPS)
@if test ! -d $(OBJDIR); then $(MKDIR) $(OBJDIR); else true; fi
@echo cd $(OBJDIR);
@echo $(CONFIGURE) $(CONFIGURE_ARGS)
@cd $(OBJDIR) && $(CONFIGURE_ENV_ARGS) $(CONFIGURE) $(CONFIGURE_ARGS) \
|| ( echo "*** Fix above errors and then restart with\
\"$(MAKE) -f client.mk build\"" && exit 1 )
@touch $(OBJDIR)/Makefile
ifdef CONFIG_STATUS
$(OBJDIR)/config/autoconf.mk: $(TOPSRCDIR)/config/autoconf.mk.in
cd $(OBJDIR); \
CONFIG_FILES=config/autoconf.mk ./config.status
endif
####################################
# Depend
depend:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
$(MOZ_MAKE) export && $(MOZ_MAKE) depend
####################################
# Build it
build:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
$(MOZ_MAKE)
####################################
# Other targets
# Pass these target onto the real build system
install export libs clean realclean distclean alldep:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
$(MOZ_MAKE) $@
cleansrcdir:
@cd $(TOPSRCDIR); \
if [ -f webshell/embed/gtk/Makefile ]; then \
$(MAKE) -C webshell/embed/gtk distclean; \
fi; \
if [ -f Makefile ]; then \
$(MAKE) distclean ; \
else \
echo "Removing object files from srcdir..."; \
rm -fr `find . -type d \( -name .deps -print -o -name CVS \
-o -exec test ! -d {}/CVS \; \) -prune \
-o \( -name '*.[ao]' -o -name '*.so' \) -type f -print`; \
build/autoconf/clean-config.sh; \
fi;
# (! IS_FIRST_CHECKOUT)
endif
.PHONY: checkout real_checkout depend build export libs alldep install clean realclean distclean cleansrcdir pull_all build_all clobber clobber_all pull_and_build_all everything

View File

@@ -0,0 +1,42 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = necko
LIBRARY_NAME = necko_datetime
SHORT_LIBNAME = neckodtm
IS_COMPONENT = 1
CPPSRCS = \
nsDateTimeHandler.cpp \
nsDateTimeChannel.cpp \
nsDateTimeModule.cpp \
$(NULL)
EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,431 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
// datetime implementation
#include "nsDateTimeChannel.h"
#include "nsIServiceManager.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsXPIDLString.h"
#include "nsISocketTransportService.h"
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
// nsDateTimeChannel methods
nsDateTimeChannel::nsDateTimeChannel() {
NS_INIT_REFCNT();
mContentLength = -1;
mPort = -1;
}
nsDateTimeChannel::~nsDateTimeChannel() {
}
NS_IMPL_ISUPPORTS4(nsDateTimeChannel, nsIChannel, nsIRequest, nsIStreamListener, nsIStreamObserver)
nsresult
nsDateTimeChannel::Init(nsIURI* uri)
{
nsresult rv;
NS_ASSERTION(uri, "no uri");
mUrl = uri;
rv = mUrl->GetPort(&mPort);
if (NS_FAILED(rv) || mPort < 1)
mPort = DATETIME_PORT;
rv = mUrl->GetPath(getter_Copies(mHost));
if (NS_FAILED(rv)) return rv;
if (!*(const char *)mHost) return NS_ERROR_NOT_INITIALIZED;
return NS_OK;
}
NS_METHOD
nsDateTimeChannel::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
{
nsDateTimeChannel* dc = new nsDateTimeChannel();
if (dc == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(dc);
nsresult rv = dc->QueryInterface(aIID, aResult);
NS_RELEASE(dc);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_IMETHODIMP
nsDateTimeChannel::IsPending(PRBool *result)
{
NS_NOTREACHED("nsDateTimeChannel::IsPending");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::GetStatus(nsresult *status)
{
*status = NS_OK;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::Cancel(nsresult status)
{
NS_NOTREACHED("nsDateTimeChannel::Cancel");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::Suspend(void)
{
NS_NOTREACHED("nsDateTimeChannel::Suspend");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::Resume(void)
{
NS_NOTREACHED("nsDateTimeChannel::Resume");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// nsIChannel methods:
NS_IMETHODIMP
nsDateTimeChannel::GetOriginalURI(nsIURI* *aURI)
{
*aURI = mOriginalURI ? mOriginalURI : mUrl;
NS_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::SetOriginalURI(nsIURI* aURI)
{
mOriginalURI = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::GetURI(nsIURI* *aURI)
{
*aURI = mUrl;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::SetURI(nsIURI* aURI)
{
mUrl = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::OpenInputStream(nsIInputStream **_retval)
{
nsresult rv = NS_OK;
NS_WITH_SERVICE(nsISocketTransportService, socketService, kSocketTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIChannel> channel;
rv = socketService->CreateTransport(mHost, mPort, mHost, 32, 32, getter_AddRefs(channel));
if (NS_FAILED(rv)) return rv;
rv = channel->SetNotificationCallbacks(mCallbacks);
if (NS_FAILED(rv)) return rv;
return channel->OpenInputStream(_retval);
}
NS_IMETHODIMP
nsDateTimeChannel::OpenOutputStream(nsIOutputStream **_retval)
{
NS_NOTREACHED("nsDateTimeChannel::OpenOutputStream");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::AsyncOpen(nsIStreamObserver *observer, nsISupports* ctxt)
{
nsresult rv = NS_OK;
NS_WITH_SERVICE(nsISocketTransportService, socketService, kSocketTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIChannel> channel;
rv = socketService->CreateTransport(mHost, mPort, mHost, 32, 32, getter_AddRefs(channel));
if (NS_FAILED(rv)) return rv;
rv = channel->SetNotificationCallbacks(mCallbacks);
if (NS_FAILED(rv)) return rv;
return channel->AsyncOpen(observer, ctxt);
}
NS_IMETHODIMP
nsDateTimeChannel::AsyncRead(nsIStreamListener *aListener,
nsISupports *ctxt)
{
nsresult rv = NS_OK;
NS_WITH_SERVICE(nsISocketTransportService, socketService, kSocketTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIChannel> channel;
rv = socketService->CreateTransport(mHost, mPort, mHost, 32, 32, getter_AddRefs(channel));
if (NS_FAILED(rv)) return rv;
rv = channel->SetNotificationCallbacks(mCallbacks);
if (NS_FAILED(rv)) return rv;
mListener = aListener;
return channel->AsyncRead(this, ctxt);
}
NS_IMETHODIMP
nsDateTimeChannel::AsyncWrite(nsIInputStream *fromStream,
nsIStreamObserver *observer,
nsISupports *ctxt)
{
NS_NOTREACHED("nsDateTimeChannel::AsyncWrite");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::GetLoadAttributes(PRUint32 *aLoadAttributes)
{
*aLoadAttributes = mLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::SetLoadAttributes(PRUint32 aLoadAttributes)
{
mLoadAttributes = aLoadAttributes;
return NS_OK;
}
#define DATETIME_TYPE "text/plain"
NS_IMETHODIMP
nsDateTimeChannel::GetContentType(char* *aContentType) {
if (!aContentType) return NS_ERROR_NULL_POINTER;
*aContentType = nsCRT::strdup(DATETIME_TYPE);
if (!*aContentType) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::SetContentType(const char *aContentType)
{
//It doesn't make sense to set the content-type on this type
// of channel...
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDateTimeChannel::GetContentLength(PRInt32 *aContentLength)
{
*aContentLength = mContentLength;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::SetContentLength(PRInt32 aContentLength)
{
NS_NOTREACHED("nsDateTimeChannel::SetContentLength");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::GetTransferOffset(PRUint32 *aTransferOffset)
{
NS_NOTREACHED("nsDateTimeChannel::GetTransferOffset");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::SetTransferOffset(PRUint32 aTransferOffset)
{
NS_NOTREACHED("nsDateTimeChannel::SetTransferOffset");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::GetTransferCount(PRInt32 *aTransferCount)
{
NS_NOTREACHED("nsDateTimeChannel::GetTransferCount");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::SetTransferCount(PRInt32 aTransferCount)
{
NS_NOTREACHED("nsDateTimeChannel::SetTransferCount");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::GetBufferSegmentSize(PRUint32 *aBufferSegmentSize)
{
NS_NOTREACHED("nsDateTimeChannel::GetBufferSegmentSize");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::SetBufferSegmentSize(PRUint32 aBufferSegmentSize)
{
NS_NOTREACHED("nsDateTimeChannel::SetBufferSegmentSize");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::GetBufferMaxSize(PRUint32 *aBufferMaxSize)
{
NS_NOTREACHED("nsDateTimeChannel::GetBufferMaxSize");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::SetBufferMaxSize(PRUint32 aBufferMaxSize)
{
NS_NOTREACHED("nsDateTimeChannel::SetBufferMaxSize");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::GetShouldCache(PRBool *aShouldCache)
{
*aShouldCache = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::GetPipeliningAllowed(PRBool *aPipeliningAllowed)
{
*aPipeliningAllowed = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::SetPipeliningAllowed(PRBool aPipeliningAllowed)
{
NS_NOTREACHED("SetPipeliningAllowed");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDateTimeChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup;
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
if (mLoadGroup) // if we already had a load group remove ourselves...
(void)mLoadGroup->RemoveChannel(this, nsnull, nsnull, nsnull);
mLoadGroup = aLoadGroup;
if (mLoadGroup) {
return mLoadGroup->AddChannel(this, nsnull);
}
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::GetOwner(nsISupports* *aOwner)
{
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::SetOwner(nsISupports* aOwner)
{
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
{
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
mCallbacks = aNotificationCallbacks;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
{
*aSecurityInfo = nsnull;
return NS_OK;
}
// nsIStreamObserver methods
NS_IMETHODIMP
nsDateTimeChannel::OnStartRequest(nsIChannel *aChannel, nsISupports *aContext) {
return mListener->OnStartRequest(this, aContext);
}
NS_IMETHODIMP
nsDateTimeChannel::OnStopRequest(nsIChannel* aChannel, nsISupports* aContext,
nsresult aStatus, const PRUnichar* aMsg) {
if (mLoadGroup) {
nsresult rv = mLoadGroup->RemoveChannel(this, nsnull, aStatus, aMsg);
if (NS_FAILED(rv)) return rv;
}
return mListener->OnStopRequest(this, aContext, aStatus, aMsg);
}
// nsIStreamListener method
NS_IMETHODIMP
nsDateTimeChannel::OnDataAvailable(nsIChannel* aChannel, nsISupports* aContext,
nsIInputStream *aInputStream, PRUint32 aSourceOffset,
PRUint32 aLength) {
mContentLength = aLength;
return mListener->OnDataAvailable(this, aContext, aInputStream, aSourceOffset, aLength);
}

View File

@@ -0,0 +1,77 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
// A datetime channel retrieves date time information from
// RFC 867 compliant datetime servers. The date/time returned
// to the caller is of MIME type "text/plain".
#ifndef nsDateTimeChannel_h___
#define nsDateTimeChannel_h___
#include "nsString.h"
#include "nsILoadGroup.h"
#include "nsIInputStream.h"
#include "nsIInterfaceRequestor.h"
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsIChannel.h"
#include "nsIURI.h"
#include "nsDateTimeHandler.h"
#include "nsIStreamListener.h"
class nsDateTimeChannel : public nsIChannel, public nsIStreamListener {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSISTREAMOBSERVER
// nsDateTimeChannel methods:
nsDateTimeChannel();
virtual ~nsDateTimeChannel();
// Define a Create method to be used with a factory:
static NS_METHOD
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
nsresult Init(nsIURI* uri);
protected:
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIStreamListener> mListener;
PRUint32 mLoadAttributes;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCString mContentType;
PRInt32 mContentLength;
nsCOMPtr<nsISupports> mOwner;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
PRInt32 mPort;
nsXPIDLCString mHost;
};
#endif /* nsDateTimeChannel_h___ */

View File

@@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nspr.h"
#include "nsDateTimeChannel.h"
#include "nsDateTimeHandler.h"
#include "nsIURL.h"
#include "nsCRT.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIInterfaceRequestor.h"
#include "nsIProgressEventSink.h"
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
////////////////////////////////////////////////////////////////////////////////
nsDateTimeHandler::nsDateTimeHandler() {
NS_INIT_REFCNT();
}
nsDateTimeHandler::~nsDateTimeHandler() {
}
NS_IMPL_ISUPPORTS(nsDateTimeHandler, NS_GET_IID(nsIProtocolHandler));
NS_METHOD
nsDateTimeHandler::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult) {
nsDateTimeHandler* ph = new nsDateTimeHandler();
if (ph == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(ph);
nsresult rv = ph->QueryInterface(aIID, aResult);
NS_RELEASE(ph);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIProtocolHandler methods:
NS_IMETHODIMP
nsDateTimeHandler::GetScheme(char* *result) {
*result = nsCRT::strdup("datetime");
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeHandler::GetDefaultPort(PRInt32 *result) {
*result = DATETIME_PORT;
return NS_OK;
}
NS_IMETHODIMP
nsDateTimeHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
nsIURI **result) {
nsresult rv;
// no concept of a relative datetime url
NS_ASSERTION(!aBaseURI, "base url passed into datetime protocol handler");
nsIURI* url;
rv = nsComponentManager::CreateInstance(kSimpleURICID, nsnull,
NS_GET_IID(nsIURI),
(void**)&url);
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)aSpec);
if (NS_FAILED(rv)) {
NS_RELEASE(url);
return rv;
}
*result = url;
return rv;
}
NS_IMETHODIMP
nsDateTimeHandler::NewChannel(nsIURI* url, nsIChannel* *result)
{
nsresult rv;
nsDateTimeChannel* channel;
rv = nsDateTimeChannel::Create(nsnull, NS_GET_IID(nsIChannel), (void**)&channel);
if (NS_FAILED(rv)) return rv;
rv = channel->Init(url);
if (NS_FAILED(rv)) {
NS_RELEASE(channel);
return rv;
}
*result = channel;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
// The datetime protocol handler creates "datetime" URIs of the form
// "datetime:RFC867Server".
#ifndef nsDateTimeHandler_h___
#define nsDateTimeHandler_h___
#include "nsIProtocolHandler.h"
#define DATETIME_PORT 13
// {AA27D2A0-B71B-11d3-A1A0-0050041CAF44}
#define NS_DATETIMEHANDLER_CID \
{ 0xaa27d2a0, 0xb71b, 0x11d3, { 0xa1, 0xa0, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44 } }
class nsDateTimeHandler : public nsIProtocolHandler
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPROTOCOLHANDLER
// nsDateTimeHandler methods:
nsDateTimeHandler();
virtual ~nsDateTimeHandler();
// Define a Create method to be used with a factory:
static NS_METHOD Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
};
#endif /* nsDateTimeHandler_h___ */

View File

@@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIGenericFactory.h"
#include "nsDateTimeHandler.h"
static nsModuleComponentInfo gResComponents[] = {
{ "The DateTime Protocol Handler",
NS_DATETIMEHANDLER_CID,
NS_NETWORK_PROTOCOL_PROGID_PREFIX "datetime",
nsDateTimeHandler::Create
}
};
NS_IMPL_NSGETMODULE("datetime", gResComponents)

View File

@@ -0,0 +1,41 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = necko
LIBRARY_NAME = necko_finger
IS_COMPONENT = 1
CPPSRCS = \
nsFingerHandler.cpp \
nsFingerChannel.cpp \
nsFingerModule.cpp \
$(NULL)
EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,517 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
// finger implementation
#include "nsFingerChannel.h"
#include "nsIServiceManager.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsXPIDLString.h"
#include "nsISocketTransportService.h"
#include "nsIStringStream.h"
#include "nsMimeTypes.h"
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
#define BUFFER_SEG_SIZE (4*1024)
#define BUFFER_MAX_SIZE (64*1024)
// nsFingerChannel methods
nsFingerChannel::nsFingerChannel()
: mContentLength(-1),
mActAsObserver(PR_TRUE),
mPort(-1),
mStatus(NS_OK)
{
NS_INIT_REFCNT();
}
nsFingerChannel::~nsFingerChannel() {
}
NS_IMPL_THREADSAFE_ISUPPORTS4(nsFingerChannel, nsIChannel, nsIRequest,
nsIStreamListener, nsIStreamObserver)
nsresult
nsFingerChannel::Init(nsIURI* uri)
{
nsresult rv;
nsXPIDLCString autoBuffer;
NS_ASSERTION(uri, "no uri");
mUrl = uri;
// For security reasons, we do not allow the user to specify a
// non-default port for finger: URL's.
mPort = FINGER_PORT;
rv = mUrl->GetPath(getter_Copies(autoBuffer)); // autoBuffer = user@host
if (NS_FAILED(rv)) return rv;
nsCString cString(autoBuffer);
nsCString tempBuf;
PRUint32 i;
// Now parse out the user and host
for (i=0; cString[i] != '\0'; i++) {
if (cString[i] == '@') {
cString.Left(tempBuf, i);
mUser = tempBuf;
cString.Right(tempBuf, cString.Length() - i - 1);
mHost = tempBuf;
break;
}
}
// Catch the case of just the host being given
if (cString[i] == '\0') {
mHost = cString;
}
#ifdef DEBUG_bryner
printf("Status:mUser = %s, mHost = %s\n", (const char*)mUser,
(const char*)mHost);
#endif
if (!*(const char *)mHost) return NS_ERROR_NOT_INITIALIZED;
return NS_OK;
}
NS_METHOD
nsFingerChannel::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
{
nsFingerChannel* fc = new nsFingerChannel();
if (fc == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(fc);
nsresult rv = fc->QueryInterface(aIID, aResult);
NS_RELEASE(fc);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_IMETHODIMP
nsFingerChannel::IsPending(PRBool *result)
{
NS_NOTREACHED("nsFingerChannel::IsPending");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::GetStatus(nsresult *status)
{
*status = mStatus;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::Cancel(nsresult status)
{
nsresult rv = NS_ERROR_FAILURE;
mStatus = status;
if (mTransport) {
rv = mTransport->Cancel(status);
}
return rv;
}
NS_IMETHODIMP
nsFingerChannel::Suspend(void)
{
NS_NOTREACHED("nsFingerChannel::Suspend");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::Resume(void)
{
NS_NOTREACHED("nsFingerChannel::Resume");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// nsIChannel methods:
NS_IMETHODIMP
nsFingerChannel::GetOriginalURI(nsIURI* *aURI)
{
*aURI = mOriginalURI ? mOriginalURI : mUrl;
NS_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::SetOriginalURI(nsIURI* aURI)
{
mOriginalURI = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::GetURI(nsIURI* *aURI)
{
*aURI = mUrl;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::SetURI(nsIURI* aURI)
{
mUrl = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::OpenInputStream(nsIInputStream **_retval)
{
nsresult rv = NS_OK;
NS_WITH_SERVICE(nsISocketTransportService, socketService, kSocketTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIChannel> channel;
rv = socketService->CreateTransport(mHost, mPort, mHost, BUFFER_SEG_SIZE,
BUFFER_MAX_SIZE, getter_AddRefs(channel));
if (NS_FAILED(rv)) return rv;
rv = channel->SetNotificationCallbacks(mCallbacks);
if (NS_FAILED(rv)) return rv;
return channel->OpenInputStream(_retval);
}
NS_IMETHODIMP
nsFingerChannel::OpenOutputStream(nsIOutputStream **_retval)
{
NS_NOTREACHED("nsFingerChannel::OpenOutputStream");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::AsyncOpen(nsIStreamObserver *observer, nsISupports* ctxt)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::AsyncRead(nsIStreamListener *aListener, nsISupports *ctxt)
{
nsresult rv = NS_OK;
NS_WITH_SERVICE(nsISocketTransportService, socketService, kSocketTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIChannel> channel;
rv = socketService->CreateTransport(mHost, mPort, mHost, BUFFER_SEG_SIZE,
BUFFER_MAX_SIZE, getter_AddRefs(channel));
if (NS_FAILED(rv)) return rv;
rv = channel->SetNotificationCallbacks(mCallbacks);
if (NS_FAILED(rv)) return rv;
mListener = aListener;
mResponseContext = ctxt;
mTransport = channel;
return SendRequest(channel);
}
NS_IMETHODIMP
nsFingerChannel::AsyncWrite(nsIInputStream *fromStream,
nsIStreamObserver *observer,
nsISupports *ctxt)
{
NS_NOTREACHED("nsFingerChannel::AsyncWrite");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::GetLoadAttributes(PRUint32 *aLoadAttributes)
{
*aLoadAttributes = mLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::SetLoadAttributes(PRUint32 aLoadAttributes)
{
mLoadAttributes = aLoadAttributes;
return NS_OK;
}
#define FINGER_TYPE TEXT_PLAIN
NS_IMETHODIMP
nsFingerChannel::GetContentType(char* *aContentType) {
if (!aContentType) return NS_ERROR_NULL_POINTER;
*aContentType = nsCRT::strdup(FINGER_TYPE);
if (!*aContentType) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::SetContentType(const char *aContentType)
{
//It doesn't make sense to set the content-type on this type
// of channel...
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsFingerChannel::GetContentLength(PRInt32 *aContentLength)
{
*aContentLength = mContentLength;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::SetContentLength(PRInt32 aContentLength)
{
NS_NOTREACHED("nsFingerChannel::SetContentLength");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::GetTransferOffset(PRUint32 *aTransferOffset)
{
NS_NOTREACHED("nsFingerChannel::GetTransferOffset");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::SetTransferOffset(PRUint32 aTransferOffset)
{
NS_NOTREACHED("nsFingerChannel::SetTransferOffset");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::GetTransferCount(PRInt32 *aTransferCount)
{
NS_NOTREACHED("nsFingerChannel::GetTransferCount");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::SetTransferCount(PRInt32 aTransferCount)
{
NS_NOTREACHED("nsFingerChannel::SetTransferCount");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::GetBufferSegmentSize(PRUint32 *aBufferSegmentSize)
{
NS_NOTREACHED("nsFingerChannel::GetBufferSegmentSize");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::SetBufferSegmentSize(PRUint32 aBufferSegmentSize)
{
NS_NOTREACHED("nsFingerChannel::SetBufferSegmentSize");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::GetBufferMaxSize(PRUint32 *aBufferMaxSize)
{
NS_NOTREACHED("nsFingerChannel::GetBufferMaxSize");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::SetBufferMaxSize(PRUint32 aBufferMaxSize)
{
NS_NOTREACHED("nsFingerChannel::SetBufferMaxSize");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::GetShouldCache(PRBool *aShouldCache)
{
*aShouldCache = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::GetPipeliningAllowed(PRBool *aPipeliningAllowed)
{
*aPipeliningAllowed = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::SetPipeliningAllowed(PRBool aPipeliningAllowed)
{
NS_NOTREACHED("SetPipeliningAllowed");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFingerChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup;
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::GetOwner(nsISupports* *aOwner)
{
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::SetOwner(nsISupports* aOwner)
{
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
{
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
mCallbacks = aNotificationCallbacks;
return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
{
*aSecurityInfo = nsnull;
return NS_OK;
}
// nsIStreamObserver methods
NS_IMETHODIMP
nsFingerChannel::OnStartRequest(nsIChannel *aChannel, nsISupports *aContext) {
if (!mActAsObserver) {
// acting as a listener
return mListener->OnStartRequest(this, aContext);
} else {
// we don't want to pass our AsyncWrite's OnStart through
// we just ignore this
return NS_OK;
}
}
NS_IMETHODIMP
nsFingerChannel::OnStopRequest(nsIChannel* aChannel, nsISupports* aContext,
nsresult aStatus, const PRUnichar* aMsg) {
#ifdef DEBUG_bryner
printf("nsFingerChannel::OnStopRequest, mActAsObserver=%d\n",
mActAsObserver);
printf(" aChannel = %p\n", aChannel);
#endif
nsresult rv = NS_OK;
if (NS_FAILED(aStatus) || !mActAsObserver) {
if (mLoadGroup) {
rv = mLoadGroup->RemoveChannel(this, nsnull, aStatus, aMsg);
if (NS_FAILED(rv)) return rv;
}
rv = mListener->OnStopRequest(this, aContext, aStatus, aMsg);
mTransport = 0;
return rv;
} else {
// at this point we know the request has been sent.
// we're no longer acting as an observer.
mActAsObserver = PR_FALSE;
return aChannel->AsyncRead(this, mResponseContext);
}
}
// nsIStreamListener method
NS_IMETHODIMP
nsFingerChannel::OnDataAvailable(nsIChannel* aChannel, nsISupports* aContext,
nsIInputStream *aInputStream, PRUint32 aSourceOffset,
PRUint32 aLength) {
mContentLength = aLength;
return mListener->OnDataAvailable(this, aContext, aInputStream, aSourceOffset, aLength);
}
nsresult
nsFingerChannel::SendRequest(nsIChannel* aChannel) {
// The text to send should already be in mUser
nsresult rv = NS_OK;
nsCOMPtr<nsISupports> result;
nsCOMPtr<nsIInputStream> charstream;
nsCString requestBuffer(mUser);
if (mLoadGroup) {
mLoadGroup->AddChannel(this, nsnull);
}
requestBuffer.Append(CRLF);
mRequest = requestBuffer.ToNewCString();
rv = NS_NewCharInputStream(getter_AddRefs(result), mRequest);
if (NS_FAILED(rv)) return rv;
charstream = do_QueryInterface(result, &rv);
if (NS_FAILED(rv)) return rv;
#ifdef DEBUG_bryner
printf("Sending: %s\n", requestBuffer.GetBuffer());
#endif
rv = aChannel->SetTransferCount(requestBuffer.Length());
if (NS_FAILED(rv)) return rv;
rv = aChannel->AsyncWrite(charstream, this, 0);
return rv;
}

View File

@@ -0,0 +1,84 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsFingerChannel_h___
#define nsFingerChannel_h___
#include "nsString.h"
#include "nsILoadGroup.h"
#include "nsIInputStream.h"
#include "nsIInterfaceRequestor.h"
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsIChannel.h"
#include "nsIURI.h"
#include "nsFingerHandler.h"
#include "nsIStreamListener.h"
class nsFingerChannel : public nsIChannel, public nsIStreamListener {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSISTREAMOBSERVER
// nsFingerChannel methods:
nsFingerChannel();
virtual ~nsFingerChannel();
// Define a Create method to be used with a factory:
static NS_METHOD
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
nsresult Init(nsIURI* uri);
protected:
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIStreamListener> mListener;
PRUint32 mLoadAttributes;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCString mContentType;
PRInt32 mContentLength;
nsCOMPtr<nsISupports> mOwner;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
PRBool mActAsObserver;
PRInt32 mPort;
nsXPIDLCString mHost;
nsXPIDLCString mUser;
nsXPIDLCString mRequest;
nsCOMPtr<nsISupports> mResponseContext;
nsCOMPtr<nsIChannel> mTransport;
nsresult mStatus;
protected:
nsresult SendRequest(nsIChannel* aChannel);
};
#endif /* nsFingerChannel_h___ */

View File

@@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nspr.h"
#include "nsFingerChannel.h"
#include "nsFingerHandler.h"
#include "nsIURL.h"
#include "nsCRT.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIInterfaceRequestor.h"
#include "nsIProgressEventSink.h"
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
////////////////////////////////////////////////////////////////////////////////
nsFingerHandler::nsFingerHandler() {
NS_INIT_REFCNT();
}
nsFingerHandler::~nsFingerHandler() {
}
NS_IMPL_ISUPPORTS(nsFingerHandler, NS_GET_IID(nsIProtocolHandler));
NS_METHOD
nsFingerHandler::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult) {
nsFingerHandler* ph = new nsFingerHandler();
if (ph == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(ph);
nsresult rv = ph->QueryInterface(aIID, aResult);
NS_RELEASE(ph);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIProtocolHandler methods:
NS_IMETHODIMP
nsFingerHandler::GetScheme(char* *result) {
*result = nsCRT::strdup("finger");
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsFingerHandler::GetDefaultPort(PRInt32 *result) {
*result = FINGER_PORT;
return NS_OK;
}
NS_IMETHODIMP
nsFingerHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
nsIURI **result) {
nsresult rv;
// no concept of a relative finger url
NS_ASSERTION(!aBaseURI, "base url passed into finger protocol handler");
nsIURI* url;
rv = nsComponentManager::CreateInstance(kSimpleURICID, nsnull,
NS_GET_IID(nsIURI),
(void**)&url);
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)aSpec);
if (NS_FAILED(rv)) {
NS_RELEASE(url);
return rv;
}
*result = url;
return rv;
}
NS_IMETHODIMP
nsFingerHandler::NewChannel(nsIURI* url, nsIChannel* *result)
{
nsresult rv;
nsFingerChannel* channel;
rv = nsFingerChannel::Create(nsnull, NS_GET_IID(nsIChannel), (void**)&channel);
if (NS_FAILED(rv)) return rv;
rv = channel->Init(url);
if (NS_FAILED(rv)) {
NS_RELEASE(channel);
return rv;
}
*result = channel;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,52 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
// The finger protocol handler creates "finger" URIs of the form
// "finger:user@host" or "finger:host".
#ifndef nsFingerHandler_h___
#define nsFingerHandler_h___
#include "nsIProtocolHandler.h"
#define FINGER_PORT 79
// {0x76d6d5d8-1dd2-11b2-b361-850ddf15ef07}
#define NS_FINGERHANDLER_CID \
{ 0x76d6d5d8, 0x1dd2, 0x11b2, \
{0xb3, 0x61, 0x85, 0x0d, 0xdf, 0x15, 0xef, 0x07} }
class nsFingerHandler : public nsIProtocolHandler
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPROTOCOLHANDLER
// nsFingerHandler methods:
nsFingerHandler();
virtual ~nsFingerHandler();
// Define a Create method to be used with a factory:
static NS_METHOD Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
};
#endif /* nsFingerHandler_h___ */

View File

@@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIGenericFactory.h"
#include "nsFingerHandler.h"
static nsModuleComponentInfo gResComponents[] = {
{ "The Finger Protocol Handler",
NS_FINGERHANDLER_CID,
NS_NETWORK_PROTOCOL_PROGID_PREFIX "finger",
nsFingerHandler::Create
}
};
NS_IMPL_NSGETMODULE("finger", gResComponents)

View File

@@ -0,0 +1,39 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIChannel.idl"
interface nsISimpleEnumerator;
[scriptable, uuid(c7e410d1-85f2-11d3-9f63-006008a6efe9)]
interface nsIJARChannel : nsIChannel
{
/**
* Enumerates all the entries in the JAR (the root URI).
* ARGUMENTS:
* aRoot - a string representing the root dir to enumerate from
* or null to enumerate the whole thing.
*/
nsISimpleEnumerator EnumerateEntries(in string aRoot);
};

View File

@@ -0,0 +1,32 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIProtocolHandler.idl"
[scriptable, uuid(92c3b42c-98c4-11d3-8cd9-0060b0fc14a3)]
interface nsIJARProtocolHandler : nsIProtocolHandler {
/**
* Add any jar-specific methods here later.
*/
};

View File

@@ -0,0 +1,42 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIURI.idl"
/**
* JAR URLs have the following syntax
*
* jar:<jar-file-uri>!/<jar-entry>
*
* EXAMPLE: jar:http://www.big.com/blue.jar!/ocean.html
*/
[scriptable, uuid(c7e410d3-85f2-11d3-9f63-006008a6efe9)]
interface nsIJARURI : nsIURI {
/**
* Returns the root URI (the one for the actual JAR file) for this JAR.
* eg http://www.big.com/blue.jar
*/
attribute nsIURI JARFile;
/**
* Returns the entry specified for this JAR URI.
* eg ocean.html
*/
attribute string JAREntry;
};

View File

@@ -0,0 +1,978 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*
*/
#include "nsNetUtil.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsSpecialSystemDirectory.h"
#include "nsJARChannel.h"
#include "nsCRT.h"
#include "nsIFileTransportService.h"
#include "nsIURL.h"
#include "nsIMIMEService.h"
#include "nsAutoLock.h"
#include "nsIFileStreams.h"
#include "nsMimeTypes.h"
#include "nsScriptSecurityManager.h"
#include "nsIAggregatePrincipal.h"
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kMIMEServiceCID, NS_MIMESERVICE_CID);
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
static NS_DEFINE_CID(kScriptSecurityManagerCID, NS_SCRIPTSECURITYMANAGER_CID);
#if defined(PR_LOGGING)
#include "nsXPIDLString.h"
//
// Log module for SocketTransport logging...
//
// To enable logging (see prlog.h for full details):
//
// set NSPR_LOG_MODULES=nsJarProtocol:5
// set NSPR_LOG_FILE=nspr.log
//
// this enables PR_LOG_DEBUG level information and places all output in
// the file nspr.log
//
PRLogModuleInfo* gJarProtocolLog = nsnull;
#endif /* PR_LOGGING */
////////////////////////////////////////////////////////////////////////////////
class nsJARDownloadObserver : public nsIStreamObserver
{
public:
NS_DECL_ISUPPORTS
NS_IMETHOD OnStartRequest(nsIChannel* jarCacheTransport,
nsISupports* context) {
return NS_OK;
}
NS_IMETHOD OnStopRequest(nsIChannel* jarCacheTransport,
nsISupports* context,
nsresult status,
const PRUnichar* aMsg) {
nsresult rv = NS_OK;
nsAutoMonitor monitor(mJARChannel->mMonitor);
#ifdef PR_LOGGING
nsCOMPtr<nsIURI> jarURI;
rv = jarCacheTransport->GetURI(getter_AddRefs(jarURI));
if (NS_SUCCEEDED(rv)) {
nsXPIDLCString jarURLStr;
rv = jarURI->GetSpec(getter_Copies(jarURLStr));
if (NS_SUCCEEDED(rv)) {
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: jar download complete %s status=%x",
(const char*)jarURLStr, status));
}
}
#endif
if (NS_SUCCEEDED(status) && mJARChannel->mJarCacheTransport) {
NS_ASSERTION(jarCacheTransport == (mJARChannel->mJarCacheTransport).get(),
"wrong transport");
// after successfully downloading the jar file to the cache,
// start the extraction process:
nsCOMPtr<nsIFileChannel> jarCacheFile;
rv = NS_NewLocalFileChannel(getter_AddRefs(jarCacheFile),
mJarCacheFile,
PR_RDONLY,
0);
if (NS_FAILED(rv)) return rv;
rv = jarCacheFile->SetLoadGroup(mJARChannel->mLoadGroup);
if (NS_FAILED(rv)) return rv;
rv = jarCacheFile->SetBufferSegmentSize(mJARChannel->mBufferSegmentSize);
if (NS_FAILED(rv)) return rv;
rv = jarCacheFile->SetBufferMaxSize(mJARChannel->mBufferMaxSize);
if (NS_FAILED(rv)) return rv;
rv = jarCacheFile->SetLoadAttributes(mJARChannel->mLoadAttributes);
if (NS_FAILED(rv)) return rv;
rv = jarCacheFile->SetNotificationCallbacks(mJARChannel->mCallbacks);
if (NS_FAILED(rv)) return rv;
mJARChannel->SetJARBaseFile(jarCacheFile);
rv = mOnJARFileAvailable(mJARChannel, mClosure);
}
mJARChannel->mJarCacheTransport = nsnull;
return rv;
}
nsJARDownloadObserver(nsIFile* jarCacheFile, nsJARChannel* jarChannel,
OnJARFileAvailableFun onJARFileAvailable,
void* closure)
: mJarCacheFile(jarCacheFile),
mJARChannel(jarChannel),
mOnJARFileAvailable(onJARFileAvailable),
mClosure(closure)
{
NS_INIT_REFCNT();
NS_ADDREF(mJARChannel);
}
virtual ~nsJARDownloadObserver() {
NS_RELEASE(mJARChannel);
}
protected:
nsCOMPtr<nsIFile> mJarCacheFile;
nsJARChannel* mJARChannel;
OnJARFileAvailableFun mOnJARFileAvailable;
void* mClosure;
};
NS_IMPL_THREADSAFE_ISUPPORTS1(nsJARDownloadObserver, nsIStreamObserver)
////////////////////////////////////////////////////////////////////////////////
nsJARChannel::nsJARChannel()
: mContentType(nsnull),
mContentLength(-1),
mLoadAttributes(LOAD_NORMAL),
mStartPosition(0),
mReadCount(-1),
mJAREntry(nsnull),
mMonitor(nsnull),
mStatus(NS_OK)
{
NS_INIT_REFCNT();
#if defined(PR_LOGGING)
//
// Initialize the global PRLogModule for socket transport logging
// if necessary...
//
if (nsnull == gJarProtocolLog) {
gJarProtocolLog = PR_NewLogModule("nsJarProtocol");
}
#endif /* PR_LOGGING */
}
nsJARChannel::~nsJARChannel()
{
if (mContentType)
nsCRT::free(mContentType);
if (mJAREntry)
nsCRT::free(mJAREntry);
if (mMonitor)
PR_DestroyMonitor(mMonitor);
}
NS_IMPL_ISUPPORTS6(nsJARChannel,
nsIJARChannel,
nsIChannel,
nsIRequest,
nsIStreamObserver,
nsIStreamListener,
nsIFileSystem)
NS_METHOD
nsJARChannel::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
nsresult rv;
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsJARChannel* jarChannel = new nsJARChannel();
if (jarChannel == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(jarChannel);
rv = jarChannel->QueryInterface(aIID, aResult);
NS_RELEASE(jarChannel);
return rv;
}
nsresult
nsJARChannel::Init(nsIJARProtocolHandler* aHandler, nsIURI* uri)
{
nsresult rv;
mURI = do_QueryInterface(uri, &rv);
if (NS_FAILED(rv)) return rv;
mMonitor = PR_NewMonitor();
if (mMonitor == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods
NS_IMETHODIMP
nsJARChannel::IsPending(PRBool* result)
{
NS_NOTREACHED("nsJARChannel::IsPending");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsJARChannel::GetStatus(nsresult *status)
{
*status = mStatus;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::Cancel(nsresult status)
{
nsresult rv;
nsAutoMonitor monitor(mMonitor);
if (mJarCacheTransport) {
rv = mJarCacheTransport->Cancel(status);
if (NS_FAILED(rv)) return rv;
mJarCacheTransport = nsnull;
}
if (mJarExtractionTransport) {
rv = mJarExtractionTransport->Cancel(status);
if (NS_FAILED(rv)) return rv;
mJarExtractionTransport = nsnull;
}
mStatus = status;
return rv;
}
NS_IMETHODIMP
nsJARChannel::Suspend()
{
nsresult rv;
nsAutoMonitor monitor(mMonitor);
if (mJarCacheTransport) {
rv = mJarCacheTransport->Suspend();
if (NS_FAILED(rv)) return rv;
}
if (mJarExtractionTransport) {
rv = mJarExtractionTransport->Suspend();
if (NS_FAILED(rv)) return rv;
}
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::Resume()
{
nsresult rv;
nsAutoMonitor monitor(mMonitor);
if (mJarCacheTransport) {
rv = mJarCacheTransport->Resume();
if (NS_FAILED(rv)) return rv;
}
if (mJarExtractionTransport) {
rv = mJarExtractionTransport->Resume();
if (NS_FAILED(rv)) return rv;
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIChannel methods
NS_IMETHODIMP
nsJARChannel::GetOriginalURI(nsIURI* *aOriginalURI)
{
*aOriginalURI = mOriginalURI ? mOriginalURI : nsCOMPtr<nsIURI>(mURI);
NS_ADDREF(*aOriginalURI);
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::SetOriginalURI(nsIURI* aOriginalURI)
{
mOriginalURI = aOriginalURI;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetURI(nsIURI* *aURI)
{
*aURI = mURI;
NS_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::SetURI(nsIURI* aURI)
{
nsresult rv;
mURI = do_QueryInterface(aURI, &rv);
return rv;
}
static nsresult
OpenJARElement(nsJARChannel* channel, void* closure)
{
nsresult rv;
nsIInputStream* *result = (nsIInputStream**)closure;
nsAutoCMonitor mon(channel);
rv = channel->Open(nsnull, nsnull);
if (NS_FAILED(rv)) return rv;
rv = channel->GetInputStream(result);
mon.Notify(); // wake up OpenInputStream
return rv;
}
NS_IMETHODIMP
nsJARChannel::OpenInputStream(nsIInputStream* *result)
{
nsAutoCMonitor mon(this);
nsresult rv;
*result = nsnull;
rv = EnsureJARFileAvailable(OpenJARElement, result);
if (NS_FAILED(rv)) return rv;
if (*result == nsnull)
mon.Wait();
return rv;
}
NS_IMETHODIMP
nsJARChannel::OpenOutputStream(nsIOutputStream* *result)
{
NS_NOTREACHED("nsJARChannel::OpenOutputStream");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsJARChannel::AsyncOpen(nsIStreamObserver* observer, nsISupports* ctxt)
{
NS_NOTREACHED("nsJARChannel::AsyncOpen");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult
ReadJARElement(nsJARChannel* channel, void* closure)
{
nsresult rv;
rv = channel->AsyncReadJARElement();
return rv;
}
NS_IMETHODIMP
nsJARChannel::AsyncRead(nsIStreamListener* listener, nsISupports* ctxt)
{
mUserContext = ctxt;
mUserListener = listener;
return EnsureJARFileAvailable(ReadJARElement, nsnull);
}
nsresult
nsJARChannel::EnsureJARFileAvailable(OnJARFileAvailableFun onJARFileAvailable,
void* closure)
{
nsresult rv;
#ifdef PR_LOGGING
nsXPIDLCString jarURLStr;
mURI->GetSpec(getter_Copies(jarURLStr));
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: EnsureJARFileAvailable %s", (const char*)jarURLStr));
#endif
rv = mURI->GetJARFile(getter_AddRefs(mJARBaseURI));
if (NS_FAILED(rv)) return rv;
rv = mURI->GetJAREntry(&mJAREntry);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIChannel> jarBaseChannel;
rv = NS_OpenURI(getter_AddRefs(jarBaseChannel), mJARBaseURI, nsnull);
if (NS_FAILED(rv)) return rv;
rv = jarBaseChannel->SetLoadGroup(mLoadGroup);
if (NS_FAILED(rv)) return rv;
rv = jarBaseChannel->SetLoadAttributes(mLoadAttributes);
if (NS_FAILED(rv)) return rv;
rv = jarBaseChannel->SetNotificationCallbacks(mCallbacks);
if (NS_FAILED(rv)) return rv;
if (mLoadGroup)
(void)mLoadGroup->AddChannel(this, nsnull);
// mJARBaseFile = do_QueryInterface(jarBaseChannel, &rv);
PRBool shouldCache;
rv = jarBaseChannel->GetShouldCache(&shouldCache);
if (NS_SUCCEEDED(rv) && !shouldCache) {
// then we've already got a local jar file -- no need to download it
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: extracting local jar file %s", (const char*)jarURLStr));
rv = onJARFileAvailable(this, closure);
}
else {
// otherwise, we need to download the jar file
nsCOMPtr<nsIFile> jarCacheFile;
rv = GetCacheFile(getter_AddRefs(jarCacheFile));
if (NS_FAILED(rv)) return rv;
PRBool filePresent;
rv = jarCacheFile->IsFile(&filePresent);
if (NS_SUCCEEDED(rv) && filePresent)
{
// then we've already got the file in the local cache -- no need to download it
rv = NS_NewLocalFileChannel(getter_AddRefs(mJARBaseFile),
jarCacheFile,
PR_RDONLY,
0);
if (NS_FAILED(rv)) return rv;
rv = mJARBaseFile->SetBufferSegmentSize(mBufferSegmentSize);
if (NS_FAILED(rv)) return rv;
rv = mJARBaseFile->SetBufferMaxSize(mBufferMaxSize);
if (NS_FAILED(rv)) return rv;
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: jar file already in cache %s", (const char*)jarURLStr));
rv = onJARFileAvailable(this, closure);
return rv;
}
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsAutoMonitor monitor(mMonitor);
// use a file transport to serve as a data pump for the download (done
// on some other thread)
nsCOMPtr<nsIChannel> jarCacheTransport;
rv = fts->CreateTransport(jarCacheFile, PR_RDONLY, 0,
getter_AddRefs(mJarCacheTransport));
if (NS_FAILED(rv)) return rv;
rv = mJarCacheTransport->SetBufferSegmentSize(mBufferSegmentSize);
if (NS_FAILED(rv)) return rv;
rv = mJarCacheTransport->SetBufferMaxSize(mBufferMaxSize);
if (NS_FAILED(rv)) return rv;
rv = mJarCacheTransport->SetNotificationCallbacks(mCallbacks);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIStreamObserver> downloadObserver =
new nsJARDownloadObserver(jarCacheFile, this, onJARFileAvailable, closure);
if (downloadObserver == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: downloading jar file %s", (const char*)jarURLStr));
nsCOMPtr<nsIInputStream> jarBaseIn;
rv = jarBaseChannel->OpenInputStream(getter_AddRefs(jarBaseIn));
if (NS_FAILED(rv)) return rv;
rv = mJarCacheTransport->AsyncWrite(jarBaseIn, nsnull, downloadObserver);
}
return rv;
}
nsresult
nsJARChannel::GetCacheFile(nsIFile* *cacheFile)
{
// XXX change later to use the real network cache
nsresult rv;
nsCOMPtr<nsIFile> jarCacheFile;
rv = NS_GetSpecialDirectory("xpcom.currentProcess.componentDirectory",
getter_AddRefs(jarCacheFile));
if (NS_FAILED(rv)) return rv;
jarCacheFile->Append("jarCache");
PRBool exists;
rv = jarCacheFile->Exists(&exists);
if (NS_FAILED(rv)) return rv;
if (!exists) {
rv = jarCacheFile->Create(nsIFile::DIRECTORY_TYPE, 0664);
if (NS_FAILED(rv)) return rv;
}
nsCOMPtr<nsIURL> jarBaseURL = do_QueryInterface(mJARBaseURI, &rv);
if (NS_FAILED(rv)) return rv;
char* jarFileName;
rv = jarBaseURL->GetFileName(&jarFileName);
if (NS_FAILED(rv)) return rv;
rv = jarCacheFile->Append(jarFileName);
nsCRT::free(jarFileName);
if (NS_FAILED(rv)) return rv;
*cacheFile = jarCacheFile;
NS_ADDREF(*cacheFile);
return rv;
}
nsresult
nsJARChannel::AsyncReadJARElement()
{
nsresult rv;
nsAutoMonitor monitor(mMonitor);
NS_ASSERTION(mJARBaseFile, "mJARBaseFile is null");
if (mLoadGroup) {
nsCOMPtr<nsILoadGroupListenerFactory> factory;
//
// Create a load group "proxy" listener...
//
rv = mLoadGroup->GetGroupListenerFactory(getter_AddRefs(factory));
if (factory) {
nsIStreamListener *newListener;
rv = factory->CreateLoadGroupListener(mUserListener, &newListener);
if (NS_SUCCEEDED(rv)) {
mUserListener = newListener;
NS_RELEASE(newListener);
}
}
rv = mLoadGroup->AddChannel(this, nsnull);
if (NS_FAILED(rv)) return rv;
}
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = fts->CreateTransportFromFileSystem(this,
getter_AddRefs(mJarExtractionTransport));
if (NS_FAILED(rv)) return rv;
rv = mJarExtractionTransport->SetBufferSegmentSize(mBufferSegmentSize);
if (NS_FAILED(rv)) return rv;
rv = mJarExtractionTransport->SetBufferMaxSize(mBufferMaxSize);
if (NS_FAILED(rv)) return rv;
rv = mJarExtractionTransport->SetNotificationCallbacks(mCallbacks);
if (NS_FAILED(rv)) return rv;
#ifdef PR_LOGGING
nsXPIDLCString jarURLStr;
mURI->GetSpec(getter_Copies(jarURLStr));
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: AsyncRead jar entry %s", (const char*)jarURLStr));
#endif
rv = mJarExtractionTransport->SetTransferOffset(mStartPosition);
if (NS_FAILED(rv)) return rv;
rv = mJarExtractionTransport->SetTransferCount(mReadCount);
if (NS_FAILED(rv)) return rv;
rv = mJarExtractionTransport->AsyncRead(this, nsnull);
return rv;
}
NS_IMETHODIMP
nsJARChannel::AsyncWrite(nsIInputStream* fromStream,
nsIStreamObserver* observer,
nsISupports* ctxt)
{
NS_NOTREACHED("nsJARChannel::AsyncWrite");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsJARChannel::GetLoadAttributes(PRUint32* aLoadFlags)
{
*aLoadFlags = mLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::SetLoadAttributes(PRUint32 aLoadFlags)
{
mLoadAttributes = aLoadFlags;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetContentType(char* *aContentType)
{
nsresult rv = NS_OK;
if (mContentType == nsnull) {
char* fileName = new char[PL_strlen(mJAREntry)+1];
PL_strcpy(fileName, mJAREntry);
if (fileName != nsnull) {
PRInt32 len = nsCRT::strlen(fileName);
const char* ext = nsnull;
for (PRInt32 i = len; i >= 0; i--) {
if (fileName[i] == '.') {
ext = &fileName[i + 1];
break;
}
}
if (ext) {
NS_WITH_SERVICE(nsIMIMEService, mimeServ, kMIMEServiceCID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = mimeServ->GetTypeFromExtension(ext, &mContentType);
}
}
else
rv = NS_ERROR_FAILURE;
nsCRT::free(fileName);
}
else {
rv = NS_ERROR_FAILURE;
}
if (NS_FAILED(rv)) {
mContentType = nsCRT::strdup(UNKNOWN_CONTENT_TYPE);
if (mContentType == nsnull)
rv = NS_ERROR_OUT_OF_MEMORY;
else
rv = NS_OK;
}
}
if (NS_SUCCEEDED(rv)) {
*aContentType = nsCRT::strdup(mContentType);
if (*aContentType == nsnull)
rv = NS_ERROR_OUT_OF_MEMORY;
}
return rv;
}
NS_IMETHODIMP
nsJARChannel::SetContentType(const char *aContentType)
{
if (mContentType) {
nsCRT::free(mContentType);
}
mContentType = nsCRT::strdup(aContentType);
if (!mContentType) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetContentLength(PRInt32* aContentLength)
{
if (mContentLength == -1)
return NS_ERROR_FAILURE;
*aContentLength = mContentLength;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::SetContentLength(PRInt32 aContentLength)
{
NS_NOTREACHED("nsJARChannel::SetContentLength");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsJARChannel::GetTransferOffset(PRUint32 *aTransferOffset)
{
*aTransferOffset = mStartPosition;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::SetTransferOffset(PRUint32 aTransferOffset)
{
mStartPosition = aTransferOffset;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetTransferCount(PRInt32 *aTransferCount)
{
*aTransferCount = mReadCount;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::SetTransferCount(PRInt32 aTransferCount)
{
mReadCount = aTransferCount;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetBufferSegmentSize(PRUint32 *aBufferSegmentSize)
{
*aBufferSegmentSize = mBufferSegmentSize;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::SetBufferSegmentSize(PRUint32 aBufferSegmentSize)
{
mBufferSegmentSize = aBufferSegmentSize;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetBufferMaxSize(PRUint32 *aBufferMaxSize)
{
*aBufferMaxSize = mBufferMaxSize;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::SetBufferMaxSize(PRUint32 aBufferMaxSize)
{
mBufferMaxSize = aBufferMaxSize;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetShouldCache(PRBool *aShouldCache)
{
// Jar files report that you shouldn't cache them because this is really
// a question about the jar entry, and the jar entry is always in a jar
// file on disk.
*aShouldCache = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetPipeliningAllowed(PRBool *aPipeliningAllowed)
{
*aPipeliningAllowed = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::SetPipeliningAllowed(PRBool aPipeliningAllowed)
{
NS_NOTREACHED("SetPipeliningAllowed");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsJARChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup;
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetOwner(nsISupports* *aOwner)
{
if (!mOwner)
{
nsCOMPtr<nsIPrincipal> certificate;
PRInt16 result;
nsresult rv = mJAR->GetCertificatePrincipal(mJAREntry,
getter_AddRefs(certificate),
&result);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
if (certificate)
{ // Get the codebase principal
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
kScriptSecurityManagerCID, &rv);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
nsCOMPtr<nsIPrincipal> codebase;
rv = secMan->GetCodebasePrincipal(mJARBaseURI,
getter_AddRefs(codebase));
if (NS_FAILED(rv)) return rv;
// Join the certificate and the codebase
nsCOMPtr<nsIAggregatePrincipal> agg;
agg = do_QueryInterface(certificate, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv),
"Certificate principal is not an aggregate");
rv = agg->SetCodebase(codebase);
if (NS_FAILED(rv)) return rv;
mOwner = do_QueryInterface(agg, &rv);
if (NS_FAILED(rv)) return rv;
}
}
*aOwner = mOwner;
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::SetOwner(nsISupports* aOwner)
{
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
{
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
mCallbacks = aNotificationCallbacks;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
{
*aSecurityInfo = nsnull;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIStreamObserver methods:
NS_IMETHODIMP
nsJARChannel::OnStartRequest(nsIChannel* jarExtractionTransport,
nsISupports* context)
{
return mUserListener->OnStartRequest(this, mUserContext);
}
NS_IMETHODIMP
nsJARChannel::OnStopRequest(nsIChannel* jarExtractionTransport,
nsISupports* context,
nsresult status,
const PRUnichar* aMsg)
{
nsresult rv;
#ifdef PR_LOGGING
nsCOMPtr<nsIURI> jarURI;
nsXPIDLCString jarURLStr;
rv = mURI->GetSpec(getter_Copies(jarURLStr));
if (NS_SUCCEEDED(rv)) {
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: jar extraction complete %s status=%x",
(const char*)jarURLStr, status));
}
#endif
rv = mUserListener->OnStopRequest(this, mUserContext, status, aMsg);
if (mLoadGroup) {
if (NS_SUCCEEDED(rv)) {
mLoadGroup->RemoveChannel(this, context, status, aMsg);
}
}
mUserListener = nsnull;
mUserContext = nsnull;
mJarExtractionTransport = nsnull;
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIStreamListener methods:
NS_IMETHODIMP
nsJARChannel::OnDataAvailable(nsIChannel* jarCacheTransport,
nsISupports* context,
nsIInputStream *inStr,
PRUint32 sourceOffset,
PRUint32 count)
{
return mUserListener->OnDataAvailable(this, mUserContext,
inStr, sourceOffset, count);
}
////////////////////////////////////////////////////////////////////////////////
// nsIFileSystem methods:
NS_IMETHODIMP
nsJARChannel::Open(char* *contentType, PRInt32 *contentLength)
{
nsresult rv;
NS_ASSERTION(mJARBaseFile, "mJARBaseFile is null");
rv = nsComponentManager::CreateInstance(kZipReaderCID,
nsnull,
NS_GET_IID(nsIZipReader),
getter_AddRefs(mJAR));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIFile> fs;
rv = mJARBaseFile->GetFile(getter_AddRefs(fs));
if (NS_FAILED(rv)) return rv;
rv = mJAR->Init(fs);
if (NS_FAILED(rv)) return rv;
rv = mJAR->Open();
if (NS_FAILED(rv)) return rv;
// If this fails, GetOwner will fail, but otherwise we can continue.
mJAR->ParseManifest();
nsCOMPtr<nsIZipEntry> entry;
rv = mJAR->GetEntry(mJAREntry, getter_AddRefs(entry));
if (NS_FAILED(rv)) return rv;
if (contentLength) {
rv = entry->GetRealSize((PRUint32*)contentLength);
if (NS_FAILED(rv)) return rv;
}
if (contentType) {
rv = GetContentType(contentType);
if (NS_FAILED(rv)) return rv;
}
return rv;
}
NS_IMETHODIMP
nsJARChannel::Close(nsresult status)
{
mJAR = null_nsCOMPtr();
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetInputStream(nsIInputStream* *aInputStream)
{
#ifdef PR_LOGGING
nsXPIDLCString jarURLStr;
mURI->GetSpec(getter_Copies(jarURLStr));
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: GetInputStream jar entry %s", (const char*)jarURLStr));
#endif
return mJAR->GetInputStream(mJAREntry, aInputStream);
}
NS_IMETHODIMP
nsJARChannel::GetOutputStream(nsIOutputStream* *aOutputStream)
{
NS_NOTREACHED("nsJARChannel::GetOutputStream");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// nsIJARChannel methods:
NS_IMETHODIMP
nsJARChannel::EnumerateEntries(const char *aRoot, nsISimpleEnumerator **_retval)
{
NS_NOTREACHED("nsJARChannel::EnumerateEntries");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,115 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsJARChannel_h__
#define nsJARChannel_h__
#include "nsIJARChannel.h"
#include "nsIStreamListener.h"
#include "nsIJARProtocolHandler.h"
#include "nsIJARURI.h"
#include "nsIFileSystem.h"
#include "nsIChannel.h"
#include "nsIZipReader.h"
#include "nsIChannel.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsCOMPtr.h"
#include "nsIFile.h"
#include "prmon.h"
class nsIFileChannel;
class nsJARChannel;
#define NS_JARCHANNEL_CID \
{ /* 0xc7e410d5-0x85f2-11d3-9f63-006008a6efe9 */ \
0xc7e410d5, \
0x85f2, \
0x11d3, \
{0x9f, 0x63, 0x00, 0x60, 0x08, 0xa6, 0xef, 0xe9} \
}
#define JAR_DIRECTORY "jarCache"
typedef nsresult
(*OnJARFileAvailableFun)(nsJARChannel* channel, void* closure);
class nsJARChannel : public nsIJARChannel,
public nsIStreamListener,
public nsIFileSystem
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSIJARCHANNEL
NS_DECL_NSISTREAMOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIFILESYSTEM
nsJARChannel();
virtual ~nsJARChannel();
// Define a Create method to be used with a factory:
static NS_METHOD
Create(nsISupports* aOuter, REFNSIID aIID, void **aResult);
nsresult Init(nsIJARProtocolHandler* aHandler, nsIURI* uri);
nsresult EnsureJARFileAvailable(OnJARFileAvailableFun fun,
void* closure);
nsresult AsyncReadJARElement();
nsresult GetCacheFile(nsIFile* *cacheFile);
void SetJARBaseFile(nsIFileChannel* channel) { mJARBaseFile = channel; }
friend class nsJARDownloadObserver;
protected:
nsCOMPtr<nsIJARURI> mURI;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIURI> mOriginalURI;
nsLoadFlags mLoadAttributes;
nsCOMPtr<nsISupports> mOwner;
PRUint32 mStartPosition;
PRInt32 mReadCount;
nsCOMPtr<nsISupports> mUserContext;
nsCOMPtr<nsIStreamListener> mUserListener;
char* mContentType;
PRInt32 mContentLength;
nsCOMPtr<nsIURI> mJARBaseURI;
nsCOMPtr<nsIFileChannel> mJARBaseFile;
char* mJAREntry;
nsCOMPtr<nsIZipReader> mJAR;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
nsresult mStatus;
PRMonitor* mMonitor;
nsCOMPtr<nsIChannel> mJarCacheTransport;
nsCOMPtr<nsIChannel> mJarExtractionTransport;
};
#endif // nsJARChannel_h__

View File

@@ -0,0 +1,138 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsJARProtocolHandler.h"
#include "nsIIOService.h"
#include "nsCRT.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsJARURI.h"
#include "nsIURL.h"
#include "nsJARChannel.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kJARUriCID, NS_JARURI_CID);
////////////////////////////////////////////////////////////////////////////////
nsJARProtocolHandler::nsJARProtocolHandler()
{
NS_INIT_REFCNT();
}
nsresult
nsJARProtocolHandler::Init()
{
return NS_OK;
}
nsJARProtocolHandler::~nsJARProtocolHandler()
{
}
NS_IMPL_ISUPPORTS2(nsJARProtocolHandler,
nsIJARProtocolHandler,
nsIProtocolHandler)
NS_METHOD
nsJARProtocolHandler::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsJARProtocolHandler* ph = new nsJARProtocolHandler();
if (ph == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(ph);
nsresult rv = ph->Init();
if (NS_SUCCEEDED(rv)) {
rv = ph->QueryInterface(aIID, aResult);
}
NS_RELEASE(ph);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIProtocolHandler methods:
NS_IMETHODIMP
nsJARProtocolHandler::GetScheme(char* *result)
{
*result = nsCRT::strdup("jar");
if (*result == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsJARProtocolHandler::GetDefaultPort(PRInt32 *result)
{
*result = -1; // no port for JAR: URLs
return NS_OK;
}
NS_IMETHODIMP
nsJARProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
nsIURI **result)
{
nsresult rv;
nsIURI* url;
if (aBaseURI) {
rv = aBaseURI->Clone(&url);
if (NS_FAILED(rv)) return rv;
rv = url->SetRelativePath(aSpec);
}
else {
rv = nsJARURI::Create(nsnull, NS_GET_IID(nsIJARURI), (void**)&url);
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)aSpec);
}
if (NS_FAILED(rv)) {
NS_RELEASE(url);
return rv;
}
*result = url;
return rv;
}
NS_IMETHODIMP
nsJARProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
{
nsresult rv;
nsJARChannel* channel;
rv = nsJARChannel::Create(nsnull, NS_GET_IID(nsIJARChannel), (void**)&channel);
if (NS_FAILED(rv)) return rv;
rv = channel->Init(this, uri);
if (NS_FAILED(rv)) {
NS_RELEASE(channel);
return rv;
}
*result = channel;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,57 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsJARProtocolHandler_h___
#define nsJARProtocolHandler_h___
#include "nsIJARProtocolHandler.h"
#include "nsIProtocolHandler.h"
#include "nsIJARURI.h"
#define NS_JARPROTOCOLHANDLER_CID \
{ /* 0xc7e410d4-0x85f2-11d3-9f63-006008a6efe9 */ \
0xc7e410d4, \
0x85f2, \
0x11d3, \
{0x9f, 0x63, 0x00, 0x60, 0x08, 0xa6, 0xef, 0xe9} \
}
class nsJARProtocolHandler : public nsIJARProtocolHandler
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPROTOCOLHANDLER
// nsJARProtocolHandler methods:
nsJARProtocolHandler();
virtual ~nsJARProtocolHandler();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsresult Init();
protected:
};
#endif /* nsJARProtocolHandler_h___ */

View File

@@ -0,0 +1,38 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIModule.h"
#include "nsIGenericFactory.h"
#include "nsJARProtocolHandler.h"
static nsModuleComponentInfo components[] =
{
{ "JAR Protocol Handler",
NS_JARPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_PROGID_PREFIX "jar",
nsJARProtocolHandler::Create
},
};
NS_IMPL_NSGETMODULE("nsJarProtocolModule", components);

View File

@@ -0,0 +1,384 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsJARURI.h"
#include "nsNetUtil.h"
#include "nsIIOService.h"
#include "nsFileSpec.h"
#include "nsCRT.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIZipReader.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
////////////////////////////////////////////////////////////////////////////////
nsJARURI::nsJARURI()
: mJAREntry(nsnull)
{
NS_INIT_REFCNT();
}
nsJARURI::~nsJARURI()
{
}
NS_IMPL_ISUPPORTS2(nsJARURI, nsIJARURI, nsIURI)
NS_METHOD
nsJARURI::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsJARURI* uri = new nsJARURI();
if (uri == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(uri);
nsresult rv = uri->Init();
if (NS_SUCCEEDED(rv)) {
rv = uri->QueryInterface(aIID, aResult);
}
NS_RELEASE(uri);
return rv;
}
nsresult
nsJARURI::Init()
{
return NS_OK;
}
#define NS_JAR_SCHEME "jar:"
#define NS_JAR_DELIMITER "!/"
nsresult
nsJARURI::FormatSpec(const char* entryPath, char* *result)
{
nsresult rv;
char* jarFileSpec;
rv = mJARFile->GetSpec(&jarFileSpec);
if (NS_FAILED(rv)) return rv;
nsCString spec(NS_JAR_SCHEME);
spec += jarFileSpec;
nsCRT::free(jarFileSpec);
spec += NS_JAR_DELIMITER;
spec += entryPath;
*result = nsCRT::strdup(spec);
return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
////////////////////////////////////////////////////////////////////////////////
// nsURI methods:
NS_IMETHODIMP
nsJARURI::GetSpec(char* *aSpec)
{
return FormatSpec(mJAREntry, aSpec);
}
NS_IMETHODIMP
nsJARURI::SetSpec(const char * aSpec)
{
nsresult rv;
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
PRUint32 startPos, endPos;
rv = serv->ExtractScheme(aSpec, &startPos, &endPos, nsnull);
if (NS_FAILED(rv)) return rv;
if (nsCRT::strncmp("jar", &aSpec[startPos], endPos - startPos - 1) != 0)
return NS_ERROR_MALFORMED_URI;
// Search backward from the end for the "!/" delimiter. Remember, jar URLs
// can nest, e.g.:
// jar:jar:http://www.foo.com/bar.jar!/a.jar!/b.html
// This gets the b.html document from out of the a.jar file, that's
// contained within the bar.jar file.
nsCAutoString jarPath(aSpec);
PRInt32 pos = jarPath.RFind(NS_JAR_DELIMITER);
if (pos == -1 || endPos + 1 > (PRUint32)pos)
return NS_ERROR_MALFORMED_URI;
jarPath.Cut(pos, jarPath.Length());
jarPath.Cut(0, endPos);
rv = serv->NewURI(jarPath, nsnull, getter_AddRefs(mJARFile));
if (NS_FAILED(rv)) return rv;
nsCAutoString entry(aSpec);
entry.Cut(0, pos + 2); // 2 == strlen(NS_JAR_DELIMITER)
rv = serv->ResolveRelativePath(entry, nsnull, &mJAREntry);
return rv;
}
NS_IMETHODIMP
nsJARURI::GetScheme(char * *aScheme)
{
*aScheme = nsCRT::strdup("jar");
return *aScheme ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
nsJARURI::SetScheme(const char * aScheme)
{
// doesn't make sense to set the scheme of a jar: URL
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::GetUsername(char * *aUsername)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::SetUsername(const char * aUsername)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::GetPassword(char * *aPassword)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::SetPassword(const char * aPassword)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::GetPreHost(char * *aPreHost)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::SetPreHost(const char * aPreHost)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::GetHost(char * *aHost)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::SetHost(const char * aHost)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::GetPort(PRInt32 *aPort)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::SetPort(PRInt32 aPort)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::GetPath(char * *aPath)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::SetPath(const char * aPath)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::GetURLParser(nsIURLParser * *aURLParser)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::SetURLParser(nsIURLParser * aURLParser)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::Equals(nsIURI *other, PRBool *result)
{
nsresult rv;
*result = PR_FALSE;
nsJARURI* otherJAR;
rv = other->QueryInterface(NS_GET_IID(nsIJARURI), (void**)&otherJAR);
if (NS_FAILED(rv))
return NS_OK; // not equal
nsCOMPtr<nsIURI> otherJARFile;
rv = otherJAR->GetJARFile(getter_AddRefs(otherJARFile));
if (NS_FAILED(rv)) return rv;
PRBool equal;
rv = mJARFile->Equals(otherJARFile, &equal);
if (NS_FAILED(rv)) return rv;
if (!equal)
return NS_OK; // not equal
char* otherJAREntry;
rv = otherJAR->GetJAREntry(&otherJAREntry);
if (NS_FAILED(rv)) return rv;
*result = nsCRT::strcmp(mJAREntry, otherJAREntry) == 0;
nsCRT::free(otherJAREntry);
return NS_OK;
}
NS_IMETHODIMP
nsJARURI::Clone(nsIURI **result)
{
nsresult rv;
nsCOMPtr<nsIURI> newJARFile;
rv = mJARFile->Clone(getter_AddRefs(newJARFile));
if (NS_FAILED(rv)) return rv;
char* newJAREntry = nsCRT::strdup(mJAREntry);
if (newJAREntry == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsJARURI* uri = new nsJARURI();
if (uri == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(uri);
uri->mJARFile = newJARFile;
uri->mJAREntry = newJAREntry;
*result = uri;
return NS_OK;
}
NS_IMETHODIMP
nsJARURI::SetRelativePath(const char *relativePath)
{
nsresult rv;
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCAutoString path(mJAREntry);
PRInt32 pos = path.RFind("/");
if (pos >= 0)
path.Truncate(pos + 1);
else
path = "";
char* resolvedEntry;
rv = serv->ResolveRelativePath(relativePath, path.GetBuffer(),
&resolvedEntry);
if (NS_FAILED(rv)) return rv;
nsCRT::free(mJAREntry);
mJAREntry = resolvedEntry;
return NS_OK;
}
NS_IMETHODIMP
nsJARURI::Resolve(const char *relativePath, char **result)
{
nsresult rv;
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCAutoString path(mJAREntry);
PRInt32 pos = path.RFind("/");
if (pos >= 0)
path.Truncate(pos + 1);
else
path = "";
char* resolvedEntry;
rv = serv->ResolveRelativePath(relativePath, path.GetBuffer(),
&resolvedEntry);
if (NS_FAILED(rv)) return rv;
rv = FormatSpec(resolvedEntry, result);
nsCRT::free(resolvedEntry);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIJARUri methods:
NS_IMETHODIMP
nsJARURI::GetJARFile(nsIURI* *jarFile)
{
*jarFile = mJARFile;
NS_ADDREF(*jarFile);
return NS_OK;
}
NS_IMETHODIMP
nsJARURI::SetJARFile(nsIURI* jarFile)
{
mJARFile = jarFile;
return NS_OK;
}
NS_IMETHODIMP
nsJARURI::GetJAREntry(char* *entryPath)
{
nsCAutoString entry(mJAREntry);
PRInt32 pos = entry.RFindCharInSet("#?;");
if (pos >= 0)
entry.Truncate(pos);
*entryPath = entry.ToNewCString();
return *entryPath ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
nsJARURI::SetJAREntry(const char* entryPath)
{
nsresult rv;
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
if (mJAREntry)
nsCRT::free(mJAREntry);
rv = serv->ResolveRelativePath(entryPath, nsnull, &mJAREntry);
return rv;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,55 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsJARURI_h__
#define nsJARURI_h__
#include "nsIJARURI.h"
#include "nsCOMPtr.h"
#define NS_JARURI_CID \
{ /* 0xc7e410d7-0x85f2-11d3-9f63-006008a6efe9 */ \
0xc7e410d7, \
0x85f2, \
0x11d3, \
{0x9f, 0x63, 0x00, 0x60, 0x08, 0xa6, 0xef, 0xe9} \
}
class nsJARURI : public nsIJARURI
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIURI
NS_DECL_NSIJARURI
// nsJARURI
nsJARURI();
virtual ~nsJARURI();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsresult Init();
nsresult FormatSpec(const char* entryPath, char* *result);
protected:
nsCOMPtr<nsIURI> mJARFile;
char *mJAREntry;
};
#endif // nsJARURI_h__

View File

@@ -0,0 +1,45 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = \
cache \
base \
dns \
socket \
build \
protocol \
mime \
streamconv \
$(NULL)
ifdef ENABLE_TESTS
DIRS += test
endif
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,32 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,31 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH = ..\..
MODULE = necko
DIRS= \
public \
src \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@@ -0,0 +1,7 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
netCore.h
nsNetUtil.h
nsUnixColorPrintf.h

View File

@@ -0,0 +1,17 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
nsIStreamListener.idl
nsIStreamObserver.idl
nsIURI.idl
nsIURL.idl
nsIChannel.idl
nsIRequest.idl
nsISocketTransportService.idl
nsIFileTransportService.idl
nsIFileSystem.idl
nsIPrompt.idl
nsIStreamLoader.idl
nsIURLParser.idl
nsIProtocolProxyService.idl

View File

@@ -0,0 +1,67 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = necko
XPIDL_MODULE = necko_base
XPIDLSRCS = \
nsIFileStreams.idl \
nsIRequest.idl \
nsIChannel.idl \
nsIURI.idl \
nsIURL.idl \
nsIStreamObserver.idl \
nsIStreamListener.idl \
nsIIOService.idl \
nsIPrompt.idl \
nsIProtocolHandler.idl \
nsIProgressEventSink.idl \
nsINetModRegEntry.idl \
nsINetModuleMgr.idl \
nsINetNotify.idl \
nsILoadGroup.idl \
nsIFileTransportService.idl \
nsISocketTransportService.idl \
nsIStatusCodeEventSink.idl \
nsIFileSystem.idl \
nsIStreamLoader.idl \
nsINetPrompt.idl \
nsISocketTransport.idl \
nsIURLParser.idl \
nsIProxy.idl \
nsIProtocolProxyService.idl \
$(NULL)
EXPORTS = \
netCore.h \
nsNetUtil.h \
nsUnixColorPrintf.h \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,66 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
MODULE = necko
DEPTH = ..\..\..
include <$(DEPTH)/config/config.mak>
EXPORTS = \
netCore.h \
nsNetUtil.h \
nsUnixColorPrintf.h \
$(NULL)
XPIDLSRCS = \
.\nsIFileStreams.idl \
.\nsIRequest.idl \
.\nsIChannel.idl \
.\nsIURI.idl \
.\nsIURL.idl \
.\nsIStreamObserver.idl \
.\nsIStreamListener.idl \
.\nsIIOService.idl \
.\nsIPrompt.idl \
.\nsIProtocolHandler.idl \
.\nsIProgressEventSink.idl \
.\nsINetModRegEntry.idl \
.\nsINetModuleMgr.idl \
.\nsINetNotify.idl \
.\nsILoadGroup.idl \
.\nsISocketTransportService.idl \
.\nsIFileTransportService.idl \
.\nsIStatusCodeEventSink.idl \
.\nsIFileSystem.idl \
.\nsIStreamLoader.idl \
.\nsINetPrompt.idl \
.\nsISocketTransport.idl \
.\nsIURLParser.idl \
.\nsIProxy.idl \
.\nsIProtocolProxyService.idl \
$(NULL)
include <$(DEPTH)/config/rules.mak>
$(DEPTH)\netwerk\dist\include:
-mkdir $(DEPTH)\netwerk\dist
-mkdir $(DEPTH)\netwerk\dist\include

View File

@@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __netCore_h__
#define __netCore_h__
#include "nsError.h"
/* networking error codes */
// NET RANGE: 1 -20
// FTP RANGE: 21-30
// HTTP RANGE: 31-40
// DNS RANGE: 41-50
#define NS_ERROR_ALREADY_CONNECTED \
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 11)
#define NS_ERROR_NOT_CONNECTED \
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 12)
/* NS_ERROR_CONNECTION_REFUSED and NS_ERROR_NET_TIMEOUT moved to nsISocketTransportService.idl */
#define NS_ERROR_IN_PROGRESS \
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 15)
#define NS_ERROR_OFFLINE \
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 16)
#undef NS_NET
#ifdef _IMPL_NS_NET
#ifdef XP_PC
#define NS_NET _declspec(dllexport)
#else /* !XP_PC */
#define NS_NET
#endif /* !XP_PC */
#else /* !_IMPL_NS_NET */
#ifdef XP_PC
#define NS_NET _declspec(dllimport)
#else /* !XP_PC */
#define NS_NET
#endif /* !XP_PC */
#endif /* !_IMPL_NS_NET */
#endif // __netCore_h__

View File

@@ -0,0 +1,403 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIRequest.idl"
interface nsIURI;
interface nsIInputStream;
interface nsIOutputStream;
interface nsIStreamObserver;
interface nsIStreamListener;
interface nsILoadGroup;
interface nsIInterfaceRequestor;
interface nsIFile;
typedef unsigned long nsLoadFlags;
/**
* The nsIChannel interface allows the user to construct I/O requests for
* specific protocols, and manage them in a uniform way. Once a channel
* is created (via nsIIOService::NewChannel), parameters for that request
* may be set by using the channel attributes, or by QueryInterfacing to a
* subclass of nsIChannel for protocol-specific parameters. Then the actual
* request can be issued in one of several ways:
*
* - AsyncRead and AsyncWrite allow for asynchronous requests, calling
* back the user's stream listener or observer,
* - OpenInputStream and OpenOutputStream allow for synchronous reads
* and writes on the underlying channel.
*
* After a request has been completed, the channel is still valid for
* accessing protocol-specific results. For example, QueryInterfacing to
* nsIHTTPChannel allows response headers to be retrieved that result from
* http transactions.
*
* Note that a channel is really only valid for one request. Reusing a channel
* after a request has completed for a subsequent request may have undefined
* results, depending on the channel implementation.
*
* Also of note are a special kind of channel called "transports." Transports
* also implement the nsIChannel interface, but operate at a lower level from
* protocol channels. The socket and file transports are notable implementations
* of transports and allow higher level channels to be implemented. The cache
* may also behave as a transport, and possibly things like sound playing services
* etc. Transports usually operate in a separate thread and often multiplex
* multiple requests for the same kind of service or resources.
*/
[scriptable, uuid(1788e79e-f947-11d3-8cda-0060b0fc14a3)]
interface nsIChannel : nsIRequest
{
////////////////////////////////////////////////////////////////////////////
// nsIChannel accessors
////////////////////////////////////////////////////////////////////////////
/**
* Returns the original URL used to construct the channel.
* This is used in the case of a redirect or URI "resolution" (e.g.
* resolving a resource: URI to a file: URI) so that the original
* pre-redirect URI can still be obtained.
*
* Note that this is distinctly different from the http referrer
* (referring URI) which is typically the page that contained the
* original URI (accessible from nsIHTTPChannel).
*/
attribute nsIURI originalURI;
/**
* Returns the URL to which the channel currently refers. If a redirect
* or URI resolution occurs, this accessor returns the current location
* to which the channel is referring.
*/
attribute nsIURI URI;
/**
* Accesses the start offset from the beginning of the data from/to which
* reads/writes will occur. Users may set the transferOffset before making
* any of the following requests: asyncOpen, asyncRead, asyncWrite,
* openInputStream, openOutputstream.
*/
attribute unsigned long transferOffset;
/**
* Accesses the count of bytes to be transfered. For openInputStream and
* asyncRead, this specifies the amount to read, for asyncWrite, this
* specifies the amount to write (note that for openOutputStream, the
* end of the data can be signified simply by closing the stream).
* If the transferCount is set after reading has been initiated, the
* amount specified will become the current remaining amount to read
* before the channel is closed (this can be useful if the content
* length is encoded at the start of the stream).
*
* A transferCount value of -1 means the amount is unspecified, i.e.
* read or write all the data that is available.
*/
attribute long transferCount;
/**
* Accesses the load attributes for the channel. E.g. setting the load
* attributes with the LOAD_QUIET bit set causes the loading process to
* not deliver status notifications to the program performing the load,
* and to not contribute to keeping any nsILoadGroup it may be contained
* in from firing its OnLoadComplete notification.
*/
attribute nsLoadFlags loadAttributes;
/**
* Returns the content MIME type of the channel if available. Note that the
* content type can often be wrongly specified (wrong file extension, wrong
* MIME type, wrong document type stored on a server, etc.) and the caller
* most likely wants to verify with the actual data.
*/
attribute string contentType;
/**
* Returns the length of the data associated with the channel if available.
* If the length is unknown then -1 is returned.
*/
attribute long contentLength;
/**
* Accesses the owner corresponding to the entity that is
* responsible for this channel. Used by security code to grant
* or deny privileges to mobile code loaded from this channel.
*
* Note: This is a strong reference to the owner, so if the owner is also
* holding a pointer to the channel, care must be taken to explicitly drop
* its reference to the channel -- otherwise a leak will result.
*/
attribute nsISupports owner;
/**
* Accesses the load group in which the channel is a currently a member.
*/
attribute nsILoadGroup loadGroup;
/**
* Accesses the capabilities callbacks of the channel. This is set by clients
* who wish to provide a means to receive progress, status and protocol-specific
* notifications.
*/
attribute nsIInterfaceRequestor notificationCallbacks;
/**
* Any security information about this channel. This can be null.
*/
readonly attribute nsISupports securityInfo;
/**
* Accesses the buffer segment size. The buffer segment size is used as
* the initial size for any transfer buffers, and the increment size for
* whenever the buffer space needs to be grown.
* (Note this parameter is passed along to any underlying nsIPipe objects.)
* If unspecified, the channel implementation picks a default.
*/
attribute unsigned long bufferSegmentSize;
/**
* Accesses the buffer maximum size. The buffer maximum size is the limit
* size that buffer will be grown to before suspending the channel.
* (Note this parameter is passed along to any underlying nsIPipe objects.)
* If unspecified, the channel implementation picks a default.
*/
attribute unsigned long bufferMaxSize;
/**
* Returns true if the data from this channel should be cached. Local files
* report false because they exist on the local disk and need not be cached.
* Input stream channels, data protocol, datetime protocol and finger
* protocol channels also should not be cached. Http and ftp on the other
* hand should. Note that the value of this attribute doesn't reflect any
* http headers that may specify that this channel should not be cached.
*/
readonly attribute boolean shouldCache;
/**
* Setting pipeliningAllowed causes the load of a URL (issued via asyncOpen,
* asyncRead or asyncWrite) to be deferred in order to allow the request to
* be pipelined for greater throughput efficiency. Pipelined requests will
* be forced to load when the first non-pipelined request is issued.
*/
attribute boolean pipeliningAllowed;
////////////////////////////////////////////////////////////////////////////
// Load attribute flags. These may be or'd together.
////////////////////////////////////////////////////////////////////////////
/**
* Note that more will follow for each protocol's implementation of a channel,
* although channel writers have to be careful to not let the flag bits
* overlap. Otherwise, users won't be able to create a single flag word
* of load attributes that applies to a number of different channel types.
*/
/**
* No special load attributes -- use defaults:
*/
const unsigned long LOAD_NORMAL = 0;
/**
* Don't deliver status notifications to the nsIProgressEventSink, or keep
* this load from completing the nsILoadGroup it may belong to:
*/
const unsigned long LOAD_BACKGROUND = 1 << 0;
const unsigned long LOAD_DOCUMENT_URI = 1 << 1;
/**
* If the end consumer for this load has been retargeted after discovering
* it's content, this flag will be set:
*/
const unsigned long LOAD_RETARGETED_DOCUMENT_URI = 1 << 2;
////////////////////////////////////////////////////////////////////////////
/**
* The following flags control caching behavior. Not all protocols pay
* attention to all these flags, but they are applicable to more than one
* protocol, so they are defined here.
*/
/**
* Don't store data in the disk cache. This can be used to preserve
* privacy, e.g. so that no https transactions are recorded, or to avoid
* caching a stream to disk that is already stored in a local file,
* e.g. the mailbox: protocol.
*/
const unsigned long INHIBIT_PERSISTENT_CACHING = 1 << 8;
/**
* Force an end-to-end download of content data from the origin server (and
* any intervening proxies that sit between it and the client), e.g. this
* flag is used for a shift-reload.
*/
const unsigned long FORCE_RELOAD = 1 << 9;
/**
* Force revalidation with server (or proxy) to verify that cached content
* is up-to-date, e.g. by comparing last-modified date on server with that
* of the cached version. For example, this flag is used when the reload
* button is pressed.
*/
const unsigned long FORCE_VALIDATION = 1 << 10;
/**
* If the CACHE_AS_FILE flag is set, any stream content is stored in the
* cache as a single disk file. Content will not be cached in the memory
* cache nor will it be stored in any other type of cache, e.g. a flat-file
* cache database. This is used to implement the jar protocol handler and
* to provide the stream-as-file semantics required by the classic browser
* plugin API.
*/
const unsigned long CACHE_AS_FILE = 1 << 11;
/**
* When cache data is potentially out of date, it can be revalidated with
* the origin server to see if the content needs to be reloaded. The
* following four flags control how often this validation occurs.
* These flags are commonly used for "normal" loading. Note that
* the VALIDATE_HEURISTICALLY and VALIDATE_ONCE_PER_SESSION flags can be
* combined to validate heuristically but no more than once per session.
*/
const unsigned long VALIDATE_NEVER = 1 << 12;
const unsigned long VALIDATE_ALWAYS = 1 << 13;
const unsigned long VALIDATE_ONCE_PER_SESSION = 1 << 14;
const unsigned long VALIDATE_HEURISTICALLY = 1 << 15;
////////////////////////////////////////////////////////////////////////////
// nsIChannel operations
////////////////////////////////////////////////////////////////////////////
/**
* Opens a blocking input stream to the URL's specified source.
* @param startPosition - The offset from the start of the data
* from which to read.
* @param readCount - The number of bytes to read. If -1, everything
* up to the end of the data is read. If greater than the end of
* the data, the amount available is returned in the stream.
*/
nsIInputStream openInputStream();
/**
* Opens a blocking output stream to the URL's specified destination.
* @param startPosition - The offset from the start of the data
* from which to begin writing.
*/
nsIOutputStream openOutputStream();
/**
* Opens the channel asynchronously. The nsIStreamObserver's OnStartRequest
* method is called back when the channel actually becomes open, providing
* the content type. Its OnStopRequest method is called when the channel
* becomes closed.
*/
void asyncOpen(in nsIStreamObserver observer,
in nsISupports ctxt);
/**
* Reads asynchronously from the URL's specified source. Notifications
* are provided to the stream listener on the thread of the specified
* event queue.
* The startPosition argument designates the offset in the source where
* the data will be read.
* If the readCount == -1 then all the available data is delivered to
* the stream listener.
*/
void asyncRead(in nsIStreamListener listener,
in nsISupports ctxt);
/**
* Writes asynchronously to the URL's specified destination. Notifications
* are provided to the stream observer on the thread of the specified
* event queue.
* The startPosition argument designates the offset in the destination where
* the data will be written.
* If the writeCount == -1, then all the available data in the input
* stream is written.
*/
void asyncWrite(in nsIInputStream fromStream,
in nsIStreamObserver observer,
in nsISupports ctxt);
};
////////////////////////////////////////////////////////////////////////////////
/**
* nsIInputStreamChannel is an interface that allows for the initialization
* of a simple nsIChannel that is constructed from a single input stream and
* associated content type. Input stream channels only allow the input stream
* to be accessed, not the output stream.
*/
[scriptable, uuid(43070d6a-f947-11d3-8cda-0060b0fc14a3)]
interface nsIInputStreamChannel : nsIChannel
{
void init(in nsIURI uri,
in nsIInputStream inStr,
in string contentType,
in long contentLength);
};
%{C++
#define NS_INPUTSTREAMCHANNEL_CID \
{ /* 54d0d8e6-f947-11d3-8cda-0060b0fc14a3 */ \
0x54d0d8e6, \
0xf947, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
%}
////////////////////////////////////////////////////////////////////////////////
/**
* nsIFileChannel is an interface that allows for the initialization
* of a simple nsIChannel that is constructed from a single nsIFile and
* associated content type.
*/
[scriptable, uuid(68a26506-f947-11d3-8cda-0060b0fc14a3)]
interface nsIFileChannel : nsIChannel
{
void init(in nsIFile file,
in long ioFlags,
in long perm);
readonly attribute nsIFile file;
attribute long ioFlags;
attribute long permissions;
};
%{C++
#define NS_LOCALFILECHANNEL_CLASSNAME "Local File Channel"
#define NS_LOCALFILECHANNEL_PROGID "component://netscape/network/local-file-channel"
#define NS_LOCALFILECHANNEL_CID \
{ /* 6d5b2d44-f947-11d3-8cda-0060b0fc14a3 */ \
0x6d5b2d44, \
0xf947, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
%}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,30 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
[scriptable, uuid(fb65fd70-1881-11d3-9337-00104ba0fd40)]
interface nsIEventSinkGetter : nsISupports
{
nsISupports getEventSink(in string command, in nsIIDRef eventSinkIID);
};

View File

@@ -0,0 +1,241 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIInputStream.idl"
#include "nsIOutputStream.idl"
#include "nsILocalFile.idl"
[scriptable, uuid(e3d56a20-c7ec-11d3-8cda-0060b0fc14a3)]
interface nsIFileInputStream : nsIInputStream
{
void init(in nsIFile file, in long ioFlags, in long perm);
};
[scriptable, uuid(e6f68040-c7ec-11d3-8cda-0060b0fc14a3)]
interface nsIFileOutputStream : nsIOutputStream
{
void init(in nsIFile file, in long ioFlags, in long perm);
};
[scriptable, uuid(e9de5df0-c7ec-11d3-8cda-0060b0fc14a3)]
interface nsISeekableStream : nsISupports
{
// correspond to PRSeekWhence values
const long NS_SEEK_SET = 0;
const long NS_SEEK_CUR = 1;
const long NS_SEEK_END = 2;
void seek(in long whence, in long offset);
unsigned long tell();
};
[scriptable, uuid(616f5b48-da09-11d3-8cda-0060b0fc14a3)]
interface nsIBufferedInputStream : nsIInputStream
{
void init(in nsIInputStream fillFromStream,
in unsigned long bufferSize);
};
[scriptable, uuid(6476378a-da09-11d3-8cda-0060b0fc14a3)]
interface nsIBufferedOutputStream : nsIOutputStream
{
void init(in nsIOutputStream sinkToStream,
in unsigned long bufferSize);
};
%{C++
////////////////////////////////////////////////////////////////////////////////
#define NS_LOCALFILEINPUTSTREAM_CLASSNAME "Local File Input Stream"
#define NS_LOCALFILEINPUTSTREAM_PROGID "component://netscape/network/file-input-stream"
#define NS_LOCALFILEINPUTSTREAM_CID \
{ /* be9a53ae-c7e9-11d3-8cda-0060b0fc14a3 */ \
0xbe9a53ae, \
0xc7e9, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_LOCALFILEOUTPUTSTREAM_CLASSNAME "Local File Output Stream"
#define NS_LOCALFILEOUTPUTSTREAM_PROGID "component://netscape/network/file-output-stream"
#define NS_LOCALFILEOUTPUTSTREAM_CID \
{ /* c272fee0-c7e9-11d3-8cda-0060b0fc14a3 */ \
0xc272fee0, \
0xc7e9, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
////////////////////////////////////////////////////////////////////////////////
#define NS_BUFFEREDINPUTSTREAM_CLASSNAME "Buffered Input Stream"
#define NS_BUFFEREDINPUTSTREAM_PROGID "component://netscape/network/buffered-input-stream"
#define NS_BUFFEREDINPUTSTREAM_CID \
{ /* 9226888e-da08-11d3-8cda-0060b0fc14a3 */ \
0x9226888e, \
0xda08, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_BUFFEREDOUTPUTSTREAM_CLASSNAME "Buffered Output Stream"
#define NS_BUFFEREDOUTPUTSTREAM_PROGID "component://netscape/network/buffered-output-stream"
#define NS_BUFFEREDOUTPUTSTREAM_CID \
{ /* 9868b4ce-da08-11d3-8cda-0060b0fc14a3 */ \
0x9868b4ce, \
0xda08, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
////////////////////////////////////////////////////////////////////////////////
// move to nsNetUtil.h later...
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsIChannel.h"
#include "nsILocalFile.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "prio.h" // for read/write flags, permissions, etc.
// This will QI the file argument to an nsILocalFile in the Init method.
inline nsresult
NS_NewLocalFileChannel(nsIFileChannel **result,
nsIFile* file,
PRInt32 ioFlags = -1,
PRInt32 perm = -1)
{
nsresult rv;
nsCOMPtr<nsIFileChannel> channel;
static NS_DEFINE_CID(kLocalFileChannelCID, NS_LOCALFILECHANNEL_CID);
rv = nsComponentManager::CreateInstance(kLocalFileChannelCID,
nsnull,
NS_GET_IID(nsIFileChannel),
getter_AddRefs(channel));
if (NS_FAILED(rv)) return rv;
rv = channel->Init(file, ioFlags, perm);
if (NS_FAILED(rv)) return rv;
*result = channel;
NS_ADDREF(*result);
return NS_OK;
}
// This will QI the file argument to an nsILocalFile in the Init method.
inline nsresult
NS_NewLocalFileInputStream(nsIInputStream* *result,
nsIFile* file,
PRInt32 ioFlags = -1,
PRInt32 perm = -1)
{
nsresult rv;
nsCOMPtr<nsIFileInputStream> in;
static NS_DEFINE_CID(kLocalFileInputStreamCID, NS_LOCALFILEINPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kLocalFileInputStreamCID,
nsnull,
NS_GET_IID(nsIFileInputStream),
getter_AddRefs(in));
if (NS_FAILED(rv)) return rv;
rv = in->Init(file, ioFlags, perm);
if (NS_FAILED(rv)) return rv;
*result = in;
NS_ADDREF(*result);
return NS_OK;
}
// This will QI the file argument to an nsILocalFile in the Init method.
inline nsresult
NS_NewLocalFileOutputStream(nsIOutputStream* *result,
nsIFile* file,
PRInt32 ioFlags = -1,
PRInt32 perm = -1)
{
nsresult rv;
nsCOMPtr<nsIFileOutputStream> out;
static NS_DEFINE_CID(kLocalFileOutputStreamCID, NS_LOCALFILEOUTPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kLocalFileOutputStreamCID,
nsnull,
NS_GET_IID(nsIFileOutputStream),
getter_AddRefs(out));
if (NS_FAILED(rv)) return rv;
rv = out->Init(file, ioFlags, perm);
if (NS_FAILED(rv)) return rv;
*result = out;
NS_ADDREF(*result);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
inline nsresult
NS_NewBufferedInputStream(nsIInputStream* *result,
nsIInputStream* str,
PRUint32 bufferSize)
{
nsresult rv;
nsCOMPtr<nsIBufferedInputStream> in;
static NS_DEFINE_CID(kBufferedInputStreamCID, NS_BUFFEREDINPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kBufferedInputStreamCID,
nsnull,
NS_GET_IID(nsIBufferedInputStream),
getter_AddRefs(in));
if (NS_FAILED(rv)) return rv;
rv = in->Init(str, bufferSize);
if (NS_FAILED(rv)) return rv;
*result = in;
NS_ADDREF(*result);
return NS_OK;
}
inline nsresult
NS_NewBufferedOutputStream(nsIOutputStream* *result,
nsIOutputStream* str,
PRUint32 bufferSize)
{
nsresult rv;
nsCOMPtr<nsIBufferedOutputStream> out;
static NS_DEFINE_CID(kBufferedOutputStreamCID, NS_BUFFEREDOUTPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kBufferedOutputStreamCID,
nsnull,
NS_GET_IID(nsIBufferedOutputStream),
getter_AddRefs(out));
if (NS_FAILED(rv)) return rv;
rv = out->Init(str, bufferSize);
if (NS_FAILED(rv)) return rv;
*result = out;
NS_ADDREF(*result);
return NS_OK;
}
%}

View File

@@ -0,0 +1,40 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
interface nsIInputStream;
interface nsIOutputStream;
[scriptable, uuid(818e1370-77c4-11d3-9395-00104ba0fd40)]
interface nsIFileSystem : nsISupports
{
void open(out string contentType,
out long contentLength);
void close(in nsresult status);
readonly attribute nsIInputStream inputStream;
readonly attribute nsIOutputStream outputStream;
};

View File

@@ -0,0 +1,65 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
%{C++
#include "nsFileSpec.h"
%}
interface nsIChannel;
interface nsIFileSystem;
interface nsIEventSinkGetter;
interface nsIInputStream;
interface nsIRunnable;
interface nsIFile;
[scriptable, uuid(57211a60-8c45-11d3-93ac-00104ba0fd40)]
interface nsIFileTransportService : nsISupports
{
nsIChannel createTransport(in nsIFile file,
in long ioFlags,
in long perm);
// This version can be used with an existing input stream to serve
// as a data pump:
nsIChannel createTransportFromStream(in nsIInputStream fromStream,
in string contentType,
in long contentLength);
nsIChannel createTransportFromFileSystem(in nsIFileSystem fsObj);
void dispatchRequest(in nsIRunnable runnable);
void suspend(in nsIRunnable trans);
void resume(in nsIRunnable trans);
void processPendingRequests();
void shutdown();
};
%{C++
#define NS_FILETRANSPORTSERVICE_CID \
{ /* 2bb2b250-ea35-11d2-931b-00104ba0fd40 */ \
0x2bb2b250, \
0xea35, \
0x11d2, \
{0x93, 0x1b, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
}
%}

View File

@@ -0,0 +1,169 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIChannel.idl"
interface nsIProtocolHandler;
interface nsIURI;
interface nsIInterfaceRequestor;
interface nsIStreamObserver;
interface nsIStreamListener;
interface nsIEventQueue;
interface nsIBufferInputStream;
interface nsIInputStream;
interface nsIBufferOutputStream;
interface nsIFileChannel;
interface nsILoadGroup;
interface nsILoadGroupObserver;
interface nsIFile;
interface nsIInputStream;
interface nsIOutputStream;
[scriptable, uuid(ab7c3a84-d488-11d3-8cda-0060b0fc14a3)]
interface nsIIOService : nsISupports
{
/**
* Returns a protocol handler for a given URI scheme.
*/
nsIProtocolHandler getProtocolHandler(in string scheme);
/**
* This method constructs a new URI by first determining the scheme
* of the URI spec, and then delegating the construction of the URI
* to the protocol handler for that scheme. QueryInterface can be used
* on the resulting URI object to obtain a more specific type of URI.
*/
nsIURI newURI(in string aSpec, in nsIURI aBaseURI);
/**
* Creates a channel for a given URI. The notificationCallbacks argument
* is used to obtain the appropriate callbacks for the URI's protocol from the
* application.
*
* @param originalURI - Specifies the original URI which caused the creation
* of this channel. This can occur when the construction of one channel
* (e.g. for resource:) causes another channel to be created on its behalf
* (e.g. a file: channel), or if a redirect occurs, causing the current
* URL to become different from the original URL. If NULL, the aURI parameter
* will be used as the originalURI instead.
*/
nsIChannel newChannelFromURI(in nsIURI aURI);
/**
* Convenience routine that first creates a URI by calling NewURI, and
* then passes the URI to NewChannelFromURI.
*
* @param originalURI - Specifies the original URI which caused the creation
* of this channel. This can occur when the construction of one channel
* (e.g. for resource:) causes another channel to be created on its behalf
* (e.g. a file: channel), or if a redirect occurs, causing the current
* URL to become different from the original URL. If NULL, the aURI parameter
* will be used as the originalURI instead.
*/
nsIChannel newChannel(in string aSpec, in nsIURI aBaseURI);
/**
* Returns true if networking is in "offline" mode. When in offline mode, attempts
* to access the network will fail (although this is not necessarily corrolated with
* whether there is actually a network available -- that's hard to detect without
* causing the dialer to come up).
*/
attribute boolean offline;
////////////////////////////////////////////////////////////////////////////
// URL parsing utilities
/**
* Utility for protocol implementors -- extracts the scheme from a URL
* string, consistently and according to spec.
* @param urlString - the URL string to parse
* @param schemeStartPos - the resulting starting position of the scheme substring
* (may skip over whitespace)
* @param schemeEndPos - the resulting ending position of the scheme substring
* (the position of the colon)
* @param scheme - an allocated substring containing the scheme. If this parameter
* is null going into the routine, then the scheme is not allocated and
* returned. Free with nsCRT::free.
*
* @return NS_OK - if successful
* @return NS_ERROR_MALFORMED_URI - if the urlString is not of the right form
*/
void extractScheme(in string urlString,
out unsigned long schemeStartPos,
out unsigned long schemeEndPos,
out string scheme);
/**
* Constants for the mask in the call to Escape
*/
const short url_Scheme = (1<<0);
const short url_Username = (1<<1);
const short url_Password = (1<<2);
const short url_Host = (1<<3);
const short url_Directory = (1<<4);
const short url_FileBaseName = (1<<5);
const short url_FileExtension = (1<<6);
const short url_Param = (1<<7);
const short url_Query = (1<<8);
const short url_Ref = (1<<9);
const short url_Forced = (1<<10);
/**
* Encode characters into % escaped hexcodes.
*/
string escape(in string str, in short mask);
/**
* Decode % escaped hex codes into character values.
*/
string unescape(in string str);
/**
* Get port from string.
*/
long extractPort(in string str);
/**
* Resolves a relative path string containing "." and ".."
* with respect to a base path (assumed to already be resolved).
* For example, resolving "../../foo/./bar/../baz.html" w.r.t.
* "/a/b/c/d/e/" yields "/a/b/c/foo/baz.html". Attempting to
* ascend above the base results in the NS_ERROR_MALFORMED_URI
* exception. If basePath is null, it treats it as "/".
*/
string resolveRelativePath(in string relativePath,
in string basePath);
};
%{C++
#define NS_IOSERVICE_CID \
{ /* 9ac9e770-18bc-11d3-9337-00104ba0fd40 */ \
0x9ac9e770, \
0x18bc, \
0x11d3, \
{0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
}
#define DUD 3.14
%}

View File

@@ -0,0 +1,104 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIRequest.idl"
interface nsIChannel;
interface nsISimpleEnumerator;
interface nsIStreamObserver;
interface nsIStreamListener;
interface nsIInputStream;
[scriptable, uuid(60fdf550-5392-11d3-9a97-0080c7cb1080)]
interface nsILoadGroupListenerFactory : nsISupports
{
nsIStreamListener createLoadGroupListener(in nsIStreamListener alistener);
};
/**
* A load group maintains a collection of active URL requests.
*/
[scriptable, uuid(19845248-29ab-11d3-8cce-0060b0fc14a3)]
interface nsILoadGroup : nsIRequest
{
void init(in nsIStreamObserver observer);
/**
* Accesses the default load attributes for the group, returned as
* a flag word. Setting the default load attributes will cause them
* to be applied to each new channel inserted into the group.
*/
attribute unsigned long defaultLoadAttributes;
/**
* Accesses the default load channel for the group. Each time a number
* of channels are added to a group, the DefaultLoadChannel may be set
* to indicate that all of the channels are related to a particular URL.
*/
attribute nsIChannel defaultLoadChannel;
/**
* Adds a new channel to the group. This will cause the default load
* attributes to be applied to that channel. If the channel added is
* the first channel in the group, the group's observer's OnStartRequest
* method is called.
*/
void addChannel(in nsIChannel channel,
in nsISupports ctxt);
/**
* Removes a channel from the group. If the channel removed is
* the last channel in the group, the group's observer's OnStopRequest
* method is called.
*/
void removeChannel(in nsIChannel channel,
in nsISupports ctxt,
in nsresult status,
in wstring errorMsg);
/**
* Returns the channels contained directly in this group.
* Enumerator element type: nsIChannel.
*/
readonly attribute nsISimpleEnumerator channels;
attribute nsIStreamObserver groupObserver;
attribute nsILoadGroupListenerFactory groupListenerFactory;
readonly attribute unsigned long activeCount;
};
%{C++
#define NS_LOADGROUP_CID \
{ /* e1c61582-2a84-11d3-8cce-0060b0fc14a3 */ \
0xe1c61582, \
0x2a84, \
0x11d3, \
{0x8c, 0xce, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
%}

View File

@@ -0,0 +1,47 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* This interface defines a registry entry for the networking libraries
* external module registry. */
#include "nsISupports.idl"
#include "nsINetNotify.idl"
interface nsIEventQueue;
interface nsINetModRegEntry;
interface nsINetNotify;
%{ C++
// {F126BD90-1472-11d3-A15A-0050041CAF44}
#define NS_NETMODREGENTRY_CID \
{ 0xf126bd90, 0x1472, 0x11d3, { 0xa1, 0x5a, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44 } }
%}
[scriptable, uuid(9F482BD0-1476-11d3-A15A-0050041CAF44)]
interface nsINetModRegEntry : nsISupports
{
readonly attribute nsINetNotify syncProxy;
readonly attribute nsINetNotify asyncProxy;
readonly attribute string topic;
boolean equals(in nsINetModRegEntry aEntry);
};

View File

@@ -0,0 +1,80 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* The nsINetModuleMgr singleton service allows external module to register
* themselves with the networking library to receive events they want to
* receive.
*
* An external module that is interested in being notified when a particular
* networking level event occurs would register with this service, and
* implement the appropriate interface(s) that correspond to the events they
* want to receive. These interfaces are defined by networking internal
* components (for example, http would define a notification interface that
* the external cookies module would implement).
*/
#include "nsISupports.idl"
#include "nsIEnumerator.idl"
#include "nsINetNotify.idl"
interface nsIEventQueue;
%{ C++
// {4EBDAFE0-13BA-11d3-A15A-0050041CAF44}
#define NS_NETMODULEMGR_CID \
{ 0x4ebdafe0, 0x13ba, 0x11d3, { 0xa1, 0x5a, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44 } }
// The list of available PROGIDS to register for notification on.
#define NS_NETWORK_MODULE_MANAGER_HTTP_REQUEST_PROGID "component://netscape/network/moduleMgr/http/request"
#define NS_NETWORK_MODULE_MANAGER_HTTP_RESPONSE_PROGID "component://netscape/network/moduleMgr/http/response"
%}
[scriptable, uuid(ff9ead40-0ef2-11d3-9de6-0010a4053fd0)]
interface nsINetModuleMgr : nsISupports {
// Register the external module to receive notifications.
//
// ARGUMENTS:
// aTopic: The internal component that the external module wants to monitor.
// aNotify: The external module interface methods to be called when an event is fired.
//
// RETURNS: nsresult
void registerModule(in string aTopic, in nsINetNotify aNotify);
// Unregister the external module. Removes the nsINetModuleMgr binding between
// internal component and external module.
//
// ARGUMENTS:
// aTopic: The internal component being monitored.
// aNotify: The external modules notification module.
//
// RETURNS: nsresult
void unregisterModule(in string aTopic, in nsINetNotify aNotify);
// Enumerates all the registered modules for the specified topic.
//
// ARGUMENTS:
// aTopic: the component to get all the notifiers for.
// aEnumerator: the array of notifiers.
void enumerateModules(in string aTopic, out nsISimpleEnumerator aEnumerator);
};

View File

@@ -0,0 +1,28 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
[uuid(4A3019E0-1CF3-11d3-A15B-0050041CAF44)]
interface nsINetNotify : nsISupports {
};

View File

@@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
[scriptable, uuid(edd8be01-8e0d-11d3-b7a0-c46e946292bc)]
interface nsINetPrompt : nsISupports
{
/**
* Puts up an alert dialog with an OK button.
*/
void alert( in string url, in boolean stripurl, in wstring title, in wstring text);
/**
* Puts up a dialog with OK and Cancel buttons.
* @return true for OK, false for Cancel
*/
boolean confirm( in string url, in boolean stripurl, in wstring title, in wstring text);
/**
* Puts up a username/password dialog with OK and Cancel buttons.
* @return true for OK, false for Cancel
*/
boolean promptUsernameAndPassword(
in string url,
in boolean stripurl,
in wstring title,
in wstring text,
out wstring user,
out wstring pwd);
/**
* Puts up a password dialog with OK and Cancel buttons.
* @return true for OK, false for Cancel
*/
boolean promptPassword(
in string url,
in boolean stripurl,
in wstring title,
in wstring text,
out wstring pwd);
/**
* Puts up a prompt dialog with OK and Cancel buttons.
* @return true for OK, false for Cancel
*/
boolean prompt(
in string url,
in boolean stripurl,
in wstring title,
in wstring text,
out wstring pwd);
};

View File

@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
interface nsIURI;
interface nsIChannel;
/**
* An instance of nsIFfpEventSink should be passed as the eventSink
* argument of nsINetService::NewConnection for ftp URLs. It defines
* the callbacks to the application program (the html parser).
*/
[scriptable, uuid(dd47ee00-18c2-11d3-9337-00104ba0fd40)]
interface nsIProgressEventSink : nsISupports
{
/**
* Notify the EventSink that progress as occurred for the URL load.<BR>
*/
void onProgress(in nsIChannel channel,
in nsISupports ctxt,
in unsigned long aProgress,
in unsigned long aProgressMax);
/**
* Notify the EventSink with a status message for the URL load.<BR>
*/
void onStatus(in nsIChannel channel,
in nsISupports ctxt,
in wstring aMsg);
};

View File

@@ -0,0 +1,102 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
[scriptable, uuid(a63f70c0-148b-11d3-9333-00104ba0fd40)]
interface nsIPrompt : nsISupports
{
/**
* Puts up an alert dialog with an OK button.
*/
void alert(in wstring text);
/**
* Puts up a dialog with OK and Cancel buttons.
* @return true for OK, false for Cancel
*/
boolean confirm(in wstring text);
/**
* Puts up a dialog with OK and Cancel buttons, and
* a message with a single checkbox.
* @return true for OK, false for Cancel
*/
boolean confirmCheck(in wstring text,
in wstring checkMsg,
out boolean checkValue);
/**
* Puts up a text input dialog with OK and Cancel buttons.
* @return true for OK, false for Cancel
*/
boolean prompt(in wstring text,
in wstring defaultText,
out wstring result);
/**
* Puts up a username/password dialog with OK and Cancel buttons.
* @return true for OK, false for Cancel
*/
boolean promptUsernameAndPassword(in wstring text,
out wstring user,
out wstring pwd);
/**
* Puts up a password dialog with OK and Cancel buttons.
* @return true for OK, false for Cancel
*/
boolean promptPassword(in wstring text,
in wstring title,
out wstring pwd);
/**
* Puts up a dialog box which has a list box of strings
*/
boolean select(in wstring inDialogTitle,
in wstring inMsg,
in PRUint32 inCount,
[array, size_is(inCount)] in wstring inList,
out long outSelection);
/**
* Put up a universal dialog
*/
void universalDialog(in wstring inTitleMessage,
in wstring inDialogTitle, /* e.g., alert, confirm, prompt, prompt password */
in wstring inMsg, /* main message for dialog */
in wstring inCheckboxMsg, /* message for checkbox */
in wstring inButton0Text, /* text for first button */
in wstring inButton1Text, /* text for second button */
in wstring inButton2Text, /* text for third button */
in wstring inButton3Text, /* text for fourth button */
in wstring inEditfield1Msg, /*message for first edit field */
in wstring inEditfield2Msg, /* message for second edit field */
inout wstring inoutEditfield1Value, /* initial and final value for first edit field */
inout wstring inoutEditfield2Value, /* initial and final value for second edit field */
in wstring inIConURL, /* url of icon to be displayed in dialog */
inout boolean inoutCheckboxState, /* initial and final state of checkbox */
in PRInt32 inNumberButtons, /* total number of buttons (0 to 4) */
in PRInt32 inNumberEditfields, /* total number of edit fields (0 to 2) */
in PRInt32 inEditField1Password, /* ??? */
out PRInt32 outButtonPressed); /* number of button that was pressed (0 to 3) */
};

View File

@@ -0,0 +1,67 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIChannel.idl"
interface nsIURI;
interface nsIInterfaceRequestor;
interface nsILoadGroup;
[scriptable, uuid(15fd6940-8ea7-11d3-93ad-00104ba0fd40)]
interface nsIProtocolHandler : nsISupports
{
readonly attribute string scheme;
readonly attribute long defaultPort;
/**
* Makes a URI object that is suitable for loading by this protocol.
* In the usual case (when only the accessors provided by nsIURI are
* needed), this method just constructs a standard URI using the
* component manager with kStandardURLCID.
*/
nsIURI newURI(in string aSpec, in nsIURI aBaseURI);
/**
* Constructs a new channel for this protocol handler.
*
* @param originalURI - Specifies the original URI which caused the creation
* of this channel. This can occur when the construction of one channel
* (e.g. for resource:) causes another channel to be created on its behalf
* (e.g. a file: channel), or if a redirect occurs, causing the current
* URL to become different from the original URL. If NULL, the aURI parameter
* will be used as the originalURI instead.
*/
nsIChannel newChannel(in nsIURI aURI);
};
%{C++
#define NS_NETWORK_PROTOCOL_PROGID "component://netscape/network/protocol"
#define NS_NETWORK_PROTOCOL_PROGID_PREFIX NS_NETWORK_PROTOCOL_PROGID "?name="
#define NS_NETWORK_PROTOCOL_PROGID_PREFIX_LENGTH 43 // nsCRT::strlen(NS_NETWORK_PROTOCOL_PROGID_PREFIX)
// Unknown Protocol Error
#define NS_ERROR_UNKNOWN_PROTOCOL NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 18)
%}

View File

@@ -0,0 +1,40 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIURI.idl"
#include "nsIProxy.idl"
%{C++
#define NS_PROTOCOLPROXYSERVICE_CID \
{ /* E9B301C0-E0E4-11d3-A1A8-0050041CAF44 */ \
0xe9b301c0, 0xe0e4, 0x11d3, { 0xa1, 0xa8, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44 } }
%}
[scriptable, uuid(495CC980-E0D4-11d3-A1A8-0050041CAF44)]
interface nsIProtocolProxyService : nsISupports
{
readonly attribute PRBool proxyEnabled;
void examineForProxy(in nsIURI aURI, in nsIProxy aProxy);
};

View File

@@ -0,0 +1,41 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
The nsIProxy interface allows setting and getting of proxy host and port.
This is for use by protocol handlers. If you are writing a protocol handler
and would like to support proxy behaviour then derive from this as well as
the nsIProtocolHandler class.
-Gagan Saksena 02/25/99
*/
#include "nsISupports.idl"
[scriptable, uuid(0492D011-CD2F-11d2-B013-006097BFC036)]
interface nsIProxy : nsISupports
{
attribute string proxyHost;
/* -1 on Set call indicates switch to default port */
attribute long proxyPort;
};

View File

@@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
[scriptable, uuid(F2CAABA0-2F25-11d3-A164-0050041CAF44)]
interface nsIRequest : nsISupports
{
/**
* Returns true if the request is pending (active). Returns false
* after completion or successful calling Cancel. Suspended requests
* are still considered pending.
*/
boolean isPending();
/**
* Returns any error status associated with the request.
*/
readonly attribute nsresult status;
/**
* Cancels the current request. This will close any open input or
* output streams and terminate any async requests. Users should
* normally pass NS_BINDING_ABORTED, although other errors may also
* be passed. The error passed in will become the value of the
* status attribute.
*/
void cancel(in nsresult status);
/**
* Suspends the current requests. This may have the effect of closing
* any underlying transport (in order to free up resources), although
* any open streams remain logically opened and will continue delivering
* data when the transport is resumed.
*/
void suspend();
/**
* Resumes the current request. This may have the effect of re-opening
* any underlying transport and will resume the delivery of data to
* any open streams.
*/
void resume();
};

View File

@@ -0,0 +1,55 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
[scriptable, uuid(785CA0F0-C39E-11d3-9ED6-0010A4053FD0)]
interface nsISocketTransport : nsISupports
{
attribute boolean reuseConnection;
/**
* socket read/write timeout in seconds; 0 = no timeout
*/
attribute unsigned long socketTimeout;
/**
* socket connect timeout in seconds; 0 = no timeout
*/
attribute unsigned long socketConnectTimeout;
/**
* Is used to tell the channel to stop reading data after a certain point;
* needed by HTTP/1.1
*/
attribute long bytesExpected;
attribute unsigned long reuseCount;
/**
* Checks if the socket is still alive
*
* @param seconds amount of time after which the socket is always deemed to be
* dead (no further checking is done in this case); seconds = 0
* will cause it not to do the timeout checking at all
*/
boolean isAlive (in unsigned long seconds);
};

View File

@@ -0,0 +1,77 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
interface nsIChannel;
interface nsIEventSinkGetter;
[scriptable, uuid(05331390-6884-11d3-9382-00104ba0fd40)]
interface nsISocketTransportService : nsISupports
{
/**
* Creates a transport for a specified host and port.
* The eventSinkGetter is used to get the appropriate callbacks
* for the socket activity from the application. These include
* the progress and the status messages like "Contacting host.."
* etc. The printHost contains the actual hostname (and not the
* proxy) for displaying in status messages.
*/
nsIChannel createTransport(in string host,
in long port,
in string printHost,
in unsigned long bufferSegmentSize,
in unsigned long bufferMaxSize);
nsIChannel createTransportOfType(in string socketType,
in string host,
in long port,
in string printHost,
in unsigned long bufferSegmentSize,
in unsigned long bufferMaxSize);
/**
* Returns true if the specified transport is good enough for
* being used again. The situations in which this may return false
* include- an error including server resets, an explicit
* Connection: close header (for HTTP) and timeouts!
*/
boolean reuseTransport(in nsIChannel i_Transport);
void init();
void shutdown();
void wakeup(in nsIChannel i_Transport);
};
%{C++
#define NS_SOCKETTRANSPORTSERVICE_CID \
{ /* c07e81e0-ef12-11d2-92b6-00105a1b0d64 */ \
0xc07e81e0, \
0xef12, \
0x11d2, \
{0x92, 0xb6, 0x00, 0x10, 0x5a, 0x1b, 0x0d, 0x64} \
}
#define NS_ERROR_CONNECTION_REFUSED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 13)
#define NS_ERROR_NET_TIMEOUT NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 14)
%}

View File

@@ -0,0 +1,48 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
interface nsIProgressEventSink;
interface nsIChannel;
/**
* The nsIStatusCodeEventSink is a temporary interface to allow passing
* status codes from the socket threads onto the UI without having to
* pass strings. This could eventually go away if the proxy events
* stuff can handle nested event loop. dougt is working on that.
* We could continue to use this if this seems reasonable enough.
*/
[scriptable, uuid(6998ff36-1dd2-11b2-9ab7-e72a0f9fdd8c)]
interface nsIStatusCodeEventSink : nsISupports
{
/**
* Notify the EventSink with a status code for the URL load.<BR>
* Use IOService to request converting that code to a string.
*/
void onStatus(in nsIProgressEventSink sink,
in nsIChannel channel,
in nsISupports ctxt,
in unsigned long aCode);
};

View File

@@ -0,0 +1,96 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIStreamObserver.idl"
interface nsIBufferInputStream;
interface nsIInputStream;
interface nsIBufferOutputStream;
interface nsIEventQueue;
[scriptable, uuid(1a637020-1482-11d3-9333-00104ba0fd40)]
interface nsIStreamListener : nsIStreamObserver
{
void onDataAvailable(in nsIChannel channel,
in nsISupports ctxt,
in nsIInputStream inStr,
in unsigned long sourceOffset,
in unsigned long count);
};
/**
* An asynchronous stream listener is used to ship data over to another thread specified
* by the thread's event queue. The receiver stream listener is then used to receive
* the notifications on the other thread.
*
* This interface only provides the initialization needed after construction. Otherwise,
* these objects are used simply as nsIStreamListener.
*/
[scriptable, uuid(1b012ade-91bf-11d3-8cd9-0060b0fc14a3)]
interface nsIAsyncStreamListener : nsIStreamListener
{
/**
* Initializes an nsIAsyncStreamListener.
* @param eventQueue - may be null indicating the calling thread's event queue
*/
void init(in nsIStreamListener receiver,
in nsIEventQueue eventQueue);
};
/**
* A synchronous stream listener pushes data through a pipe that ends up
* in an input stream to be read by another thread.
*
* This interface only provides the initialization needed after construction. Otherwise,
* these objects are used simply as nsIStreamListener.
*/
[scriptable, uuid(1f9fb93e-91bf-11d3-8cd9-0060b0fc14a3)]
interface nsISyncStreamListener : nsIStreamListener
{
/**
* Initializes an nsISyncStreamListener.
*/
void init(out nsIInputStream inStream,
out nsIBufferOutputStream outStream);
};
%{C++
// Use this CID to construct an nsIAsyncStreamListener
#define NS_ASYNCSTREAMLISTENER_CID \
{ /* 60047bb2-91c0-11d3-8cd9-0060b0fc14a3 */ \
0x60047bb2, \
0x91c0, \
0x11d3, \
{0x8c, 0xd9, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
// Use this CID to construct an nsISyncStreamListener
#define NS_SYNCSTREAMLISTENER_CID \
{ /* 65fa5cb2-91c0-11d3-8cd9-0060b0fc14a3 */ \
0x65fa5cb2, \
0x91c0, \
0x11d3, \
{0x8c, 0xd9, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
%}

View File

@@ -0,0 +1,72 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIChannel.idl"
interface nsIURI;
interface nsILoadGroup;
interface nsIStreamObserver;
interface nsIStreamLoader;
interface nsIInterfaceRequestor;
[scriptable, uuid(359F7990-D4E9-11d3-A1A5-0050041CAF44)]
interface nsIStreamLoaderObserver : nsISupports
{
void onStreamComplete(in nsIStreamLoader loader,
in nsISupports ctxt,
in nsresult status,
in unsigned long resultLength,
[size_is(resultLength)] in string result);
};
[scriptable, uuid(31d37360-8e5a-11d3-93ad-00104ba0fd40)]
interface nsIStreamLoader : nsISupports
{
void init(in nsIURI uri,
in nsIStreamLoaderObserver completionObserver,
in nsISupports ctxt,
in nsILoadGroup loadGroup,
in nsIInterfaceRequestor notificationCallbacks,
in nsLoadFlags loadAttributes,
in unsigned long bufferSegmentSize,
in unsigned long bufferMaxSize);
/**
* Gets the number of bytes read so far.
*/
readonly attribute unsigned long numBytesRead;
/**
* Gets the owner of this file
*/
readonly attribute nsISupports owner;
};
%{C++
#define NS_STREAMLOADER_CID \
{ /* 5BA6D920-D4E9-11d3-A1A5-0050041CAF44 */ \
0x5ba6d920, 0xd4e9, 0x11d3, { 0xa1, 0xa5, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44 } \
}
%}

View File

@@ -0,0 +1,78 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
interface nsIEventQueue;
interface nsIChannel;
[scriptable, uuid(fd91e2e0-1481-11d3-9333-00104ba0fd40)]
interface nsIStreamObserver : nsISupports
{
void onStartRequest(in nsIChannel channel,
in nsISupports ctxt);
void onStopRequest(in nsIChannel channel,
in nsISupports ctxt,
in nsresult status,
in wstring errorMsg);
};
/**
* An asynchronous stream observer is used to ship data over to another thread specified
* by the thread's event queue. The receiver stream observer is then used to receive
* the notifications on the other thread.
*
* This interface only provides the initialization needed after construction. Otherwise,
* these objects are used simply as nsIStreamObservers.
*/
[scriptable, uuid(a28dc590-91b3-11d3-8cd9-0060b0fc14a3)]
interface nsIAsyncStreamObserver : nsIStreamObserver
{
/**
* Initializes an nsIAsyncStreamObserver.
* @param eventQueue - may be null indicating the calling thread's event queue
*/
void init(in nsIStreamObserver receiver,
in nsIEventQueue eventQueue);
};
%{C++
// Use this CID to construct an nsIAsyncStreamObserver
#define NS_ASYNCSTREAMOBSERVER_CID \
{ /* fcc7c380-91b3-11d3-8cd9-0060b0fc14a3 */ \
0xfcc7c380, \
0x91b3, \
0x11d3, \
{0x8c, 0xd9, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
////////////////////////////////////////////////////////////////////////////////
// Generic status codes for OnStopRequest:
#define NS_BINDING_SUCCEEDED NS_OK
#define NS_BINDING_FAILED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 1)
#define NS_BINDING_ABORTED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 2)
%}

View File

@@ -0,0 +1,183 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIURLParser.idl"
/**
* URIs are essentially structured names for things -- anything.
* This interface provides accessors to destructure those names.
*
* This interface follows Tim Berners-Lee's URI spec:
*
* http://www.w3.org/Addressing/URI/URI_Overview.html
*
* essentially:
*
* ftp://username:password@hostname:portnumber/pathname
* \ / \ / \ / \ /\ /
* - --------------- ------ -------- -------
* | | | | |
* | | | | Path
* | | | Port
* | | Host
* | PreHost
* Scheme
*
* The subclass nsIURL provides a means to open an input or output
* stream to a URI as a source/destination, as well as providing additional
* accessors to destructure the path, query and reference portions typically
* associated with URLs.
*/
%{C++
#undef GetPort // XXX Windows!
#undef SetPort // XXX Windows!
%}
[scriptable, uuid(07a22cc0-0ce5-11d3-9331-00104ba0fd40)]
interface nsIURI : nsISupports
{
/**
* Returns a string representation of the URI. Setting the spec
* causes the new spec to be parsed, initializing the URI. Setting
* the spec (or any of the accessors) causes also any currently
* open streams on the URI's channel to be closed.
*/
attribute string spec;
/**
* The Scheme is the protocol to which this URI refers. Setting
* the scheme is a special operation that builds up an equivalent
* URI string from the new scheme and all the other URI attributes
* and passes the it to the nsIOService to create a new URI for
* the new scheme.
*/
attribute string scheme;
/**
* The PreHost portion includes elements like the optional
* username:password, or maybe other scheme specific items.
*/
attribute string preHost;
attribute string username;
attribute string password;
/**
* The Host is the internet domain name to which this URI refers.
* Note that it could be an IP address as well.
*/
attribute string host;
/**
* A return value of -1 indicates that no port value is set and the
* implementor of the specific scheme will use its default port.
* Similarly setting a value of -1 indicates that the default is to be used.
* Thus as an example:
* for HTTP, Port 80 is same as a return value of -1.
* However after setting a port (even if its default), the port number will
* appear in the ToNewCString function.
*/
attribute long port;
/**
* Note that the path includes the leading '/' Thus if no path is
* available the Path accessor will return a "/"
* For SetPath if none is provided, one would be prefixed to the path.
*/
attribute string path;
/**
* This is a handle to the Parser used to parse the URI
*/
attribute nsIURLParser URLParser;
/**
* Note that this comparison is only on char* level. Use
* the scheme specific URI to do a more thorough check. For example,
* in HTTP:
* http://foo.com:80 == http://foo.com
* but this function through nsIURI alone will not return equality
* for this case.
*/
boolean equals(in nsIURI other);
/**
* Clones the current URI. The newly created URI will be in a closed
* state even if the underlying channel of the cloned URI is open.
* Cloning allows the current location to be retained since once the
* channel is opened the URI may get redirected to a new location.
*/
nsIURI clone();
/**
* Sets the given string to be a relative path for this URI, and
* changes this to read relative. Thus for example- if this =
* http://foo.com/bar/index.html, then calling SetRelativePath("/baz") will
* change this to http://foo.com/baz and calling it with "baz" will
* change this to http://foo.com/bar/baz.
*/
void setRelativePath(in string relativePath);
/**
* This method resolves a relative string into an absolute URI string,
* using the URI as the base.
*
* This method subsumes the deprecated method nsIIOService::MakeAbsolute.
*/
string resolve(in string relativePath);
};
%{C++
// Malformed URI Error
#define NS_ERROR_MALFORMED_URI NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 10)
/**
* Protocol writers can obtain a very basic (ok, degenerate) implementation
* of nsIURI by calling the component manager with NS_SIMPLEURI_CID. The
* implementation returned will only parse things of the form:
*
* about:cache
* \ / \ /
* --- ---
* | |
* Scheme Path
*
* where the path is everything after the colon. Note that this is probably
* only useful for cases like about: or javascript: URIs.
*
* *** What you most likely will want is NS_STANDARDURL_CID which is much more
* full featured. Look at nsIURL.idl for more details.
*/
#define NS_SIMPLEURI_CID \
{ /* e0da1d70-2f7b-11d3-8cd0-0060b0fc14a3 */ \
0xe0da1d70, \
0x2f7b, \
0x11d3, \
{0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
%}

View File

@@ -0,0 +1,149 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIURI.idl"
interface nsIChannel;
interface nsIEventSinkGetter;
/**
* The nsIURL interface provides convenience methods that further
* break down the path portion of nsIURI:
*
* http://directory/fileBaseName.fileExtension?query
* http://directory/fileBaseName.fileExtension#ref
* http://directory/fileBaseName.fileExtension;param
* \ \ /
* \ -----------------------
* \ | /
* \ fileName /
* ----------------------------
* |
* filePath
*/
[scriptable, uuid(d6116970-8034-11d3-9399-00104ba0fd40)]
interface nsIURL : nsIURI
{
////////////////////////////////////////////////////////////////////////////
// The path attribute is broken down into the following attributes:
// filePath, param, query, and ref:
/**
* Returns a path including the directory and file portions of a
* URL. E.g. The filePath of "http://foo/bar.html#baz" is
* "/foo/bar.html".
*/
attribute string filePath;
/**
* Returns the parameters specified after the ; in the URL.
*
*/
attribute string param;
/**
* Returns the query portion (the part after the "?") of the URL.
* If there isn't one, an empty string is returned.
*/
attribute string query;
/**
* Returns the reference portion (the part after the "#") of the URL.
* If there isn't one, an empty string is returned.
*/
attribute string ref;
////////////////////////////////////////////////////////////////////////////
// The filePath attribute is further broken down into the following
// attributes: directory, file:
/**
* Returns the directory portion of a URL.
* If the URL denotes a path to a directory and not a file,
* e.g. http://foo/bar/, then the Directory attribute accesses
* the complete /foo/bar/ portion, and the FileName is the
* empty string. If the trailing slash is omitted, then the
* Directory is /foo/ and the file is bar (i.e. this is a
* syntactic, not a semantic breakdown of the Path).
* And hence dont rely on this for something to be a definitely
* be a file. But you can get just the leading directory portion
* for sure.
*/
attribute string directory;
/**
* Returns the file name portion of a URL.
* If the URL denotes a path to a directory and not a file,
* e.g. http://foo/bar/, then the Directory attribute accesses
* the complete /foo/bar/ portion, and the FileName is the
* empty string. Note that this is purely based on searching
* for the last trailing slash. And hence dont rely on this to
* be a definite file.
*/
attribute string fileName;
////////////////////////////////////////////////////////////////////////////
// The fileName attribute is further broken down into the following
// attributes: fileName, fileExtension:
attribute string fileBaseName;
/**
* Returns the file extension portion of a filename in a url.
* If a file extension does not exist, the empty string is returned.
*/
attribute string fileExtension;
};
%{C++
/**
* Protocol writers can obtain a default nsIURL implementation by calling the
* component manager with NS_STANDARDURL_CID. The implementation returned will
* only implement the set of accessors specified by nsIURL. After obtaining the
* instance from the component manager, the Init routine must be called on it
* to initialize it from the user's URL spec.
*/
#define NS_STANDARDURL_CID \
{ /* de9472d0-8034-11d3-9399-00104ba0fd40 */ \
0xde9472d0, \
0x8034, \
0x11d3, \
{0x93, 0x99, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
}
%}
////////////////////////////////////////////////////////////////////////////////
interface nsIFile;
/**
* nsIFileURL is used for the file: protocol, and gives access to the
* underlying nsIFile object.
*/
[scriptable, uuid(d26b2e2e-1dd1-11b2-88f3-8545a7ba7949)]
interface nsIFileURL : nsIURL
{
attribute nsIFile file;
};

View File

@@ -0,0 +1,125 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Andreas Otte
*
* Contributor(s):
*/
#include "nsISupports.idl"
/**
* nsIURLParser is the abstract base class for parsing URLs
*/
[scriptable, uuid(4b4975f9-f128-47fd-b11e-88402233cbdf)]
interface nsIURLParser : nsISupports
{
/**
* Parses a URL and thinks it is parsing the scheme
*/
void ParseAtScheme(in string i_Spec,
out string o_Scheme,
out string o_Username,
out string o_Password,
out string o_Host,
out long o_Port,
out string o_Path);
/**
* Parses a URL and thinks it is parsing the prehost
*/
void ParseAtPreHost(in string i_Spec,
out string o_Username,
out string o_Password,
out string o_Host,
out long o_Port,
out string o_Path);
/**
* Parses a URL and thinks it is parsing the host
*/
void ParseAtHost(in string i_Spec,
out string o_Host,
out long o_Port,
out string o_Path);
/**
* Parses a URL and thinks it is parsing the port
*/
void ParseAtPort(in string i_Spec,
out long o_Port,
out string o_Path);
/**
* Parses a URL and thinks it is parsing the path
*/
void ParseAtPath(in string i_Spec,
out string o_Path);
/**
* Parses a URL-path and thinks it is parsing the directory
*/
void ParseAtDirectory(in string i_Path,
out string o_Directory,
out string o_FileBaseName,
out string o_FileExtension,
out string o_Param,
out string o_Query,
out string o_Ref);
/**
* Parses the URL-PreHost into its components
*/
void ParsePreHost(in string i_PreHost,
out string o_Username,
out string o_Password);
/**
* Parses the URL-Filename into its components
*/
void ParseFileName(in string i_FileName,
out string o_FileBaseName,
out string o_FileExtension);
};
%{C++
#define NS_STANDARDURLPARSER_CID \
{ /* dbf72351-4fd8-46f0-9dbc-fa5ba60a30c5 */ \
0xdbf72351, \
0x4fd8, \
0x46f0, \
{0x9d, 0xbc, 0xfa, 0x5b, 0xa6, 0x0a, 0x30, 0x5c} \
}
#define NS_AUTHORITYURLPARSER_CID \
{ /* 90012125-1616-4fa1-ae14-4e7fa5766eb6 */ \
0x90012125, \
0x1616, \
0x4fa1, \
{0xae, 0x14, 0x4e, 0x7f, 0xa5, 0x76, 0x6e, 0xb6} \
}
#define NS_NOAUTHORITYURLPARSER_CID \
{ /* 9eeb1b89-c87e-4404-9de6-dbd41aeaf3d7 */ \
0x9eeb1b89, \
0xc87e, \
0x4404, \
{0x9d, 0xe6, 0xdb, 0xd4, 0x1a, 0xea, 0xf3, 0xd7} \
}
%}

View File

@@ -0,0 +1,409 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsNetUtil_h__
#define nsNetUtil_h__
#include "nsIURI.h"
#include "netCore.h"
#include "nsIInputStream.h"
#include "nsIStreamListener.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsString.h"
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsIChannel.h"
#include "nsIAllocator.h"
#include "nsCOMPtr.h"
#include "nsIHTTPProtocolHandler.h"
#include "nsIStreamLoader.h"
#include "prio.h" // for read/write flags, permissions, etc.
inline nsresult
NS_NewURI(nsIURI* *result,
const char* spec,
nsIURI* baseURI = nsnull,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
{
nsresult rv;
nsIIOService* serv = ioService;
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
if (serv == nsnull) {
rv = nsServiceManager::GetService(kIOServiceCID, NS_GET_IID(nsIIOService),
(nsISupports**)&serv);
if (NS_FAILED(rv)) return rv;
}
rv = serv->NewURI(spec, baseURI, result);
if (ioService == nsnull) {
(void)nsServiceManager::ReleaseService(kIOServiceCID, serv);
}
return rv;
}
inline nsresult
NS_NewURI(nsIURI* *result,
const nsString& spec,
nsIURI* baseURI = nsnull,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
{
char* specStr = spec.ToNewUTF8String(); // this forces a single byte char*
if (specStr == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = NS_NewURI(result, specStr, baseURI, ioService);
nsAllocator::Free(specStr);
return rv;
}
inline nsresult
NS_OpenURI(nsIChannel* *result,
nsIURI* uri,
nsIIOService* ioService = nsnull, // pass in nsIIOService to optimize callers
nsILoadGroup* loadGroup = nsnull,
nsIInterfaceRequestor* notificationCallbacks = nsnull,
nsLoadFlags loadAttributes = nsIChannel::LOAD_NORMAL,
PRUint32 bufferSegmentSize = 0,
PRUint32 bufferMaxSize = 0)
{
nsresult rv;
nsIIOService* serv = ioService;
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
if (serv == nsnull) {
rv = nsServiceManager::GetService(kIOServiceCID, NS_GET_IID(nsIIOService),
(nsISupports**)&serv);
if (NS_FAILED(rv)) return rv;
}
nsIChannel* channel = nsnull;
rv = serv->NewChannelFromURI(uri, &channel);
if (NS_FAILED(rv)) return rv;
if (loadGroup) {
rv = channel->SetLoadGroup(loadGroup);
if (NS_FAILED(rv)) return rv;
}
if (notificationCallbacks) {
rv = channel->SetNotificationCallbacks(notificationCallbacks);
if (NS_FAILED(rv)) return rv;
}
if (loadAttributes != nsIChannel::LOAD_NORMAL) {
rv = channel->SetLoadAttributes(loadAttributes);
if (NS_FAILED(rv)) return rv;
}
if (bufferSegmentSize != 0) {
rv = channel->SetBufferSegmentSize(bufferSegmentSize);
if (NS_FAILED(rv)) return rv;
}
if (bufferMaxSize != 0) {
rv = channel->SetBufferMaxSize(bufferMaxSize);
if (NS_FAILED(rv)) return rv;
}
if (ioService == nsnull) {
(void)nsServiceManager::ReleaseService(kIOServiceCID, serv);
}
*result = channel;
return rv;
}
// Use this function with CAUTION. And do not use it on
// the UI thread. It creates a stream that blocks when
// you Read() from it and blocking the UI thread is
// illegal. If you don't want to implement a full
// blown asyncrhonous consumer (via nsIStreamListener)
// look at nsIStreamLoader instead.
inline nsresult
NS_OpenURI(nsIInputStream* *result,
nsIURI* uri,
nsIIOService* ioService = nsnull, // pass in nsIIOService to optimize callers
nsILoadGroup* loadGroup = nsnull,
nsIInterfaceRequestor* notificationCallbacks = nsnull,
nsLoadFlags loadAttributes = nsIChannel::LOAD_NORMAL,
PRUint32 bufferSegmentSize = 0,
PRUint32 bufferMaxSize = 0)
{
nsresult rv;
nsCOMPtr<nsIChannel> channel;
rv = NS_OpenURI(getter_AddRefs(channel), uri, ioService,
loadGroup, notificationCallbacks, loadAttributes,
bufferSegmentSize, bufferMaxSize);
if (NS_FAILED(rv)) return rv;
nsIInputStream* inStr;
rv = channel->OpenInputStream(&inStr);
if (NS_FAILED(rv)) return rv;
*result = inStr;
return rv;
}
inline nsresult
NS_OpenURI(nsIStreamListener* aConsumer,
nsISupports* context,
nsIURI* uri,
nsIIOService* ioService = nsnull, // pass in nsIIOService to optimize callers
nsILoadGroup* loadGroup = nsnull,
nsIInterfaceRequestor* notificationCallbacks = nsnull,
nsLoadFlags loadAttributes = nsIChannel::LOAD_NORMAL,
PRUint32 bufferSegmentSize = 0,
PRUint32 bufferMaxSize = 0)
{
nsresult rv;
nsCOMPtr<nsIChannel> channel;
rv = NS_OpenURI(getter_AddRefs(channel), uri, ioService,
loadGroup, notificationCallbacks, loadAttributes,
bufferSegmentSize, bufferMaxSize);
if (NS_FAILED(rv)) return rv;
rv = channel->AsyncRead(aConsumer, context);
return rv;
}
inline nsresult
NS_MakeAbsoluteURI(char* *result,
const char* spec,
nsIURI* baseURI = nsnull,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
{
nsresult rv;
NS_ASSERTION(baseURI, "It doesn't make sense to not supply a base URI");
if (spec == nsnull)
return baseURI->GetSpec(result);
nsIIOService* serv = ioService;
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
if (serv == nsnull) {
rv = nsServiceManager::GetService(kIOServiceCID, NS_GET_IID(nsIIOService),
(nsISupports**)&serv);
if (NS_FAILED(rv)) return rv;
}
PRUint32 startPos, endPos;
rv = serv->ExtractScheme(spec, &startPos, &endPos, nsnull);
if (NS_SUCCEEDED(rv)) {
// if spec has a scheme, then it's already absolute
*result = nsCRT::strdup(spec);
rv = (*result == nsnull) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}
else {
rv = baseURI->Resolve(spec, result);
}
if (ioService == nsnull) {
(void)nsServiceManager::ReleaseService(kIOServiceCID, serv);
}
return rv;
}
inline nsresult
NS_MakeAbsoluteURI(nsString& result,
const nsString& spec,
nsIURI* baseURI = nsnull,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
{
char* resultStr;
char* specStr = spec.ToNewUTF8String();
if (!specStr) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult rv = NS_MakeAbsoluteURI(&resultStr, specStr, baseURI, ioService);
nsAllocator::Free(specStr);
if (NS_FAILED(rv)) return rv;
result.AssignWithConversion(resultStr);
nsAllocator::Free(resultStr);
return rv;
}
inline nsresult
NS_NewPostDataStream(nsIInputStream **result,
PRBool isFile,
const char *data,
PRUint32 encodeFlags,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
{
nsresult rv;
nsIIOService* serv = ioService;
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
if (serv == nsnull) {
rv = nsServiceManager::GetService(kIOServiceCID, NS_GET_IID(nsIIOService),
(nsISupports**)&serv);
if (NS_FAILED(rv)) return rv;
}
nsCOMPtr<nsIProtocolHandler> handler;
rv = serv->GetProtocolHandler("http", getter_AddRefs(handler));
if (ioService == nsnull) {
(void)nsServiceManager::ReleaseService(kIOServiceCID, serv);
}
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIHTTPProtocolHandler> http = do_QueryInterface(handler, &rv);
if (NS_FAILED(rv)) return rv;
return http->NewPostDataStream(isFile, data, encodeFlags, result);
}
inline nsresult
NS_NewInputStreamChannel(nsIChannel **result,
nsIURI* uri,
nsIInputStream* inStr,
const char* contentType,
PRInt32 contentLength)
{
nsresult rv;
nsCOMPtr<nsIInputStreamChannel> channel;
static NS_DEFINE_CID(kInputStreamChannelCID, NS_INPUTSTREAMCHANNEL_CID);
rv = nsComponentManager::CreateInstance(kInputStreamChannelCID,
nsnull,
NS_GET_IID(nsIInputStreamChannel),
getter_AddRefs(channel));
if (NS_FAILED(rv)) return rv;
rv = channel->Init(uri, inStr, contentType, contentLength);
if (NS_FAILED(rv)) return rv;
*result = channel;
NS_ADDREF(*result);
return NS_OK;
}
inline nsresult
NS_NewLoadGroup(nsILoadGroup* *result, nsIStreamObserver* obs)
{
nsresult rv;
nsCOMPtr<nsILoadGroup> group;
static NS_DEFINE_CID(kLoadGroupCID, NS_LOADGROUP_CID);
rv = nsComponentManager::CreateInstance(kLoadGroupCID, nsnull,
NS_GET_IID(nsILoadGroup),
getter_AddRefs(group));
if (NS_FAILED(rv)) return rv;
rv = group->Init(obs);
if (NS_FAILED(rv)) return rv;
*result = group;
NS_ADDREF(*result);
return NS_OK;
}
inline nsresult
NS_NewStreamLoader(nsIStreamLoader* *result,
nsIURI* uri,
nsIStreamLoaderObserver* observer,
nsISupports* context = nsnull,
nsILoadGroup* loadGroup = nsnull,
nsIInterfaceRequestor* notificationCallbacks = nsnull,
nsLoadFlags loadAttributes = nsIChannel::LOAD_NORMAL,
PRUint32 bufferSegmentSize = 0,
PRUint32 bufferMaxSize = 0)
{
nsresult rv;
nsCOMPtr<nsIStreamLoader> loader;
static NS_DEFINE_CID(kStreamLoaderCID, NS_STREAMLOADER_CID);
rv = nsComponentManager::CreateInstance(kStreamLoaderCID,
nsnull,
NS_GET_IID(nsIStreamLoader),
getter_AddRefs(loader));
if (NS_FAILED(rv)) return rv;
rv = loader->Init(uri, observer, context, loadGroup, notificationCallbacks, loadAttributes,
bufferSegmentSize, bufferMaxSize);
if (NS_FAILED(rv)) return rv;
*result = loader;
NS_ADDREF(*result);
return rv;
}
inline nsresult
NS_NewAsyncStreamObserver(nsIStreamObserver **result,
nsIStreamObserver *receiver,
nsIEventQueue *eventQueue)
{
nsresult rv;
nsCOMPtr<nsIAsyncStreamObserver> obs;
static NS_DEFINE_CID(kAsyncStreamObserverCID, NS_ASYNCSTREAMOBSERVER_CID);
rv = nsComponentManager::CreateInstance(kAsyncStreamObserverCID,
nsnull,
NS_GET_IID(nsIAsyncStreamObserver),
getter_AddRefs(obs));
if (NS_FAILED(rv)) return rv;
rv = obs->Init(receiver, eventQueue);
if (NS_FAILED(rv)) return rv;
*result = obs;
NS_ADDREF(*result);
return NS_OK;
}
inline nsresult
NS_NewAsyncStreamListener(nsIStreamListener **result,
nsIStreamListener *receiver,
nsIEventQueue *eventQueue)
{
nsresult rv;
nsCOMPtr<nsIAsyncStreamListener> lsnr;
static NS_DEFINE_CID(kAsyncStreamListenerCID, NS_ASYNCSTREAMLISTENER_CID);
rv = nsComponentManager::CreateInstance(kAsyncStreamListenerCID,
nsnull,
NS_GET_IID(nsIAsyncStreamListener),
getter_AddRefs(lsnr));
if (NS_FAILED(rv)) return rv;
rv = lsnr->Init(receiver, eventQueue);
if (NS_FAILED(rv)) return rv;
*result = lsnr;
NS_ADDREF(*result);
return NS_OK;
}
inline nsresult
NS_NewSyncStreamListener(nsIInputStream **inStream,
nsIBufferOutputStream **outStream,
nsIStreamListener **listener)
{
nsresult rv;
nsCOMPtr<nsISyncStreamListener> lsnr;
static NS_DEFINE_CID(kSyncStreamListenerCID, NS_SYNCSTREAMLISTENER_CID);
rv = nsComponentManager::CreateInstance(kSyncStreamListenerCID,
nsnull,
NS_GET_IID(nsISyncStreamListener),
getter_AddRefs(lsnr));
if (NS_FAILED(rv)) return rv;
rv = lsnr->Init(inStream, outStream);
if (NS_FAILED(rv)) return rv;
*listener = lsnr;
NS_ADDREF(*listener);
return NS_OK;
}
#endif // nsNetUtil_h__

View File

@@ -0,0 +1,100 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef _nsUnixColorPrintf_h_
#define _nsUnixColorPrintf_h_
#if defined(XP_UNIX) && defined(NS_DEBUG)
#define STARTGRAY "\033[1;30m"
#define STARTRED "\033[1;31m"
#define STARTGREEN "\033[1;32m"
#define STARTYELLOW "\033[1;33m"
#define STARTBLUE "\033[1;34m"
#define STARTMAGENTA "\033[1;35m"
#define STARTCYAN "\033[1;36m"
#define STARTUNDERLINE "\033[4m"
#define STARTREVERSE "\033[7m"
#define ENDCOLOR "\033[0m"
#define PRINTF_GRAY nsUnixColorPrintf __color_printf(STARTGREY)
#define PRINTF_RED nsUnixColorPrintf __color_printf(STARTRED)
#define PRINTF_GREEN nsUnixColorPrintf __color_printf(STARTGREEN)
#define PRINTF_YELLOW nsUnixColorPrintf __color_printf(STARTYELLOW)
#define PRINTF_BLUE nsUnixColorPrintf __color_printf(STARTBLUE)
#define PRINTF_MAGENTA nsUnixColorPrintf __color_printf(STARTMAGENTA)
#define PRINTF_CYAN nsUnixColorPrintf __color_printf(STARTCYAN)
#define PRINTF_UNDERLINE nsUnixColorPrintf __color_printf(STARTUNDERLINE)
#define PRINTF_REVERSE nsUnixColorPrintf __color_printf(STARTREVERSE)
/*
The nsUnixColorPrintf is a handy set of color term codes to change
the color of console texts for easier spotting. As of now this is
Unix and Debug only.
Usage is simple.
See examples in
mozilla/netwerk/protocol/http/src/nsHTTPHandler.cpp
-Gagan Saksena 11/01/99
*/
class nsUnixColorPrintf
{
public:
nsUnixColorPrintf(const char* colorCode)
{
printf("%s",colorCode);
}
~nsUnixColorPrintf()
{
printf("%s",ENDCOLOR);
}
};
#else // XP_UNIX
#define STARTGRAY ""
#define STARTRED ""
#define STARTGREEN ""
#define STARTYELLOW ""
#define STARTBLUE ""
#define STARTMAGENTA ""
#define STARTCYAN ""
#define STARTUNDERLINE ""
#define STARTREVERSE ""
#define ENDCOLOR ""
#define PRINTF_GRAY
#define PRINTF_RED
#define PRINTF_GREEN
#define PRINTF_YELLOW
#define PRINTF_BLUE
#define PRINTF_MAGENTA
#define PRINTF_CYAN
#define PRINTF_UNDERLINE
#define PRINTF_REVERSE
#endif // XP_UNIX
#endif // nsUnixColorPrintf

View File

@@ -0,0 +1,63 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = necko
LIBRARY_NAME = neckobase_s
CPPSRCS = \
nsURLHelper.cpp \
nsFileStreams.cpp \
nsBufferedStreams.cpp \
nsAsyncStreamListener.cpp \
nsSyncStreamListener.cpp \
nsIOService.cpp \
nsSocketTransport.cpp \
nsSocketTransportService.cpp \
nsFileTransport.cpp \
nsFileTransportService.cpp \
nsStdURLParser.cpp \
nsAuthURLParser.cpp \
nsNoAuthURLParser.cpp \
nsStdURL.cpp \
nsSimpleURI.cpp \
nsNetModuleMgr.cpp \
nsNetModRegEntry.cpp \
nsLoadGroup.cpp \
nsInputStreamChannel.cpp \
nsDirectoryIndexStream.cpp \
nsStreamLoader.cpp \
nsProtocolProxyService.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a
# static lib.
override NO_SHARED_LIB=1
override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,64 @@
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
MODULE = necko
DEPTH = ..\..\..
include <$(DEPTH)/config/config.mak>
LCFLAGS = -DWIN32_LEAN_AND_MEAN -D_IMPL_NS_NET
LIBRARY_NAME=neckobase_s
CPP_OBJS = \
.\$(OBJDIR)\nsURLHelper.obj \
.\$(OBJDIR)\nsFileStreams.obj \
.\$(OBJDIR)\nsBufferedStreams.obj \
.\$(OBJDIR)\nsAsyncStreamListener.obj \
.\$(OBJDIR)\nsSyncStreamListener.obj \
.\$(OBJDIR)\nsIOService.obj \
.\$(OBJDIR)\nsSocketTransport.obj \
.\$(OBJDIR)\nsSocketTransportService.obj \
.\$(OBJDIR)\nsFileTransport.obj \
.\$(OBJDIR)\nsFileTransportService.obj \
.\$(OBJDIR)\nsStdURLParser.obj \
.\$(OBJDIR)\nsAuthURLParser.obj \
.\$(OBJDIR)\nsNoAuthURLParser.obj \
.\$(OBJDIR)\nsStdURL.obj \
.\$(OBJDIR)\nsSimpleURI.obj \
.\$(OBJDIR)\nsNetModuleMgr.obj \
.\$(OBJDIR)\nsNetModRegEntry.obj \
.\$(OBJDIR)\nsLoadGroup.obj \
.\$(OBJDIR)\nsInputStreamChannel.obj \
.\$(OBJDIR)\nsDirectoryIndexStream.obj \
.\$(OBJDIR)\nsStreamLoader.obj \
.\$(OBJDIR)\nsProtocolProxyService.obj \
$(NULL)
INCS = $(INCS) \
-I$(DEPTH)\dist\include \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -0,0 +1,476 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsAsyncStreamListener.h"
#include "nsIBufferInputStream.h"
#include "nsString.h"
#include "nsCRT.h"
#include "nsIEventQueueService.h"
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsIChannel.h"
#include "prlog.h"
static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
#if defined(PR_LOGGING)
PRLogModuleInfo* gStreamEventLog = 0;
#endif
////////////////////////////////////////////////////////////////////////////////
class nsStreamListenerEvent
{
public:
nsStreamListenerEvent(nsAsyncStreamObserver* listener,
nsIChannel* channel, nsISupports* context);
virtual ~nsStreamListenerEvent();
nsresult Fire(nsIEventQueue* aEventQ);
NS_IMETHOD HandleEvent() = 0;
protected:
static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent);
static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent);
nsAsyncStreamObserver* mListener;
nsIChannel* mChannel;
nsISupports* mContext;
PLEvent * mEvent;
};
////////////////////////////////////////////////////////////////////////////////
nsStreamListenerEvent::nsStreamListenerEvent(nsAsyncStreamObserver* listener,
nsIChannel* channel, nsISupports* context)
: mListener(listener), mChannel(channel), mContext(context), mEvent(nsnull)
{
MOZ_COUNT_CTOR(nsStreamListenerEvent);
NS_IF_ADDREF(mListener);
NS_IF_ADDREF(mChannel);
NS_IF_ADDREF(mContext);
}
nsStreamListenerEvent::~nsStreamListenerEvent()
{
MOZ_COUNT_DTOR(nsStreamListenerEvent);
NS_IF_RELEASE(mListener);
NS_IF_RELEASE(mChannel);
NS_IF_RELEASE(mContext);
if (nsnull != mEvent)
{
delete mEvent;
mEvent = nsnull;
}
}
void PR_CALLBACK nsStreamListenerEvent::HandlePLEvent(PLEvent* aEvent)
{
nsStreamListenerEvent * ev =
(nsStreamListenerEvent *) PL_GetEventOwner(aEvent);
NS_ASSERTION(nsnull != ev,"null event.");
nsresult rv = ev->HandleEvent();
//
// If the consumer fails, then cancel the transport. This is necessary
// in case where the socket transport is blocked waiting for room in the
// pipe, but the consumer fails without consuming all the data.
//
// Unless the transport is cancelled, it will block forever, waiting for
// the pipe to empty...
//
if (NS_FAILED(rv)) {
nsresult cancelRv = ev->mChannel->Cancel(rv);
NS_ASSERTION(NS_SUCCEEDED(cancelRv), "Cancel failed");
}
}
void PR_CALLBACK nsStreamListenerEvent::DestroyPLEvent(PLEvent* aEvent)
{
nsStreamListenerEvent * ev =
(nsStreamListenerEvent *) PL_GetEventOwner(aEvent);
NS_ASSERTION(nsnull != ev,"null event.");
delete ev;
}
nsresult
nsStreamListenerEvent::Fire(nsIEventQueue* aEventQueue)
{
NS_PRECONDITION(nsnull != aEventQueue, "nsIEventQueue for thread is null");
NS_PRECONDITION(nsnull == mEvent, "Init plevent only once.");
mEvent = new PLEvent;
PL_InitEvent(mEvent,
this,
(PLHandleEventProc) nsStreamListenerEvent::HandlePLEvent,
(PLDestroyEventProc) nsStreamListenerEvent::DestroyPLEvent);
PRStatus status = aEventQueue->PostEvent(mEvent);
return status == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE;
}
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_THREADSAFE_ISUPPORTS2(nsAsyncStreamObserver,
nsIAsyncStreamObserver,
nsIStreamObserver)
NS_IMPL_ADDREF_INHERITED(nsAsyncStreamListener, nsAsyncStreamObserver);
NS_IMPL_RELEASE_INHERITED(nsAsyncStreamListener, nsAsyncStreamObserver);
NS_IMETHODIMP
nsAsyncStreamListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (!aInstancePtr) return NS_ERROR_NULL_POINTER;
if (aIID.Equals(NS_GET_IID(nsIAsyncStreamListener))) {
*aInstancePtr = NS_STATIC_CAST(nsIAsyncStreamListener*, this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsIStreamListener))) {
*aInstancePtr = NS_STATIC_CAST(nsIStreamListener*, this);
NS_ADDREF_THIS();
return NS_OK;
}
return nsAsyncStreamObserver::QueryInterface(aIID, aInstancePtr);
}
NS_IMETHODIMP
nsAsyncStreamObserver::Init(nsIStreamObserver* aObserver, nsIEventQueue* aEventQ)
{
nsresult rv = NS_OK;
mReceiver = aObserver;
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueService, &rv);
if (NS_FAILED(rv))
return rv;
rv = eventQService->ResolveEventQueue(aEventQ, getter_AddRefs(mEventQueue));
return rv;
}
////////////////////////////////////////////////////////////////////////////////
//
// OnStartRequest...
//
////////////////////////////////////////////////////////////////////////////////
class nsOnStartRequestEvent : public nsStreamListenerEvent
{
public:
nsOnStartRequestEvent(nsAsyncStreamObserver* listener,
nsIChannel* channel, nsISupports* context)
: nsStreamListenerEvent(listener, channel, context) {}
virtual ~nsOnStartRequestEvent() {}
NS_IMETHOD HandleEvent();
};
NS_IMETHODIMP
nsOnStartRequestEvent::HandleEvent()
{
#if defined(PR_LOGGING)
if (!gStreamEventLog)
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
("netlibEvent: Handle Start [event=%x]", this));
#endif
nsIStreamObserver* receiver = (nsIStreamObserver*)mListener->GetReceiver();
nsresult status;
nsresult rv = mChannel->GetStatus(&status);
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
rv = receiver->OnStartRequest(mChannel, mContext);
}
else {
NS_WARNING("not calling OnStartRequest");
}
return rv;
}
NS_IMETHODIMP
nsAsyncStreamObserver::OnStartRequest(nsIChannel* channel, nsISupports* context)
{
nsresult rv;
nsOnStartRequestEvent* event =
new nsOnStartRequestEvent(this, channel, context);
if (event == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
#if defined(PR_LOGGING)
PLEventQueue *equeue;
mEventQueue->GetPLEventQueue(&equeue);
char ts[80];
sprintf(ts, "nsAsyncStreamObserver: Start [this=%lx queue=%lx",
(long)this, (long)equeue);
if (!gStreamEventLog)
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
("nsAsyncStreamObserver: Start [this=%x queue=%x event=%x]",
this, equeue, event));
#endif
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) goto failed;
return rv;
failed:
delete event;
return rv;
}
////////////////////////////////////////////////////////////////////////////////
//
// OnStopRequest
//
////////////////////////////////////////////////////////////////////////////////
class nsOnStopRequestEvent : public nsStreamListenerEvent
{
public:
nsOnStopRequestEvent(nsAsyncStreamObserver* listener,
nsISupports* context, nsIChannel* channel)
: nsStreamListenerEvent(listener, channel, context),
mStatus(NS_OK), mMessage(nsnull) {}
virtual ~nsOnStopRequestEvent();
nsresult Init(nsresult status, const PRUnichar* aMsg);
NS_IMETHOD HandleEvent();
protected:
nsresult mStatus;
PRUnichar* mMessage;
};
nsOnStopRequestEvent::~nsOnStopRequestEvent()
{
}
nsresult
nsOnStopRequestEvent::Init(nsresult status, const PRUnichar* aMsg)
{
mStatus = status;
mMessage = (PRUnichar*)aMsg;
return NS_OK;
}
NS_IMETHODIMP
nsOnStopRequestEvent::HandleEvent()
{
#if defined(PR_LOGGING)
if (!gStreamEventLog)
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
("netlibEvent: Handle Stop [event=%x]", this));
#endif
nsIStreamObserver* receiver = (nsIStreamObserver*)mListener->GetReceiver();
nsresult status = NS_OK;
nsresult rv = mChannel->GetStatus(&status);
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
//
// If the consumer returned a failure code, then pass it out in the
// OnStopRequest(...) notification...
//
if (NS_SUCCEEDED(rv) && NS_FAILED(status)) {
mStatus = status;
}
return receiver->OnStopRequest(mChannel, mContext, mStatus, mMessage);
}
NS_IMETHODIMP
nsAsyncStreamObserver::OnStopRequest(nsIChannel* channel, nsISupports* context,
nsresult aStatus,
const PRUnichar* aMsg)
{
nsresult rv;
//
// Fire the OnStopRequest(...) regardless of what the current
// Status is...
//
nsOnStopRequestEvent* event =
new nsOnStopRequestEvent(this, context, channel);
if (event == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
rv = event->Init(aStatus, aMsg);
if (NS_FAILED(rv)) goto failed;
#if defined(PR_LOGGING)
PLEventQueue *equeue;
mEventQueue->GetPLEventQueue(&equeue);
if (!gStreamEventLog)
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
("nsAsyncStreamObserver: Stop [this=%x queue=%x event=%x]",
this, equeue, event));
#endif
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) goto failed;
return rv;
failed:
delete event;
return rv;
}
////////////////////////////////////////////////////////////////////////////////
//
// OnDataAvailable
//
////////////////////////////////////////////////////////////////////////////////
class nsOnDataAvailableEvent : public nsStreamListenerEvent
{
public:
nsOnDataAvailableEvent(nsAsyncStreamObserver* listener,
nsIChannel* channel, nsISupports* context)
: nsStreamListenerEvent(listener, channel, context),
mIStream(nsnull), mLength(0) {}
virtual ~nsOnDataAvailableEvent();
nsresult Init(nsIInputStream* aIStream, PRUint32 aSourceOffset,
PRUint32 aLength);
NS_IMETHOD HandleEvent();
protected:
nsIInputStream* mIStream;
PRUint32 mSourceOffset;
PRUint32 mLength;
};
nsOnDataAvailableEvent::~nsOnDataAvailableEvent()
{
NS_RELEASE(mIStream);
}
nsresult
nsOnDataAvailableEvent::Init(nsIInputStream* aIStream, PRUint32 aSourceOffset,
PRUint32 aLength)
{
mSourceOffset = aSourceOffset;
mLength = aLength;
mIStream = aIStream;
NS_ADDREF(mIStream);
return NS_OK;
}
NS_IMETHODIMP
nsOnDataAvailableEvent::HandleEvent()
{
#if defined(PR_LOGGING)
if (!gStreamEventLog)
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
("netlibEvent: Handle Data [event=%x]", this));
#endif
nsIStreamListener* receiver = (nsIStreamListener*)mListener->GetReceiver();
nsresult status;
nsresult rv = mChannel->GetStatus(&status);
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
//
// Only send OnDataAvailable(... ) notifications if all previous calls
// have succeeded...
//
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
rv = receiver->OnDataAvailable(mChannel, mContext,
mIStream, mSourceOffset, mLength);
}
else {
NS_WARNING("not calling OnDataAvailable");
}
return rv;
}
NS_IMETHODIMP
nsAsyncStreamListener::OnDataAvailable(nsIChannel* channel, nsISupports* context,
nsIInputStream *aIStream,
PRUint32 aSourceOffset,
PRUint32 aLength)
{
nsresult rv;
nsOnDataAvailableEvent* event =
new nsOnDataAvailableEvent(this, channel, context);
if (event == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
rv = event->Init(aIStream, aSourceOffset, aLength);
if (NS_FAILED(rv)) goto failed;
#if defined(PR_LOGGING)
PLEventQueue *equeue;
mEventQueue->GetPLEventQueue(&equeue);
if (!gStreamEventLog)
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
("nsAsyncStreamObserver: Data [this=%x queue=%x event=%x]",
this, equeue, event));
#endif
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) goto failed;
return rv;
failed:
delete event;
return rv;
}
////////////////////////////////////////////////////////////////////////////////
NS_METHOD
nsAsyncStreamObserver::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsAsyncStreamObserver* l = new nsAsyncStreamObserver();
if (l == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(l);
nsresult rv = l->QueryInterface(aIID, aResult);
NS_RELEASE(l);
return rv;
}
NS_METHOD
nsAsyncStreamListener::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsAsyncStreamListener* l = new nsAsyncStreamListener();
if (l == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(l);
nsresult rv = l->QueryInterface(aIID, aResult);
NS_RELEASE(l);
return rv;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,108 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsAsyncStreamListener_h__
#define nsAsyncStreamListener_h__
#include "nsIStreamListener.h"
#include "nsCOMPtr.h"
#include "nsIEventQueue.h"
#include "nsIStreamObserver.h"
#include "nsIStreamListener.h"
////////////////////////////////////////////////////////////////////////////////
class nsAsyncStreamObserver : public nsIAsyncStreamObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMOBSERVER
NS_DECL_NSIASYNCSTREAMOBSERVER
// nsAsyncStreamObserver methods:
nsAsyncStreamObserver()
{
NS_INIT_REFCNT();
}
virtual ~nsAsyncStreamObserver() {}
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsISupports* GetReceiver() { return mReceiver.get(); }
protected:
nsCOMPtr<nsIEventQueue> mEventQueue;
nsCOMPtr<nsIStreamObserver> mReceiver;
};
////////////////////////////////////////////////////////////////////////////////
class nsAsyncStreamListener : public nsAsyncStreamObserver,
public nsIAsyncStreamListener
{
public:
NS_DECL_ISUPPORTS_INHERITED
// nsIStreamListener methods:
NS_IMETHOD OnStartRequest(nsIChannel* channel,
nsISupports* context)
{
return nsAsyncStreamObserver::OnStartRequest(channel, context);
}
NS_IMETHOD OnStopRequest(nsIChannel* channel,
nsISupports* context,
nsresult aStatus,
const PRUnichar* aMsg)
{
return nsAsyncStreamObserver::OnStopRequest(channel, context, aStatus, aMsg);
}
NS_IMETHOD OnDataAvailable(nsIChannel* channel, nsISupports* context,
nsIInputStream *aIStream,
PRUint32 aSourceOffset,
PRUint32 aLength);
// nsIAsyncStreamListener methods:
NS_IMETHOD Init(nsIStreamListener* aListener, nsIEventQueue* aEventQ) {
return nsAsyncStreamObserver::Init(aListener, aEventQ);
}
// nsAsyncStreamListener methods:
nsAsyncStreamListener() {
MOZ_COUNT_CTOR(nsAsyncStreamListener);
}
virtual ~nsAsyncStreamListener() {
MOZ_COUNT_DTOR(nsAsyncStreamListener);
}
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
};
////////////////////////////////////////////////////////////////////////////////
#endif // nsAsyncStreamListener_h__

View File

@@ -0,0 +1,522 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Andreas Otte.
*
* Contributor(s):
*/
#include "nsAuthURLParser.h"
#include "nsURLHelper.h"
#include "nsCRT.h"
#include "nsString.h"
#include "prprf.h"
NS_IMPL_THREADSAFE_ISUPPORTS(nsAuthURLParser, NS_GET_IID(nsIURLParser))
nsAuthURLParser::~nsAuthURLParser()
{
}
NS_METHOD
nsAuthURLParser::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsAuthURLParser* p = new nsAuthURLParser();
if (p == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(p);
nsresult rv = p->QueryInterface(aIID, aResult);
NS_RELEASE(p);
return rv;
}
nsresult
nsAuthURLParser::ParseAtScheme(const char* i_Spec, char* *o_Scheme,
char* *o_Username, char* *o_Password,
char* *o_Host, PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
NS_PRECONDITION( (nsnull != i_Spec), "Parse called on empty url!");
if (!i_Spec)
return NS_ERROR_MALFORMED_URI;
int len = PL_strlen(i_Spec);
if (len >= 2 && *i_Spec == '/' && *(i_Spec+1) == '/') // No Scheme
{
rv = ParseAtPreHost(i_Spec, o_Username, o_Password, o_Host, o_Port,
o_Path);
return rv;
}
static const char delimiters[] = "/:@?"; //this order is optimized.
char* brk = PL_strpbrk(i_Spec, delimiters);
if (!brk) // everything is a host
{
rv = ExtractString((char*)i_Spec, o_Host, len);
ToLowerCase(*o_Host);
return rv;
} else
len = PL_strlen(brk);
switch (*brk)
{
case '/' :
case '?' :
// If the URL starts with a slash then everything is a path
if (brk == i_Spec)
{
rv = ParseAtPath(brk, o_Path);
return rv;
}
else // The first part is host, so its host/path
{
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Host);
rv = ParseAtPath(brk, o_Path);
return rv;
}
break;
case ':' :
if (len >= 2 && *(brk+1) == '/') {
// Standard http://... or malformed http:/...
rv = ExtractString((char*)i_Spec, o_Scheme, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Scheme);
rv = ParseAtPreHost(brk+1, o_Username, o_Password, o_Host,
o_Port, o_Path);
return rv;
} else {
// Could be host:port, so try conversion to number
PRInt32 port = ExtractPortFrom(brk+1);
if (port > 0)
{
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Host);
rv = ParseAtPort(brk+1, o_Port, o_Path);
return rv;
} else {
// No, it's not a number try scheme:host...
rv = ExtractString((char*)i_Spec, o_Scheme,
(brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Scheme);
rv = ParseAtPreHost(brk+1, o_Username, o_Password, o_Host,
o_Port, o_Path);
return rv;
}
}
break;
case '@' :
rv = ParseAtPreHost(i_Spec, o_Username, o_Password, o_Host,
o_Port, o_Path);
return rv;
break;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
return NS_OK;
}
nsresult
nsAuthURLParser::ParseAtPreHost(const char* i_Spec, char* *o_Username,
char* *o_Password, char* *o_Host,
PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
// Skip leading two slashes
char* fwdPtr= (char*) i_Spec;
if (fwdPtr && (*fwdPtr != '\0') && (*fwdPtr == '/'))
fwdPtr++;
if (fwdPtr && (*fwdPtr != '\0') && (*fwdPtr == '/'))
fwdPtr++;
static const char delimiters[] = "/:@?";
char* brk = PL_strpbrk(fwdPtr, delimiters);
char* brk2 = nsnull;
if (!brk)
{
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
return rv;
}
char* e_PreHost = nsnull;
switch (*brk)
{
case ':' :
// this maybe the : of host:port or username:password
// look if the next special char is @
brk2 = PL_strpbrk(brk+1, delimiters);
if (!brk2)
{
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
return rv;
}
switch (*brk2)
{
case '@' :
rv = ExtractString(fwdPtr, &e_PreHost, (brk2 - fwdPtr));
if (NS_FAILED(rv)) {
CRTFREEIF(e_PreHost);
return rv;
}
rv = ParsePreHost(e_PreHost,o_Username,o_Password);
CRTFREEIF(e_PreHost);
if (NS_FAILED(rv))
return rv;
rv = ParseAtHost(brk2+1, o_Host, o_Port, o_Path);
break;
default:
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
return rv;
}
break;
case '@' :
rv = ExtractString(fwdPtr, &e_PreHost, (brk - fwdPtr));
if (NS_FAILED(rv)) {
CRTFREEIF(e_PreHost);
return rv;
}
rv = ParsePreHost(e_PreHost,o_Username,o_Password);
CRTFREEIF(e_PreHost);
if (NS_FAILED(rv))
return rv;
rv = ParseAtHost(brk+1, o_Host, o_Port, o_Path);
break;
default:
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
}
return rv;
}
nsresult
nsAuthURLParser::ParseAtHost(const char* i_Spec, char* *o_Host,
PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
int len = PL_strlen(i_Spec);
static const char delimiters[] = ":/?"; //this order is optimized.
char* brk = PL_strpbrk(i_Spec, delimiters);
if (!brk) // everything is a host
{
rv = ExtractString((char*)i_Spec, o_Host, len);
if (PL_strlen(*o_Host)==0) {
return NS_ERROR_MALFORMED_URI;
}
ToLowerCase(*o_Host);
return rv;
}
switch (*brk)
{
case '/' :
case '?' :
// Get the Host, the rest is Path
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
if (PL_strlen(*o_Host)==0) {
return NS_ERROR_MALFORMED_URI;
}
ToLowerCase(*o_Host);
rv = ParseAtPath(brk, o_Path);
return rv;
break;
case ':' :
// Get the Host
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
if (PL_strlen(*o_Host)==0) {
return NS_ERROR_MALFORMED_URI;
}
ToLowerCase(*o_Host);
rv = ParseAtPort(brk+1, o_Port, o_Path);
return rv;
break;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
return NS_OK;
}
nsresult
nsAuthURLParser::ParseAtPort(const char* i_Spec, PRInt32 *o_Port,
char* *o_Path)
{
nsresult rv = NS_OK;
static const char delimiters[] = "/?"; //this order is optimized.
char* brk = PL_strpbrk(i_Spec, delimiters);
if (!brk) // everything is a Port
{
if (PL_strlen(i_Spec)==0) {
*o_Port = -1;
return NS_OK;
} else {
*o_Port = ExtractPortFrom(i_Spec);
if (*o_Port <= 0)
return NS_ERROR_MALFORMED_URI;
else
return NS_OK;
}
}
char* e_Port = nsnull;
switch (*brk)
{
case '/' :
case '?' :
// Get the Port, the rest is Path
rv = ExtractString((char*)i_Spec, &e_Port, brk-i_Spec);
if (NS_FAILED(rv)) {
CRTFREEIF(e_Port);
return rv;
}
if (PL_strlen(e_Port)==0) {
*o_Port = -1;
} else {
*o_Port = ExtractPortFrom(e_Port);
if (*o_Port <= 0)
return NS_ERROR_MALFORMED_URI;
}
CRTFREEIF(e_Port);
rv = ParseAtPath(brk, o_Path);
return rv;
break;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
return NS_OK;
}
nsresult
nsAuthURLParser::ParseAtPath(const char* i_Spec, char* *o_Path)
{
// Just write the path and check for a starting /
nsCAutoString dir;
if ('/' != *i_Spec)
dir += "/";
dir += i_Spec;
*o_Path = dir.ToNewCString();
return (*o_Path ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
}
nsresult
nsAuthURLParser::ParseAtDirectory(const char* i_Path, char* *o_Directory,
char* *o_FileBaseName, char* *o_FileExtension,
char* *o_Param, char* *o_Query, char* *o_Ref)
{
// Cleanout
CRTFREEIF(*o_Directory);
CRTFREEIF(*o_FileBaseName);
CRTFREEIF(*o_FileExtension);
CRTFREEIF(*o_Param);
CRTFREEIF(*o_Query);
CRTFREEIF(*o_Ref);
nsresult rv = NS_OK;
// Parse the Path into its components
if (!i_Path)
{
DupString(o_Directory, "/");
return (o_Directory ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
}
char* dirfile = nsnull;
char* options = nsnull;
int len = PL_strlen(i_Path);
/* Factor out the optionpart with ;?# */
static const char delimiters[] = ";?#"; // for param, query and ref
char* brk = PL_strpbrk(i_Path, delimiters);
if (!brk) // Everything is just path and filename
{
DupString(&dirfile, i_Path);
}
else
{
int dirfileLen = brk - i_Path;
ExtractString((char*)i_Path, &dirfile, dirfileLen);
len -= dirfileLen;
ExtractString((char*)i_Path + dirfileLen, &options, len);
brk = options;
}
/* now that we have broken up the path treat every part differently */
/* first dir+file */
char* file;
int dlen = PL_strlen(dirfile);
if (dlen == 0)
{
DupString(o_Directory, "/");
file = dirfile;
} else {
CoaleseDirs(dirfile);
// Get length again
dlen = PL_strlen(dirfile);
// First find the last slash
file = PL_strrchr(dirfile, '/');
if (!file)
{
DupString(o_Directory, "/");
file = dirfile;
}
// If its not the same as the first slash then extract directory
if (file != dirfile)
{
ExtractString(dirfile, o_Directory, (file - dirfile)+1);
} else {
DupString(o_Directory, "/");
}
}
/* Extract FileBaseName and FileExtension */
if (dlen > 0) {
// Look again if there was a slash
char* slash = PL_strrchr(dirfile, '/');
char* e_FileName = nsnull;
if (slash) {
if (dirfile+dlen-1>slash)
ExtractString(slash+1, &e_FileName, dlen-(slash-dirfile+1));
} else {
// Use the full String as Filename
ExtractString(dirfile, &e_FileName, dlen);
}
rv = ParseFileName(e_FileName,o_FileBaseName,o_FileExtension);
CRTFREEIF(e_FileName);
}
// Now take a look at the options. "#" has precedence over "?"
// which has precedence over ";"
if (options) {
// Look for "#" first. Everything following it is in the ref
brk = PL_strchr(options, '#');
if (brk) {
int pieceLen = len - (brk + 1 - options);
ExtractString(brk+1, o_Ref, pieceLen);
len -= pieceLen + 1;
*brk = '\0';
}
// Now look for "?"
brk = PL_strchr(options, '?');
if (brk) {
int pieceLen = len - (brk + 1 - options);
ExtractString(brk+1, o_Query, pieceLen);
len -= pieceLen + 1;
*brk = '\0';
}
// Now look for ';'
brk = PL_strchr(options, ';');
if (brk) {
int pieceLen = len - (brk + 1 - options);
ExtractString(brk+1, o_Param, pieceLen);
len -= pieceLen + 1;
*brk = '\0';
}
}
nsCRT::free(dirfile);
nsCRT::free(options);
return rv;
}
nsresult
nsAuthURLParser::ParsePreHost(const char* i_PreHost, char* *o_Username,
char* *o_Password)
{
nsresult rv = NS_OK;
if (!i_PreHost) {
*o_Username = nsnull;
*o_Password = nsnull;
return rv;
}
// Search for :
static const char delimiters[] = ":";
char* brk = PL_strpbrk(i_PreHost, delimiters);
if (brk)
{
rv = ExtractString((char*)i_PreHost, o_Username, (brk - i_PreHost));
if (NS_FAILED(rv))
return rv;
rv = ExtractString(brk+1, o_Password,
(i_PreHost+PL_strlen(i_PreHost) - brk - 1));
} else {
CRTFREEIF(*o_Password);
rv = DupString(o_Username, i_PreHost);
}
return rv;
}
nsresult
nsAuthURLParser::ParseFileName(const char* i_FileName, char* *o_FileBaseName,
char* *o_FileExtension)
{
nsresult rv = NS_OK;
if (!i_FileName) {
*o_FileBaseName = nsnull;
*o_FileExtension = nsnull;
return rv;
}
// Search for FileExtension
// Search for last .
// Ignore . at the beginning
char* brk = PL_strrchr(i_FileName+1, '.');
if (brk)
{
rv = ExtractString((char*)i_FileName, o_FileBaseName,
(brk - i_FileName));
if (NS_FAILED(rv))
return rv;
rv = ExtractString(brk + 1, o_FileExtension,
(i_FileName+PL_strlen(i_FileName) - brk - 1));
} else {
rv = DupString(o_FileBaseName, i_FileName);
}
return rv;
}

View File

@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsAuthURLParser_h__
#define nsAuthURLParser_h__
#include "nsIURLParser.h"
#include "nsIURI.h"
#include "nsAgg.h"
#include "nsCRT.h"
class nsAuthURLParser : public nsIURLParser
{
public:
NS_DECL_ISUPPORTS
///////////////////////////////////////////////////////////////////////////
// nsAuthURLParser methods:
nsAuthURLParser() {
NS_INIT_REFCNT();
}
virtual ~nsAuthURLParser();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
///////////////////////////////////////////////////////////////////////////
// nsIURLParser methods:
NS_DECL_NSIURLPARSER
};
#endif // nsAuthURLParser_h__

View File

@@ -0,0 +1,318 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsBufferedStreams.h"
#include "nsCRT.h"
////////////////////////////////////////////////////////////////////////////////
// nsBufferedStream
nsBufferedStream::nsBufferedStream()
: mBuffer(nsnull),
mBufferStartOffset(0),
mCursor(0),
mFillPoint(0),
mStream(nsnull)
{
NS_INIT_REFCNT();
}
nsBufferedStream::~nsBufferedStream()
{
Close();
}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsBufferedStream,
nsIBaseStream,
nsISeekableStream);
nsresult
nsBufferedStream::Init(nsIBaseStream* stream, PRUint32 bufferSize)
{
NS_ASSERTION(stream, "need to supply a stream");
NS_ASSERTION(mStream == nsnull, "already inited");
mStream = stream;
NS_ADDREF(mStream);
mBufferSize = bufferSize;
mBufferStartOffset = 0;
mCursor = 0;
mBuffer = new char[bufferSize];
if (mBuffer == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsBufferedStream::Close()
{
nsresult rv = NS_OK;
if (mStream) {
rv = mStream->Close();
NS_RELEASE(mStream);
mStream = nsnull;
delete[] mBuffer;
mBuffer = nsnull;
mBufferSize = 0;
mBufferStartOffset = 0;
mCursor = 0;
}
return rv;
}
NS_IMETHODIMP
nsBufferedStream::Seek(PRInt32 whence, PRInt32 offset)
{
if (mStream == nsnull)
return NS_BASE_STREAM_CLOSED;
// If the underlying stream isn't a random access store, then fail early.
// We could possibly succeed for the case where the seek position denotes
// something that happens to be read into the buffer, but that would make
// the failure data-dependent.
nsresult rv;
nsCOMPtr<nsISeekableStream> ras = do_QueryInterface(mStream, &rv);
if (NS_FAILED(rv)) return rv;
PRInt32 absPos;
switch (whence) {
case nsISeekableStream::NS_SEEK_SET:
absPos = offset;
break;
case nsISeekableStream::NS_SEEK_CUR:
absPos = mBufferStartOffset + mCursor + offset;
break;
case nsISeekableStream::NS_SEEK_END:
absPos = -1;
break;
default:
NS_NOTREACHED("bogus seek whence parameter");
return NS_ERROR_UNEXPECTED;
}
if ((PRInt32)mBufferStartOffset <= absPos
&& absPos < (PRInt32)(mBufferStartOffset + mFillPoint)) {
mCursor = absPos - mBufferStartOffset;
return NS_OK;
}
rv = Flush();
if (NS_FAILED(rv)) return rv;
rv = ras->Seek(whence, offset);
if (NS_FAILED(rv)) return rv;
if (absPos == -1) {
// then we had the SEEK_END case, above
rv = ras->Tell(&mBufferStartOffset);
if (NS_FAILED(rv)) return rv;
}
else {
mBufferStartOffset = absPos;
}
mCursor = 0;
mFillPoint = 0;
return Fill();
}
NS_IMETHODIMP
nsBufferedStream::Tell(PRUint32 *result)
{
if (mStream == nsnull)
return NS_BASE_STREAM_CLOSED;
*result = mBufferStartOffset + mCursor;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsBufferedInputStream
NS_IMPL_ISUPPORTS_INHERITED2(nsBufferedInputStream,
nsBufferedStream,
nsIInputStream,
nsIBufferedInputStream);
NS_METHOD
nsBufferedInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
NS_ENSURE_NO_AGGREGATION(aOuter);
nsBufferedInputStream* stream = new nsBufferedInputStream();
if (stream == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(stream);
nsresult rv = stream->QueryInterface(aIID, aResult);
NS_RELEASE(stream);
return rv;
}
NS_IMETHODIMP
nsBufferedInputStream::Init(nsIInputStream* stream, PRUint32 bufferSize)
{
return nsBufferedStream::Init(stream, bufferSize);
}
NS_IMETHODIMP
nsBufferedInputStream::Close()
{
return nsBufferedStream::Close();
}
NS_IMETHODIMP
nsBufferedInputStream::Available(PRUint32 *result)
{
*result = mFillPoint - mCursor;
return NS_OK;
}
NS_IMETHODIMP
nsBufferedInputStream::Read(char * buf, PRUint32 count, PRUint32 *result)
{
nsresult rv = NS_OK;
PRUint32 read = 0;
while (count > 0) {
PRUint32 amt = PR_MIN(count, mFillPoint - mCursor);
if (amt > 0) {
nsCRT::memcpy(buf, mBuffer + mCursor, amt);
read += amt;
count -= amt;
mCursor += amt;
}
else {
rv = Fill();
if (NS_FAILED(rv)) break;
}
}
*result = read;
return (read > 0 || rv == NS_BASE_STREAM_CLOSED) ? NS_OK : rv;
}
NS_IMETHODIMP
nsBufferedInputStream::Fill()
{
nsresult rv;
PRUint32 rem = mFillPoint - mCursor;
if (rem > 0) {
// slide the remainder down to the start of the buffer
// |<------------->|<--rem-->|<--->|
// b c f s
nsCRT::memcpy(mBuffer, mBuffer + mCursor, rem);
}
mBufferStartOffset += mCursor;
mFillPoint = rem;
mCursor = 0;
PRUint32 amt;
rv = Source()->Read(mBuffer + mFillPoint, mBufferSize - mFillPoint, &amt);
if (NS_FAILED(rv)) return rv;
mFillPoint += amt;
return amt > 0 ? NS_OK : NS_BASE_STREAM_CLOSED;
}
////////////////////////////////////////////////////////////////////////////////
// nsBufferedOutputStream
NS_IMPL_ISUPPORTS_INHERITED2(nsBufferedOutputStream,
nsBufferedStream,
nsIOutputStream,
nsIBufferedOutputStream);
NS_METHOD
nsBufferedOutputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
NS_ENSURE_NO_AGGREGATION(aOuter);
nsBufferedOutputStream* stream = new nsBufferedOutputStream();
if (stream == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(stream);
nsresult rv = stream->QueryInterface(aIID, aResult);
NS_RELEASE(stream);
return rv;
}
NS_IMETHODIMP
nsBufferedOutputStream::Init(nsIOutputStream* stream, PRUint32 bufferSize)
{
mFillPoint = bufferSize; // always fill to the end for buffered output streams
return nsBufferedStream::Init(stream, bufferSize);
}
NS_IMETHODIMP
nsBufferedOutputStream::Close()
{
nsresult rv1, rv2;
rv1 = Flush();
// If we fail to Flush all the data, then we close anyway and drop the
// remaining data in the buffer. We do this because it's what Unix does
// for fclose and close. However, we report the error from Flush anyway.
rv2 = nsBufferedStream::Close();
if (NS_FAILED(rv1)) return rv1;
return rv2;
}
NS_IMETHODIMP
nsBufferedOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *result)
{
nsresult rv = NS_OK;
PRUint32 written = 0;
while (count > 0) {
PRUint32 amt = PR_MIN(count, mFillPoint - mCursor);
if (amt > 0) {
nsCRT::memcpy(mBuffer + mCursor, buf + written, amt);
written += amt;
count -= amt;
mCursor += amt;
}
else {
rv = Flush();
if (NS_FAILED(rv)) break;
}
}
*result = written;
return (written > 0) ? NS_OK : rv;
}
NS_IMETHODIMP
nsBufferedOutputStream::Flush(void)
{
nsresult rv;
PRUint32 amt;
rv = Sink()->Write(mBuffer, mCursor, &amt);
if (NS_FAILED(rv)) return rv;
mBufferStartOffset += amt;
if (mCursor == amt) {
mCursor = 0;
return NS_OK; // flushed everything
}
// slide the remainder down to the start of the buffer
// |<-------------->|<---|----->|
// b a c s
PRUint32 rem = mCursor - amt;
nsCRT::memcpy(mBuffer, mBuffer + amt, rem);
mCursor = rem;
return NS_ERROR_FAILURE; // didn't flush all
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,117 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsBufferedStreams_h__
#define nsBufferedStreams_h__
#include "nsIFileStreams.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsCOMPtr.h"
////////////////////////////////////////////////////////////////////////////////
class nsBufferedStream : public nsIBaseStream,
public nsISeekableStream
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIBASESTREAM
NS_DECL_NSISEEKABLESTREAM
nsBufferedStream();
virtual ~nsBufferedStream();
protected:
nsresult Init(nsIBaseStream* stream, PRUint32 bufferSize);
NS_IMETHOD Fill() = 0;
NS_IMETHOD Flush() = 0;
protected:
PRUint32 mBufferSize;
char* mBuffer;
// mBufferStartOffset is the offset relative to the start of mStream:
PRUint32 mBufferStartOffset;
// mCursor is the read cursor for input streams, or write cursor for
// output streams, and is relative to mBufferStartOffset:
PRUint32 mCursor;
// mFillPoint is the amount available in the buffer for input streams,
// or the end of the buffer for output streams, and is relative to
// mBufferStartOffset:
PRUint32 mFillPoint;
nsIBaseStream* mStream; // cast to appropriate subclass
};
////////////////////////////////////////////////////////////////////////////////
class nsBufferedInputStream : public nsBufferedStream,
public nsIBufferedInputStream
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIBASESTREAM
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSIBUFFEREDINPUTSTREAM
nsBufferedInputStream() : nsBufferedStream() {}
virtual ~nsBufferedInputStream() {}
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsIInputStream* Source() {
return (nsIInputStream*)mStream;
}
protected:
NS_IMETHOD Fill();
NS_IMETHOD Flush() { return NS_OK; } // no-op for input streams
};
////////////////////////////////////////////////////////////////////////////////
class nsBufferedOutputStream : public nsBufferedStream,
public nsIBufferedOutputStream
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIBASESTREAM
NS_DECL_NSIOUTPUTSTREAM
NS_DECL_NSIBUFFEREDOUTPUTSTREAM
nsBufferedOutputStream() : nsBufferedStream() {}
virtual ~nsBufferedOutputStream() {}
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsIOutputStream* Sink() {
return (nsIOutputStream*)mStream;
}
protected:
NS_IMETHOD Fill() { return NS_OK; } // no-op for output streams
};
////////////////////////////////////////////////////////////////////////////////
#endif // nsBufferedStreams_h__

View File

@@ -0,0 +1,272 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
The converts a filesystem directory into an "HTTP index" stream per
Lou Montulli's original spec:
http://www.area.com/~roeber/file_format.html
*/
#include "nsEscape.h"
#include "nsDirectoryIndexStream.h"
#include "nsXPIDLString.h"
#include "prio.h"
#include "prlog.h"
#include "prlong.h"
#ifdef PR_LOGGING
static PRLogModuleInfo* gLog;
#endif
nsDirectoryIndexStream::nsDirectoryIndexStream()
: mOffset(0)
{
NS_INIT_REFCNT();
#ifdef PR_LOGGING
if (! gLog)
gLog = PR_NewLogModule("nsDirectoryIndexStream");
#endif
PR_LOG(gLog, PR_LOG_DEBUG,
("nsDirectoryIndexStream[%p]: created", this));
}
nsresult
nsDirectoryIndexStream::Init(nsIFile* aDir)
{
nsresult rv;
PRBool isDir;
rv = aDir->IsDirectory(&isDir);
if (NS_FAILED(rv)) return rv;
NS_PRECONDITION(isDir, "not a directory");
if (!isDir)
return NS_ERROR_ILLEGAL_VALUE;
#ifdef PR_LOGGING
if (PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
nsXPIDLCString path;
aDir->GetPath(getter_Copies(path));
PR_LOG(gLog, PR_LOG_DEBUG,
("nsDirectoryIndexStream[%p]: initialized on %s",
this, (const char*) path));
}
#endif
mDir = aDir;
// Sigh. We have to allocate on the heap because there are no
// assignment operators defined.
rv = mDir->GetDirectoryEntries(getter_AddRefs(mIter));
if (NS_FAILED(rv)) return rv;
mBuf = "200: filename content-length last-modified file-type\n";
return NS_OK;
}
nsDirectoryIndexStream::~nsDirectoryIndexStream()
{
PR_LOG(gLog, PR_LOG_DEBUG,
("nsDirectoryIndexStream[%p]: destroyed", this));
}
nsresult
nsDirectoryIndexStream::Create(nsIFile* aDir, nsIInputStream** aResult)
{
nsDirectoryIndexStream* result = new nsDirectoryIndexStream();
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv;
rv = result->Init(aDir);
if (NS_FAILED(rv)) {
delete result;
return rv;
}
*aResult = result;
NS_ADDREF(*aResult);
return NS_OK;
}
NS_IMPL_ISUPPORTS2(nsDirectoryIndexStream,
nsIInputStream,
nsIBaseStream)
NS_IMETHODIMP
nsDirectoryIndexStream::Close()
{
return NS_OK;
}
NS_IMETHODIMP
nsDirectoryIndexStream::Available(PRUint32* aLength)
{
// Lie, and tell the caller that the stream is endless (until we
// actually don't have anything left).
PRBool more;
nsresult rv = mIter->HasMoreElements(&more);
if (NS_FAILED(rv)) return rv;
if (more) {
*aLength = PRUint32(-1);
return NS_OK;
}
else {
*aLength = 0;
return NS_OK;
}
}
NS_IMETHODIMP
nsDirectoryIndexStream::Read(char* aBuf, PRUint32 aCount, PRUint32* aReadCount)
{
PRUint32 nread = 0;
// If anything is enqueued (or left-over) in mBuf, then feed it to
// the reader first.
while (mOffset < mBuf.Length() && aCount != 0) {
*(aBuf++) = char(mBuf.CharAt(mOffset++));
--aCount;
++nread;
}
// Room left?
if (aCount > 0) {
mOffset = 0;
mBuf.Truncate();
// Okay, now we'll suck stuff off of our iterator into the mBuf...
while (PRUint32(mBuf.Length()) < aCount) {
PRBool more;
nsresult rv = mIter->HasMoreElements(&more);
if (NS_FAILED(rv)) return rv;
if (!more) break;
nsCOMPtr<nsISupports> cur;
rv = mIter->GetNext(getter_AddRefs(cur));
nsCOMPtr<nsIFile> current = do_QueryInterface(cur, &rv);
if (NS_FAILED(rv)) return rv;
#ifdef PR_LOGGING
if (PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
nsXPIDLCString path;
current->GetPath(getter_Copies(path));
PR_LOG(gLog, PR_LOG_DEBUG,
("nsDirectoryIndexStream[%p]: iterated %s",
this, (const char*) path));
}
#endif
// rjc: don't return hidden files/directories!
PRBool hidden;
rv = current->IsHidden(&hidden);
if (NS_FAILED(rv)) return rv;
if (hidden) {
PR_LOG(gLog, PR_LOG_DEBUG,
("nsDirectoryIndexStream[%p]: skipping hidden file/directory",
this));
continue;
}
PRInt64 fileSize;
PRInt64 fileInfoModifyTime;
rv = current->GetFileSize( &fileSize );
if (NS_FAILED(rv)) return rv;
PROffset32 fileInfoSize;
LL_L2I( fileInfoSize,fileSize );
rv = current->GetLastModificationDate( &fileInfoModifyTime );
if (NS_FAILED(rv)) return rv;
mBuf += "201: ";
// The "filename" field
{
char* leafname;
rv = current->GetLeafName(&leafname);
if (NS_FAILED(rv)) return rv;
if (leafname) {
char* escaped = nsEscape(leafname, url_Path);
if (escaped) {
mBuf += escaped;
mBuf.Append(' ');
nsCRT::free(escaped);
}
nsCRT::free(leafname);
}
}
// The "content-length" field
mBuf.AppendWithConversion(fileInfoSize, 10);
mBuf.Append(' ');
// The "last-modified" field
PRExplodedTime tm;
PR_ExplodeTime(fileInfoModifyTime, PR_GMTParameters, &tm);
{
char buf[64];
PR_FormatTimeUSEnglish(buf, sizeof(buf), "%a,%%20%d%%20%b%%20%Y%%20%H:%M:%S%%20GMT ", &tm);
mBuf.Append(buf);
}
// The "file-type" field
PRBool isFile;
rv = current->IsFile(&isFile);
if (NS_FAILED(rv)) return rv;
if (isFile) {
mBuf += "FILE ";
}
else {
PRBool isDir;
rv = current->IsDirectory(&isDir);
if (NS_FAILED(rv)) return rv;
if (isDir) {
mBuf += "DIRECTORY ";
}
else {
PRBool isLink;
rv = current->IsSymlink(&isLink);
if (NS_FAILED(rv)) return rv;
if (isLink) {
mBuf += "SYMBOLIC-LINK ";
}
}
}
mBuf.Append('\n');
}
// ...and once we've either run out of directory entries, or
// filled up the buffer, then we'll push it to the reader.
while (mOffset < mBuf.Length() && aCount != 0) {
*(aBuf++) = char(mBuf.CharAt(mOffset++));
--aCount;
++nread;
}
}
*aReadCount = nread;
return NS_OK;
}

View File

@@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsDirectoryIndexStream_h__
#define nsDirectoryIndexStream_h__
#include "nsIFile.h"
#include "nsString.h"
#include "nsIInputStream.h"
#include "nsCOMPtr.h"
class nsDirectoryIndexStream : public nsIInputStream
{
protected:
nsCAutoString mBuf;
PRInt32 mOffset;
nsCOMPtr<nsIFile> mDir;
nsCOMPtr<nsISimpleEnumerator> mIter;
nsDirectoryIndexStream();
nsresult Init(nsIFile* aDir);
virtual ~nsDirectoryIndexStream();
public:
static nsresult
Create(nsIFile* aDir, nsIInputStream** aStreamResult);
// nsISupportsInterface
NS_DECL_ISUPPORTS
// nsIBaseStream interface
NS_DECL_NSIBASESTREAM
// nsIInputStream interface
NS_DECL_NSIINPUTSTREAM
};
#endif // nsDirectoryIndexStream_h__

View File

@@ -0,0 +1,225 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsFileStreams.h"
#include "nsILocalFile.h"
#include "prerror.h"
////////////////////////////////////////////////////////////////////////////////
// nsFileStream
nsFileStream::nsFileStream()
: mFD(nsnull)
{
NS_INIT_REFCNT();
}
nsFileStream::~nsFileStream()
{
Close();
}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsFileStream,
nsIBaseStream,
nsISeekableStream);
NS_IMETHODIMP
nsFileStream::Close()
{
if (mFD) {
PR_Close(mFD);
mFD = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP
nsFileStream::Seek(PRInt32 whence, PRInt32 offset)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Seek(mFD, offset, (PRSeekWhence)whence);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
return NS_OK;
}
NS_IMETHODIMP
nsFileStream::Tell(PRUint32 *result)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Seek(mFD, 0, PR_SEEK_CUR);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
*result = cnt;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsFileInputStream
NS_IMPL_ISUPPORTS_INHERITED2(nsFileInputStream,
nsFileStream,
nsIInputStream,
nsIFileInputStream);
NS_METHOD
nsFileInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
NS_ENSURE_NO_AGGREGATION(aOuter);
nsFileInputStream* stream = new nsFileInputStream();
if (stream == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(stream);
nsresult rv = stream->QueryInterface(aIID, aResult);
NS_RELEASE(stream);
return rv;
}
NS_IMETHODIMP
nsFileInputStream::Init(nsIFile* file, PRInt32 ioFlags, PRInt32 perm)
{
NS_ASSERTION(mFD == nsnull, "already inited");
if (mFD != nsnull)
return NS_ERROR_FAILURE;
nsresult rv;
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file, &rv);
if (NS_FAILED(rv)) return rv;
if (ioFlags == -1)
ioFlags = PR_RDONLY;
if (perm == -1)
perm = 0;
return localFile->OpenNSPRFileDesc(ioFlags, perm, &mFD);
}
NS_IMETHODIMP
nsFileInputStream::Close()
{
return nsFileStream::Close();
}
NS_IMETHODIMP
nsFileInputStream::Available(PRUint32 *result)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 avail = PR_Available(mFD);
if (avail == -1) {
return NS_ErrorAccordingToNSPR();
}
*result = avail;
return NS_OK;
}
NS_IMETHODIMP
nsFileInputStream::Read(char * buf, PRUint32 count, PRUint32 *result)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Read(mFD, buf, count);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
*result = cnt;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsFileOutputStream
NS_IMPL_ISUPPORTS_INHERITED2(nsFileOutputStream,
nsFileStream,
nsIOutputStream,
nsIFileOutputStream);
NS_METHOD
nsFileOutputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
NS_ENSURE_NO_AGGREGATION(aOuter);
nsFileOutputStream* stream = new nsFileOutputStream();
if (stream == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(stream);
nsresult rv = stream->QueryInterface(aIID, aResult);
NS_RELEASE(stream);
return rv;
}
NS_IMETHODIMP
nsFileOutputStream::Init(nsIFile* file, PRInt32 ioFlags, PRInt32 perm)
{
NS_ASSERTION(mFD == nsnull, "already inited");
if (mFD != nsnull)
return NS_ERROR_FAILURE;
nsresult rv;
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file, &rv);
if (NS_FAILED(rv)) return rv;
if (ioFlags == -1)
ioFlags = PR_WRONLY | PR_CREATE_FILE;
if (perm == -1)
perm = 0664;
return localFile->OpenNSPRFileDesc(ioFlags, perm, &mFD);
}
NS_IMETHODIMP
nsFileOutputStream::Close()
{
return nsFileStream::Close();
}
NS_IMETHODIMP
nsFileOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *result)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Write(mFD, buf, count);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
*result = cnt;
return NS_OK;
}
NS_IMETHODIMP
nsFileOutputStream::Flush(void)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Sync(mFD);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsFileStreams_h__
#define nsFileStreams_h__
#include "nsIFileStreams.h"
#include "nsIFile.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsCOMPtr.h"
////////////////////////////////////////////////////////////////////////////////
class nsFileStream : public nsIBaseStream,
public nsISeekableStream
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIBASESTREAM
NS_DECL_NSISEEKABLESTREAM
nsFileStream();
virtual ~nsFileStream();
protected:
PRFileDesc* mFD;
};
////////////////////////////////////////////////////////////////////////////////
class nsFileInputStream : public nsFileStream,
public nsIFileInputStream
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIBASESTREAM
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSIFILEINPUTSTREAM
nsFileInputStream() : nsFileStream() {}
virtual ~nsFileInputStream() {}
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
};
////////////////////////////////////////////////////////////////////////////////
class nsFileOutputStream : public nsFileStream,
public nsIFileOutputStream
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIBASESTREAM
NS_DECL_NSIOUTPUTSTREAM
NS_DECL_NSIFILEOUTPUTSTREAM
nsFileOutputStream() : nsFileStream() {}
virtual ~nsFileOutputStream() {}
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
};
////////////////////////////////////////////////////////////////////////////////
#endif // nsFileStreams_h__

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,139 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsFileTransport_h__
#define nsFileTransport_h__
#include "nsIChannel.h"
#include "nsIRunnable.h"
#include "nsFileSpec.h"
#include "prlock.h"
#include "nsIEventQueueService.h"
#include "nsIPipe.h"
#include "nsILoadGroup.h"
#include "nsCOMPtr.h"
#include "nsIStreamListener.h"
#include "nsIProgressEventSink.h"
#include "nsIBufferInputStream.h"
#include "nsIBufferOutputStream.h"
#include "nsIFileSystem.h"
#include "nsIInterfaceRequestor.h"
#include "nsIFile.h"
#include "prlog.h"
class nsIInterfaceRequestor;
class nsFileTransport : public nsIChannel,
public nsIRunnable,
public nsIPipeObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSIPIPEOBSERVER
NS_DECL_NSIRUNNABLE
nsFileTransport();
// Always make the destructor virtual:
virtual ~nsFileTransport();
// Define a Create method to be used with a factory:
static NS_METHOD
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
nsresult Init(nsIFile* file,
PRInt32 ioFlags,
PRInt32 perm);
nsresult Init(nsIInputStream* fromStream,
const char* contentType,
PRInt32 contentLength);
nsresult Init(nsIFileSystem* fsObj);
void Process(void);
void DoClose(void);
enum State {
CLOSED,
OPENING,
OPENED,
START_READ,
READING,
END_READ,
START_WRITE,
WRITING,
END_WRITE,
CLOSING
};
enum Command {
NONE,
INITIATE_READ,
INITIATE_WRITE
};
protected:
nsCOMPtr<nsIFile> mFile;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIProgressEventSink> mProgress;
nsCOMPtr<nsIFileSystem> mFileObject;
char* mContentType;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
PRInt32 mIOFlags;
PRInt32 mPerm;
nsCOMPtr<nsIStreamObserver> mOpenObserver;
nsCOMPtr<nsISupports> mOpenContext;
nsCOMPtr<nsISupports> mContext;
State mState;
Command mCommand;
PRBool mSuspended;
PRMonitor* mMonitor;
// state variables:
nsresult mStatus;
PRUint32 mOffset;
PRInt32 mTotalAmount;
PRInt32 mTransferAmount;
// reading state varialbles:
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsIInputStream> mSource;
nsCOMPtr<nsIBufferInputStream> mBufferInputStream;
nsCOMPtr<nsIBufferOutputStream> mBufferOutputStream;
// writing state variables:
nsCOMPtr<nsIStreamObserver> mObserver;
nsCOMPtr<nsIOutputStream> mSink;
char* mBuffer;
#ifdef PR_LOGGING
char* mSpec;
#endif
};
#define NS_FILE_TRANSPORT_DEFAULT_SEGMENT_SIZE (2*1024)
#define NS_FILE_TRANSPORT_DEFAULT_BUFFER_SIZE (8*1024)
#endif // nsFileTransport_h__

View File

@@ -0,0 +1,191 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsFileTransport.h"
#include "nsFileTransportService.h"
#include "nsIURL.h"
#include "nsCRT.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIProgressEventSink.h"
#include "nsIThreadPool.h"
#include "nsISupportsArray.h"
#include "nsFileSpec.h"
#include "nsAutoLock.h"
static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
////////////////////////////////////////////////////////////////////////////////
nsFileTransportService::nsFileTransportService()
{
NS_INIT_REFCNT();
}
#define NS_FILE_TRANSPORT_WORKER_STACK_SIZE (64 * 1024) /* (8*1024) */
nsresult
nsFileTransportService::Init()
{
nsresult rv;
rv = NS_NewThreadPool(getter_AddRefs(mPool),
NS_FILE_TRANSPORT_WORKER_COUNT_MIN,
NS_FILE_TRANSPORT_WORKER_COUNT_MAX,
NS_FILE_TRANSPORT_WORKER_STACK_SIZE);
return rv;
}
nsFileTransportService::~nsFileTransportService()
{
mPool->Shutdown();
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsFileTransportService, nsFileTransportService);
NS_IMETHODIMP
nsFileTransportService::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsFileTransportService* ph = new nsFileTransportService();
if (ph == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(ph);
nsresult rv = ph->Init();
if (NS_SUCCEEDED(rv)) {
rv = ph->QueryInterface(aIID, aResult);
}
NS_RELEASE(ph);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsFileTransportService::CreateTransport(nsIFile* file,
PRInt32 ioFlags,
PRInt32 perm,
nsIChannel** result)
{
nsresult rv;
nsFileTransport* trans = new nsFileTransport();
if (trans == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(trans);
rv = trans->Init(file, ioFlags, perm);
if (NS_FAILED(rv)) {
NS_RELEASE(trans);
return rv;
}
*result = trans;
return NS_OK;
}
NS_IMETHODIMP
nsFileTransportService::CreateTransportFromStream(nsIInputStream *fromStream,
const char* contentType,
PRInt32 contentLength,
nsIChannel** result)
{
nsresult rv;
nsFileTransport* trans = new nsFileTransport();
if (trans == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(trans);
rv = trans->Init(fromStream, contentType, contentLength);
if (NS_FAILED(rv)) {
NS_RELEASE(trans);
return rv;
}
*result = trans;
return NS_OK;
}
NS_IMETHODIMP
nsFileTransportService::CreateTransportFromFileSystem(nsIFileSystem *fsObj,
nsIChannel **result)
{
nsresult rv;
nsFileTransport* trans = new nsFileTransport();
if (trans == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(trans);
rv = trans->Init(fsObj);
if (NS_FAILED(rv)) {
NS_RELEASE(trans);
return rv;
}
*result = trans;
return NS_OK;
}
nsresult
nsFileTransportService::ProcessPendingRequests(void)
{
return mPool->ProcessPendingRequests();
}
nsresult
nsFileTransportService::Shutdown(void)
{
return mPool->Shutdown();
}
nsresult
nsFileTransportService::DispatchRequest(nsIRunnable* runnable)
{
return mPool->DispatchRequest(runnable);
}
////////////////////////////////////////////////////////////////////////////////
nsresult
nsFileTransportService::Suspend(nsIRunnable* request)
{
nsresult rv;
nsAutoCMonitor mon(this); // protect mSuspended
if (mSuspended == nsnull) {
rv = NS_NewISupportsArray(getter_AddRefs(mSuspended));
if (NS_FAILED(rv)) return rv;
}
return mSuspended->AppendElement(request) ? NS_OK : NS_ERROR_FAILURE; // XXX this method incorrectly returns a bool
}
nsresult
nsFileTransportService::Resume(nsIRunnable* request)
{
nsresult rv;
nsAutoCMonitor mon(this); // protect mSuspended
if (mSuspended == nsnull)
return NS_ERROR_FAILURE;
// XXX RemoveElement returns a bool instead of nsresult!
PRBool removed = mSuspended->RemoveElement(request);
rv = removed ? NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
// restart the request
rv = mPool->DispatchRequest(request);
return rv;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsFileTransportService_h___
#define nsFileTransportService_h___
#include "nsIFileTransportService.h"
#include "nsIThreadPool.h"
#include "nsISupportsArray.h"
#define NS_FILE_TRANSPORT_WORKER_COUNT_MIN 1
#define NS_FILE_TRANSPORT_WORKER_COUNT_MAX 16
class nsFileTransportService : public nsIFileTransportService
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIFILETRANSPORTSERVICE
// nsFileTransportService methods:
nsFileTransportService();
virtual ~nsFileTransportService();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsresult Init();
protected:
nsCOMPtr<nsIThreadPool> mPool;
nsCOMPtr<nsISupportsArray> mOpened;
nsCOMPtr<nsISupportsArray> mSuspended;
};
#endif /* nsFileTransportService_h___ */

View File

@@ -0,0 +1,400 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIOService.h"
#include "nsIProtocolHandler.h"
#include "nscore.h"
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
#include "nsIFileTransportService.h"
#include "nsIURI.h"
#include "nsIStreamListener.h"
#include "prprf.h"
#include "nsLoadGroup.h"
#include "nsInputStreamChannel.h"
#include "nsXPIDLString.h"
static NS_DEFINE_CID(kFileTransportService, NS_FILETRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kDNSServiceCID, NS_DNSSERVICE_CID);
////////////////////////////////////////////////////////////////////////////////
nsIOService::nsIOService()
: mOffline(PR_FALSE)
{
NS_INIT_REFCNT();
}
nsresult
nsIOService::Init()
{
nsresult rv = NS_OK;
// We need to get references to these services so that we can shut them
// down later. If we wait until the nsIOService is being shut down,
// GetService will fail at that point.
rv = nsServiceManager::GetService(kSocketTransportServiceCID,
NS_GET_IID(nsISocketTransportService),
getter_AddRefs(mSocketTransportService));
if (NS_FAILED(rv)) return rv;
rv = nsServiceManager::GetService(kFileTransportService,
NS_GET_IID(nsIFileTransportService),
getter_AddRefs(mFileTransportService));
if (NS_FAILED(rv)) return rv;
rv = nsServiceManager::GetService(kDNSServiceCID,
NS_GET_IID(nsIDNSService),
getter_AddRefs(mDNSService));
return rv;
}
nsIOService::~nsIOService()
{
(void)SetOffline(PR_TRUE);
}
NS_METHOD
nsIOService::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
nsresult rv;
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsIOService* _ios = new nsIOService();
if (_ios == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(_ios);
rv = _ios->Init();
if (NS_FAILED(rv)) {
delete _ios;
return rv;
}
rv = _ios->QueryInterface(aIID, aResult);
NS_RELEASE(_ios);
return rv;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsIOService, nsIIOService);
////////////////////////////////////////////////////////////////////////////////
#define MAX_SCHEME_LENGTH 64 // XXX big enough?
#define MAX_NET_PROGID_LENGTH (MAX_SCHEME_LENGTH + NS_NETWORK_PROTOCOL_PROGID_PREFIX_LENGTH + 1)
NS_IMETHODIMP
nsIOService::GetProtocolHandler(const char* scheme, nsIProtocolHandler* *result)
{
nsresult rv;
NS_ASSERTION(NS_NETWORK_PROTOCOL_PROGID_PREFIX_LENGTH
== nsCRT::strlen(NS_NETWORK_PROTOCOL_PROGID_PREFIX),
"need to fix NS_NETWORK_PROTOCOL_PROGID_PREFIX_LENGTH");
// XXX we may want to speed this up by introducing our own protocol
// scheme -> protocol handler mapping, avoiding the string manipulation
// and service manager stuff
char buf[MAX_NET_PROGID_LENGTH];
nsCAutoString progID(NS_NETWORK_PROTOCOL_PROGID_PREFIX);
progID += scheme;
progID.ToLowerCase();
progID.ToCString(buf, MAX_NET_PROGID_LENGTH);
rv = nsServiceManager::GetService(buf, NS_GET_IID(nsIProtocolHandler), (nsISupports **)result);
if (NS_FAILED(rv))
return NS_ERROR_UNKNOWN_PROTOCOL;
return NS_OK;
}
NS_IMETHODIMP
nsIOService::ExtractScheme(const char* inURI, PRUint32 *startPos, PRUint32 *endPos,
char* *scheme)
{
// search for something up to a colon, and call it the scheme
NS_ASSERTION(inURI, "null pointer");
if (!inURI) return NS_ERROR_NULL_POINTER;
const char* uri = inURI;
// skip leading white space
while (nsCRT::IsAsciiSpace(*uri))
uri++;
PRUint32 start = uri - inURI;
if (startPos) {
*startPos = start;
}
PRUint32 length = 0;
char c;
while ((c = *uri++) != '\0') {
if (c == ':') {
if (endPos) {
*endPos = start + length + 1;
}
if (scheme) {
char* str = (char*)nsAllocator::Alloc(length + 1);
if (str == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsCRT::memcpy(str, &inURI[start], length);
str[length] = '\0';
*scheme = str;
}
return NS_OK;
}
else if (nsCRT::IsAsciiAlpha(c)) {
length++;
}
else
break;
}
return NS_ERROR_MALFORMED_URI;
}
nsresult
nsIOService::NewURI(const char* aSpec, nsIURI* aBaseURI,
nsIURI* *result, nsIProtocolHandler* *hdlrResult)
{
nsresult rv;
nsIURI* base;
char* scheme;
rv = ExtractScheme(aSpec, nsnull, nsnull, &scheme);
if (NS_SUCCEEDED(rv)) {
// then aSpec is absolute
// ignore aBaseURI in this case
base = nsnull;
}
else {
// then aSpec is relative
if (aBaseURI == nsnull)
return NS_ERROR_MALFORMED_URI;
rv = aBaseURI->GetScheme(&scheme);
if (NS_FAILED(rv)) return rv;
base = aBaseURI;
}
nsCOMPtr<nsIProtocolHandler> handler;
rv = GetProtocolHandler(scheme, getter_AddRefs(handler));
nsCRT::free(scheme);
if (NS_FAILED(rv)) return rv;
if (hdlrResult) {
*hdlrResult = handler;
NS_ADDREF(*hdlrResult);
}
return handler->NewURI(aSpec, base, result);
}
NS_IMETHODIMP
nsIOService::NewURI(const char* aSpec, nsIURI* aBaseURI,
nsIURI* *result)
{
return NewURI(aSpec, aBaseURI, result, nsnull);
}
NS_IMETHODIMP
nsIOService::NewChannelFromURI(nsIURI *aURI, nsIChannel **result)
{
nsresult rv;
nsXPIDLCString scheme;
rv = aURI->GetScheme(getter_Copies(scheme));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIProtocolHandler> handler;
rv = GetProtocolHandler((const char*)scheme, getter_AddRefs(handler));
if (NS_FAILED(rv)) return rv;
rv = handler->NewChannel(aURI, result);
return rv;
}
NS_IMETHODIMP
nsIOService::NewChannel(const char *aSpec, nsIURI *aBaseURI, nsIChannel **result)
{
nsresult rv;
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIProtocolHandler> handler;
rv = NewURI(aSpec, aBaseURI, getter_AddRefs(uri), getter_AddRefs(handler));
if (NS_FAILED(rv)) return rv;
rv = handler->NewChannel(uri, result);
return rv;
}
NS_IMETHODIMP
nsIOService::GetOffline(PRBool *offline)
{
*offline = mOffline;
return NS_OK;
}
NS_IMETHODIMP
nsIOService::SetOffline(PRBool offline)
{
nsresult rv1 = NS_OK;
nsresult rv2 = NS_OK;
if (offline) {
// be sure to try and shutdown both (even if the first fails)
if (mSocketTransportService)
rv1 = mSocketTransportService->Shutdown();
if (mDNSService)
rv2 = mDNSService->Shutdown();
if (NS_FAILED(rv1)) return rv1;
if (NS_FAILED(rv2)) return rv2;
}
else if (!offline && mOffline) {
// go online
if (mSocketTransportService)
rv1 = mSocketTransportService->Init();
if (NS_FAILED(rv1)) return rv1;
if (mDNSService)
rv2 = mDNSService->Init();
if (NS_FAILED(rv2)) return rv2; //XXX should we shutdown the socket transport service?
}
mOffline = offline;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// URL parsing utilities
/* encode characters into % escaped hexcodes */
/* use the following masks to specify which
part of an URL you want to escape:
url_Scheme = 1
url_Username = 2
url_Password = 4
url_Host = 8
url_Directory = 16
url_FileBaseName = 32
url_FileExtension = 64
url_Param = 128
url_Query = 256
url_Ref = 512
*/
/* by default this function will not escape parts of a string
that already look escaped, which means it already includes
a valid hexcode. This is done to avoid multiple escapes of
a string. Use the following mask to force escaping of a
string:
url_Forced = 1024
*/
NS_IMETHODIMP
nsIOService::Escape(const char *str, PRInt16 mask, char** result)
{
nsCAutoString esc_str;
nsresult rv = nsURLEscape((char*)str,mask,esc_str);
CRTFREEIF(*result);
if (NS_FAILED(rv))
return rv;
*result = esc_str.ToNewCString();
if (!*result)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsIOService::Unescape(const char *str, char **result)
{
return nsURLUnescape((char*)str,result);
}
NS_IMETHODIMP
nsIOService::ExtractPort(const char *str, PRInt32 *result)
{
PRInt32 returnValue = -1;
*result = (0 < PR_sscanf(str, "%d", &returnValue)) ? returnValue : -1;
return NS_OK;
}
NS_IMETHODIMP
nsIOService::ResolveRelativePath(const char *relativePath, const char* basePath,
char **result)
{
nsCAutoString name;
nsCAutoString path(basePath);
PRUnichar last = path.Last();
PRBool needsDelim = !(last == '/' || last == '\\' || last == '\0');
PRBool end = PR_FALSE;
char c;
while (!end) {
c = *relativePath++;
switch (c) {
case '\0':
case '#':
case ';':
case '?':
end = PR_TRUE;
// fall through...
case '/':
case '\\':
// delimiter found
if (name.Equals("..")) {
// pop path
PRInt32 pos = path.RFind("/");
if (pos > 0) {
path.Truncate(pos + 1);
path += name;
}
else {
return NS_ERROR_MALFORMED_URI;
}
}
else if (name.Equals(".") || name.Equals("")) {
// do nothing
}
else {
// append name to path
if (needsDelim)
path += "/";
path += name;
needsDelim = PR_TRUE;
}
name = "";
break;
default:
// append char to name
name += c;
}
}
// append anything left on relativePath (e.g. #..., ;..., ?...)
if (c != '\0')
path += --relativePath;
*result = path.ToNewCString();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsIOService_h__
#define nsIOService_h__
#include "nsIIOService.h"
#include "nsString.h"
#include "nsISocketTransportService.h"
#include "nsIFileTransportService.h"
#include "nsIDNSService.h"
#include "nsCOMPtr.h"
#include "nsURLHelper.h"
class nsIOService : public nsIIOService
{
public:
NS_DECL_ISUPPORTS
// nsIIOService methods:
NS_DECL_NSIIOSERVICE
// nsIOService methods:
nsIOService();
virtual ~nsIOService();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsresult Init();
nsresult NewURI(const char* aSpec, nsIURI* aBaseURI,
nsIURI* *result, nsIProtocolHandler* *hdlrResult);
protected:
PRBool mOffline;
nsCOMPtr<nsISocketTransportService> mSocketTransportService;
nsCOMPtr<nsIFileTransportService> mFileTransportService;
nsCOMPtr<nsIDNSService> mDNSService;
};
#endif // nsIOService_h__

View File

@@ -0,0 +1,487 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsInputStreamChannel.h"
#include "nsCOMPtr.h"
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsIMIMEService.h"
#include "nsIFileTransportService.h"
#include "netCore.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kMIMEServiceCID, NS_MIMESERVICE_CID);
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
////////////////////////////////////////////////////////////////////////////////
// nsInputStreamChannel methods:
nsInputStreamChannel::nsInputStreamChannel()
: mContentType(nsnull), mContentLength(-1), mLoadAttributes(LOAD_NORMAL),
mBufferSegmentSize(0), mBufferMaxSize(0), mStatus(NS_OK)
{
NS_INIT_REFCNT();
}
nsInputStreamChannel::~nsInputStreamChannel()
{
if (mContentType) nsCRT::free(mContentType);
}
NS_METHOD
nsInputStreamChannel::Create(nsISupports *aOuter, REFNSIID aIID,
void **aResult)
{
nsInputStreamChannel* channel = new nsInputStreamChannel();
if (channel == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(channel);
nsresult rv = channel->QueryInterface(aIID, aResult);
NS_RELEASE(channel);
return rv;
}
NS_IMETHODIMP
nsInputStreamChannel::Init(nsIURI* uri,
nsIInputStream* in,
const char* contentType,
PRInt32 contentLength)
{
mURI = uri;
mContentLength = contentLength;
if (contentType) {
mContentType = nsCRT::strdup(contentType);
const char *constContentType = mContentType;
if (!constContentType) return NS_ERROR_OUT_OF_MEMORY;
char* semicolon = PL_strchr(constContentType, ';');
CBufDescriptor cbd(constContentType,
PR_TRUE,
semicolon ? (semicolon-constContentType) + 1: PL_strlen(constContentType), // capacity
semicolon ? (semicolon-constContentType) : PL_strlen(constContentType));
nsCAutoString(cbd).ToLowerCase();
}
mInputStream = in;
return NS_OK;
}
NS_IMPL_THREADSAFE_ISUPPORTS5(nsInputStreamChannel,
nsIInputStreamChannel,
nsIChannel,
nsIRequest,
nsIStreamObserver,
nsIStreamListener);
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_IMETHODIMP
nsInputStreamChannel::IsPending(PRBool *result)
{
if (mFileTransport)
return mFileTransport->IsPending(result);
*result = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::GetStatus(nsresult *status)
{
*status = mStatus;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::Cancel(nsresult status)
{
mStatus = status;
if (mFileTransport)
return mFileTransport->Cancel(status);
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::Suspend(void)
{
if (mFileTransport)
return mFileTransport->Suspend();
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::Resume(void)
{
if (mFileTransport)
return mFileTransport->Resume();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIChannel methods:
NS_IMETHODIMP
nsInputStreamChannel::GetOriginalURI(nsIURI* *aURI)
{
*aURI = mOriginalURI ? mOriginalURI : mURI;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::SetOriginalURI(nsIURI* aURI)
{
mOriginalURI = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::GetURI(nsIURI* *aURI)
{
*aURI = mURI;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::SetURI(nsIURI* aURI)
{
mURI = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::AsyncOpen(nsIStreamObserver *observer, nsISupports* ctxt)
{
if (mFileTransport)
return NS_ERROR_IN_PROGRESS;
nsresult rv;
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = fts->CreateTransportFromStream(mInputStream, mContentType, mContentLength,
getter_AddRefs(mFileTransport));
if (NS_FAILED(rv)) return rv;
if (mBufferSegmentSize > 0) {
rv = mFileTransport->SetBufferSegmentSize(mBufferSegmentSize);
if (NS_FAILED(rv)) return rv;
}
if (mBufferMaxSize > 0) {
rv = mFileTransport->SetBufferMaxSize(mBufferMaxSize);
if (NS_FAILED(rv)) return rv;
}
return mFileTransport->AsyncOpen(observer, ctxt);
}
NS_IMETHODIMP
nsInputStreamChannel::OpenInputStream(nsIInputStream **result)
{
*result = mInputStream;
NS_ADDREF(*result);
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::OpenOutputStream(nsIOutputStream **_retval)
{
// we don't do output
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsInputStreamChannel::AsyncRead(nsIStreamListener *listener, nsISupports *ctxt)
{
nsresult rv;
NS_ASSERTION(listener, "no listener");
mRealListener = listener;
if (mLoadGroup) {
nsCOMPtr<nsILoadGroupListenerFactory> factory;
//
// Create a load group "proxy" listener...
//
rv = mLoadGroup->GetGroupListenerFactory(getter_AddRefs(factory));
if (factory) {
nsIStreamListener *newListener;
rv = factory->CreateLoadGroupListener(mRealListener, &newListener);
if (NS_SUCCEEDED(rv)) {
mRealListener = newListener;
NS_RELEASE(newListener);
}
}
rv = mLoadGroup->AddChannel(this, nsnull);
if (NS_FAILED(rv)) return rv;
}
if (mFileTransport == nsnull) {
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = fts->CreateTransportFromStream(mInputStream, mContentType, mContentLength,
getter_AddRefs(mFileTransport));
if (NS_FAILED(rv)) return rv;
if (mBufferSegmentSize > 0) {
rv = mFileTransport->SetBufferSegmentSize(mBufferSegmentSize);
if (NS_FAILED(rv)) return rv;
}
if (mBufferMaxSize > 0) {
rv = mFileTransport->SetBufferMaxSize(mBufferMaxSize);
if (NS_FAILED(rv)) return rv;
}
}
return mFileTransport->AsyncRead(this, ctxt);
}
NS_IMETHODIMP
nsInputStreamChannel::AsyncWrite(nsIInputStream *fromStream,
nsIStreamObserver *observer, nsISupports *ctxt)
{
// we don't do output
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsInputStreamChannel::GetLoadAttributes(nsLoadFlags *aLoadAttributes)
{
*aLoadAttributes = mLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::SetLoadAttributes(nsLoadFlags aLoadAttributes)
{
mLoadAttributes = aLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::GetContentType(char * *aContentType)
{
*aContentType = nsCRT::strdup(mContentType);
if (*aContentType == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::SetContentType(const char *aContentType)
{
if (mContentType) {
nsCRT::free(mContentType);
}
mContentType = nsCRT::strdup(aContentType);
if (aContentType == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::GetContentLength(PRInt32 *aContentLength)
{
*aContentLength = mContentLength;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::SetContentLength(PRInt32 aContentLength)
{
NS_NOTREACHED("SetContentLength");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsInputStreamChannel::GetTransferOffset(PRUint32 *aTransferOffset)
{
NS_NOTREACHED("GetTransferOffset");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsInputStreamChannel::SetTransferOffset(PRUint32 aTransferOffset)
{
NS_NOTREACHED("SetTransferOffset");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsInputStreamChannel::GetTransferCount(PRInt32 *aTransferCount)
{
NS_NOTREACHED("GetTransferCount");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsInputStreamChannel::SetTransferCount(PRInt32 aTransferCount)
{
NS_NOTREACHED("SetTransferCount");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsInputStreamChannel::GetBufferSegmentSize(PRUint32 *aBufferSegmentSize)
{
*aBufferSegmentSize = mBufferSegmentSize;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::SetBufferSegmentSize(PRUint32 aBufferSegmentSize)
{
mBufferSegmentSize = aBufferSegmentSize;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::GetBufferMaxSize(PRUint32 *aBufferMaxSize)
{
*aBufferMaxSize = mBufferMaxSize;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::SetBufferMaxSize(PRUint32 aBufferMaxSize)
{
mBufferMaxSize = aBufferMaxSize;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::GetShouldCache(PRBool *aShouldCache)
{
*aShouldCache = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::GetPipeliningAllowed(PRBool *aPipeliningAllowed)
{
*aPipeliningAllowed = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::SetPipeliningAllowed(PRBool aPipeliningAllowed)
{
NS_NOTREACHED("SetPipeliningAllowed");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsInputStreamChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup.get();
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::GetOwner(nsISupports* *aOwner)
{
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::SetOwner(nsISupports* aOwner)
{
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
{
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
mCallbacks = aNotificationCallbacks;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
{
*aSecurityInfo = nsnull;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIStreamListener methods:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsInputStreamChannel::OnStartRequest(nsIChannel* transportChannel, nsISupports* context)
{
NS_ASSERTION(mRealListener, "No listener...");
return mRealListener->OnStartRequest(this, context);
}
NS_IMETHODIMP
nsInputStreamChannel::OnStopRequest(nsIChannel* transportChannel, nsISupports* context,
nsresult aStatus, const PRUnichar* aMsg)
{
nsresult rv;
rv = mRealListener->OnStopRequest(this, context, aStatus, aMsg);
if (mLoadGroup) {
if (NS_SUCCEEDED(rv)) {
mLoadGroup->RemoveChannel(this, context, aStatus, aMsg);
}
}
// Release the reference to the consumer stream listener...
mRealListener = null_nsCOMPtr();
mFileTransport = null_nsCOMPtr();
return rv;
}
NS_IMETHODIMP
nsInputStreamChannel::OnDataAvailable(nsIChannel* transportChannel, nsISupports* context,
nsIInputStream *aIStream, PRUint32 aSourceOffset,
PRUint32 aLength)
{
return mRealListener->OnDataAvailable(this, context, aIStream,
aSourceOffset, aLength);
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsInputStreamChannel_h__
#define nsInputStreamChannel_h__
#include "nsIChannel.h"
#include "nsIInputStream.h"
#include "nsIURI.h"
#include "nsCRT.h"
#include "nsILoadGroup.h"
#include "nsIStreamListener.h"
#include "nsIInterfaceRequestor.h"
#include "nsCOMPtr.h"
class nsInputStreamChannel : public nsIInputStreamChannel,
public nsIStreamListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSIINPUTSTREAMCHANNEL
NS_DECL_NSISTREAMOBSERVER
NS_DECL_NSISTREAMLISTENER
nsInputStreamChannel();
virtual ~nsInputStreamChannel();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
protected:
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mURI;
char* mContentType;
PRInt32 mContentLength;
nsCOMPtr<nsIInputStream> mInputStream;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsIChannel> mFileTransport;
nsCOMPtr<nsIStreamListener> mRealListener;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
PRUint32 mLoadAttributes;
nsresult mStatus;
};
#endif // nsInputStreamChannel_h__

View File

@@ -0,0 +1,679 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsLoadGroup.h"
#include "nsIStreamObserver.h"
#include "nsIChannel.h"
#include "nsISupportsArray.h"
#include "nsEnumeratorUtils.h"
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
#include "nsCOMPtr.h"
#include "nsIURI.h"
#include "prlog.h"
#include "nsCRT.h"
#if defined(PR_LOGGING)
//
// Log module for nsILoadGroup logging...
//
// To enable logging (see prlog.h for full details):
//
// set NSPR_LOG_MODULES=LoadGroup:5
// set NSPR_LOG_FILE=nspr.log
//
// this enables PR_LOG_DEBUG level information and places all output in
// the file nspr.log
//
PRLogModuleInfo* gLoadGroupLog = nsnull;
#endif /* PR_LOGGING */
////////////////////////////////////////////////////////////////////////////////
nsLoadGroup::nsLoadGroup(nsISupports* outer)
: mDefaultLoadAttributes(nsIChannel::LOAD_NORMAL),
mForegroundCount(0),
mChannels(nsnull)
{
NS_INIT_AGGREGATED(outer);
#if defined(PR_LOGGING)
//
// Initialize the global PRLogModule for nsILoadGroup logging
// if necessary...
//
if (nsnull == gLoadGroupLog) {
gLoadGroupLog = PR_NewLogModule("LoadGroup");
}
#endif /* PR_LOGGING */
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Created.\n", this));
}
nsLoadGroup::~nsLoadGroup()
{
nsresult rv;
rv = Cancel(NS_BINDING_ABORTED);
NS_ASSERTION(NS_SUCCEEDED(rv), "Cancel failed");
NS_IF_RELEASE(mChannels);
mDefaultLoadChannel = null_nsCOMPtr();
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Destroyed.\n", this));
}
nsresult nsLoadGroup::Init()
{
return NS_NewISupportsArray(&mChannels);
}
NS_METHOD
nsLoadGroup::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
NS_ENSURE_PROPER_AGGREGATION(aOuter, aIID);
nsresult rv;
nsLoadGroup* group = new nsLoadGroup(aOuter);
if (group == nsnull) {
*aResult = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
rv = group->Init();
if (NS_SUCCEEDED(rv)) {
rv = group->AggregatedQueryInterface(aIID, aResult);
}
if (NS_FAILED(rv)) {
delete group;
}
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsISupports methods:
NS_IMPL_AGGREGATED(nsLoadGroup);
NS_IMETHODIMP
nsLoadGroup::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_ENSURE_ARG_POINTER(aInstancePtr);
if (aIID.Equals(NS_GET_IID(nsISupports)))
*aInstancePtr = GetInner();
else if (aIID.Equals(NS_GET_IID(nsILoadGroup)) ||
aIID.Equals(NS_GET_IID(nsIRequest)) ||
aIID.Equals(NS_GET_IID(nsISupports))) {
*aInstancePtr = NS_STATIC_CAST(nsILoadGroup*, this);
}
else if (aIID.Equals(NS_GET_IID(nsISupportsWeakReference))) {
*aInstancePtr = NS_STATIC_CAST(nsISupportsWeakReference*,this);
}
else {
*aInstancePtr = nsnull;
return NS_NOINTERFACE;
}
NS_ADDREF((nsISupports*)*aInstancePtr);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_IMETHODIMP
nsLoadGroup::IsPending(PRBool *aResult)
{
if (mForegroundCount > 0) {
*aResult = PR_TRUE;
} else {
*aResult = PR_FALSE;
}
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::GetStatus(nsresult *status)
{
*status = NS_OK;
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::Cancel(nsresult status)
{
nsresult rv, firstError;
PRUint32 count;
rv = mChannels->Count(&count);
if (NS_FAILED(rv)) return rv;
firstError = NS_OK;
if (count) {
nsIChannel* channel;
//
// Operate the elements from back to front so that if items get
// get removed from the list it won't affect our iteration
//
while (count > 0) {
channel = NS_STATIC_CAST(nsIChannel*, mChannels->ElementAt(--count));
NS_ASSERTION(channel, "NULL channel found in list.");
if (!channel) {
continue;
}
#if defined(PR_LOGGING)
char* uriStr;
nsCOMPtr<nsIURI> uri;
rv = channel->GetURI(getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) {
rv = uri->GetSpec(&uriStr);
}
if (NS_FAILED(rv)) {
uriStr = nsCRT::strdup("?");
}
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Canceling channel %x %s.\n",
this, channel, uriStr));
nsCRT::free(uriStr);
#endif /* PR_LOGGING */
//
// Remove the channel from the load group... This may cause
// the OnStopRequest notification to fire...
//
// XXX: What should the context and error message be?
//
(void)RemoveChannel(channel, nsnull, status, nsnull);
// Cancel the channel...
rv = channel->Cancel(status);
// Remember the first failure and return it...
if (NS_FAILED(rv) && NS_SUCCEEDED(firstError)) {
firstError = rv;
}
NS_RELEASE(channel);
}
#if defined(DEBUG)
(void)mChannels->Count(&count);
NS_ASSERTION(count == 0, "Channel list is not empty.");
NS_ASSERTION(mForegroundCount == 0, "Foreground URLs are active.");
#endif /* DEBUG */
}
return firstError;
}
NS_IMETHODIMP
nsLoadGroup::Suspend()
{
nsresult rv, firstError;
PRUint32 count;
rv = mChannels->Count(&count);
if (NS_FAILED(rv)) return rv;
firstError = NS_OK;
//
// Operate the elements from back to front so that if items get
// get removed from the list it won't affect our iteration
//
while (count > 0) {
nsIChannel* channel;
channel = NS_STATIC_CAST(nsIChannel*, mChannels->ElementAt(--count));
NS_ASSERTION(channel, "NULL channel found in list.");
if (!channel) {
continue;
}
#if defined(PR_LOGGING)
char* uriStr;
nsCOMPtr<nsIURI> uri;
rv = channel->GetURI(getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) {
rv = uri->GetSpec(&uriStr);
}
if (NS_FAILED(rv)) {
uriStr = nsCRT::strdup("?");
}
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Suspending channel %x %s.\n",
this, channel, uriStr));
nsCRT::free(uriStr);
#endif /* PR_LOGGING */
// Suspend the channel...
rv = channel->Suspend();
// Remember the first failure and return it...
if (NS_FAILED(rv) && NS_SUCCEEDED(firstError)) {
firstError = rv;
}
NS_RELEASE(channel);
}
return firstError;
}
NS_IMETHODIMP
nsLoadGroup::Resume()
{
nsresult rv, firstError;
PRUint32 count;
rv = mChannels->Count(&count);
if (NS_FAILED(rv)) return rv;
firstError = NS_OK;
//
// Operate the elements from back to front so that if items get
// get removed from the list it won't affect our iteration
//
while (count > 0) {
nsIChannel* channel;
channel = NS_STATIC_CAST(nsIChannel*, mChannels->ElementAt(--count));
NS_ASSERTION(channel, "NULL channel found in list.");
if (!channel) {
continue;
}
#if defined(PR_LOGGING)
char* uriStr;
nsCOMPtr<nsIURI> uri;
rv = channel->GetURI(getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) {
rv = uri->GetSpec(&uriStr);
}
if (NS_FAILED(rv)) {
uriStr = nsCRT::strdup("?");
}
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Resuming channel %x %s.\n",
this, channel, uriStr));
nsCRT::free(uriStr);
#endif /* PR_LOGGING */
// Resume the channel...
rv = channel->Resume();
// Remember the first failure and return it...
if (NS_FAILED(rv) && NS_SUCCEEDED(firstError)) {
firstError = rv;
}
NS_RELEASE(channel);
}
return firstError;
}
////////////////////////////////////////////////////////////////////////////////
// nsILoadGroup methods:
NS_IMETHODIMP
nsLoadGroup::Init(nsIStreamObserver *aObserver)
{
nsresult rv;
rv = SetGroupObserver(aObserver);
return rv;
}
NS_IMETHODIMP
nsLoadGroup::GetDefaultLoadAttributes(PRUint32 *aDefaultLoadAttributes)
{
*aDefaultLoadAttributes = mDefaultLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::SetDefaultLoadAttributes(PRUint32 aDefaultLoadAttributes)
{
mDefaultLoadAttributes = aDefaultLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::GetDefaultLoadChannel(nsIChannel * *aChannel)
{
*aChannel = mDefaultLoadChannel;
NS_IF_ADDREF(*aChannel);
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::SetDefaultLoadChannel(nsIChannel *aChannel)
{
mDefaultLoadChannel = aChannel;
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::AddChannel(nsIChannel *channel, nsISupports* ctxt)
{
nsresult rv;
#if defined(PR_LOGGING)
{
PRUint32 count;
char* uriStr;
nsCOMPtr<nsIURI> uri;
rv = channel->GetURI(getter_AddRefs(uri));
if (NS_SUCCEEDED(rv))
rv = uri->GetSpec(&uriStr);
if (NS_FAILED(rv))
uriStr = nsCRT::strdup("?");
(void)mChannels->Count(&count);
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Adding channel %x %s (count=%d).\n",
this, channel, uriStr, count));
nsCRT::free(uriStr);
}
#endif /* PR_LOGGING */
nsLoadFlags flags;
MergeLoadAttributes(channel);
rv = channel->GetLoadAttributes(&flags);
if (NS_FAILED(rv)) return rv;
//
// Add the channel to the list of active channels...
//
// XXX this method incorrectly returns a bool
//
rv = mChannels->AppendElement(channel) ? NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
if (!(flags & nsIChannel::LOAD_BACKGROUND)) {
// Update the count of foreground URIs..
mForegroundCount += 1;
//
// Fire the OnStartRequest notification out to the observer...
//
// If the notification fails then DO NOT add the channel to
// the load group.
//
nsCOMPtr<nsIStreamObserver> observer (do_QueryReferent(mObserver));
if (observer) {
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Firing OnStartRequest for channel %x."
"(foreground count=%d).\n",
this, channel, mForegroundCount));
rv = observer->OnStartRequest(channel, ctxt);
if (NS_FAILED(rv)) {
PR_LOG(gLoadGroupLog, PR_LOG_ERROR,
("LOADGROUP [%x]: OnStartRequest for channel %x FAILED.\n",
this, channel));
//
// The URI load has been canceled by the observer. Clean up
// the damage...
//
// XXX this method incorrectly returns a bool
//
rv = mChannels->RemoveElement(channel) ? NS_OK : NS_ERROR_FAILURE;
mForegroundCount -= 1;
}
}
}
return rv;
}
NS_IMETHODIMP
nsLoadGroup::RemoveChannel(nsIChannel *channel, nsISupports* ctxt,
nsresult status, const PRUnichar *errorMsg)
{
nsresult rv;
#if defined(PR_LOGGING)
{
PRUint32 count = 0;
char* uriStr;
nsCOMPtr<nsIURI> uri;
if (channel) {
rv = channel->GetURI(getter_AddRefs(uri));
}
else {
rv = NS_ERROR_NULL_POINTER;
}
if (NS_SUCCEEDED(rv))
rv = uri->GetSpec(&uriStr);
if (NS_FAILED(rv))
uriStr = nsCRT::strdup("?");
(void)mChannels->Count(&count);
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Removing channel %x %s status %x (count=%d).\n",
this, channel, uriStr, status, count-1));
nsCRT::free(uriStr);
}
#endif /* PR_LOGGING */
//
// Remove the channel from the group. If this fails, it means that
// the channel was *not* in the group so do not update the foreground
// count or it will get messed up...
//
//
// XXX this method incorrectly returns a bool
//
rv = mChannels->RemoveElement(channel) ? NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) {
PR_LOG(gLoadGroupLog, PR_LOG_ERROR,
("LOADGROUP [%x]: Unable to remove channel %x. Not in group!\n",
this, channel));
return rv;
}
nsLoadFlags flags;
rv = channel->GetLoadAttributes(&flags);
if (NS_FAILED(rv)) return rv;
if (!(flags & nsIChannel::LOAD_BACKGROUND)) {
NS_ASSERTION(mForegroundCount > 0, "ForegroundCount messed up");
mForegroundCount -= 1;
// Fire the OnStopRequest out to the observer...
nsCOMPtr<nsIStreamObserver> observer (do_QueryReferent(mObserver));
if (observer) {
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Firing OnStopRequest for channel %x."
"(foreground count=%d).\n",
this, channel, mForegroundCount));
rv = observer->OnStopRequest(channel, ctxt, status, errorMsg);
if (NS_FAILED(rv)) {
PR_LOG(gLoadGroupLog, PR_LOG_ERROR,
("LOADGROUP [%x]: OnStopRequest for channel %x FAILED.\n",
this, channel));
}
}
}
return rv;
}
NS_IMETHODIMP
nsLoadGroup::GetChannels(nsISimpleEnumerator * *aChannels)
{
return NS_NewArrayEnumerator(aChannels, mChannels);
}
NS_IMETHODIMP
nsLoadGroup::GetGroupListenerFactory(nsILoadGroupListenerFactory * *aFactory)
{
if (mGroupListenerFactory) {
mGroupListenerFactory->QueryReferent(NS_GET_IID(nsILoadGroupListenerFactory), (void**)aFactory);
}
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::SetGroupListenerFactory(nsILoadGroupListenerFactory *aFactory)
{
mGroupListenerFactory = getter_AddRefs(NS_GetWeakReference(aFactory));
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::SetGroupObserver(nsIStreamObserver* aObserver)
{
nsresult rv = NS_OK;
// Release the old observer (if any...)
mObserver = null_nsCOMPtr();
#if 0
if (aObserver) {
nsCOMPtr<nsIEventQueue> eventQueue;
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueService, &rv);
if (NS_FAILED(rv)) return rv;
rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eventQueue));
if (NS_FAILED(rv)) return rv;
rv = NS_NewAsyncStreamObserver(getter_AddRefs(mObserver),
eventQueue, aObserver);
}
#else
//mObserver = aObserver;
mObserver = getter_AddRefs(NS_GetWeakReference(aObserver));
#endif
return rv;
}
NS_IMETHODIMP
nsLoadGroup::GetGroupObserver(nsIStreamObserver* *aResult)
{
nsCOMPtr<nsIStreamObserver> observer (do_QueryReferent(mObserver));
*aResult = observer;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::GetActiveCount(PRUint32* aResult)
{
*aResult = mForegroundCount;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
nsresult nsLoadGroup::MergeLoadAttributes(nsIChannel *aChannel)
{
nsresult rv;
nsLoadFlags flags, oldFlags;
rv = aChannel->GetLoadAttributes(&flags);
if (NS_FAILED(rv)) return rv;
oldFlags = flags;
//
// Inherit the group cache validation policy (bits 12-15)
//
if ( !((nsIChannel::VALIDATE_NEVER |
nsIChannel::VALIDATE_ALWAYS |
nsIChannel::VALIDATE_ONCE_PER_SESSION |
nsIChannel::VALIDATE_HEURISTICALLY) & flags)) {
flags |= (nsIChannel::VALIDATE_NEVER |
nsIChannel::VALIDATE_ALWAYS |
nsIChannel::VALIDATE_ONCE_PER_SESSION |
nsIChannel::VALIDATE_HEURISTICALLY) & mDefaultLoadAttributes;
}
//
// Inherit the group reload policy (bits 9-10)
//
if (!(nsIChannel::FORCE_VALIDATION & flags)) {
flags |= (nsIChannel::FORCE_VALIDATION & mDefaultLoadAttributes);
}
if (!(nsIChannel::FORCE_RELOAD & flags)) {
flags |= (nsIChannel::FORCE_RELOAD & mDefaultLoadAttributes);
}
//
// Inherit the group persistent cache policy (bit 8)
//
if (!(nsIChannel::INHIBIT_PERSISTENT_CACHING & flags)) {
flags |= (nsIChannel::INHIBIT_PERSISTENT_CACHING & mDefaultLoadAttributes);
}
//
// Inherit the group loading policy (bit 0)
//
if (!(nsIChannel::LOAD_BACKGROUND & flags)) {
flags |= (nsIChannel::LOAD_BACKGROUND & mDefaultLoadAttributes);
}
if (flags != oldFlags) {
rv = aChannel->SetLoadAttributes(flags);
}
return rv;
}

View File

@@ -0,0 +1,77 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsLoadGroup_h__
#define nsLoadGroup_h__
#include "nsILoadGroup.h"
#include "nsIChannel.h"
#include "nsIStreamListener.h"
#include "nsAgg.h"
#include "nsCOMPtr.h"
#include "nsWeakPtr.h"
#include "nsWeakReference.h"
class nsISupportsArray;
class nsLoadGroup : public nsILoadGroup,
public nsSupportsWeakReference
{
public:
NS_DECL_AGGREGATED
////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_DECL_NSIREQUEST
////////////////////////////////////////////////////////////////////////////
// nsILoadGroup methods:
NS_DECL_NSILOADGROUP
////////////////////////////////////////////////////////////////////////////
// nsLoadGroup methods:
nsLoadGroup(nsISupports* outer);
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
protected:
virtual ~nsLoadGroup();
nsresult Init();
nsresult MergeLoadAttributes(nsIChannel *aChannel);
protected:
PRUint32 mDefaultLoadAttributes;
PRUint32 mForegroundCount;
nsISupportsArray* mChannels;
nsWeakPtr mObserver;
// nsCOMPtr<nsIStreamObserver> mObserver;
nsCOMPtr<nsIChannel> mDefaultLoadChannel;
nsWeakPtr mGroupListenerFactory;
};
#endif // nsLoadGroup_h__

View File

@@ -0,0 +1,183 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsNetModRegEntry.h"
#include "plstr.h"
#include "nsIAllocator.h"
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
#include "nsProxyObjectManager.h"
static NS_DEFINE_IID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
//////////////////////////////
//// nsISupports
//////////////////////////////
NS_IMPL_ISUPPORTS(nsNetModRegEntry, NS_GET_IID(nsINetModRegEntry));
//////////////////////////////
//// nsINetModRegEntry
//////////////////////////////
NS_IMETHODIMP
nsNetModRegEntry::GetSyncProxy(nsINetNotify **aNotify)
{
if (mSyncProxy)
{
*aNotify = mSyncProxy;
NS_ADDREF(*aNotify);
return NS_OK;
}
nsresult rv = BuildProxy(PR_TRUE);
if (NS_SUCCEEDED(rv))
{
*aNotify = mSyncProxy;
NS_ADDREF(*aNotify);
}
return rv;
}
NS_IMETHODIMP
nsNetModRegEntry::GetAsyncProxy(nsINetNotify **aNotify)
{
if (mAsyncProxy)
{
*aNotify = mAsyncProxy;
NS_ADDREF(*aNotify);
return NS_OK;
}
nsresult rv = BuildProxy(PR_FALSE);
if (NS_SUCCEEDED(rv))
{
*aNotify = mAsyncProxy;
NS_ADDREF(*aNotify);
}
return rv;
}
NS_IMETHODIMP
nsNetModRegEntry::GetTopic(char **topic)
{
if (mTopic)
{
*topic = (char *) nsAllocator::Clone(mTopic, nsCRT::strlen(mTopic) + 1);
return NS_OK;
}
return NS_ERROR_NULL_POINTER;
}
NS_IMETHODIMP
nsNetModRegEntry::Equals(nsINetModRegEntry* aEntry, PRBool *_retVal)
{
nsresult rv = NS_OK;
*_retVal = PR_FALSE;
char* topic;
rv = aEntry->GetTopic(&topic);
if (NS_FAILED(rv))
return rv;
if (topic && PL_strcmp(topic, mTopic))
{
nsCOMPtr<nsINetNotify> aSyncProxy;
rv = aEntry->GetSyncProxy(getter_AddRefs(aSyncProxy));
if(aSyncProxy == mSyncProxy)
{
*_retVal = PR_TRUE;
}
nsAllocator::Free(topic);
}
return rv;
}
//////////////////////////////
//// nsNetModRegEntry
//////////////////////////////
nsNetModRegEntry::nsNetModRegEntry(const char *aTopic,
nsINetNotify *aNotify,
nsresult *result)
{
NS_INIT_REFCNT();
mTopic = new char [PL_strlen(aTopic) + 1];
PL_strcpy(mTopic, aTopic);
mAsyncProxy = nsnull;
mSyncProxy = nsnull;
mRealNotifier = aNotify;
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, result);
if (NS_FAILED(*result)) return;
*result = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(mEventQ));
}
nsresult
nsNetModRegEntry::BuildProxy(PRBool sync)
{
if (mEventQ == nsnull)
return NS_ERROR_NULL_POINTER;
nsresult result;
NS_WITH_SERVICE( nsIProxyObjectManager, proxyManager, kProxyObjectManagerCID, &result);
if (NS_FAILED(result))
return result;
if (sync)
{
result = proxyManager->GetProxyObject( mEventQ,
NS_GET_IID(nsINetNotify),
mRealNotifier,
PROXY_SYNC | PROXY_ALWAYS,
getter_AddRefs(mSyncProxy));
}
else
{
result = proxyManager->GetProxyObject( mEventQ,
NS_GET_IID(nsINetNotify),
mRealNotifier,
PROXY_ASYNC | PROXY_ALWAYS,
getter_AddRefs(mAsyncProxy));
}
return result;
}
nsNetModRegEntry::~nsNetModRegEntry()
{
delete [] mTopic;
}

View File

@@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef ___nsNetModRegEntry_h___
#define ___nsNetModRegEntry_h___
#include "nsINetModRegEntry.h"
#include "nsIEventQueue.h"
#include "nsCOMPtr.h"
class nsNetModRegEntry : public nsINetModRegEntry {
public:
// nsISupports
NS_DECL_ISUPPORTS
// nsINetModRegEntry
NS_IMETHOD GetSyncProxy(nsINetNotify * *aSyncProxy);
NS_IMETHOD GetAsyncProxy(nsINetNotify * *aAsyncProxy);
NS_IMETHOD GetTopic(char * *aTopic);
NS_IMETHOD Equals(nsINetModRegEntry* aEntry, PRBool *_retVal);
// nsNetModRegEntry
nsNetModRegEntry(const char *aTopic, nsINetNotify *aNotify, nsresult *result);
virtual ~nsNetModRegEntry();
protected:
char *mTopic;
nsCOMPtr<nsINetNotify> mRealNotifier;
nsCOMPtr<nsINetNotify> mSyncProxy;
nsCOMPtr<nsINetNotify> mAsyncProxy;
nsCOMPtr<nsIEventQueue> mEventQ;
nsresult BuildProxy(PRBool sync);
};
#endif //___nsNetModRegEntry_h___

View File

@@ -0,0 +1,203 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsAutoLock.h"
#include "nsNetModuleMgr.h"
#include "nsNetModRegEntry.h"
#include "nsEnumeratorUtils.h" // for nsArrayEnumerator
#include "nsString.h"
#include "nsXPIDLString.h"
#include "nsIEventQueue.h"
nsNetModuleMgr* nsNetModuleMgr::gManager;
///////////////////////////////////
//// nsISupports
///////////////////////////////////
NS_IMPL_ISUPPORTS(nsNetModuleMgr, NS_GET_IID(nsINetModuleMgr));
///////////////////////////////////
//// nsINetModuleMgr
///////////////////////////////////
NS_IMETHODIMP
nsNetModuleMgr::RegisterModule(const char *aTopic, nsINetNotify *aNotify)
{
nsresult rv;
PRUint32 cnt;
// XXX before registering an object for a particular topic
// XXX QI the nsINetNotify interface passed in for the interfaces
// XXX supported by the topic.
nsAutoLock lock(mLock);
nsNetModRegEntry *newEntry = new nsNetModRegEntry(aTopic, aNotify, &rv);
if (!newEntry)
return NS_ERROR_OUT_OF_MEMORY;
if (NS_FAILED(rv)) {
delete newEntry;
return rv;
}
nsCOMPtr<nsINetModRegEntry> newEntryI = do_QueryInterface(newEntry, &rv);
if (NS_FAILED(rv)) {
delete newEntry;
return rv;
}
// Check for a previous registration
mEntries->Count(&cnt);
for (PRUint32 i = 0; i < cnt; i++)
{
nsCOMPtr<nsINetModRegEntry> curEntry =
dont_AddRef(NS_STATIC_CAST(nsINetModRegEntry*, mEntries->ElementAt(i)));
PRBool same = PR_FALSE;
rv = newEntryI->Equals(curEntry, &same);
if (NS_FAILED(rv)) return rv;
// if we've already got this one registered, yank it, and replace it with the new one
if (same) {
mEntries->DeleteElementAt(i);
break;
}
}
rv = mEntries->AppendElement(NS_STATIC_CAST(nsISupports*, newEntryI)) ? NS_OK : NS_ERROR_FAILURE; // XXX this method incorrectly returns a bool
return rv;
}
NS_IMETHODIMP
nsNetModuleMgr::UnregisterModule(const char *aTopic, nsINetNotify *aNotify)
{
nsAutoLock lock(mLock);
nsresult rv;
nsCOMPtr<nsINetModRegEntry> tmpEntryI;
nsNetModRegEntry *tmpEntry = new nsNetModRegEntry(aTopic, aNotify, &rv);
if (!tmpEntry)
return NS_ERROR_OUT_OF_MEMORY;
if (NS_FAILED(rv)) return rv;
rv = tmpEntry->QueryInterface(NS_GET_IID(nsINetModRegEntry), getter_AddRefs(tmpEntryI));
if (NS_FAILED(rv)) return rv;
PRUint32 cnt;
mEntries->Count(&cnt);
for (PRUint32 i = 0; i < cnt; i++) {
nsCOMPtr<nsINetModRegEntry> curEntry =
dont_AddRef(NS_STATIC_CAST(nsINetModRegEntry*, mEntries->ElementAt(i)));
PRBool same = PR_FALSE;
rv = tmpEntryI->Equals(curEntry, &same);
if (NS_FAILED(rv)) return rv;
if (same) {
mEntries->DeleteElementAt(i);
break;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsNetModuleMgr::EnumerateModules(const char *aTopic, nsISimpleEnumerator **aEnumerator) {
nsresult rv;
// get all the entries for this topic
nsAutoLock lock(mLock);
PRUint32 cnt;
rv = mEntries->Count(&cnt);
if (NS_FAILED(rv)) return rv;
// create the new array
nsCOMPtr<nsISupportsArray> topicEntries;
rv = NS_NewISupportsArray(getter_AddRefs(topicEntries));
if (NS_FAILED(rv)) return rv;
// run through the main entry array looking for topic matches.
for (PRUint32 i = 0; i < cnt; i++) {
nsCOMPtr<nsINetModRegEntry> entry =
dont_AddRef(NS_STATIC_CAST(nsINetModRegEntry*, mEntries->ElementAt(i)));
nsXPIDLCString topic;
rv = entry->GetTopic(getter_Copies(topic));
if (NS_FAILED(rv)) return rv;
if (0 == PL_strcmp(aTopic, topic)) {
// found a match, add it to the list
rv = topicEntries->AppendElement(NS_STATIC_CAST(nsISupports*, entry)) ? NS_OK : NS_ERROR_FAILURE; // XXX this method incorrectly returns a bool
if (NS_FAILED(rv)) return rv;
}
}
nsCOMPtr<nsISimpleEnumerator> enumerator;
rv = NS_NewArrayEnumerator(getter_AddRefs(enumerator), topicEntries);
if (NS_FAILED(rv)) return rv;
*aEnumerator = enumerator;
NS_ADDREF(*aEnumerator);
return NS_OK;
}
///////////////////////////////////
//// nsNetModuleMgr
///////////////////////////////////
nsNetModuleMgr::nsNetModuleMgr() {
NS_INIT_REFCNT();
NS_NewISupportsArray(&mEntries);
mLock = PR_NewLock();
}
nsNetModuleMgr::~nsNetModuleMgr() {
NS_IF_RELEASE(mEntries);
PR_DestroyLock(mLock);
gManager = nsnull;
}
NS_METHOD
nsNetModuleMgr::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
if (! gManager) {
gManager = new nsNetModuleMgr();
if (! gManager)
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(gManager);
nsresult rv = gManager->QueryInterface(aIID, aResult);
NS_RELEASE(gManager);
return rv;
}

Some files were not shown because too many files have changed in this diff Show More