char ConvertJSONEscape(const char **in) { int uc; char c = *++(*in); switch (c) { case 'u': { /* \u is a Unicode escape; 4 hex digits follow. */ const char* digits = *in + 1; *in += 4; uc = (digitToInt(digits[0]) << 12) | (digitToInt(digits[1]) << 8) | (digitToInt(digits[2]) << 4) | (digitToInt(digits[3])); if (uc > 127) fprintf(stderr, "CouchStore CollateJSON: Can't correctly compare \\u%.4s\n", digits); return (char)uc; } case 'b': return '\b'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; default: return c; } }
static char convertEscape(const char **in) { char c = *++(*in); switch (c) { case 'u': { // \u is a Unicode escape; 4 hex digits follow. const char* digits = *in + 1; *in += 4; int uc = (digitToInt(digits[0]) << 12) | (digitToInt(digits[1]) << 8) | (digitToInt(digits[2]) << 4) | (digitToInt(digits[3])); if (uc > 127) { // TODO: How/should we log unexpected characters? } return (char)uc; } case 'b': return '\b'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; default: return c; } }
ChessBoard* ChessBoard_new(const char* fen){ ChessBoard* board = (ChessBoard*)malloc(sizeof(ChessBoard)); if(strcmp(fen, FEN_START)==0) board->standard = 1; else board->standard = 0; board->extra = malloc(sizeof(GameInfo)); GameInfo* info = (GameInfo*)board->extra; info->capturedCount = 0; info->movesCount = 0; int i; for(i=0; i<64; i++) board->squares[i]=NULL; info->pieceSets[(int)WHITE] = ChessPieceSet_new(); info->pieceSets[(int)BLACK] = ChessPieceSet_new(); board->hash = 0; board->flags = 0; board->fiftyMoveCount = 0; //read FEN squares ChessPiece* piece; int rank=7, file=0; for(i=0;(rank!=0) || (file!=8);i++){ if(isDigit(fen[i])) file+=digitToInt(fen[i]); else if(fen[i]=='/'){ assert(file==8); rank--; file = 0; } else{ assert((rank&7)==rank); assert((file&7)==file); piece = __newPieceFromChar(fen[i], RANK_FILE(rank,file)); __addPiece(board, piece); file++; } } assert(fen[i]==' '); i++; //read FEN to-play flag if(fen[i]=='b'){ board->hash^=ZOBRIST_TABLE[ZOB_TO_PLAY]; board->flags^=TO_PLAY_FLAG; } else{ assert(fen[i]=='w'); } i++; assert(fen[i]==' '); i++; //read FEN castle flags while(fen[i]!=' '){ switch(fen[i]){ case 'K': board->hash^=ZOBRIST_TABLE[ZOB_WHITE_KING_CASTLE]; board->flags^=WHITE_KING_CASTLE_FLAG; break; case 'Q': board->hash^=ZOBRIST_TABLE[ZOB_WHITE_QUEEN_CASTLE]; board->flags^=WHITE_QUEEN_CASTLE_FLAG; break; case 'k': board->hash^=ZOBRIST_TABLE[ZOB_BLACK_KING_CASTLE]; board->flags^=BLACK_KING_CASTLE_FLAG; break; case 'q': board->hash^=ZOBRIST_TABLE[ZOB_BLACK_QUEEN_CASTLE]; board->flags^=BLACK_QUEEN_CASTLE_FLAG; break; case '-': break; default: assert(0); } i++; } assert(fen[i]==' '); i++; //read FEN en-passant flag if(fen[i]!='-'){ i++; //skip the rank assert(isDigit(fen[i])); __setEnPassantFlags(board, digitToInt(fen[i])); } //TODO implement and capture other FEN flags return board; }