Пример #1
0
int
BCMROMFN(aes_ccm_decrypt)(unsigned int *rk,
                          const size_t key_len,
                          const uint8 *nonce,
                          const size_t aad_len,
                          const uint8 *aad,
                          const size_t data_len,
                          const uint8 *ctxt,
                          uint8 *ptxt)
{
	uint8 A[AES_BLOCK_SZ], X[AES_BLOCK_SZ];

	/* initialize counter */
	A[0] = AES_CCM_CRYPT_FLAGS;
	memcpy(&A[1], nonce, AES_CCM_NONCE_LEN);
	A[AES_BLOCK_SZ - 2] = 0;
	A[AES_BLOCK_SZ - 1] = 1;
	pres("aes_ccm_decrypt: initial counter:", AES_BLOCK_SZ, A);

	/* decrypt data */
	if (aes_ctr_crypt(rk, key_len, A, data_len-AES_CCM_AUTH_LEN, ctxt, ptxt))
		return (-1);
	pres("aes_ccm_decrypt: decrypted data:", data_len-AES_CCM_AUTH_LEN, ptxt);

	/* decrypt MAC */
	A[AES_BLOCK_SZ - 2] = 0;
	A[AES_BLOCK_SZ - 1] = 0;
	if (aes_ctr_crypt(rk, key_len, A, AES_CCM_AUTH_LEN,
	                  ctxt+data_len-AES_CCM_AUTH_LEN, ptxt + data_len - AES_CCM_AUTH_LEN))
		return (-1);
	pres("aes_ccm_decrypt: decrypted MAC:", AES_CCM_AUTH_LEN,
	     ptxt + data_len - AES_CCM_AUTH_LEN);

	/* calculate MAC */
	if (aes_ccm_mac(rk, key_len, nonce, aad_len, aad,
	                data_len - AES_CCM_AUTH_LEN, ptxt, X))
		return (-1);
	pres("aes_ccm_decrypt: MAC:", AES_CCM_AUTH_LEN, X);
	if (memcmp(X, ptxt + data_len - AES_CCM_AUTH_LEN, AES_CCM_AUTH_LEN) != 0)
		return (-1);

	return (0);
}
Пример #2
0
void main(void) {
	bank_spr (1);
	bank_bg (0);

	ppu_off ();
	first_game = 1;

	// Main loop

	while (1) {	
		pres (palts0, scr_title);

#ifdef MULTI_LEVEL		
		level = 0;
#endif
		plife = PLAYER_LIFE;

		// Game loop

		while (1) {
			scroll (0, SCROLL_Y);
			game_init (); 
			game_loop ();

			if (game_over) {
				pres (palts0, scr_game_over);
				break;
			} else {
#ifdef MULTI_LEVEL
				level ++;
				if (level == MAX_LEVELS) 
#endif
				{
					pres (palts0, scr_the_end);
					break;
				}
			}
		}

		first_game = 0;
	}
}
Пример #3
0
void test_rsmc()
{
  rsmc *rs, *ars = new rsmc[10];
  rsmcDao *rsd = new rsmcDao();
  //vector<rsmc> vrs(10);
  char name[20];
  ull *indices = new ull[10];
  windDao *wnd = new windDao();
  wind *w = wnd->findById(0);
  
  printf(">>>> wind force = %f\n", w->getForce());
  rs = new rsmc();
  rs->setId(1);
  rs->setName("tunoshna_station");
  rs->setType(0);
  rsd->insert(rs);
  delete rs;
  pres(rs = rsd->findById(1), 1);
  rs->setType(1);
  rsd->update(rs);
  pres(rs = rsd->findById(1), 1);
  rsd->remove(rs);
  //EXEC SQL COMMIT WORK RELEASE;

  init_test_rsmc(ars, name, indices, 10);
  rsd->insert(ars, 10);
  delete [] ars;
  ars = rsd->findById(indices, 10);
  pres(ars, 10);
  for (int i = 1; i < 10; ++i) { 
    ars[i].setType(i + 10);
  }

  rsd->update(ars, 10);
  delete [] ars;
  ars = rsd->findById(indices, 10);
  pres(ars, 10);
  rsd->remove(ars, 10);
}
Пример #4
0
void 
unixfd::rcb ()
{
  if (reof) {
    fdcb (localfd_in, selread, NULL);
    return;
  }

  char buf[16*1024];
  int fdrecved = -1;
  ssize_t n;
  if (unixsock)
    n = readfd (localfd_in, buf, sizeof (buf), &fdrecved);
  else
    n = read (localfd_in, buf, sizeof (buf));

  if (n < 0) {
    if (errno != EAGAIN)
      abort ();
    return;
  }

  if (!n) {
    readeof ();
    return;
  }
  else {
    rex_payload arg;
    arg.channel = channo;
    arg.fd = fd;
    arg.data.set (buf, n);

    if (fdrecved >= 0) {
      close_on_exec (fdrecved);
      rex_newfd_arg arg;
      arg.channel = channo;
      arg.fd = fd;
      ref<rex_newfd_res> resp (New refcounted<rex_newfd_res> (false));
      proxy->call (REX_NEWFD, &arg, resp,
		   wrap (mkref (this), &unixfd::newfdcb, fdrecved, resp));
    }

    ref<bool> pres (New refcounted<bool> (false));
    rsize += n;
    proxy->call (REX_DATA, &arg, pres,
		 wrap (mkref (this), &unixfd::datacb, n, pres));
  }

  if (rsize >= hiwat)
    fdcb (localfd_in, selread, NULL);
}
Пример #5
0
oop processOopClass::AbortProcess_prim(void *FH) {
  Process* proc = checkProcess(this);
  if (!proc) {
    prim_failure(FH, NOPROCESSERROR);
    return NULL;
  }
  if (proc == twainsProcess)  {
    prim_failure(FH, PRIMITIVEFAILEDERROR);
    return NULL;
  }
  preserved pres(this);
  proc->abort();
  if (proc->state == defunct) fatal("process already deleted");
  delete proc;
  return pres.value;
}
Пример #6
0
vector<KnowledgeAnswer> solver::arbiterStep(drt question)
{
	vector<KnowledgeAnswer> to_return;

	int n = 0;
	DrtMgu mgu;
	bool yn_question;
	vector<DrtPred> qlist = question.getQuestionList().get();
	if (qlist.size() == 0)
		yn_question = true;
	else
		yn_question = false;

	int max_level = min(standard_max_level,wi_->getAccuracyLevel());


	int approx_level = 5;
	if (yn_question)
		max_level = min(max_level,4); // the 5th level is only word association, it does not work well with yes/no questions
	drt old_question;

	vector<int> approximations_with_same_candidates; //C++11// = {0,1,2};
	approximations_with_same_candidates.push_back(0);
	approximations_with_same_candidates.push_back(1);
	approximations_with_same_candidates.push_back(2);

	k_->setWisdomInfo(*wi_);

	vector<int> skip_level; //C++11// = {};
	vector<Candidate> candidates;
	do {
		if(shortfind(skip_level,n) )
			continue;
		if(wi_->getTimeout() < 0)
			break;



		pair<drt, DrtMgu> answer_pair = relax_conditions_in_question_at_level(question, mgu, n);
		question = answer_pair.first;
		mgu = answer_pair.second;


		// Finds the answers by searching in the knowledge
		clock_t start;

		vector<KnowledgeAnswer> tmp_answers;
		if(n == 0) {
			candidates = k_->getAnswerCandidates(question);
		}
		if(shortfind(approximations_with_same_candidates,n) ) {
			tmp_answers = k_->getAnswers(question,candidates);
		} else {
			tmp_answers = k_->getAnswers(question);
		}


		to_return.insert(to_return.end(), tmp_answers.begin(), tmp_answers.end());

		bool skip_presuppositions = true; // Skip them for now, it adds too much complexity ( questions can be truncated)
		//bool skip_presuppositions = false;
		if( to_return.size() == 0 && wi_->getSkipPresuppositions() )
			skip_presuppositions = true;
		if (n == 0 && !skip_presuppositions) {

			// Adds the answers to the presupposed questions
			vector<drt> presupp_questions;
			question.set_question();
			Presupposition pres(question); /// CORRECT: it considers only one question!!
			vector<drt> pres_drtvect = pres.get();
			if (debug)
				cout << "PRESUPPOSITION:::" << pres_drtvect.size() << endl;
			presupp_questions.insert(presupp_questions.end(), pres_drtvect.begin(), pres_drtvect.end());

			// Finds the answers to the presupposed questions by searching in the knowledge
			vector<vector<KnowledgeAnswer> > presupp_answers;
			for (int qnum = 0; qnum < presupp_questions.size(); ++qnum) {
				if(wi_->getTimeout() < 0)
					break;
				vector<KnowledgeAnswer> tmp_answers = k_->getAnswers(presupp_questions.at(qnum));
				presupp_answers.push_back(tmp_answers);
			}

			for (int q = 0; q < presupp_answers.size(); ++q)
				to_return.insert(to_return.end(), presupp_answers.at(q).begin(), presupp_answers.at(q).end());
		}


	} while (to_return.size() == 0 && n++ < max_level);

	if (debug)
		puts("END_SOLVER:::");

	if (debug)
		cout << "ADDITIONAL_MGU:::" << mgu;

	use_mgu_prior(to_return, mgu);

	return to_return;
}
Пример #7
0
int
main (void)
{
  spline = NULL;
  acc = NULL;
  int i, status;
  double r, r1, y[2];
  // bounds for making grid of m(R) vs. rho(0)
  const double rho_min = 1.0e+13, rho_max = 9.0e+14;
  const int MAX = 100;
  // pressure/density arrays from tabulated EOS data
  int n_eos_pts;
  FILE *fp = NULL;
  double (*pres) (double, void *);	// EOS pressure pointer
  double (*rho) (double, void *);	// EOS density pointer
  double tmp;
  // pointers to tabulated EOS data
  double *eos_tab_pres = NULL, *eos_tab_dens = NULL;

  /* this is the "third arm" of the EOS inversion routine. GSL calls
     the function whose root is being found several times during
     initialization and if we leave the pressure here uninitialized,
     it might be 0 or something crazy, which will be out of bounds of
     the "forward" EOS, and since the forward EOS uses interpolation,
     an out-of-bounds value of pressure will make it crash. */
  tmp_pres = 1.0e+25;

  pres = &eos_pres;
  rho = &eos_rho;

  //  fp = fopen("bck.eos", "r");
  //  fp = fopen("eosC", "r");
  //  fp = fopen("timmes.eos", "r");
  fp = fopen ("../EOS/helmholtz.eos", "r");

  if (fp == NULL)
    {
      fprintf (stderr, "Can't open file!\n");
      exit (1);
    }

  // read in # of EOS data points
  fscanf (fp, "%i", &n_eos_pts);

  eos_tab_dens = (double *) malloc (n_eos_pts * sizeof (double));
  eos_tab_pres = (double *) malloc (n_eos_pts * sizeof (double));

  // read in density and pressure data
  for (i = 0; i < n_eos_pts; i++)
    {
      fscanf (fp, "%le %le", &eos_tab_dens[i], &eos_tab_pres[i]);
    }
  fclose (fp);

  // set up interpolation machinery for EOS
  acc = gsl_interp_accel_alloc ();
  spline = gsl_spline_alloc (gsl_interp_cspline, n_eos_pts);
  gsl_spline_init (spline, eos_tab_dens, eos_tab_pres, n_eos_pts);

  // now make grid
  r = 1.0;			// the integrator will go nuts if we start right at r=0
  r1 = 1.0e+10;			// some final 'radius' (much larger than actual radius)

  printf ("%12s %12s %12s\n", "R", "M(r=R)", "rho(r=0)");

  params.single_star = 1;
  for (i = 0; i < MAX; i++)
    {
      // rho(0) evenly spaced in log
      params.rho_init = log10 (rho_min) +
	(double) i *((log10 (rho_max) - log10 (rho_min)) / (double) MAX);
      params.rho_init = pow (10.0, params.rho_init);

      y[1] = pres (params.rho_init, &params);
      y[0] = (4.0 / 3.0) * M_PI * pow (r, 3.0) * rho (y[1], &params);

      params.pinit = y[1];
      // This function is useful if you want to plot, e.g., central
      // pressure vs. total mass. You can also hang onto the run of
      // pressure with radius, which can be interesting when compared to
      // the Newtonian case.
      status = make_grid (params, r, r1, y);
    }

/*
  params.single_star = 0;
  printf("\nnow for a single star!\n");
  printf("%12s %12s %12s %12s\n", "r", "M(r)", "P(r)", "rho(r)");
  // print P and M vs r for Chandrasekhar-mass star
  params.rho_init = 1.0e+13;

  y[1] = pres(params.rho_init, &params); // rho(0) (roughly) for maximum mass
  y[0] = (4.0/3.0) * M_PI * pow(r, 3.0) * rho(y[1], &params);

  params.pinit = y[1];
  status = make_grid(params, r, r1, y);
*/

  gsl_spline_free (spline);
  gsl_interp_accel_free (acc);

  free (eos_tab_pres);
  free (eos_tab_dens);

  eos_tab_dens = NULL;
  eos_tab_pres = NULL;
  fp = NULL;
  pres = NULL;
  rho = NULL;
  return 0;
}
Пример #8
0
PresentationForNG NilpotentGroupRep::makePresentation() const {
  PresentationForNG pres(collector(), relators() );
  pres.build();
  return pres;
}
Пример #9
0
bool Controller::Start(char* serverIp, char* name) {
	connection = new ConnectionAPI(this);
	UdpConnection udp;
	SessionLayer sess(&udp);
	PresentationLayer pres(&sess);
	ApplicationLayer app(&pres);
	udp.SetCallback(&sess);
	sess.SetCallback(&pres);
	pres.SetCallback(&app);
	app.SetCallback(connection);

	short roll, pitch, yaw;

	strcpy(serverAddress, serverIp);

	connection->SetConnection(&app);
	bool res = false;

	while (res == false) {
		Debugger(INFO) << "Trying to connecto to the server " << serverIp << " at " << DEFAULT_ROBOT_PORT << "\n";

		res = connection->Connect(name, serverIp, DEFAULT_ROBOT_PORT);
		if (res == false) {
			Debugger(WARNING) << "Connection was not succesful. Trying to reconnect in 10s...\n";
			usleep(10 * 1000 * 1000);
		}
	}
	Debugger(INFO) << "Connection was succesful\n";
	running = true;
	while(running)
	{
		for (int i = 0; i < 20; i++) {
			// Read and send orientation data
			robot.GetOrientation_10(&roll, &pitch, &yaw);
			connection->SendOrientation(roll, pitch, yaw);

			// Read lidar data
			if (robot.IsLidarEnabled())
			{
				int dist = robot.ReadLidar();
				int tempDist = lastDistance;
				lastDistance = dist;
				if (lastDistance < BLOCK_DISTANCE && blockForward && christKindle == false) {
					if (robot.GetMotorLeftValue() > 0) {
						robot.MotorLeft(0, false);
					}
					if (robot.GetMotorRightValue() > 0) {
						robot.MotorRight(0, false);
					}
				}
				if (christKindle == true && lastDistance < 100) {
					robot.MotorLeft((100 - lastDistance) * (-1), false);
					robot.MotorRight((100 - lastDistance) * (-1), false);
				} else if (christKindle == true && lastDistance > 100 && tempDist < 100) {
					robot.MotorStop(false);
				}
				Debugger(INFO) << "Lidar distance: " << dist << "\n";
			}
			usleep(1000000 / 20);
		}
		connection->SendHeartBeat();

		// Check if we have received a heartbeat (or any other message) within a given timespan
		struct timeval tp;
		gettimeofday(&tp, NULL);
		long int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000;
		if (connection->GetLastMessageTime() + TIMEOUT_MS < ms)
		{
			break;
		}
	}
	connection->Disconnect();
	robot.MotorStop(true);
	CameraOff();
	return running;
}
Пример #10
0
void
BCMROMFN(aes_ccmp_cal_params)(struct dot11_header *h, bool legacy,
	uint8 nonce_1st_byte, uint8 *nonce, uint8 *aad, uint *la, uint *lh)
{
	uint8 *iv_data;
	uint16 fc, subtype;
	uint16 seq, qc = 0;
	uint addlen = 0;
	bool wds, qos;

	memset(nonce, 0, AES_CCMP_NONCE_LEN);
	memset(aad, 0, AES_CCMP_AAD_MAX_LEN);

	fc = ltoh16(h->fc);
	subtype = (fc & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT;
	wds = ((fc & (FC_TODS | FC_FROMDS)) == (FC_TODS | FC_FROMDS));
	/* all QoS subtypes have the FC_SUBTYPE_QOS_DATA bit set */
	qos = (FC_TYPE(fc) == FC_TYPE_DATA) && (subtype & FC_SUBTYPE_QOS_DATA);

	if (qos) {
		qc = ltoh16(*((uint16 *)((uchar *)h +
		                         (wds ? DOT11_A4_HDR_LEN : DOT11_A3_HDR_LEN))));
	}

	if (wds) {
		dbg(("aes_ccmp_cal_params: A4 present\n"));
		addlen += ETHER_ADDR_LEN;
	}
	if (qos) {
		dbg(("aes_ccmp_cal_params: QC present\n"));
		addlen += DOT11_QOS_LEN;
	}

	/* length of MPDU header, including IV */
	*lh = DOT11_A3_HDR_LEN + DOT11_IV_AES_CCM_LEN + addlen;
	/* length of AAD */
	*la = AES_CCMP_AAD_MIN_LEN + addlen;
	/* pointer to IV */
	iv_data = (uint8 *)h + DOT11_A3_HDR_LEN + addlen;

	*nonce++ = nonce_1st_byte;

	memcpy(nonce, (uchar *)&h->a2, ETHER_ADDR_LEN);
	nonce += ETHER_ADDR_LEN;

	/* PN[5] */
	*nonce++ = iv_data[7];
	/* PN[4] */
	*nonce++ = iv_data[6];
	/* PN[3] */
	*nonce++ = iv_data[5];
	/* PN[2] */
	*nonce++ = iv_data[4];
	/* PN[1] */
	*nonce++ = iv_data[1];
	/* PN[0] */
	*nonce++ = iv_data[0];

	pres("aes_ccmp_cal_params: nonce:", AES_CCM_NONCE_LEN, nonce - AES_CCM_NONCE_LEN);

	/* B1..B2 =  l(aad) || aad || pad(aad) */
	/* aad: maskedFC || A1 || A2 || A3 || maskedSC || A4 || maskedQC */

	if (!legacy) {
#ifdef MFP
		/* For a management frame, don't mask the the subtype bits */
		if (nonce_1st_byte & AES_CCMP_NF_MANAGEMENT)
			fc &= (FC_SUBTYPE_MASK | AES_CCMP_FC_MASK);
		else
#endif /* MFP */
			fc &= AES_CCMP_FC_MASK;
	} else {
		/* 802.11i Draft 3 inconsistencies:
		 * Clause 8.3.4.4.3: "FC - MPDU Frame Control field, with Retry bit masked
		 * to zero."  (8.3.4.4.3).
		 * Figure 29: "FC - MPDU Frame Control field, with Retry, MoreData, CF-ACK,
		 * CF-POLL bits masked to zero."
		 * F.10.4.1: "FC - MPDU Frame Control field, with Retry, MoreData,
		 * PwrMgmt bits masked to zero."
		 */

		/* Our implementation: match 8.3.4.4.3 */
		fc &= AES_CCMP_LEGACY_FC_MASK;
	}
	*aad++ = (uint8)(fc & 0xff);
	*aad++ = (uint8)((fc >> 8) & 0xff);

	memcpy(aad, (uchar *)&h->a1, 3*ETHER_ADDR_LEN);
	aad += 3*ETHER_ADDR_LEN;

	seq = ltoh16(h->seq);
	if (!legacy) {
		seq &= AES_CCMP_SEQ_MASK;
	} else {
		seq &= AES_CCMP_LEGACY_SEQ_MASK;
	}

	*aad++ = (uint8)(seq & 0xff);
	*aad++ = (uint8)((seq >> 8) & 0xff);

	if (wds) {
		memcpy(aad, (uchar *)&h->a4, ETHER_ADDR_LEN);
		aad += ETHER_ADDR_LEN;
	}
	if (qos) {
		if (!legacy) {
			/* 802.11i Draft 7.0 inconsistencies:
			 * Clause 8.3.3.3.2: "QC - The Quality of Service Control, a
			 * two-octet field that includes the MSDU priority, reserved
			 * for future use."
			 * I.7.4: TID portion of QoS
			 */

			/* Our implementation: match the test vectors */
			qc &= AES_CCMP_QOS_MASK;
			*aad++ = (uint8)(qc & 0xff);
			*aad++ = (uint8)((qc >> 8) & 0xff);
		} else {
Пример #11
0
int
BCMROMFN(aes_ccm_mac)(unsigned int *rk,
                      const size_t key_len,
                      const uint8 *nonce,
                      const size_t aad_len,
                      const uint8 *aad,
                      const size_t data_len,
                      const uint8 *ptxt,
                      uint8 *mac)
{
	uint8 B_0[AES_BLOCK_SZ], X[AES_BLOCK_SZ];
	size_t j, k;

	if (aad_len > AES_CCM_AAD_MAX_LEN) return (-1);

	pres("aes_ccm_mac: nonce:", AES_CCM_NONCE_LEN, nonce);
	pres("aes_ccm_mac: aad:", aad_len, aad);
	pres("aes_ccm_mac: input:", data_len, ptxt);

	/* B_0 = Flags || Nonce || l(m) */
	B_0[0] = AES_CCM_AUTH_FLAGS;
	if (aad_len)
		B_0[0] |= AES_CCM_AUTH_AAD_FLAG;
	memcpy(&B_0[1], nonce, AES_CCM_NONCE_LEN);
	B_0[AES_BLOCK_SZ - 2] = (uint8)(data_len >> 8) & 0xff;
	B_0[AES_BLOCK_SZ - 1] = (uint8)(data_len & 0xff);

	/* X_1 := E( K, B_0 ) */
	pres("aes_ccm_mac: CBC IV in:", AES_BLOCK_SZ, B_0);
	aes_block_encrypt((int)AES_ROUNDS(key_len), rk, B_0, X);
	pres("aes_ccm_mac: CBC IV out:", AES_BLOCK_SZ, X);

	/* X_i + 1 := E( K, X_i XOR B_i )  for i = 1, ..., n */

	/* first the AAD */
	if (aad_len) {
		pres("aes_ccm_mac: aad:", aad_len, aad);
		X[0] ^= (aad_len >> 8) & 0xff;
		X[1] ^= aad_len & 0xff;
		k = 2;
		j = aad_len;
		while (j--) {
			X[k] ^= *aad++;
			k++;
			if (k == AES_BLOCK_SZ) {
				pres("aes_ccm_mac: After xor (full block aad):", AES_BLOCK_SZ, X);
				aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
				pres("aes_ccm_mac: After AES (full block aad):", AES_BLOCK_SZ, X);
				k = 0;
			}
		}
		/* handle partial last block */
		if (k % AES_BLOCK_SZ) {
			pres("aes_ccm_mac: After xor (partial block aad):", AES_BLOCK_SZ, X);
			aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
			pres("aes_ccm_mac: After AES (partial block aad):", AES_BLOCK_SZ, X);
		}
	}

	/* then the message data */
	for (k = 0; k < (data_len / AES_BLOCK_SZ); k++) {
		xor_128bit_block(X, ptxt, X);
		pres("aes_ccm_mac: After xor (full block data):", AES_BLOCK_SZ, X);
		ptxt += AES_BLOCK_SZ;
		aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
		pres("aes_ccm_mac: After AES (full block data):", AES_BLOCK_SZ, X);
	}
	/* last block may be partial, padding is implicit in this xor */
	for (k = 0; k < (data_len % AES_BLOCK_SZ); k++)
		X[k] ^= *ptxt++;
	if (data_len % AES_BLOCK_SZ) {
		pres("aes_ccm_mac: After xor (final block data):", AES_BLOCK_SZ, X);
		aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
		pres("aes_ccm_mac: After AES (final block data):", AES_BLOCK_SZ, X);
	}

	/* T := first-M-bytes( X_n+1 ) */
	memcpy(mac, X, AES_CCM_AUTH_LEN);
	pres("aes_ccm_mac: MAC:", AES_CCM_AUTH_LEN, mac);

	return (0);
}
Пример #12
0
//
//      *  - type ... calgray, calrgb, cielab, icc, [palette]
//      *  - white   = x, z
//      *  - black   = x, y, z
//      *  - range   = amin, amax, bmin, bmax (cielab)
//      *  - gamma   = val [,val, val]        (calgray [,calrgb])
//      *  - matrix  = 9 vals                 (calrgb)
//      *  - profile = file-path              (icc based)
//      *  - name    = sRGB  .. some predefined name
IColorSpaceMan::cs_handle_pair_t
ColorSpaceManImpl::color_space_load(Char const* spec_str)
{
    ParseArgs pargs(&g_cs_kwds, &g_cs_names);
    ParsedResult pres(parse_options(spec_str, pargs));

    unsigned name = pres.explicit_value();
    if (name == ParsedResult::NO_EXPL_VALUE)
        throw exception_invalid_value(msg_invalid_cs_spec()) << JAGLOC;

    cs_str_spec_t spec(name, pres);
    cs_handle_pair_t result;

    switch (name)
    {
    case CSN_SRGB:
        result.first = register_icc_from_memory(binres::icc_srgb,
                                                binres::icc_srgb_size,
                                                3);
        break;

    case CSN_ADOBE_RGB:
        result.first = register_icc_from_memory(binres::icc_adobe_rgb,
                                                binres::icc_adobe_rgb_size,
                                                3);
        break;

    case CSN_BYID:
        if (!spec.id)
            throw exception_invalid_value(msg_invalid_cs_spec()) << JAGLOC;

        result.first = ColorSpaceHandle(
            handle_from_id<RESOURCE_COLOR_SPACE>(spec.id));
        break;

    case CSN_DEVICE_RGB:
        result.first = ColorSpaceHandle(CS_DEVICE_RGB);
        break;

    case CSN_DEVICE_GRAY:
        result.first = ColorSpaceHandle(CS_DEVICE_GRAY);
        break;

    case CSN_DEVICE_CMYK:
        result.first = ColorSpaceHandle(CS_DEVICE_CMYK);
        break;

    case CSN_CALGRAY:
    {
        intrusive_ptr<ICIECalGray> gray(define_calgray());
        set_cie_base(spec, *gray);
        if (!spec.gamma.empty())
            gray->gamma(spec.gamma[0]);

        result.first = color_space_load(gray);
        break;
    }

    case CSN_CALRGB:
    {
        intrusive_ptr<ICIECalRGB> rgb(define_calrgb());
        set_cie_base(spec, *rgb);
        if (!spec.gamma.empty())
        {
            JAG_ASSERT(spec.gamma.size()==3);
            rgb->gamma(spec.gamma[0], spec.gamma[1], spec.gamma[2]);
        }
        if (!spec.matrix.empty())
        {
            JAG_ASSERT(spec.matrix.size()==9);
            rgb->matrix(spec.matrix[0], spec.matrix[1], spec.matrix[2],
                        spec.matrix[3], spec.matrix[4], spec.matrix[5],
                        spec.matrix[6], spec.matrix[7], spec.matrix[8]);
        }
        result.first = color_space_load(rgb);
        break;
    }

    case CSN_CIELAB:
    {
        intrusive_ptr<ICIELab> lab(define_cielab());
        set_cie_base(spec, *lab);

        if (!spec.range.empty())
        {
            JAG_ASSERT(4 == spec.range.size());
            lab->range(spec.range[0], spec.range[1], spec.range[2], spec.range[3]);
        }
        result.first = color_space_load(lab);
        break;
    }

    case CSN_ICC:
    {
        if (-1==spec.components || spec.icc_profile.empty())
            throw exception_invalid_value(msg_invalid_cs_spec()) << JAGLOC;

        intrusive_ptr<IICCBased> icc(define_iccbased());
        icc->num_components(spec.components);
        icc->icc_profile(spec.icc_profile.c_str());
        result.first = color_space_load(icc);
        break;
    }


    default:
        ;
    } // switch


    JAG_ASSERT(is_valid(result.first));

    // is it palette?
    if (!spec.palette.empty())
    {
        intrusive_ptr<IPalette> indexed(define_indexed());
        indexed->set(
            id_from_handle<ColorSpace>(result.first),
            &spec.palette[0],
            static_cast<UInt>(spec.palette.size()));
        result.second = result.first;
        result.first = color_space_load(indexed);
    }

    return result;
}